diff options
author | thegeorg <thegeorg@yandex-team.ru> | 2022-02-10 16:45:08 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:08 +0300 |
commit | 4e839db24a3bbc9f1c610c43d6faaaa99824dcca (patch) | |
tree | 506dac10f5df94fab310584ee51b24fc5a081c22 /contrib/restricted | |
parent | 2d37894b1b037cf24231090eda8589bbb44fb6fc (diff) | |
download | ydb-4e839db24a3bbc9f1c610c43d6faaaa99824dcca.tar.gz |
Restoring authorship annotation for <thegeorg@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/restricted')
482 files changed, 22185 insertions, 22185 deletions
diff --git a/contrib/restricted/abseil-cpp-tstring/FAQ.md b/contrib/restricted/abseil-cpp-tstring/FAQ.md index fc2192a89e..f1a038ee6b 100644 --- a/contrib/restricted/abseil-cpp-tstring/FAQ.md +++ b/contrib/restricted/abseil-cpp-tstring/FAQ.md @@ -27,10 +27,10 @@ compiler, there several ways to do this: file](https://docs.bazel.build/versions/master/guide.html#bazelrc) If you are using CMake as the build system, you'll need to add a line like -`set(CMAKE_CXX_STANDARD 17)` to your top level `CMakeLists.txt` file. If you -are developing a library designed to be used by other clients, you should -instead leave `CMAKE_CXX_STANDARD` unset and configure the minimum C++ standard -required by each of your library targets via `target_compile_features`. See the +`set(CMAKE_CXX_STANDARD 17)` to your top level `CMakeLists.txt` file. If you +are developing a library designed to be used by other clients, you should +instead leave `CMAKE_CXX_STANDARD` unset and configure the minimum C++ standard +required by each of your library targets via `target_compile_features`. See the [CMake build instructions](https://github.com/abseil/abseil-cpp/blob/master/CMake/README.md) for more information. diff --git a/contrib/restricted/abseil-cpp-tstring/README.md b/contrib/restricted/abseil-cpp-tstring/README.md index a63901a422..251ace7370 100644 --- a/contrib/restricted/abseil-cpp-tstring/README.md +++ b/contrib/restricted/abseil-cpp-tstring/README.md @@ -92,9 +92,9 @@ Abseil contains the following C++ library components: available within C++14 and C++17 versions of the C++ `<type_traits>` library. * [`numeric`](y_absl/numeric/) <br /> The `numeric` library contains C++11-compatible 128-bit integers. -* [`profiling`](y_absl/profiling/) - <br /> The `profiling` library contains utility code for profiling C++ - entities. It is currently a private dependency of other Abseil libraries. +* [`profiling`](y_absl/profiling/) + <br /> The `profiling` library contains utility code for profiling C++ + entities. It is currently a private dependency of other Abseil libraries. * [`status`](y_absl/status/) <br /> The `status` contains abstractions for error handling, specifically `y_absl::Status` and `y_absl::StatusOr<T>`. diff --git a/contrib/restricted/abseil-cpp-tstring/provides.pbtxt b/contrib/restricted/abseil-cpp-tstring/provides.pbtxt index 34db641a55..63baa23427 100644 --- a/contrib/restricted/abseil-cpp-tstring/provides.pbtxt +++ b/contrib/restricted/abseil-cpp-tstring/provides.pbtxt @@ -1,66 +1,66 @@ -p { i: "abseil-cpp" x: "absl_bad_any_cast_impl" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_any_cast" } -p { i: "abseil-cpp" x: "absl_bad_optional_access" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_optional_access" } -p { i: "abseil-cpp" x: "absl_bad_variant_access" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_variant_access" } -p { i: "abseil-cpp" x: "absl_base" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/base" } -p { i: "abseil-cpp" x: "absl_city" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/city" } -p { i: "abseil-cpp" x: "absl_civil_time" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time" } -p { i: "abseil-cpp" x: "absl_cord" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord" } -p { i: "abseil-cpp" x: "absl_cord_internal" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_cord_internal" } -p { i: "abseil-cpp" x: "absl_cordz_functions" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions" } -p { i: "abseil-cpp" x: "absl_cordz_handle" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle" } -p { i: "abseil-cpp" x: "absl_cordz_info" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info" } -p { i: "abseil-cpp" x: "absl_cordz_sample_token" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_sample_token" } -p { i: "abseil-cpp" x: "absl_debugging_internal" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/debugging" } -p { i: "abseil-cpp" x: "absl_demangle_internal" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/demangle" } -p { i: "abseil-cpp" x: "absl_examine_stack" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal" } -p { i: "abseil-cpp" x: "absl_exponential_biased" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased" } -p { i: "abseil-cpp" x: "absl_failure_signal_handler" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/debugging/failure_signal_handler" } -p { i: "abseil-cpp" x: "absl_flags" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/flags" } +p { i: "abseil-cpp" x: "absl_bad_any_cast_impl" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_any_cast" } +p { i: "abseil-cpp" x: "absl_bad_optional_access" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_optional_access" } +p { i: "abseil-cpp" x: "absl_bad_variant_access" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_variant_access" } +p { i: "abseil-cpp" x: "absl_base" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/base" } +p { i: "abseil-cpp" x: "absl_city" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/city" } +p { i: "abseil-cpp" x: "absl_civil_time" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time" } +p { i: "abseil-cpp" x: "absl_cord" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord" } +p { i: "abseil-cpp" x: "absl_cord_internal" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_cord_internal" } +p { i: "abseil-cpp" x: "absl_cordz_functions" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions" } +p { i: "abseil-cpp" x: "absl_cordz_handle" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle" } +p { i: "abseil-cpp" x: "absl_cordz_info" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info" } +p { i: "abseil-cpp" x: "absl_cordz_sample_token" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_sample_token" } +p { i: "abseil-cpp" x: "absl_debugging_internal" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/debugging" } +p { i: "abseil-cpp" x: "absl_demangle_internal" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/demangle" } +p { i: "abseil-cpp" x: "absl_examine_stack" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal" } +p { i: "abseil-cpp" x: "absl_exponential_biased" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased" } +p { i: "abseil-cpp" x: "absl_failure_signal_handler" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/debugging/failure_signal_handler" } +p { i: "abseil-cpp" x: "absl_flags" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/flags" } p { i: "abseil-cpp" x: "absl_flags_commandlineflag" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/flags/commandlineflag" } p { i: "abseil-cpp" x: "absl_flags_commandlineflag_internal" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/flags/internal/commandlineflag" } -p { i: "abseil-cpp" x: "absl_flags_config" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/flags/usage_config" } -p { i: "abseil-cpp" x: "absl_flags_internal" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/flags/internal/flag" } -p { i: "abseil-cpp" x: "absl_flags_marshalling" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/flags/marshalling" } -p { i: "abseil-cpp" x: "absl_flags_parse" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/flags/parse" } +p { i: "abseil-cpp" x: "absl_flags_config" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/flags/usage_config" } +p { i: "abseil-cpp" x: "absl_flags_internal" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/flags/internal/flag" } +p { i: "abseil-cpp" x: "absl_flags_marshalling" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/flags/marshalling" } +p { i: "abseil-cpp" x: "absl_flags_parse" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/flags/parse" } p { i: "abseil-cpp" x: "absl_flags_private_handle_accessor" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/flags/internal/private_handle_accessor" } -p { i: "abseil-cpp" x: "absl_flags_program_name" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/flags/internal/program_name" } +p { i: "abseil-cpp" x: "absl_flags_program_name" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/flags/internal/program_name" } p { i: "abseil-cpp" x: "absl_flags_reflection" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/flags/reflection" } -p { i: "abseil-cpp" x: "absl_flags_usage" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/flags/usage" } -p { i: "abseil-cpp" x: "absl_flags_usage_internal" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/flags/internal/usage" } -p { i: "abseil-cpp" x: "absl_graphcycles_internal" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal" } -p { i: "abseil-cpp" x: "absl_hash" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/hash" } -p { i: "abseil-cpp" x: "absl_hashtablez_sampler" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/absl_hashtablez_sampler" } -p { i: "abseil-cpp" x: "absl_int128" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/numeric" } -p { i: "abseil-cpp" x: "absl_leak_check" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/debugging/leak_check" } -p { i: "abseil-cpp" x: "absl_leak_check_disable" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/debugging/leak_check_disable" } -p { i: "abseil-cpp" x: "absl_log_severity" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity" } -p { i: "abseil-cpp" x: "absl_low_level_hash" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal" } -p { i: "abseil-cpp" x: "absl_malloc_internal" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/low_level_alloc" } -p { i: "abseil-cpp" x: "absl_periodic_sampler" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/periodic_sampler" } -p { i: "abseil-cpp" x: "absl_random_distributions" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/random/absl_random_distributions" } -p { i: "abseil-cpp" x: "absl_random_internal_distribution_test_util" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/random/internal/absl_random_internal_distribution_test_util" } +p { i: "abseil-cpp" x: "absl_flags_usage" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/flags/usage" } +p { i: "abseil-cpp" x: "absl_flags_usage_internal" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/flags/internal/usage" } +p { i: "abseil-cpp" x: "absl_graphcycles_internal" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal" } +p { i: "abseil-cpp" x: "absl_hash" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/hash" } +p { i: "abseil-cpp" x: "absl_hashtablez_sampler" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/absl_hashtablez_sampler" } +p { i: "abseil-cpp" x: "absl_int128" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/numeric" } +p { i: "abseil-cpp" x: "absl_leak_check" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/debugging/leak_check" } +p { i: "abseil-cpp" x: "absl_leak_check_disable" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/debugging/leak_check_disable" } +p { i: "abseil-cpp" x: "absl_log_severity" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity" } +p { i: "abseil-cpp" x: "absl_low_level_hash" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal" } +p { i: "abseil-cpp" x: "absl_malloc_internal" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/low_level_alloc" } +p { i: "abseil-cpp" x: "absl_periodic_sampler" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/periodic_sampler" } +p { i: "abseil-cpp" x: "absl_random_distributions" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/random/absl_random_distributions" } +p { i: "abseil-cpp" x: "absl_random_internal_distribution_test_util" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/random/internal/absl_random_internal_distribution_test_util" } p { i: "abseil-cpp" x: "absl_random_internal_platform" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/random/internal/randen_round_keys" } -p { i: "abseil-cpp" x: "absl_random_internal_pool_urbg" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/random/internal/pool_urbg" } -p { i: "abseil-cpp" x: "absl_random_internal_randen" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/random/internal/randen" } -p { i: "abseil-cpp" x: "absl_random_internal_randen_hwaes" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/random/internal/randen_detect" } -p { i: "abseil-cpp" x: "absl_random_internal_randen_hwaes_impl" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/random/internal/randen_hwaes" } -p { i: "abseil-cpp" x: "absl_random_internal_randen_slow" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/random/internal/randen_slow" } -p { i: "abseil-cpp" x: "absl_random_internal_seed_material" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/random/internal/seed_material" } -p { i: "abseil-cpp" x: "absl_random_seed_gen_exception" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/random/seed_gen_exception" } -p { i: "abseil-cpp" x: "absl_random_seed_sequences" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/random/seed_sequences" } -p { i: "abseil-cpp" x: "absl_raw_hash_set" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/raw_hash_set" } -p { i: "abseil-cpp" x: "absl_raw_logging_internal" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/raw_logging" } -p { i: "abseil-cpp" x: "absl_scoped_set_env" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/scoped_set_env" } -p { i: "abseil-cpp" x: "absl_spinlock_wait" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock_wait" } -p { i: "abseil-cpp" x: "absl_stacktrace" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace" } -p { i: "abseil-cpp" x: "absl_status" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/status" } +p { i: "abseil-cpp" x: "absl_random_internal_pool_urbg" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/random/internal/pool_urbg" } +p { i: "abseil-cpp" x: "absl_random_internal_randen" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/random/internal/randen" } +p { i: "abseil-cpp" x: "absl_random_internal_randen_hwaes" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/random/internal/randen_detect" } +p { i: "abseil-cpp" x: "absl_random_internal_randen_hwaes_impl" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/random/internal/randen_hwaes" } +p { i: "abseil-cpp" x: "absl_random_internal_randen_slow" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/random/internal/randen_slow" } +p { i: "abseil-cpp" x: "absl_random_internal_seed_material" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/random/internal/seed_material" } +p { i: "abseil-cpp" x: "absl_random_seed_gen_exception" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/random/seed_gen_exception" } +p { i: "abseil-cpp" x: "absl_random_seed_sequences" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/random/seed_sequences" } +p { i: "abseil-cpp" x: "absl_raw_hash_set" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/raw_hash_set" } +p { i: "abseil-cpp" x: "absl_raw_logging_internal" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/raw_logging" } +p { i: "abseil-cpp" x: "absl_scoped_set_env" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/scoped_set_env" } +p { i: "abseil-cpp" x: "absl_spinlock_wait" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock_wait" } +p { i: "abseil-cpp" x: "absl_stacktrace" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace" } +p { i: "abseil-cpp" x: "absl_status" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/status" } p { i: "abseil-cpp" x: "absl_statusor" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/status/statusor" } -p { i: "abseil-cpp" x: "absl_str_format_internal" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format" } +p { i: "abseil-cpp" x: "absl_str_format_internal" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format" } p { i: "abseil-cpp" x: "absl_strerror" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/strerror" } -p { i: "abseil-cpp" x: "absl_strings" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/strings" } -p { i: "abseil-cpp" x: "absl_strings_internal" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal" } -p { i: "abseil-cpp" x: "absl_symbolize" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize" } -p { i: "abseil-cpp" x: "absl_synchronization" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/synchronization" } -p { i: "abseil-cpp" x: "absl_throw_delegate" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/throw_delegate" } -p { i: "abseil-cpp" x: "absl_time" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/time" } -p { i: "abseil-cpp" x: "absl_time_zone" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone" } +p { i: "abseil-cpp" x: "absl_strings" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/strings" } +p { i: "abseil-cpp" x: "absl_strings_internal" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal" } +p { i: "abseil-cpp" x: "absl_symbolize" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize" } +p { i: "abseil-cpp" x: "absl_synchronization" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/synchronization" } +p { i: "abseil-cpp" x: "absl_throw_delegate" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/throw_delegate" } +p { i: "abseil-cpp" x: "absl_time" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/time" } +p { i: "abseil-cpp" x: "absl_time_zone" ix: true peerdir: "contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone" } diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/algorithm/container.h b/contrib/restricted/abseil-cpp-tstring/y_absl/algorithm/container.h index d6bf385964..b9cbce0a17 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/algorithm/container.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/algorithm/container.h @@ -905,11 +905,11 @@ void c_sort(C& c) { // Overload of c_sort() for performing a `comp` comparison other than the // default `operator<`. -template <typename C, typename LessThan> -void c_sort(C& c, LessThan&& comp) { +template <typename C, typename LessThan> +void c_sort(C& c, LessThan&& comp) { std::sort(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_stable_sort() @@ -925,11 +925,11 @@ void c_stable_sort(C& c) { // Overload of c_stable_sort() for performing a `comp` comparison other than the // default `operator<`. -template <typename C, typename LessThan> -void c_stable_sort(C& c, LessThan&& comp) { +template <typename C, typename LessThan> +void c_stable_sort(C& c, LessThan&& comp) { std::stable_sort(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_is_sorted() @@ -944,11 +944,11 @@ bool c_is_sorted(const C& c) { // c_is_sorted() overload for performing a `comp` comparison other than the // default `operator<`. -template <typename C, typename LessThan> -bool c_is_sorted(const C& c, LessThan&& comp) { +template <typename C, typename LessThan> +bool c_is_sorted(const C& c, LessThan&& comp) { return std::is_sorted(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_partial_sort() @@ -966,14 +966,14 @@ void c_partial_sort( // Overload of c_partial_sort() for performing a `comp` comparison other than // the default `operator<`. -template <typename RandomAccessContainer, typename LessThan> +template <typename RandomAccessContainer, typename LessThan> void c_partial_sort( RandomAccessContainer& sequence, container_algorithm_internal::ContainerIter<RandomAccessContainer> middle, - LessThan&& comp) { + LessThan&& comp) { std::partial_sort(container_algorithm_internal::c_begin(sequence), middle, container_algorithm_internal::c_end(sequence), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_partial_sort_copy() @@ -994,15 +994,15 @@ c_partial_sort_copy(const C& sequence, RandomAccessContainer& result) { // Overload of c_partial_sort_copy() for performing a `comp` comparison other // than the default `operator<`. -template <typename C, typename RandomAccessContainer, typename LessThan> +template <typename C, typename RandomAccessContainer, typename LessThan> container_algorithm_internal::ContainerIter<RandomAccessContainer> c_partial_sort_copy(const C& sequence, RandomAccessContainer& result, - LessThan&& comp) { + LessThan&& comp) { return std::partial_sort_copy(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), container_algorithm_internal::c_begin(result), container_algorithm_internal::c_end(result), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_is_sorted_until() @@ -1018,12 +1018,12 @@ container_algorithm_internal::ContainerIter<C> c_is_sorted_until(C& c) { // Overload of c_is_sorted_until() for performing a `comp` comparison other than // the default `operator<`. -template <typename C, typename LessThan> +template <typename C, typename LessThan> container_algorithm_internal::ContainerIter<C> c_is_sorted_until( - C& c, LessThan&& comp) { + C& c, LessThan&& comp) { return std::is_sorted_until(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_nth_element() @@ -1043,14 +1043,14 @@ void c_nth_element( // Overload of c_nth_element() for performing a `comp` comparison other than // the default `operator<`. -template <typename RandomAccessContainer, typename LessThan> +template <typename RandomAccessContainer, typename LessThan> void c_nth_element( RandomAccessContainer& sequence, container_algorithm_internal::ContainerIter<RandomAccessContainer> nth, - LessThan&& comp) { + LessThan&& comp) { std::nth_element(container_algorithm_internal::c_begin(sequence), nth, container_algorithm_internal::c_end(sequence), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } //------------------------------------------------------------------------------ @@ -1072,12 +1072,12 @@ container_algorithm_internal::ContainerIter<Sequence> c_lower_bound( // Overload of c_lower_bound() for performing a `comp` comparison other than // the default `operator<`. -template <typename Sequence, typename T, typename LessThan> +template <typename Sequence, typename T, typename LessThan> container_algorithm_internal::ContainerIter<Sequence> c_lower_bound( - Sequence& sequence, T&& value, LessThan&& comp) { + Sequence& sequence, T&& value, LessThan&& comp) { return std::lower_bound(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<T>(value), std::forward<LessThan>(comp)); + std::forward<T>(value), std::forward<LessThan>(comp)); } // c_upper_bound() @@ -1095,12 +1095,12 @@ container_algorithm_internal::ContainerIter<Sequence> c_upper_bound( // Overload of c_upper_bound() for performing a `comp` comparison other than // the default `operator<`. -template <typename Sequence, typename T, typename LessThan> +template <typename Sequence, typename T, typename LessThan> container_algorithm_internal::ContainerIter<Sequence> c_upper_bound( - Sequence& sequence, T&& value, LessThan&& comp) { + Sequence& sequence, T&& value, LessThan&& comp) { return std::upper_bound(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<T>(value), std::forward<LessThan>(comp)); + std::forward<T>(value), std::forward<LessThan>(comp)); } // c_equal_range() @@ -1118,12 +1118,12 @@ c_equal_range(Sequence& sequence, T&& value) { // Overload of c_equal_range() for performing a `comp` comparison other than // the default `operator<`. -template <typename Sequence, typename T, typename LessThan> +template <typename Sequence, typename T, typename LessThan> container_algorithm_internal::ContainerIterPairType<Sequence, Sequence> -c_equal_range(Sequence& sequence, T&& value, LessThan&& comp) { +c_equal_range(Sequence& sequence, T&& value, LessThan&& comp) { return std::equal_range(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<T>(value), std::forward<LessThan>(comp)); + std::forward<T>(value), std::forward<LessThan>(comp)); } // c_binary_search() @@ -1140,12 +1140,12 @@ bool c_binary_search(Sequence&& sequence, T&& value) { // Overload of c_binary_search() for performing a `comp` comparison other than // the default `operator<`. -template <typename Sequence, typename T, typename LessThan> -bool c_binary_search(Sequence&& sequence, T&& value, LessThan&& comp) { +template <typename Sequence, typename T, typename LessThan> +bool c_binary_search(Sequence&& sequence, T&& value, LessThan&& comp) { return std::binary_search(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<T>(value), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } //------------------------------------------------------------------------------ @@ -1166,14 +1166,14 @@ OutputIterator c_merge(const C1& c1, const C2& c2, OutputIterator result) { // Overload of c_merge() for performing a `comp` comparison other than // the default `operator<`. -template <typename C1, typename C2, typename OutputIterator, typename LessThan> +template <typename C1, typename C2, typename OutputIterator, typename LessThan> OutputIterator c_merge(const C1& c1, const C2& c2, OutputIterator result, - LessThan&& comp) { + LessThan&& comp) { return std::merge(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2), result, - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_inplace_merge() @@ -1189,13 +1189,13 @@ void c_inplace_merge(C& c, // Overload of c_inplace_merge() for performing a merge using a `comp` other // than `operator<`. -template <typename C, typename LessThan> +template <typename C, typename LessThan> void c_inplace_merge(C& c, container_algorithm_internal::ContainerIter<C> middle, - LessThan&& comp) { + LessThan&& comp) { std::inplace_merge(container_algorithm_internal::c_begin(c), middle, container_algorithm_internal::c_end(c), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_includes() @@ -1213,13 +1213,13 @@ bool c_includes(const C1& c1, const C2& c2) { // Overload of c_includes() for performing a merge using a `comp` other than // `operator<`. -template <typename C1, typename C2, typename LessThan> -bool c_includes(const C1& c1, const C2& c2, LessThan&& comp) { +template <typename C1, typename C2, typename LessThan> +bool c_includes(const C1& c1, const C2& c2, LessThan&& comp) { return std::includes(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_set_union() @@ -1243,7 +1243,7 @@ OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output) { // Overload of c_set_union() for performing a merge using a `comp` other than // `operator<`. -template <typename C1, typename C2, typename OutputIterator, typename LessThan, +template <typename C1, typename C2, typename OutputIterator, typename LessThan, typename = typename std::enable_if< !container_algorithm_internal::IsUnorderedContainer<C1>::value, void>::type, @@ -1251,18 +1251,18 @@ template <typename C1, typename C2, typename OutputIterator, typename LessThan, !container_algorithm_internal::IsUnorderedContainer<C2>::value, void>::type> OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output, - LessThan&& comp) { + LessThan&& comp) { return std::set_union(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2), output, - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_set_intersection() // // Container-based version of the <algorithm> `std::set_intersection()` function -// to return an iterator containing the intersection of two sorted containers. +// to return an iterator containing the intersection of two sorted containers. template <typename C1, typename C2, typename OutputIterator, typename = typename std::enable_if< !container_algorithm_internal::IsUnorderedContainer<C1>::value, @@ -1272,11 +1272,11 @@ template <typename C1, typename C2, typename OutputIterator, void>::type> OutputIterator c_set_intersection(const C1& c1, const C2& c2, OutputIterator output) { - // In debug builds, ensure that both containers are sorted with respect to the - // default comparator. std::set_intersection requires the containers be sorted - // using operator<. - assert(y_absl::c_is_sorted(c1)); - assert(y_absl::c_is_sorted(c2)); + // In debug builds, ensure that both containers are sorted with respect to the + // default comparator. std::set_intersection requires the containers be sorted + // using operator<. + assert(y_absl::c_is_sorted(c1)); + assert(y_absl::c_is_sorted(c2)); return std::set_intersection(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), @@ -1285,7 +1285,7 @@ OutputIterator c_set_intersection(const C1& c1, const C2& c2, // Overload of c_set_intersection() for performing a merge using a `comp` other // than `operator<`. -template <typename C1, typename C2, typename OutputIterator, typename LessThan, +template <typename C1, typename C2, typename OutputIterator, typename LessThan, typename = typename std::enable_if< !container_algorithm_internal::IsUnorderedContainer<C1>::value, void>::type, @@ -1293,17 +1293,17 @@ template <typename C1, typename C2, typename OutputIterator, typename LessThan, !container_algorithm_internal::IsUnorderedContainer<C2>::value, void>::type> OutputIterator c_set_intersection(const C1& c1, const C2& c2, - OutputIterator output, LessThan&& comp) { - // In debug builds, ensure that both containers are sorted with respect to the - // default comparator. std::set_intersection requires the containers be sorted - // using the same comparator. - assert(y_absl::c_is_sorted(c1, comp)); - assert(y_absl::c_is_sorted(c2, comp)); + OutputIterator output, LessThan&& comp) { + // In debug builds, ensure that both containers are sorted with respect to the + // default comparator. std::set_intersection requires the containers be sorted + // using the same comparator. + assert(y_absl::c_is_sorted(c1, comp)); + assert(y_absl::c_is_sorted(c2, comp)); return std::set_intersection(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2), output, - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_set_difference() @@ -1328,7 +1328,7 @@ OutputIterator c_set_difference(const C1& c1, const C2& c2, // Overload of c_set_difference() for performing a merge using a `comp` other // than `operator<`. -template <typename C1, typename C2, typename OutputIterator, typename LessThan, +template <typename C1, typename C2, typename OutputIterator, typename LessThan, typename = typename std::enable_if< !container_algorithm_internal::IsUnorderedContainer<C1>::value, void>::type, @@ -1336,12 +1336,12 @@ template <typename C1, typename C2, typename OutputIterator, typename LessThan, !container_algorithm_internal::IsUnorderedContainer<C2>::value, void>::type> OutputIterator c_set_difference(const C1& c1, const C2& c2, - OutputIterator output, LessThan&& comp) { + OutputIterator output, LessThan&& comp) { return std::set_difference(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2), output, - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_set_symmetric_difference() @@ -1367,7 +1367,7 @@ OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2, // Overload of c_set_symmetric_difference() for performing a merge using a // `comp` other than `operator<`. -template <typename C1, typename C2, typename OutputIterator, typename LessThan, +template <typename C1, typename C2, typename OutputIterator, typename LessThan, typename = typename std::enable_if< !container_algorithm_internal::IsUnorderedContainer<C1>::value, void>::type, @@ -1376,13 +1376,13 @@ template <typename C1, typename C2, typename OutputIterator, typename LessThan, void>::type> OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2, OutputIterator output, - LessThan&& comp) { + LessThan&& comp) { return std::set_symmetric_difference( container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2), output, - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } //------------------------------------------------------------------------------ @@ -1401,11 +1401,11 @@ void c_push_heap(RandomAccessContainer& sequence) { // Overload of c_push_heap() for performing a push operation on a heap using a // `comp` other than `operator<`. -template <typename RandomAccessContainer, typename LessThan> -void c_push_heap(RandomAccessContainer& sequence, LessThan&& comp) { +template <typename RandomAccessContainer, typename LessThan> +void c_push_heap(RandomAccessContainer& sequence, LessThan&& comp) { std::push_heap(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_pop_heap() @@ -1420,11 +1420,11 @@ void c_pop_heap(RandomAccessContainer& sequence) { // Overload of c_pop_heap() for performing a pop operation on a heap using a // `comp` other than `operator<`. -template <typename RandomAccessContainer, typename LessThan> -void c_pop_heap(RandomAccessContainer& sequence, LessThan&& comp) { +template <typename RandomAccessContainer, typename LessThan> +void c_pop_heap(RandomAccessContainer& sequence, LessThan&& comp) { std::pop_heap(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_make_heap() @@ -1439,11 +1439,11 @@ void c_make_heap(RandomAccessContainer& sequence) { // Overload of c_make_heap() for performing heap comparisons using a // `comp` other than `operator<` -template <typename RandomAccessContainer, typename LessThan> -void c_make_heap(RandomAccessContainer& sequence, LessThan&& comp) { +template <typename RandomAccessContainer, typename LessThan> +void c_make_heap(RandomAccessContainer& sequence, LessThan&& comp) { std::make_heap(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_sort_heap() @@ -1458,11 +1458,11 @@ void c_sort_heap(RandomAccessContainer& sequence) { // Overload of c_sort_heap() for performing heap comparisons using a // `comp` other than `operator<` -template <typename RandomAccessContainer, typename LessThan> -void c_sort_heap(RandomAccessContainer& sequence, LessThan&& comp) { +template <typename RandomAccessContainer, typename LessThan> +void c_sort_heap(RandomAccessContainer& sequence, LessThan&& comp) { std::sort_heap(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_is_heap() @@ -1477,11 +1477,11 @@ bool c_is_heap(const RandomAccessContainer& sequence) { // Overload of c_is_heap() for performing heap comparisons using a // `comp` other than `operator<` -template <typename RandomAccessContainer, typename LessThan> -bool c_is_heap(const RandomAccessContainer& sequence, LessThan&& comp) { +template <typename RandomAccessContainer, typename LessThan> +bool c_is_heap(const RandomAccessContainer& sequence, LessThan&& comp) { return std::is_heap(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_is_heap_until() @@ -1497,12 +1497,12 @@ c_is_heap_until(RandomAccessContainer& sequence) { // Overload of c_is_heap_until() for performing heap comparisons using a // `comp` other than `operator<` -template <typename RandomAccessContainer, typename LessThan> +template <typename RandomAccessContainer, typename LessThan> container_algorithm_internal::ContainerIter<RandomAccessContainer> -c_is_heap_until(RandomAccessContainer& sequence, LessThan&& comp) { +c_is_heap_until(RandomAccessContainer& sequence, LessThan&& comp) { return std::is_heap_until(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } //------------------------------------------------------------------------------ @@ -1523,12 +1523,12 @@ container_algorithm_internal::ContainerIter<Sequence> c_min_element( // Overload of c_min_element() for performing a `comp` comparison other than // `operator<`. -template <typename Sequence, typename LessThan> +template <typename Sequence, typename LessThan> container_algorithm_internal::ContainerIter<Sequence> c_min_element( - Sequence& sequence, LessThan&& comp) { + Sequence& sequence, LessThan&& comp) { return std::min_element(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_max_element() @@ -1545,12 +1545,12 @@ container_algorithm_internal::ContainerIter<Sequence> c_max_element( // Overload of c_max_element() for performing a `comp` comparison other than // `operator<`. -template <typename Sequence, typename LessThan> +template <typename Sequence, typename LessThan> container_algorithm_internal::ContainerIter<Sequence> c_max_element( - Sequence& sequence, LessThan&& comp) { + Sequence& sequence, LessThan&& comp) { return std::max_element(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_minmax_element() @@ -1568,12 +1568,12 @@ c_minmax_element(C& c) { // Overload of c_minmax_element() for performing `comp` comparisons other than // `operator<`. -template <typename C, typename LessThan> +template <typename C, typename LessThan> container_algorithm_internal::ContainerIterPairType<C, C> -c_minmax_element(C& c, LessThan&& comp) { +c_minmax_element(C& c, LessThan&& comp) { return std::minmax_element(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } //------------------------------------------------------------------------------ @@ -1598,15 +1598,15 @@ bool c_lexicographical_compare(Sequence1&& sequence1, Sequence2&& sequence2) { // Overload of c_lexicographical_compare() for performing a lexicographical // comparison using a `comp` operator instead of `operator<`. -template <typename Sequence1, typename Sequence2, typename LessThan> +template <typename Sequence1, typename Sequence2, typename LessThan> bool c_lexicographical_compare(Sequence1&& sequence1, Sequence2&& sequence2, - LessThan&& comp) { + LessThan&& comp) { return std::lexicographical_compare( container_algorithm_internal::c_begin(sequence1), container_algorithm_internal::c_end(sequence1), container_algorithm_internal::c_begin(sequence2), container_algorithm_internal::c_end(sequence2), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_next_permutation() @@ -1622,11 +1622,11 @@ bool c_next_permutation(C& c) { // Overload of c_next_permutation() for performing a lexicographical // comparison using a `comp` operator instead of `operator<`. -template <typename C, typename LessThan> -bool c_next_permutation(C& c, LessThan&& comp) { +template <typename C, typename LessThan> +bool c_next_permutation(C& c, LessThan&& comp) { return std::next_permutation(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_prev_permutation() @@ -1642,11 +1642,11 @@ bool c_prev_permutation(C& c) { // Overload of c_prev_permutation() for performing a lexicographical // comparison using a `comp` operator instead of `operator<`. -template <typename C, typename LessThan> -bool c_prev_permutation(C& c, LessThan&& comp) { +template <typename C, typename LessThan> +bool c_prev_permutation(C& c, LessThan&& comp) { return std::prev_permutation(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } //------------------------------------------------------------------------------ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/base/attributes.h b/contrib/restricted/abseil-cpp-tstring/y_absl/base/attributes.h index 8321acda51..ffdd4cffc0 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/base/attributes.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/base/attributes.h @@ -131,14 +131,14 @@ // ABSL_ATTRIBUTE_WEAK // // Tags a function as weak for the purposes of compilation and linking. -// Weak attributes did not work properly in LLVM's Windows backend before -// 9.0.0, so disable them there. See https://bugs.llvm.org/show_bug.cgi?id=37598 +// Weak attributes did not work properly in LLVM's Windows backend before +// 9.0.0, so disable them there. See https://bugs.llvm.org/show_bug.cgi?id=37598 // for further information. // The MinGW compiler doesn't complain about the weak attribute until the link // step, presumably because Windows doesn't use ELF binaries. #if (ABSL_HAVE_ATTRIBUTE(weak) || \ (defined(__GNUC__) && !defined(__clang__))) && \ - (!defined(_WIN32) || __clang_major__ < 9) && !defined(__MINGW32__) + (!defined(_WIN32) || __clang_major__ < 9) && !defined(__MINGW32__) #undef ABSL_ATTRIBUTE_WEAK #define ABSL_ATTRIBUTE_WEAK __attribute__((weak)) #define ABSL_HAVE_ATTRIBUTE_WEAK 1 @@ -281,7 +281,7 @@ // ABSL_ATTRIBUTE_RETURNS_NONNULL // // Tells the compiler that a particular function never returns a null pointer. -#if ABSL_HAVE_ATTRIBUTE(returns_nonnull) +#if ABSL_HAVE_ATTRIBUTE(returns_nonnull) #define ABSL_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull)) #else #define ABSL_ATTRIBUTE_RETURNS_NONNULL @@ -318,16 +318,16 @@ // `__start_ ## name` and `__stop_ ## name` symbols to bracket the section. // This functionality is supported by GNU linker. #ifndef ABSL_ATTRIBUTE_SECTION_VARIABLE -#ifdef _AIX -// __attribute__((section(#name))) on AIX is achived by using the `.csect` psudo -// op which includes an additional integer as part of its syntax indcating -// alignment. If data fall under different alignments then you might get a -// compilation error indicating a `Section type conflict`. -#define ABSL_ATTRIBUTE_SECTION_VARIABLE(name) -#else +#ifdef _AIX +// __attribute__((section(#name))) on AIX is achived by using the `.csect` psudo +// op which includes an additional integer as part of its syntax indcating +// alignment. If data fall under different alignments then you might get a +// compilation error indicating a `Section type conflict`. +#define ABSL_ATTRIBUTE_SECTION_VARIABLE(name) +#else #define ABSL_ATTRIBUTE_SECTION_VARIABLE(name) __attribute__((section(#name))) #endif -#endif +#endif // ABSL_DECLARE_ATTRIBUTE_SECTION_VARS // @@ -529,13 +529,13 @@ // ABSL_ATTRIBUTE_UNUSED // // Prevents the compiler from complaining about variables that appear unused. -// -// For code or headers that are assured to only build with C++17 and up, prefer -// just using the standard '[[maybe_unused]]' directly over this macro. -// -// Due to differences in positioning requirements between the old, compiler -// specific __attribute__ syntax and the now standard [[maybe_unused]], this -// macro does not attempt to take advantage of '[[maybe_unused]]'. +// +// For code or headers that are assured to only build with C++17 and up, prefer +// just using the standard '[[maybe_unused]]' directly over this macro. +// +// Due to differences in positioning requirements between the old, compiler +// specific __attribute__ syntax and the now standard [[maybe_unused]], this +// macro does not attempt to take advantage of '[[maybe_unused]]'. #if ABSL_HAVE_ATTRIBUTE(unused) || (defined(__GNUC__) && !defined(__clang__)) #undef ABSL_ATTRIBUTE_UNUSED #define ABSL_ATTRIBUTE_UNUSED __attribute__((__unused__)) @@ -556,20 +556,20 @@ // ABSL_ATTRIBUTE_PACKED // // Instructs the compiler not to use natural alignment for a tagged data -// structure, but instead to reduce its alignment to 1. -// -// Therefore, DO NOT APPLY THIS ATTRIBUTE TO STRUCTS CONTAINING ATOMICS. Doing -// so can cause atomic variables to be mis-aligned and silently violate -// atomicity on x86. -// -// This attribute can either be applied to members of a structure or to a -// structure in its entirety. Applying this attribute (judiciously) to a -// structure in its entirety to optimize the memory footprint of very -// commonly-used structs is fine. Do not apply this attribute to a structure in -// its entirety if the purpose is to control the offsets of the members in the -// structure. Instead, apply this attribute only to structure members that need -// it. -// +// structure, but instead to reduce its alignment to 1. +// +// Therefore, DO NOT APPLY THIS ATTRIBUTE TO STRUCTS CONTAINING ATOMICS. Doing +// so can cause atomic variables to be mis-aligned and silently violate +// atomicity on x86. +// +// This attribute can either be applied to members of a structure or to a +// structure in its entirety. Applying this attribute (judiciously) to a +// structure in its entirety to optimize the memory footprint of very +// commonly-used structs is fine. Do not apply this attribute to a structure in +// its entirety if the purpose is to control the offsets of the members in the +// structure. Instead, apply this attribute only to structure members that need +// it. +// // When applying ABSL_ATTRIBUTE_PACKED only to specific structure members the // natural alignment of structure members not annotated is preserved. Aligned // member accesses are faster than non-aligned member accesses even if the @@ -613,24 +613,24 @@ // case 42: // ... // -// Notes: When supported, GCC and Clang can issue a warning on switch labels -// with unannotated fallthrough using the warning `-Wimplicit-fallthrough`. See -// clang documentation on language extensions for details: +// Notes: When supported, GCC and Clang can issue a warning on switch labels +// with unannotated fallthrough using the warning `-Wimplicit-fallthrough`. See +// clang documentation on language extensions for details: // https://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough // -// When used with unsupported compilers, the ABSL_FALLTHROUGH_INTENDED macro has -// no effect on diagnostics. In any case this macro has no effect on runtime +// When used with unsupported compilers, the ABSL_FALLTHROUGH_INTENDED macro has +// no effect on diagnostics. In any case this macro has no effect on runtime // behavior and performance of code. #ifdef ABSL_FALLTHROUGH_INTENDED #error "ABSL_FALLTHROUGH_INTENDED should not be defined." -#elif ABSL_HAVE_CPP_ATTRIBUTE(fallthrough) -#define ABSL_FALLTHROUGH_INTENDED [[fallthrough]] -#elif ABSL_HAVE_CPP_ATTRIBUTE(clang::fallthrough) +#elif ABSL_HAVE_CPP_ATTRIBUTE(fallthrough) +#define ABSL_FALLTHROUGH_INTENDED [[fallthrough]] +#elif ABSL_HAVE_CPP_ATTRIBUTE(clang::fallthrough) #define ABSL_FALLTHROUGH_INTENDED [[clang::fallthrough]] -#elif ABSL_HAVE_CPP_ATTRIBUTE(gnu::fallthrough) +#elif ABSL_HAVE_CPP_ATTRIBUTE(gnu::fallthrough) #define ABSL_FALLTHROUGH_INTENDED [[gnu::fallthrough]] -#else +#else #define ABSL_FALLTHROUGH_INTENDED \ do { \ } while (0) @@ -710,26 +710,26 @@ #define ABSL_ATTRIBUTE_PURE_FUNCTION #endif -// ABSL_ATTRIBUTE_LIFETIME_BOUND indicates that a resource owned by a function -// parameter or implicit object parameter is retained by the return value of the -// annotated function (or, for a parameter of a constructor, in the value of the -// constructed object). This attribute causes warnings to be produced if a -// temporary object does not live long enough. -// -// When applied to a reference parameter, the referenced object is assumed to be -// retained by the return value of the function. When applied to a non-reference -// parameter (for example, a pointer or a class type), all temporaries -// referenced by the parameter are assumed to be retained by the return value of -// the function. -// -// See also the upstream documentation: -// https://clang.llvm.org/docs/AttributeReference.html#lifetimebound -#if ABSL_HAVE_CPP_ATTRIBUTE(clang::lifetimebound) -#define ABSL_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]] -#elif ABSL_HAVE_ATTRIBUTE(lifetimebound) -#define ABSL_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound)) -#else -#define ABSL_ATTRIBUTE_LIFETIME_BOUND -#endif - +// ABSL_ATTRIBUTE_LIFETIME_BOUND indicates that a resource owned by a function +// parameter or implicit object parameter is retained by the return value of the +// annotated function (or, for a parameter of a constructor, in the value of the +// constructed object). This attribute causes warnings to be produced if a +// temporary object does not live long enough. +// +// When applied to a reference parameter, the referenced object is assumed to be +// retained by the return value of the function. When applied to a non-reference +// parameter (for example, a pointer or a class type), all temporaries +// referenced by the parameter are assumed to be retained by the return value of +// the function. +// +// See also the upstream documentation: +// https://clang.llvm.org/docs/AttributeReference.html#lifetimebound +#if ABSL_HAVE_CPP_ATTRIBUTE(clang::lifetimebound) +#define ABSL_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]] +#elif ABSL_HAVE_ATTRIBUTE(lifetimebound) +#define ABSL_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound)) +#else +#define ABSL_ATTRIBUTE_LIFETIME_BOUND +#endif + #endif // ABSL_BASE_ATTRIBUTES_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/base/config.h b/contrib/restricted/abseil-cpp-tstring/y_absl/base/config.h index 162843aa00..b8d3e44d79 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/base/config.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/base/config.h @@ -66,35 +66,35 @@ #include "y_absl/base/options.h" #include "y_absl/base/policy_checks.h" -// Abseil long-term support (LTS) releases will define -// `ABSL_LTS_RELEASE_VERSION` to the integer representing the date string of the -// LTS release version, and will define `ABSL_LTS_RELEASE_PATCH_LEVEL` to the -// integer representing the patch-level for that release. -// -// For example, for LTS release version "20300401.2", this would give us -// ABSL_LTS_RELEASE_VERSION == 20300401 && ABSL_LTS_RELEASE_PATCH_LEVEL == 2 -// -// These symbols will not be defined in non-LTS code. -// -// Abseil recommends that clients live-at-head. Therefore, if you are using -// these symbols to assert a minimum version requirement, we recommend you do it -// as -// -// #if defined(ABSL_LTS_RELEASE_VERSION) && ABSL_LTS_RELEASE_VERSION < 20300401 -// #error Project foo requires Abseil LTS version >= 20300401 -// #endif -// -// The `defined(ABSL_LTS_RELEASE_VERSION)` part of the check excludes -// live-at-head clients from the minimum version assertion. -// -// See https://abseil.io/about/releases for more information on Abseil release -// management. -// -// LTS releases can be obtained from -// https://github.com/abseil/abseil-cpp/releases. -#define ABSL_LTS_RELEASE_VERSION 20211102 -#define ABSL_LTS_RELEASE_PATCH_LEVEL 0 - +// Abseil long-term support (LTS) releases will define +// `ABSL_LTS_RELEASE_VERSION` to the integer representing the date string of the +// LTS release version, and will define `ABSL_LTS_RELEASE_PATCH_LEVEL` to the +// integer representing the patch-level for that release. +// +// For example, for LTS release version "20300401.2", this would give us +// ABSL_LTS_RELEASE_VERSION == 20300401 && ABSL_LTS_RELEASE_PATCH_LEVEL == 2 +// +// These symbols will not be defined in non-LTS code. +// +// Abseil recommends that clients live-at-head. Therefore, if you are using +// these symbols to assert a minimum version requirement, we recommend you do it +// as +// +// #if defined(ABSL_LTS_RELEASE_VERSION) && ABSL_LTS_RELEASE_VERSION < 20300401 +// #error Project foo requires Abseil LTS version >= 20300401 +// #endif +// +// The `defined(ABSL_LTS_RELEASE_VERSION)` part of the check excludes +// live-at-head clients from the minimum version assertion. +// +// See https://abseil.io/about/releases for more information on Abseil release +// management. +// +// LTS releases can be obtained from +// https://github.com/abseil/abseil-cpp/releases. +#define ABSL_LTS_RELEASE_VERSION 20211102 +#define ABSL_LTS_RELEASE_PATCH_LEVEL 0 + // Helper macro to convert a CPP variable to a string literal. #define ABSL_INTERNAL_DO_TOKEN_STR(x) #x #define ABSL_INTERNAL_TOKEN_STR(x) ABSL_INTERNAL_DO_TOKEN_STR(x) @@ -195,22 +195,22 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #define ABSL_HAVE_FEATURE(f) 0 #endif -// Portable check for GCC minimum version: -// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html -#if defined(__GNUC__) && defined(__GNUC_MINOR__) -#define ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(x, y) \ - (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y)) -#else -#define ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(x, y) 0 -#endif - -#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__) -#define ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(x, y) \ - (__clang_major__ > (x) || __clang_major__ == (x) && __clang_minor__ >= (y)) -#else -#define ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(x, y) 0 -#endif - +// Portable check for GCC minimum version: +// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html +#if defined(__GNUC__) && defined(__GNUC_MINOR__) +#define ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(x, y) \ + (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y)) +#else +#define ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(x, y) 0 +#endif + +#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__) +#define ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(x, y) \ + (__clang_major__ > (x) || __clang_major__ == (x) && __clang_minor__ >= (y)) +#else +#define ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(x, y) 0 +#endif + // ABSL_HAVE_TLS is defined to 1 when __thread should be supported. // We assume __thread is supported on Linux when compiled with Clang or compiled // against libstdc++ with _GLIBCXX_HAVE_TLS defined. @@ -228,9 +228,9 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || // gcc >= 4.8.1 using libstdc++, and Visual Studio. #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE #error ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE cannot be directly set -#elif defined(_LIBCPP_VERSION) || defined(_MSC_VER) || \ - (!defined(__clang__) && defined(__GLIBCXX__) && \ - ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(4, 8)) +#elif defined(_LIBCPP_VERSION) || defined(_MSC_VER) || \ + (!defined(__clang__) && defined(__GLIBCXX__) && \ + ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(4, 8)) #define ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 1 #endif @@ -243,17 +243,17 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || // // Checks whether `std::is_trivially_copy_assignable<T>` is supported. -// Notes: Clang with libc++ supports these features, as does gcc >= 7.4 with -// libstdc++, or gcc >= 8.2 with libc++, and Visual Studio (but not NVCC). +// Notes: Clang with libc++ supports these features, as does gcc >= 7.4 with +// libstdc++, or gcc >= 8.2 with libc++, and Visual Studio (but not NVCC). #if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) #error ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE cannot be directly set #elif defined(ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE) #error ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE cannot directly set -#elif (defined(__clang__) && defined(_LIBCPP_VERSION)) || \ - (!defined(__clang__) && \ - ((ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(7, 4) && defined(__GLIBCXX__)) || \ - (ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(8, 2) && \ - defined(_LIBCPP_VERSION)))) || \ +#elif (defined(__clang__) && defined(_LIBCPP_VERSION)) || \ + (!defined(__clang__) && \ + ((ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(7, 4) && defined(__GLIBCXX__)) || \ + (ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(8, 2) && \ + defined(_LIBCPP_VERSION)))) || \ (defined(_MSC_VER) && !defined(__NVCC__)) #define ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 1 #define ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 1 @@ -267,7 +267,7 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #if ABSL_INTERNAL_HAS_KEYWORD(__builtin_LINE) && \ ABSL_INTERNAL_HAS_KEYWORD(__builtin_FILE) #define ABSL_HAVE_SOURCE_LOCATION_CURRENT 1 -#elif ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(5, 0) +#elif ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(5, 0) #define ABSL_HAVE_SOURCE_LOCATION_CURRENT 1 #endif #endif @@ -364,21 +364,21 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || // For further details, consult the compiler's documentation. #ifdef ABSL_HAVE_EXCEPTIONS #error ABSL_HAVE_EXCEPTIONS cannot be directly set. -#elif ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(3, 6) +#elif ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(3, 6) // Clang >= 3.6 #if ABSL_HAVE_FEATURE(cxx_exceptions) #define ABSL_HAVE_EXCEPTIONS 1 #endif // ABSL_HAVE_FEATURE(cxx_exceptions) -#elif defined(__clang__) +#elif defined(__clang__) // Clang < 3.6 // http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro #if defined(__EXCEPTIONS) && ABSL_HAVE_FEATURE(cxx_exceptions) #define ABSL_HAVE_EXCEPTIONS 1 #endif // defined(__EXCEPTIONS) && ABSL_HAVE_FEATURE(cxx_exceptions) // Handle remaining special cases and default to exceptions being supported. -#elif !(defined(__GNUC__) && (__GNUC__ < 5) && !defined(__EXCEPTIONS)) && \ - !(ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(5, 0) && \ - !defined(__cpp_exceptions)) && \ +#elif !(defined(__GNUC__) && (__GNUC__ < 5) && !defined(__EXCEPTIONS)) && \ + !(ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(5, 0) && \ + !defined(__cpp_exceptions)) && \ !(defined(_MSC_VER) && !defined(_CPPUNWIND)) #define ABSL_HAVE_EXCEPTIONS 1 #endif @@ -410,11 +410,11 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || // POSIX.1-2001. #ifdef ABSL_HAVE_MMAP #error ABSL_HAVE_MMAP cannot be directly set -#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ - defined(_AIX) || defined(__ros__) || defined(__native_client__) || \ - defined(__asmjs__) || defined(__wasm__) || defined(__Fuchsia__) || \ - defined(__sun) || defined(__ASYLO__) || defined(__myriad2__) || \ - defined(__HAIKU__) +#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ + defined(_AIX) || defined(__ros__) || defined(__native_client__) || \ + defined(__asmjs__) || defined(__wasm__) || defined(__Fuchsia__) || \ + defined(__sun) || defined(__ASYLO__) || defined(__myriad2__) || \ + defined(__HAIKU__) #define ABSL_HAVE_MMAP 1 #endif @@ -425,7 +425,7 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #ifdef ABSL_HAVE_PTHREAD_GETSCHEDPARAM #error ABSL_HAVE_PTHREAD_GETSCHEDPARAM cannot be directly set #elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ - defined(_AIX) || defined(__ros__) + defined(_AIX) || defined(__ros__) #define ABSL_HAVE_PTHREAD_GETSCHEDPARAM 1 #endif diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/base/dynamic_annotations.h b/contrib/restricted/abseil-cpp-tstring/y_absl/base/dynamic_annotations.h index 50b3122cf7..a4e96b6608 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/base/dynamic_annotations.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/base/dynamic_annotations.h @@ -446,7 +446,7 @@ ABSL_NAMESPACE_END __sanitizer_annotate_contiguous_container(beg, end, old_mid, new_mid) #define ABSL_ADDRESS_SANITIZER_REDZONE(name) \ struct { \ - alignas(8) char x[8]; \ + alignas(8) char x[8]; \ } name #else diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/exception_safety_testing.h b/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/exception_safety_testing.h index 3009f17875..1a6edd9186 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/exception_safety_testing.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/exception_safety_testing.h @@ -536,22 +536,22 @@ class ThrowingValue : private exceptions_internal::TrackedObject { } // Memory management operators - static void* operator new(size_t s) noexcept( - IsSpecified(TypeSpec::kNoThrowNew)) { - if (!IsSpecified(TypeSpec::kNoThrowNew)) { - exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION, true); - } - return ::operator new(s); - } - - static void* operator new[](size_t s) noexcept( - IsSpecified(TypeSpec::kNoThrowNew)) { - if (!IsSpecified(TypeSpec::kNoThrowNew)) { - exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION, true); - } - return ::operator new[](s); - } - + static void* operator new(size_t s) noexcept( + IsSpecified(TypeSpec::kNoThrowNew)) { + if (!IsSpecified(TypeSpec::kNoThrowNew)) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION, true); + } + return ::operator new(s); + } + + static void* operator new[](size_t s) noexcept( + IsSpecified(TypeSpec::kNoThrowNew)) { + if (!IsSpecified(TypeSpec::kNoThrowNew)) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION, true); + } + return ::operator new[](s); + } + template <typename... Args> static void* operator new(size_t s, Args&&... args) noexcept( IsSpecified(TypeSpec::kNoThrowNew)) { @@ -736,7 +736,7 @@ class ThrowingAllocator : private exceptions_internal::TrackedObject { ThrowingAllocator select_on_container_copy_construction() noexcept( IsSpecified(AllocSpec::kNoThrowAllocate)) { ReadStateAndMaybeThrow(ABSL_PRETTY_FUNCTION); - return *this; + return *this; } template <typename U> diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock.h b/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock.h index ef88cb52c0..0c5539b940 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock.h @@ -16,15 +16,15 @@ // Most users requiring mutual exclusion should use Mutex. // SpinLock is provided for use in two situations: -// - for use by Abseil internal code that Mutex itself depends on +// - for use by Abseil internal code that Mutex itself depends on // - for async signal safety (see below) // SpinLock is async signal safe. If a spinlock is used within a signal // handler, all code that acquires the lock must ensure that the signal cannot // arrive while they are holding the lock. Typically, this is done by blocking // the signal. -// -// Threads waiting on a SpinLock may be woken in an arbitrary order. +// +// Threads waiting on a SpinLock may be woken in an arbitrary order. #ifndef ABSL_BASE_INTERNAL_SPINLOCK_H_ #define ABSL_BASE_INTERNAL_SPINLOCK_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock_wait.h b/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock_wait.h index 2e34d7026b..1d67c32560 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock_wait.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock_wait.h @@ -39,8 +39,8 @@ struct SpinLockWaitTransition { // satisfying 0<=i<n && trans[i].done, atomically make the transition, // then return the old value of *w. Make any other atomic transitions // where !trans[i].done, but continue waiting. -// -// Wakeups for threads blocked on SpinLockWait do not respect priorities. +// +// Wakeups for threads blocked on SpinLockWait do not respect priorities. uint32_t SpinLockWait(std::atomic<uint32_t> *w, int n, const SpinLockWaitTransition trans[], SchedulingMode scheduling_mode); diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/sysinfo.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/sysinfo.cc index 9eb0cf3f8c..0e3beedfbc 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/sysinfo.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/sysinfo.cc @@ -61,78 +61,78 @@ namespace y_absl { ABSL_NAMESPACE_BEGIN namespace base_internal { -namespace { - -#if defined(_WIN32) - -// Returns number of bits set in `bitMask` -DWORD Win32CountSetBits(ULONG_PTR bitMask) { - for (DWORD bitSetCount = 0; ; ++bitSetCount) { - if (bitMask == 0) return bitSetCount; - bitMask &= bitMask - 1; - } -} - -// Returns the number of logical CPUs using GetLogicalProcessorInformation(), or -// 0 if the number of processors is not available or can not be computed. -// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlogicalprocessorinformation -int Win32NumCPUs() { -#pragma comment(lib, "kernel32.lib") - using Info = SYSTEM_LOGICAL_PROCESSOR_INFORMATION; - - DWORD info_size = sizeof(Info); - Info* info(static_cast<Info*>(malloc(info_size))); - if (info == nullptr) return 0; - - bool success = GetLogicalProcessorInformation(info, &info_size); - if (!success && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { - free(info); - info = static_cast<Info*>(malloc(info_size)); - if (info == nullptr) return 0; - success = GetLogicalProcessorInformation(info, &info_size); - } - - DWORD logicalProcessorCount = 0; - if (success) { - Info* ptr = info; - DWORD byteOffset = 0; - while (byteOffset + sizeof(Info) <= info_size) { - switch (ptr->Relationship) { - case RelationProcessorCore: - logicalProcessorCount += Win32CountSetBits(ptr->ProcessorMask); - break; - - case RelationNumaNode: - case RelationCache: - case RelationProcessorPackage: - // Ignore other entries - break; - - default: - // Ignore unknown entries - break; - } - byteOffset += sizeof(Info); - ptr++; - } - } - free(info); - return logicalProcessorCount; -} - -#endif - -} // namespace - - +namespace { + +#if defined(_WIN32) + +// Returns number of bits set in `bitMask` +DWORD Win32CountSetBits(ULONG_PTR bitMask) { + for (DWORD bitSetCount = 0; ; ++bitSetCount) { + if (bitMask == 0) return bitSetCount; + bitMask &= bitMask - 1; + } +} + +// Returns the number of logical CPUs using GetLogicalProcessorInformation(), or +// 0 if the number of processors is not available or can not be computed. +// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlogicalprocessorinformation +int Win32NumCPUs() { +#pragma comment(lib, "kernel32.lib") + using Info = SYSTEM_LOGICAL_PROCESSOR_INFORMATION; + + DWORD info_size = sizeof(Info); + Info* info(static_cast<Info*>(malloc(info_size))); + if (info == nullptr) return 0; + + bool success = GetLogicalProcessorInformation(info, &info_size); + if (!success && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + free(info); + info = static_cast<Info*>(malloc(info_size)); + if (info == nullptr) return 0; + success = GetLogicalProcessorInformation(info, &info_size); + } + + DWORD logicalProcessorCount = 0; + if (success) { + Info* ptr = info; + DWORD byteOffset = 0; + while (byteOffset + sizeof(Info) <= info_size) { + switch (ptr->Relationship) { + case RelationProcessorCore: + logicalProcessorCount += Win32CountSetBits(ptr->ProcessorMask); + break; + + case RelationNumaNode: + case RelationCache: + case RelationProcessorPackage: + // Ignore other entries + break; + + default: + // Ignore unknown entries + break; + } + byteOffset += sizeof(Info); + ptr++; + } + } + free(info); + return logicalProcessorCount; +} + +#endif + +} // namespace + + static int GetNumCPUs() { #if defined(__myriad2__) return 1; -#elif defined(_WIN32) - const unsigned hardware_concurrency = Win32NumCPUs(); - return hardware_concurrency ? hardware_concurrency : 1; -#elif defined(_AIX) - return sysconf(_SC_NPROCESSORS_ONLN); +#elif defined(_WIN32) + const unsigned hardware_concurrency = Win32NumCPUs(); + return hardware_concurrency ? hardware_concurrency : 1; +#elif defined(_AIX) + return sysconf(_SC_NPROCESSORS_ONLN); #else // Other possibilities: // - Read /sys/devices/system/cpu/online and use cpumask_parse() diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/thread_identity.h b/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/thread_identity.h index 09a6c0bce1..0d8a7a3807 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/thread_identity.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/thread_identity.h @@ -188,25 +188,25 @@ void ClearCurrentThreadIdentity(); // May be chosen at compile time via: -DABSL_FORCE_THREAD_IDENTITY_MODE=<mode // index> #ifdef ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC -#error ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC cannot be directly set +#error ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC cannot be directly set #else #define ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC 0 #endif #ifdef ABSL_THREAD_IDENTITY_MODE_USE_TLS -#error ABSL_THREAD_IDENTITY_MODE_USE_TLS cannot be directly set +#error ABSL_THREAD_IDENTITY_MODE_USE_TLS cannot be directly set #else #define ABSL_THREAD_IDENTITY_MODE_USE_TLS 1 #endif #ifdef ABSL_THREAD_IDENTITY_MODE_USE_CPP11 -#error ABSL_THREAD_IDENTITY_MODE_USE_CPP11 cannot be directly set +#error ABSL_THREAD_IDENTITY_MODE_USE_CPP11 cannot be directly set #else #define ABSL_THREAD_IDENTITY_MODE_USE_CPP11 2 #endif #ifdef ABSL_THREAD_IDENTITY_MODE -#error ABSL_THREAD_IDENTITY_MODE cannot be directly set +#error ABSL_THREAD_IDENTITY_MODE cannot be directly set #elif defined(ABSL_FORCE_THREAD_IDENTITY_MODE) #define ABSL_THREAD_IDENTITY_MODE ABSL_FORCE_THREAD_IDENTITY_MODE #elif defined(_WIN32) && !defined(__MINGW32__) diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/unscaledcycleclock.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/unscaledcycleclock.cc index 072a9852fa..d8047586e9 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/unscaledcycleclock.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/unscaledcycleclock.cc @@ -87,10 +87,10 @@ int64_t UnscaledCycleClock::Now() { double UnscaledCycleClock::Frequency() { #ifdef __GLIBC__ return __ppc_get_timebase_freq(); -#elif defined(_AIX) - // This is the same constant value as returned by - // __ppc_get_timebase_freq(). - return static_cast<double>(512000000); +#elif defined(_AIX) + // This is the same constant value as returned by + // __ppc_get_timebase_freq(). + return static_cast<double>(512000000); #elif defined(__FreeBSD__) static once_flag init_timebase_frequency_once; static double timebase_frequency = 0.0; @@ -123,18 +123,18 @@ double UnscaledCycleClock::Frequency() { return aarch64_timer_frequency; } -#elif defined(__riscv) - -int64_t UnscaledCycleClock::Now() { - int64_t virtual_timer_value; - asm volatile("rdcycle %0" : "=r"(virtual_timer_value)); - return virtual_timer_value; -} - -double UnscaledCycleClock::Frequency() { - return base_internal::NominalCPUFrequency(); -} - +#elif defined(__riscv) + +int64_t UnscaledCycleClock::Now() { + int64_t virtual_timer_value; + asm volatile("rdcycle %0" : "=r"(virtual_timer_value)); + return virtual_timer_value; +} + +double UnscaledCycleClock::Frequency() { + return base_internal::NominalCPUFrequency(); +} + #elif defined(_M_IX86) || defined(_M_X64) #pragma intrinsic(__rdtsc) diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/unscaledcycleclock.h b/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/unscaledcycleclock.h index 618c5c7e73..83e9b877ce 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/unscaledcycleclock.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/unscaledcycleclock.h @@ -46,8 +46,8 @@ // The following platforms have an implementation of a hardware counter. #if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) || \ - defined(__powerpc__) || defined(__ppc__) || defined(__riscv) || \ - defined(_M_IX86) || defined(_M_X64) + defined(__powerpc__) || defined(__ppc__) || defined(__riscv) || \ + defined(_M_IX86) || defined(_M_X64) #define ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION 1 #else #define ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION 0 @@ -80,8 +80,8 @@ // This macro can be used to test if UnscaledCycleClock::Frequency() // is NominalCPUFrequency() on a particular platform. -#if (defined(__i386__) || defined(__x86_64__) || defined(__riscv) || \ - defined(_M_IX86) || defined(_M_X64)) +#if (defined(__i386__) || defined(__x86_64__) || defined(__riscv) || \ + defined(_M_IX86) || defined(_M_X64)) #define ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY #endif diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/base/options.h b/contrib/restricted/abseil-cpp-tstring/y_absl/base/options.h index 906310cde0..d442046ce7 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/base/options.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/base/options.h @@ -206,7 +206,7 @@ // allowed. #define ABSL_OPTION_USE_INLINE_NAMESPACE 1 -#define ABSL_OPTION_INLINE_NAMESPACE_NAME lts_y_20211102 +#define ABSL_OPTION_INLINE_NAMESPACE_NAME lts_y_20211102 // ABSL_OPTION_HARDENED // diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/container/btree_map.h b/contrib/restricted/abseil-cpp-tstring/y_absl/container/btree_map.h index 3f46c541b8..222a2fa098 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/container/btree_map.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/container/btree_map.h @@ -366,8 +366,8 @@ class btree_map // Determines whether an element comparing equal to the given `key` exists // within the `btree_map`, returning `true` if so or `false` otherwise. // - // Supports heterogeneous lookup, provided that the map has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the map has a compatible + // heterogeneous comparator. using Base::contains; // btree_map::count() @@ -378,8 +378,8 @@ class btree_map // the `btree_map`. Note that this function will return either `1` or `0` // since duplicate elements are not allowed within a `btree_map`. // - // Supports heterogeneous lookup, provided that the map has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the map has a compatible + // heterogeneous comparator. using Base::count; // btree_map::equal_range() @@ -395,34 +395,34 @@ class btree_map // // Finds an element with the passed `key` within the `btree_map`. // - // Supports heterogeneous lookup, provided that the map has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the map has a compatible + // heterogeneous comparator. using Base::find; - // btree_map::lower_bound() - // - // template <typename K> iterator lower_bound(const K& key): - // template <typename K> const_iterator lower_bound(const K& key) const: - // - // Finds the first element with a key that is not less than `key` within the - // `btree_map`. - // - // Supports heterogeneous lookup, provided that the map has a compatible - // heterogeneous comparator. - using Base::lower_bound; - - // btree_map::upper_bound() - // - // template <typename K> iterator upper_bound(const K& key): - // template <typename K> const_iterator upper_bound(const K& key) const: - // - // Finds the first element with a key that is greater than `key` within the - // `btree_map`. - // - // Supports heterogeneous lookup, provided that the map has a compatible - // heterogeneous comparator. - using Base::upper_bound; - + // btree_map::lower_bound() + // + // template <typename K> iterator lower_bound(const K& key): + // template <typename K> const_iterator lower_bound(const K& key) const: + // + // Finds the first element with a key that is not less than `key` within the + // `btree_map`. + // + // Supports heterogeneous lookup, provided that the map has a compatible + // heterogeneous comparator. + using Base::lower_bound; + + // btree_map::upper_bound() + // + // template <typename K> iterator upper_bound(const K& key): + // template <typename K> const_iterator upper_bound(const K& key) const: + // + // Finds the first element with a key that is greater than `key` within the + // `btree_map`. + // + // Supports heterogeneous lookup, provided that the map has a compatible + // heterogeneous comparator. + using Base::upper_bound; + // btree_map::operator[]() // // Returns a reference to the value mapped to the passed key within the @@ -693,8 +693,8 @@ class btree_multimap // btree_multimap::merge() // - // Extracts all elements from a given `source` btree_multimap into this - // `btree_multimap`. + // Extracts all elements from a given `source` btree_multimap into this + // `btree_multimap`. using Base::merge; // btree_multimap::swap(btree_multimap& other) @@ -714,8 +714,8 @@ class btree_multimap // Determines whether an element comparing equal to the given `key` exists // within the `btree_multimap`, returning `true` if so or `false` otherwise. // - // Supports heterogeneous lookup, provided that the map has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the map has a compatible + // heterogeneous comparator. using Base::contains; // btree_multimap::count() @@ -725,8 +725,8 @@ class btree_multimap // Returns the number of elements comparing equal to the given `key` within // the `btree_multimap`. // - // Supports heterogeneous lookup, provided that the map has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the map has a compatible + // heterogeneous comparator. using Base::count; // btree_multimap::equal_range() @@ -743,34 +743,34 @@ class btree_multimap // // Finds an element with the passed `key` within the `btree_multimap`. // - // Supports heterogeneous lookup, provided that the map has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the map has a compatible + // heterogeneous comparator. using Base::find; - // btree_multimap::lower_bound() - // - // template <typename K> iterator lower_bound(const K& key): - // template <typename K> const_iterator lower_bound(const K& key) const: - // - // Finds the first element with a key that is not less than `key` within the - // `btree_multimap`. - // - // Supports heterogeneous lookup, provided that the map has a compatible - // heterogeneous comparator. - using Base::lower_bound; - - // btree_multimap::upper_bound() - // - // template <typename K> iterator upper_bound(const K& key): - // template <typename K> const_iterator upper_bound(const K& key) const: - // - // Finds the first element with a key that is greater than `key` within the - // `btree_multimap`. - // - // Supports heterogeneous lookup, provided that the map has a compatible - // heterogeneous comparator. - using Base::upper_bound; - + // btree_multimap::lower_bound() + // + // template <typename K> iterator lower_bound(const K& key): + // template <typename K> const_iterator lower_bound(const K& key) const: + // + // Finds the first element with a key that is not less than `key` within the + // `btree_multimap`. + // + // Supports heterogeneous lookup, provided that the map has a compatible + // heterogeneous comparator. + using Base::lower_bound; + + // btree_multimap::upper_bound() + // + // template <typename K> iterator upper_bound(const K& key): + // template <typename K> const_iterator upper_bound(const K& key) const: + // + // Finds the first element with a key that is greater than `key` within the + // `btree_multimap`. + // + // Supports heterogeneous lookup, provided that the map has a compatible + // heterogeneous comparator. + using Base::upper_bound; + // btree_multimap::get_allocator() // // Returns the allocator function associated with this `btree_multimap`. diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/container/btree_set.h b/contrib/restricted/abseil-cpp-tstring/y_absl/container/btree_set.h index 905fb8e964..bfee05c2eb 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/container/btree_set.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/container/btree_set.h @@ -300,8 +300,8 @@ class btree_set // Determines whether an element comparing equal to the given `key` exists // within the `btree_set`, returning `true` if so or `false` otherwise. // - // Supports heterogeneous lookup, provided that the set has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the set has a compatible + // heterogeneous comparator. using Base::contains; // btree_set::count() @@ -312,8 +312,8 @@ class btree_set // the `btree_set`. Note that this function will return either `1` or `0` // since duplicate elements are not allowed within a `btree_set`. // - // Supports heterogeneous lookup, provided that the set has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the set has a compatible + // heterogeneous comparator. using Base::count; // btree_set::equal_range() @@ -330,32 +330,32 @@ class btree_set // // Finds an element with the passed `key` within the `btree_set`. // - // Supports heterogeneous lookup, provided that the set has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the set has a compatible + // heterogeneous comparator. using Base::find; - // btree_set::lower_bound() - // - // template <typename K> iterator lower_bound(const K& key): - // template <typename K> const_iterator lower_bound(const K& key) const: - // - // Finds the first element that is not less than `key` within the `btree_set`. - // - // Supports heterogeneous lookup, provided that the set has a compatible - // heterogeneous comparator. - using Base::lower_bound; - - // btree_set::upper_bound() - // - // template <typename K> iterator upper_bound(const K& key): - // template <typename K> const_iterator upper_bound(const K& key) const: - // - // Finds the first element that is greater than `key` within the `btree_set`. - // - // Supports heterogeneous lookup, provided that the set has a compatible - // heterogeneous comparator. - using Base::upper_bound; - + // btree_set::lower_bound() + // + // template <typename K> iterator lower_bound(const K& key): + // template <typename K> const_iterator lower_bound(const K& key) const: + // + // Finds the first element that is not less than `key` within the `btree_set`. + // + // Supports heterogeneous lookup, provided that the set has a compatible + // heterogeneous comparator. + using Base::lower_bound; + + // btree_set::upper_bound() + // + // template <typename K> iterator upper_bound(const K& key): + // template <typename K> const_iterator upper_bound(const K& key) const: + // + // Finds the first element that is greater than `key` within the `btree_set`. + // + // Supports heterogeneous lookup, provided that the set has a compatible + // heterogeneous comparator. + using Base::upper_bound; + // btree_set::get_allocator() // // Returns the allocator function associated with this `btree_set`. @@ -604,8 +604,8 @@ class btree_multiset // btree_multiset::merge() // - // Extracts all elements from a given `source` btree_multiset into this - // `btree_multiset`. + // Extracts all elements from a given `source` btree_multiset into this + // `btree_multiset`. using Base::merge; // btree_multiset::swap(btree_multiset& other) @@ -625,8 +625,8 @@ class btree_multiset // Determines whether an element comparing equal to the given `key` exists // within the `btree_multiset`, returning `true` if so or `false` otherwise. // - // Supports heterogeneous lookup, provided that the set has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the set has a compatible + // heterogeneous comparator. using Base::contains; // btree_multiset::count() @@ -636,8 +636,8 @@ class btree_multiset // Returns the number of elements comparing equal to the given `key` within // the `btree_multiset`. // - // Supports heterogeneous lookup, provided that the set has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the set has a compatible + // heterogeneous comparator. using Base::count; // btree_multiset::equal_range() @@ -654,34 +654,34 @@ class btree_multiset // // Finds an element with the passed `key` within the `btree_multiset`. // - // Supports heterogeneous lookup, provided that the set has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the set has a compatible + // heterogeneous comparator. using Base::find; - // btree_multiset::lower_bound() - // - // template <typename K> iterator lower_bound(const K& key): - // template <typename K> const_iterator lower_bound(const K& key) const: - // - // Finds the first element that is not less than `key` within the - // `btree_multiset`. - // - // Supports heterogeneous lookup, provided that the set has a compatible - // heterogeneous comparator. - using Base::lower_bound; - - // btree_multiset::upper_bound() - // - // template <typename K> iterator upper_bound(const K& key): - // template <typename K> const_iterator upper_bound(const K& key) const: - // - // Finds the first element that is greater than `key` within the - // `btree_multiset`. - // - // Supports heterogeneous lookup, provided that the set has a compatible - // heterogeneous comparator. - using Base::upper_bound; - + // btree_multiset::lower_bound() + // + // template <typename K> iterator lower_bound(const K& key): + // template <typename K> const_iterator lower_bound(const K& key) const: + // + // Finds the first element that is not less than `key` within the + // `btree_multiset`. + // + // Supports heterogeneous lookup, provided that the set has a compatible + // heterogeneous comparator. + using Base::lower_bound; + + // btree_multiset::upper_bound() + // + // template <typename K> iterator upper_bound(const K& key): + // template <typename K> const_iterator upper_bound(const K& key) const: + // + // Finds the first element that is greater than `key` within the + // `btree_multiset`. + // + // Supports heterogeneous lookup, provided that the set has a compatible + // heterogeneous comparator. + using Base::upper_bound; + // btree_multiset::get_allocator() // // Returns the allocator function associated with this `btree_multiset`. diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/container/inlined_vector.h b/contrib/restricted/abseil-cpp-tstring/y_absl/container/inlined_vector.h index 34af121cf7..1fdef2be6a 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/container/inlined_vector.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/container/inlined_vector.h @@ -72,43 +72,43 @@ class InlinedVector { using Storage = inlined_vector_internal::Storage<T, N, A>; - template <typename TheA> - using AllocatorTraits = inlined_vector_internal::AllocatorTraits<TheA>; - template <typename TheA> - using MoveIterator = inlined_vector_internal::MoveIterator<TheA>; - template <typename TheA> - using IsMemcpyOk = inlined_vector_internal::IsMemcpyOk<TheA>; - - template <typename TheA, typename Iterator> + template <typename TheA> + using AllocatorTraits = inlined_vector_internal::AllocatorTraits<TheA>; + template <typename TheA> + using MoveIterator = inlined_vector_internal::MoveIterator<TheA>; + template <typename TheA> + using IsMemcpyOk = inlined_vector_internal::IsMemcpyOk<TheA>; + + template <typename TheA, typename Iterator> using IteratorValueAdapter = - inlined_vector_internal::IteratorValueAdapter<TheA, Iterator>; - template <typename TheA> - using CopyValueAdapter = inlined_vector_internal::CopyValueAdapter<TheA>; - template <typename TheA> - using DefaultValueAdapter = - inlined_vector_internal::DefaultValueAdapter<TheA>; + inlined_vector_internal::IteratorValueAdapter<TheA, Iterator>; + template <typename TheA> + using CopyValueAdapter = inlined_vector_internal::CopyValueAdapter<TheA>; + template <typename TheA> + using DefaultValueAdapter = + inlined_vector_internal::DefaultValueAdapter<TheA>; template <typename Iterator> using EnableIfAtLeastForwardIterator = y_absl::enable_if_t< - inlined_vector_internal::IsAtLeastForwardIterator<Iterator>::value, int>; + inlined_vector_internal::IsAtLeastForwardIterator<Iterator>::value, int>; template <typename Iterator> using DisableIfAtLeastForwardIterator = y_absl::enable_if_t< - !inlined_vector_internal::IsAtLeastForwardIterator<Iterator>::value, int>; + !inlined_vector_internal::IsAtLeastForwardIterator<Iterator>::value, int>; public: - using allocator_type = A; - using value_type = inlined_vector_internal::ValueType<A>; - using pointer = inlined_vector_internal::Pointer<A>; - using const_pointer = inlined_vector_internal::ConstPointer<A>; - using size_type = inlined_vector_internal::SizeType<A>; - using difference_type = inlined_vector_internal::DifferenceType<A>; - using reference = inlined_vector_internal::Reference<A>; - using const_reference = inlined_vector_internal::ConstReference<A>; - using iterator = inlined_vector_internal::Iterator<A>; - using const_iterator = inlined_vector_internal::ConstIterator<A>; - using reverse_iterator = inlined_vector_internal::ReverseIterator<A>; - using const_reverse_iterator = - inlined_vector_internal::ConstReverseIterator<A>; + using allocator_type = A; + using value_type = inlined_vector_internal::ValueType<A>; + using pointer = inlined_vector_internal::Pointer<A>; + using const_pointer = inlined_vector_internal::ConstPointer<A>; + using size_type = inlined_vector_internal::SizeType<A>; + using difference_type = inlined_vector_internal::DifferenceType<A>; + using reference = inlined_vector_internal::Reference<A>; + using const_reference = inlined_vector_internal::ConstReference<A>; + using iterator = inlined_vector_internal::Iterator<A>; + using const_iterator = inlined_vector_internal::ConstIterator<A>; + using reverse_iterator = inlined_vector_internal::ReverseIterator<A>; + using const_reverse_iterator = + inlined_vector_internal::ConstReverseIterator<A>; // --------------------------------------------------------------------------- // InlinedVector Constructors and Destructor @@ -117,28 +117,28 @@ class InlinedVector { // Creates an empty inlined vector with a value-initialized allocator. InlinedVector() noexcept(noexcept(allocator_type())) : storage_() {} - // Creates an empty inlined vector with a copy of `allocator`. - explicit InlinedVector(const allocator_type& allocator) noexcept - : storage_(allocator) {} + // Creates an empty inlined vector with a copy of `allocator`. + explicit InlinedVector(const allocator_type& allocator) noexcept + : storage_(allocator) {} // Creates an inlined vector with `n` copies of `value_type()`. explicit InlinedVector(size_type n, - const allocator_type& allocator = allocator_type()) - : storage_(allocator) { - storage_.Initialize(DefaultValueAdapter<A>(), n); + const allocator_type& allocator = allocator_type()) + : storage_(allocator) { + storage_.Initialize(DefaultValueAdapter<A>(), n); } // Creates an inlined vector with `n` copies of `v`. InlinedVector(size_type n, const_reference v, - const allocator_type& allocator = allocator_type()) - : storage_(allocator) { - storage_.Initialize(CopyValueAdapter<A>(std::addressof(v)), n); + const allocator_type& allocator = allocator_type()) + : storage_(allocator) { + storage_.Initialize(CopyValueAdapter<A>(std::addressof(v)), n); } // Creates an inlined vector with copies of the elements of `list`. InlinedVector(std::initializer_list<value_type> list, - const allocator_type& allocator = allocator_type()) - : InlinedVector(list.begin(), list.end(), allocator) {} + const allocator_type& allocator = allocator_type()) + : InlinedVector(list.begin(), list.end(), allocator) {} // Creates an inlined vector with elements constructed from the provided // forward iterator range [`first`, `last`). @@ -147,36 +147,36 @@ class InlinedVector { // this constructor with two integral arguments and a call to the above // `InlinedVector(size_type, const_reference)` constructor. template <typename ForwardIterator, - EnableIfAtLeastForwardIterator<ForwardIterator> = 0> + EnableIfAtLeastForwardIterator<ForwardIterator> = 0> InlinedVector(ForwardIterator first, ForwardIterator last, - const allocator_type& allocator = allocator_type()) - : storage_(allocator) { - storage_.Initialize(IteratorValueAdapter<A, ForwardIterator>(first), + const allocator_type& allocator = allocator_type()) + : storage_(allocator) { + storage_.Initialize(IteratorValueAdapter<A, ForwardIterator>(first), std::distance(first, last)); } // Creates an inlined vector with elements constructed from the provided input // iterator range [`first`, `last`). template <typename InputIterator, - DisableIfAtLeastForwardIterator<InputIterator> = 0> + DisableIfAtLeastForwardIterator<InputIterator> = 0> InlinedVector(InputIterator first, InputIterator last, - const allocator_type& allocator = allocator_type()) - : storage_(allocator) { + const allocator_type& allocator = allocator_type()) + : storage_(allocator) { std::copy(first, last, std::back_inserter(*this)); } // Creates an inlined vector by copying the contents of `other` using // `other`'s allocator. InlinedVector(const InlinedVector& other) - : InlinedVector(other, other.storage_.GetAllocator()) {} + : InlinedVector(other, other.storage_.GetAllocator()) {} - // Creates an inlined vector by copying the contents of `other` using the - // provided `allocator`. - InlinedVector(const InlinedVector& other, const allocator_type& allocator) - : storage_(allocator) { + // Creates an inlined vector by copying the contents of `other` using the + // provided `allocator`. + InlinedVector(const InlinedVector& other, const allocator_type& allocator) + : storage_(allocator) { if (other.empty()) { // Empty; nothing to do. - } else if (IsMemcpyOk<A>::value && !other.storage_.GetIsAllocated()) { + } else if (IsMemcpyOk<A>::value && !other.storage_.GetIsAllocated()) { // Memcpy-able and do not need allocation. storage_.MemcpyFrom(other.storage_); } else { @@ -201,23 +201,23 @@ class InlinedVector { InlinedVector(InlinedVector&& other) noexcept( y_absl::allocator_is_nothrow<allocator_type>::value || std::is_nothrow_move_constructible<value_type>::value) - : storage_(other.storage_.GetAllocator()) { - if (IsMemcpyOk<A>::value) { + : storage_(other.storage_.GetAllocator()) { + if (IsMemcpyOk<A>::value) { storage_.MemcpyFrom(other.storage_); other.storage_.SetInlinedSize(0); } else if (other.storage_.GetIsAllocated()) { - storage_.SetAllocation({other.storage_.GetAllocatedData(), - other.storage_.GetAllocatedCapacity()}); + storage_.SetAllocation({other.storage_.GetAllocatedData(), + other.storage_.GetAllocatedCapacity()}); storage_.SetAllocatedSize(other.storage_.GetSize()); other.storage_.SetInlinedSize(0); } else { - IteratorValueAdapter<A, MoveIterator<A>> other_values( - MoveIterator<A>(other.storage_.GetInlinedData())); + IteratorValueAdapter<A, MoveIterator<A>> other_values( + MoveIterator<A>(other.storage_.GetInlinedData())); - inlined_vector_internal::ConstructElements<A>( - storage_.GetAllocator(), storage_.GetInlinedData(), other_values, + inlined_vector_internal::ConstructElements<A>( + storage_.GetAllocator(), storage_.GetInlinedData(), other_values, other.storage_.GetSize()); storage_.SetInlinedSize(other.storage_.GetSize()); @@ -225,32 +225,32 @@ class InlinedVector { } // Creates an inlined vector by moving in the contents of `other` with a copy - // of `allocator`. + // of `allocator`. // - // NOTE: if `other`'s allocator is not equal to `allocator`, even if `other` + // NOTE: if `other`'s allocator is not equal to `allocator`, even if `other` // contains allocated memory, this move constructor will still allocate. Since // allocation is performed, this constructor can only be `noexcept` if the // specified allocator is also `noexcept`. - InlinedVector( - InlinedVector&& other, - const allocator_type& allocator) - noexcept(y_absl::allocator_is_nothrow<allocator_type>::value) - : storage_(allocator) { - if (IsMemcpyOk<A>::value) { + InlinedVector( + InlinedVector&& other, + const allocator_type& allocator) + noexcept(y_absl::allocator_is_nothrow<allocator_type>::value) + : storage_(allocator) { + if (IsMemcpyOk<A>::value) { storage_.MemcpyFrom(other.storage_); other.storage_.SetInlinedSize(0); - } else if ((storage_.GetAllocator() == other.storage_.GetAllocator()) && + } else if ((storage_.GetAllocator() == other.storage_.GetAllocator()) && other.storage_.GetIsAllocated()) { - storage_.SetAllocation({other.storage_.GetAllocatedData(), - other.storage_.GetAllocatedCapacity()}); + storage_.SetAllocation({other.storage_.GetAllocatedData(), + other.storage_.GetAllocatedCapacity()}); storage_.SetAllocatedSize(other.storage_.GetSize()); other.storage_.SetInlinedSize(0); } else { - storage_.Initialize(IteratorValueAdapter<A, MoveIterator<A>>( - MoveIterator<A>(other.data())), - other.size()); + storage_.Initialize(IteratorValueAdapter<A, MoveIterator<A>>( + MoveIterator<A>(other.data())), + other.size()); } } @@ -451,7 +451,7 @@ class InlinedVector { // `InlinedVector::get_allocator()` // // Returns a copy of the inlined vector's allocator. - allocator_type get_allocator() const { return storage_.GetAllocator(); } + allocator_type get_allocator() const { return storage_.GetAllocator(); } // --------------------------------------------------------------------------- // InlinedVector Member Mutators @@ -485,16 +485,16 @@ class InlinedVector { // unspecified state. InlinedVector& operator=(InlinedVector&& other) { if (ABSL_PREDICT_TRUE(this != std::addressof(other))) { - if (IsMemcpyOk<A>::value || other.storage_.GetIsAllocated()) { - inlined_vector_internal::DestroyElements<A>(storage_.GetAllocator(), - data(), size()); + if (IsMemcpyOk<A>::value || other.storage_.GetIsAllocated()) { + inlined_vector_internal::DestroyElements<A>(storage_.GetAllocator(), + data(), size()); storage_.DeallocateIfAllocated(); storage_.MemcpyFrom(other.storage_); other.storage_.SetInlinedSize(0); } else { - storage_.Assign(IteratorValueAdapter<A, MoveIterator<A>>( - MoveIterator<A>(other.storage_.GetInlinedData())), + storage_.Assign(IteratorValueAdapter<A, MoveIterator<A>>( + MoveIterator<A>(other.storage_.GetInlinedData())), other.size()); } } @@ -506,7 +506,7 @@ class InlinedVector { // // Replaces the contents of the inlined vector with `n` copies of `v`. void assign(size_type n, const_reference v) { - storage_.Assign(CopyValueAdapter<A>(std::addressof(v)), n); + storage_.Assign(CopyValueAdapter<A>(std::addressof(v)), n); } // Overload of `InlinedVector::assign(...)` that replaces the contents of the @@ -520,9 +520,9 @@ class InlinedVector { // // NOTE: this overload is for iterators that are "forward" category or better. template <typename ForwardIterator, - EnableIfAtLeastForwardIterator<ForwardIterator> = 0> + EnableIfAtLeastForwardIterator<ForwardIterator> = 0> void assign(ForwardIterator first, ForwardIterator last) { - storage_.Assign(IteratorValueAdapter<A, ForwardIterator>(first), + storage_.Assign(IteratorValueAdapter<A, ForwardIterator>(first), std::distance(first, last)); } @@ -531,7 +531,7 @@ class InlinedVector { // // NOTE: this overload is for iterators that are "input" category. template <typename InputIterator, - DisableIfAtLeastForwardIterator<InputIterator> = 0> + DisableIfAtLeastForwardIterator<InputIterator> = 0> void assign(InputIterator first, InputIterator last) { size_type i = 0; for (; i < size() && first != last; ++i, static_cast<void>(++first)) { @@ -550,7 +550,7 @@ class InlinedVector { // is larger than `size()`, new elements are value-initialized. void resize(size_type n) { ABSL_HARDENING_ASSERT(n <= max_size()); - storage_.Resize(DefaultValueAdapter<A>(), n); + storage_.Resize(DefaultValueAdapter<A>(), n); } // Overload of `InlinedVector::resize(...)` that resizes the inlined vector to @@ -560,7 +560,7 @@ class InlinedVector { // is larger than `size()`, new elements are copied-constructed from `v`. void resize(size_type n, const_reference v) { ABSL_HARDENING_ASSERT(n <= max_size()); - storage_.Resize(CopyValueAdapter<A>(std::addressof(v)), n); + storage_.Resize(CopyValueAdapter<A>(std::addressof(v)), n); } // `InlinedVector::insert(...)` @@ -573,7 +573,7 @@ class InlinedVector { // Overload of `InlinedVector::insert(...)` that inserts `v` at `pos` using // move semantics, returning an `iterator` to the newly inserted element. - iterator insert(const_iterator pos, value_type&& v) { + iterator insert(const_iterator pos, value_type&& v) { return emplace(pos, std::move(v)); } @@ -586,8 +586,8 @@ class InlinedVector { if (ABSL_PREDICT_TRUE(n != 0)) { value_type dealias = v; - return storage_.Insert(pos, CopyValueAdapter<A>(std::addressof(dealias)), - n); + return storage_.Insert(pos, CopyValueAdapter<A>(std::addressof(dealias)), + n); } else { return const_cast<iterator>(pos); } @@ -606,15 +606,15 @@ class InlinedVector { // // NOTE: this overload is for iterators that are "forward" category or better. template <typename ForwardIterator, - EnableIfAtLeastForwardIterator<ForwardIterator> = 0> + EnableIfAtLeastForwardIterator<ForwardIterator> = 0> iterator insert(const_iterator pos, ForwardIterator first, ForwardIterator last) { ABSL_HARDENING_ASSERT(pos >= begin()); ABSL_HARDENING_ASSERT(pos <= end()); if (ABSL_PREDICT_TRUE(first != last)) { - return storage_.Insert(pos, - IteratorValueAdapter<A, ForwardIterator>(first), + return storage_.Insert(pos, + IteratorValueAdapter<A, ForwardIterator>(first), std::distance(first, last)); } else { return const_cast<iterator>(pos); @@ -627,7 +627,7 @@ class InlinedVector { // // NOTE: this overload is for iterators that are "input" category. template <typename InputIterator, - DisableIfAtLeastForwardIterator<InputIterator> = 0> + DisableIfAtLeastForwardIterator<InputIterator> = 0> iterator insert(const_iterator pos, InputIterator first, InputIterator last) { ABSL_HARDENING_ASSERT(pos >= begin()); ABSL_HARDENING_ASSERT(pos <= end()); @@ -651,8 +651,8 @@ class InlinedVector { value_type dealias(std::forward<Args>(args)...); return storage_.Insert(pos, - IteratorValueAdapter<A, MoveIterator<A>>( - MoveIterator<A>(std::addressof(dealias))), + IteratorValueAdapter<A, MoveIterator<A>>( + MoveIterator<A>(std::addressof(dealias))), 1); } @@ -672,7 +672,7 @@ class InlinedVector { // Overload of `InlinedVector::push_back(...)` for inserting `v` at `end()` // using move semantics. - void push_back(value_type&& v) { + void push_back(value_type&& v) { static_cast<void>(emplace_back(std::move(v))); } @@ -682,7 +682,7 @@ class InlinedVector { void pop_back() noexcept { ABSL_HARDENING_ASSERT(!empty()); - AllocatorTraits<A>::destroy(storage_.GetAllocator(), data() + (size() - 1)); + AllocatorTraits<A>::destroy(storage_.GetAllocator(), data() + (size() - 1)); storage_.SubtractSize(1); } @@ -721,8 +721,8 @@ class InlinedVector { // Destroys all elements in the inlined vector, setting the size to `0` and // deallocating any held memory. void clear() noexcept { - inlined_vector_internal::DestroyElements<A>(storage_.GetAllocator(), data(), - size()); + inlined_vector_internal::DestroyElements<A>(storage_.GetAllocator(), data(), + size()); storage_.DeallocateIfAllocated(); storage_.SetInlinedSize(0); @@ -735,12 +735,12 @@ class InlinedVector { // `InlinedVector::shrink_to_fit()` // - // Attempts to reduce memory usage by moving elements to (or keeping elements - // in) the smallest available buffer sufficient for containing `size()` - // elements. + // Attempts to reduce memory usage by moving elements to (or keeping elements + // in) the smallest available buffer sufficient for containing `size()` + // elements. // - // If `size()` is sufficiently small, the elements will be moved into (or kept - // in) the inlined space. + // If `size()` is sufficiently small, the elements will be moved into (or kept + // in) the inlined space. void shrink_to_fit() { if (storage_.GetIsAllocated()) { storage_.ShrinkToFit(); diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/absl_hashtablez_sampler/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/absl_hashtablez_sampler/ya.make index 54874c0466..671ade908f 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/absl_hashtablez_sampler/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/absl_hashtablez_sampler/ya.make @@ -13,24 +13,24 @@ LICENSE(Apache-2.0) PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/base - contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/low_level_alloc contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/raw_logging contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/throw_delegate contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity - contrib/restricted/abseil-cpp-tstring/y_absl/debugging - contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace - contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize - contrib/restricted/abseil-cpp-tstring/y_absl/demangle + contrib/restricted/abseil-cpp-tstring/y_absl/debugging + contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace + contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize + contrib/restricted/abseil-cpp-tstring/y_absl/demangle contrib/restricted/abseil-cpp-tstring/y_absl/numeric - contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased contrib/restricted/abseil-cpp-tstring/y_absl/strings - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp-tstring/y_absl/synchronization - contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal - contrib/restricted/abseil-cpp-tstring/y_absl/time - contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time - contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp-tstring/y_absl/synchronization + contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal + contrib/restricted/abseil-cpp-tstring/y_absl/time + contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time + contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone ) ADDINCL( @@ -39,11 +39,11 @@ ADDINCL( NO_COMPILER_WARNINGS() -SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/container/internal) +SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/container/internal) SRCS( - hashtablez_sampler.cc - hashtablez_sampler_force_weak_definition.cc + hashtablez_sampler.cc + hashtablez_sampler_force_weak_definition.cc ) END() diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/btree.h b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/btree.h index a249260811..c8302a9b12 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/btree.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/btree.h @@ -88,13 +88,13 @@ struct StringBtreeDefaultLess { // Compatibility constructor. StringBtreeDefaultLess(std::less<TString>) {} // NOLINT - StringBtreeDefaultLess(std::less<y_absl::string_view>) {} // NOLINT - - // Allow converting to std::less for use in key_comp()/value_comp(). - explicit operator std::less<TString>() const { return {}; } - explicit operator std::less<y_absl::string_view>() const { return {}; } - explicit operator std::less<y_absl::Cord>() const { return {}; } + StringBtreeDefaultLess(std::less<y_absl::string_view>) {} // NOLINT + // Allow converting to std::less for use in key_comp()/value_comp(). + explicit operator std::less<TString>() const { return {}; } + explicit operator std::less<y_absl::string_view>() const { return {}; } + explicit operator std::less<y_absl::Cord>() const { return {}; } + y_absl::weak_ordering operator()(y_absl::string_view lhs, y_absl::string_view rhs) const { return compare_internal::compare_result_as_ordering(lhs.compare(rhs)); @@ -120,13 +120,13 @@ struct StringBtreeDefaultGreater { StringBtreeDefaultGreater() = default; StringBtreeDefaultGreater(std::greater<TString>) {} // NOLINT - StringBtreeDefaultGreater(std::greater<y_absl::string_view>) {} // NOLINT - - // Allow converting to std::greater for use in key_comp()/value_comp(). - explicit operator std::greater<TString>() const { return {}; } - explicit operator std::greater<y_absl::string_view>() const { return {}; } - explicit operator std::greater<y_absl::Cord>() const { return {}; } + StringBtreeDefaultGreater(std::greater<y_absl::string_view>) {} // NOLINT + // Allow converting to std::greater for use in key_comp()/value_comp(). + explicit operator std::greater<TString>() const { return {}; } + explicit operator std::greater<y_absl::string_view>() const { return {}; } + explicit operator std::greater<y_absl::Cord>() const { return {}; } + y_absl::weak_ordering operator()(y_absl::string_view lhs, y_absl::string_view rhs) const { return compare_internal::compare_result_as_ordering(rhs.compare(lhs)); @@ -227,8 +227,8 @@ struct prefers_linear_node_search< template <typename Key, typename Compare, typename Alloc, int TargetNodeSize, bool Multi, typename SlotPolicy> struct common_params { - using original_key_compare = Compare; - + using original_key_compare = Compare; + // If Compare is a common comparator for a string-like type, then we adapt it // to use heterogeneous lookup and to be a key-compare-to comparator. using key_compare = typename key_compare_to_adapter<Compare>::type; @@ -329,21 +329,21 @@ struct map_params : common_params<Key, Compare, Alloc, TargetNodeSize, Multi, using value_type = typename super_type::value_type; using init_type = typename super_type::init_type; - using original_key_compare = typename super_type::original_key_compare; - // Reference: https://en.cppreference.com/w/cpp/container/map/value_compare - class value_compare { - template <typename Params> - friend class btree; - - protected: - explicit value_compare(original_key_compare c) : comp(std::move(c)) {} - - original_key_compare comp; // NOLINT - - public: - auto operator()(const value_type &lhs, const value_type &rhs) const - -> decltype(comp(lhs.first, rhs.first)) { - return comp(lhs.first, rhs.first); + using original_key_compare = typename super_type::original_key_compare; + // Reference: https://en.cppreference.com/w/cpp/container/map/value_compare + class value_compare { + template <typename Params> + friend class btree; + + protected: + explicit value_compare(original_key_compare c) : comp(std::move(c)) {} + + original_key_compare comp; // NOLINT + + public: + auto operator()(const value_type &lhs, const value_type &rhs) const + -> decltype(comp(lhs.first, rhs.first)) { + return comp(lhs.first, rhs.first); } }; using is_map_container = std::true_type; @@ -409,8 +409,8 @@ struct set_params : common_params<Key, Compare, Alloc, TargetNodeSize, Multi, set_slot_policy<Key>> { using value_type = Key; using slot_type = typename set_params::common_params::slot_type; - using value_compare = - typename set_params::common_params::original_key_compare; + using value_compare = + typename set_params::common_params::original_key_compare; using is_map_container = std::false_type; template <typename V> @@ -502,8 +502,8 @@ class btree_node { std::is_same<std::greater<key_type>, key_compare>::value)>; - // This class is organized by y_absl::container_internal::Layout as if it had - // the following structure: + // This class is organized by y_absl::container_internal::Layout as if it had + // the following structure: // // A pointer to the node's parent. // btree_node *parent; // @@ -1147,7 +1147,7 @@ class btree { using size_type = typename Params::size_type; using difference_type = typename Params::difference_type; using key_compare = typename Params::key_compare; - using original_key_compare = typename Params::original_key_compare; + using original_key_compare = typename Params::original_key_compare; using value_compare = typename Params::value_compare; using allocator_type = typename Params::allocator_type; using reference = typename Params::reference; @@ -1357,9 +1357,9 @@ class btree { return compare_internal::compare_result_as_less_than(key_comp()(a, b)); } - value_compare value_comp() const { - return value_compare(original_key_compare(key_comp())); - } + value_compare value_comp() const { + return value_compare(original_key_compare(key_comp())); + } // Verifies the structure of the btree. void verify() const; diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/btree_container.h b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/btree_container.h index d23feff31b..557bccbd51 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/btree_container.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/btree_container.h @@ -20,7 +20,7 @@ #include <iterator> #include <utility> -#include "y_absl/base/attributes.h" +#include "y_absl/base/attributes.h" #include "y_absl/base/internal/throw_delegate.h" #include "y_absl/container/internal/btree.h" // IWYU pragma: export #include "y_absl/container/internal/common.h" @@ -52,7 +52,7 @@ class btree_container { using value_type = typename Tree::value_type; using size_type = typename Tree::size_type; using difference_type = typename Tree::difference_type; - using key_compare = typename Tree::original_key_compare; + using key_compare = typename Tree::original_key_compare; using value_compare = typename Tree::value_compare; using allocator_type = typename Tree::allocator_type; using reference = typename Tree::reference; @@ -177,7 +177,7 @@ class btree_container { } // Utility routines. - ABSL_ATTRIBUTE_REINITIALIZES void clear() { tree_.clear(); } + ABSL_ATTRIBUTE_REINITIALIZES void clear() { tree_.clear(); } void swap(btree_container &other) { tree_.swap(other.tree_); } void verify() const { tree_.verify(); } @@ -215,7 +215,7 @@ class btree_container { allocator_type get_allocator() const { return tree_.get_allocator(); } // The key comparator used by the btree. - key_compare key_comp() const { return key_compare(tree_.key_comp()); } + key_compare key_comp() const { return key_compare(tree_.key_comp()); } value_compare value_comp() const { return tree_.value_comp(); } // Support y_absl::Hash. @@ -248,7 +248,7 @@ class btree_set_container : public btree_container<Tree> { using key_type = typename Tree::key_type; using value_type = typename Tree::value_type; using size_type = typename Tree::size_type; - using key_compare = typename Tree::original_key_compare; + using key_compare = typename Tree::original_key_compare; using allocator_type = typename Tree::allocator_type; using iterator = typename Tree::iterator; using const_iterator = typename Tree::const_iterator; @@ -399,7 +399,7 @@ class btree_map_container : public btree_set_container<Tree> { using key_type = typename Tree::key_type; using mapped_type = typename params_type::mapped_type; using value_type = typename Tree::value_type; - using key_compare = typename Tree::original_key_compare; + using key_compare = typename Tree::original_key_compare; using allocator_type = typename Tree::allocator_type; using iterator = typename Tree::iterator; using const_iterator = typename Tree::const_iterator; @@ -544,7 +544,7 @@ class btree_multiset_container : public btree_container<Tree> { using key_type = typename Tree::key_type; using value_type = typename Tree::value_type; using size_type = typename Tree::size_type; - using key_compare = typename Tree::original_key_compare; + using key_compare = typename Tree::original_key_compare; using allocator_type = typename Tree::allocator_type; using iterator = typename Tree::iterator; using const_iterator = typename Tree::const_iterator; diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/hash_function_defaults.h b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/hash_function_defaults.h index 68a18058d1..477d0c278f 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/hash_function_defaults.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/hash_function_defaults.h @@ -78,26 +78,26 @@ struct StringHash { } }; -struct StringEq { - using is_transparent = void; - bool operator()(y_absl::string_view lhs, y_absl::string_view rhs) const { - return lhs == rhs; - } - bool operator()(const y_absl::Cord& lhs, const y_absl::Cord& rhs) const { - return lhs == rhs; - } - bool operator()(const y_absl::Cord& lhs, y_absl::string_view rhs) const { - return lhs == rhs; - } - bool operator()(y_absl::string_view lhs, const y_absl::Cord& rhs) const { - return lhs == rhs; - } -}; - +struct StringEq { + using is_transparent = void; + bool operator()(y_absl::string_view lhs, y_absl::string_view rhs) const { + return lhs == rhs; + } + bool operator()(const y_absl::Cord& lhs, const y_absl::Cord& rhs) const { + return lhs == rhs; + } + bool operator()(const y_absl::Cord& lhs, y_absl::string_view rhs) const { + return lhs == rhs; + } + bool operator()(y_absl::string_view lhs, const y_absl::Cord& rhs) const { + return lhs == rhs; + } +}; + // Supports heterogeneous lookup for string-like elements. struct StringHashEq { using Hash = StringHash; - using Eq = StringEq; + using Eq = StringEq; }; template <> diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/hash_generator_testing.h b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/hash_generator_testing.h index 79b215465e..a3c6bca1fb 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/hash_generator_testing.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/hash_generator_testing.h @@ -21,13 +21,13 @@ #include <stdint.h> #include <algorithm> -#include <cassert> +#include <cassert> #include <iosfwd> #include <random> #include <tuple> #include <type_traits> #include <utility> -#include <vector> +#include <vector> #include "y_absl/container/internal/hash_policy_testing.h" #include "y_absl/memory/memory.h" @@ -155,25 +155,25 @@ using GeneratedType = decltype( typename Container::value_type, typename Container::key_type>::type>&>()()); -// Naive wrapper that performs a linear search of previous values. -// Beware this is O(SQR), which is reasonable for smaller kMaxValues. -template <class T, size_t kMaxValues = 64, class E = void> -struct UniqueGenerator { - Generator<T, E> gen; - std::vector<T> values; - - T operator()() { - assert(values.size() < kMaxValues); - for (;;) { - T value = gen(); - if (std::find(values.begin(), values.end(), value) == values.end()) { - values.push_back(value); - return value; - } - } - } -}; - +// Naive wrapper that performs a linear search of previous values. +// Beware this is O(SQR), which is reasonable for smaller kMaxValues. +template <class T, size_t kMaxValues = 64, class E = void> +struct UniqueGenerator { + Generator<T, E> gen; + std::vector<T> values; + + T operator()() { + assert(values.size() < kMaxValues); + for (;;) { + T value = gen(); + if (std::find(values.begin(), values.end(), value) == values.end()) { + values.push_back(value); + return value; + } + } + } +}; + } // namespace hash_internal } // namespace container_internal ABSL_NAMESPACE_END diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/hashtablez_sampler.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/hashtablez_sampler.cc index 6017ac9bb0..ab50d607cd 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/hashtablez_sampler.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/hashtablez_sampler.cc @@ -24,8 +24,8 @@ #include "y_absl/container/internal/have_sse.h" #include "y_absl/debugging/stacktrace.h" #include "y_absl/memory/memory.h" -#include "y_absl/profiling/internal/exponential_biased.h" -#include "y_absl/profiling/internal/sample_recorder.h" +#include "y_absl/profiling/internal/exponential_biased.h" +#include "y_absl/profiling/internal/sample_recorder.h" #include "y_absl/synchronization/mutex.h" namespace y_absl { @@ -40,7 +40,7 @@ ABSL_CONST_INIT std::atomic<bool> g_hashtablez_enabled{ ABSL_CONST_INIT std::atomic<int32_t> g_hashtablez_sample_parameter{1 << 10}; #if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) -ABSL_PER_THREAD_TLS_KEYWORD y_absl::profiling_internal::ExponentialBiased +ABSL_PER_THREAD_TLS_KEYWORD y_absl::profiling_internal::ExponentialBiased g_exponential_biased_generator; #endif @@ -50,14 +50,14 @@ ABSL_PER_THREAD_TLS_KEYWORD y_absl::profiling_internal::ExponentialBiased ABSL_PER_THREAD_TLS_KEYWORD int64_t global_next_sample = 0; #endif // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) -HashtablezSampler& GlobalHashtablezSampler() { +HashtablezSampler& GlobalHashtablezSampler() { static auto* sampler = new HashtablezSampler(); return *sampler; } -// TODO(bradleybear): The comments at this constructors declaration say that the -// fields are not initialized, but this definition does initialize the fields. -// Something needs to be cleaned up. +// TODO(bradleybear): The comments at this constructors declaration say that the +// fields are not initialized, but this definition does initialize the fields. +// Something needs to be cleaned up. HashtablezInfo::HashtablezInfo() { PrepareForSampling(); } HashtablezInfo::~HashtablezInfo() = default; @@ -71,7 +71,7 @@ void HashtablezInfo::PrepareForSampling() { hashes_bitwise_or.store(0, std::memory_order_relaxed); hashes_bitwise_and.store(~size_t{}, std::memory_order_relaxed); hashes_bitwise_xor.store(0, std::memory_order_relaxed); - max_reserve.store(0, std::memory_order_relaxed); + max_reserve.store(0, std::memory_order_relaxed); create_time = y_absl::Now(); // The inliner makes hardcoded skip_count difficult (especially when combined @@ -101,12 +101,12 @@ static bool ShouldForceSampling() { return state == kForce; } -HashtablezInfo* SampleSlow(int64_t* next_sample, size_t inline_element_size) { +HashtablezInfo* SampleSlow(int64_t* next_sample, size_t inline_element_size) { if (ABSL_PREDICT_FALSE(ShouldForceSampling())) { *next_sample = 1; - HashtablezInfo* result = GlobalHashtablezSampler().Register(); - result->inline_element_size = inline_element_size; - return result; + HashtablezInfo* result = GlobalHashtablezSampler().Register(); + result->inline_element_size = inline_element_size; + return result; } #if !defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) @@ -128,17 +128,17 @@ HashtablezInfo* SampleSlow(int64_t* next_sample, size_t inline_element_size) { // that case. if (first) { if (ABSL_PREDICT_TRUE(--*next_sample > 0)) return nullptr; - return SampleSlow(next_sample, inline_element_size); + return SampleSlow(next_sample, inline_element_size); } - HashtablezInfo* result = GlobalHashtablezSampler().Register(); - result->inline_element_size = inline_element_size; - return result; + HashtablezInfo* result = GlobalHashtablezSampler().Register(); + result->inline_element_size = inline_element_size; + return result; #endif } void UnsampleSlow(HashtablezInfo* info) { - GlobalHashtablezSampler().Unregister(info); + GlobalHashtablezSampler().Unregister(info); } void RecordInsertSlow(HashtablezInfo* info, size_t hash, @@ -178,7 +178,7 @@ void SetHashtablezSampleParameter(int32_t rate) { void SetHashtablezMaxSamples(int32_t max) { if (max > 0) { - GlobalHashtablezSampler().SetMaxSamples(max); + GlobalHashtablezSampler().SetMaxSamples(max); } else { ABSL_RAW_LOG(ERROR, "Invalid hashtablez max samples: %lld", static_cast<long long>(max)); // NOLINT(runtime/int) diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/hashtablez_sampler.h b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/hashtablez_sampler.h index 8521ee754a..caaacafcaf 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/hashtablez_sampler.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/hashtablez_sampler.h @@ -47,7 +47,7 @@ #include "y_absl/base/internal/per_thread_tls.h" #include "y_absl/base/optimization.h" #include "y_absl/container/internal/have_sse.h" -#include "y_absl/profiling/internal/sample_recorder.h" +#include "y_absl/profiling/internal/sample_recorder.h" #include "y_absl/synchronization/mutex.h" #include "y_absl/utility/utility.h" @@ -58,7 +58,7 @@ namespace container_internal { // Stores information about a sampled hashtable. All mutations to this *must* // be made through `Record*` functions below. All reads from this *must* only // occur in the callback to `HashtablezSampler::Iterate`. -struct HashtablezInfo : public profiling_internal::Sample<HashtablezInfo> { +struct HashtablezInfo : public profiling_internal::Sample<HashtablezInfo> { // Constructs the object but does not fill in any fields. HashtablezInfo(); ~HashtablezInfo(); @@ -80,7 +80,7 @@ struct HashtablezInfo : public profiling_internal::Sample<HashtablezInfo> { std::atomic<size_t> hashes_bitwise_or; std::atomic<size_t> hashes_bitwise_and; std::atomic<size_t> hashes_bitwise_xor; - std::atomic<size_t> max_reserve; + std::atomic<size_t> max_reserve; // All of the fields below are set by `PrepareForSampling`, they must not be // mutated in `Record*` functions. They are logically `const` in that sense. @@ -91,7 +91,7 @@ struct HashtablezInfo : public profiling_internal::Sample<HashtablezInfo> { y_absl::Time create_time; int32_t depth; void* stack[kMaxStackDepth]; - size_t inline_element_size; + size_t inline_element_size; }; inline void RecordRehashSlow(HashtablezInfo* info, size_t total_probe_length) { @@ -109,18 +109,18 @@ inline void RecordRehashSlow(HashtablezInfo* info, size_t total_probe_length) { std::memory_order_relaxed); } -inline void RecordReservationSlow(HashtablezInfo* info, - size_t target_capacity) { - info->max_reserve.store( - (std::max)(info->max_reserve.load(std::memory_order_relaxed), - target_capacity), - std::memory_order_relaxed); -} - -inline void RecordClearedReservationSlow(HashtablezInfo* info) { - info->max_reserve.store(0, std::memory_order_relaxed); -} - +inline void RecordReservationSlow(HashtablezInfo* info, + size_t target_capacity) { + info->max_reserve.store( + (std::max)(info->max_reserve.load(std::memory_order_relaxed), + target_capacity), + std::memory_order_relaxed); +} + +inline void RecordClearedReservationSlow(HashtablezInfo* info) { + info->max_reserve.store(0, std::memory_order_relaxed); +} + inline void RecordStorageChangedSlow(HashtablezInfo* info, size_t size, size_t capacity) { info->size.store(size, std::memory_order_relaxed); @@ -144,7 +144,7 @@ inline void RecordEraseSlow(HashtablezInfo* info) { std::memory_order_relaxed); } -HashtablezInfo* SampleSlow(int64_t* next_sample, size_t inline_element_size); +HashtablezInfo* SampleSlow(int64_t* next_sample, size_t inline_element_size); void UnsampleSlow(HashtablezInfo* info); #if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) @@ -184,16 +184,16 @@ class HashtablezInfoHandle { RecordRehashSlow(info_, total_probe_length); } - inline void RecordReservation(size_t target_capacity) { - if (ABSL_PREDICT_TRUE(info_ == nullptr)) return; - RecordReservationSlow(info_, target_capacity); - } - - inline void RecordClearedReservation() { - if (ABSL_PREDICT_TRUE(info_ == nullptr)) return; - RecordClearedReservationSlow(info_); - } - + inline void RecordReservation(size_t target_capacity) { + if (ABSL_PREDICT_TRUE(info_ == nullptr)) return; + RecordReservationSlow(info_, target_capacity); + } + + inline void RecordClearedReservation() { + if (ABSL_PREDICT_TRUE(info_ == nullptr)) return; + RecordClearedReservationSlow(info_); + } + inline void RecordInsert(size_t hash, size_t distance_from_desired) { if (ABSL_PREDICT_TRUE(info_ == nullptr)) return; RecordInsertSlow(info_, hash, distance_from_desired); @@ -223,8 +223,8 @@ class HashtablezInfoHandle { inline void RecordStorageChanged(size_t /*size*/, size_t /*capacity*/) {} inline void RecordRehash(size_t /*total_probe_length*/) {} - inline void RecordReservation(size_t /*target_capacity*/) {} - inline void RecordClearedReservation() {} + inline void RecordReservation(size_t /*target_capacity*/) {} + inline void RecordClearedReservation() {} inline void RecordInsert(size_t /*hash*/, size_t /*distance_from_desired*/) {} inline void RecordErase() {} @@ -239,24 +239,24 @@ extern ABSL_PER_THREAD_TLS_KEYWORD int64_t global_next_sample; // Returns an RAII sampling handle that manages registration and unregistation // with the global sampler. -inline HashtablezInfoHandle Sample( - size_t inline_element_size ABSL_ATTRIBUTE_UNUSED) { +inline HashtablezInfoHandle Sample( + size_t inline_element_size ABSL_ATTRIBUTE_UNUSED) { #if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) if (ABSL_PREDICT_TRUE(--global_next_sample > 0)) { return HashtablezInfoHandle(nullptr); } - return HashtablezInfoHandle( - SampleSlow(&global_next_sample, inline_element_size)); + return HashtablezInfoHandle( + SampleSlow(&global_next_sample, inline_element_size)); #else return HashtablezInfoHandle(nullptr); #endif // !ABSL_PER_THREAD_TLS } -using HashtablezSampler = - ::y_absl::profiling_internal::SampleRecorder<HashtablezInfo>; +using HashtablezSampler = + ::y_absl::profiling_internal::SampleRecorder<HashtablezInfo>; -// Returns a global Sampler. -HashtablezSampler& GlobalHashtablezSampler(); +// Returns a global Sampler. +HashtablezSampler& GlobalHashtablezSampler(); // Enables or disables sampling for Swiss tables. void SetHashtablezEnabled(bool enabled); diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/inlined_vector.h b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/inlined_vector.h index e6488e843e..436fb1b457 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/inlined_vector.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/inlined_vector.h @@ -21,11 +21,11 @@ #include <iterator> #include <limits> #include <memory> -#include <new> -#include <type_traits> +#include <new> +#include <type_traits> #include <utility> -#include "y_absl/base/attributes.h" +#include "y_absl/base/attributes.h" #include "y_absl/base/macros.h" #include "y_absl/container/internal/compressed_tuple.h" #include "y_absl/memory/memory.h" @@ -39,132 +39,132 @@ namespace inlined_vector_internal { // GCC does not deal very well with the below code #if !defined(__clang__) && defined(__GNUC__) #pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Warray-bounds" +#pragma GCC diagnostic ignored "-Warray-bounds" #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif -template <typename A> -using AllocatorTraits = std::allocator_traits<A>; -template <typename A> -using ValueType = typename AllocatorTraits<A>::value_type; -template <typename A> -using SizeType = typename AllocatorTraits<A>::size_type; -template <typename A> -using Pointer = typename AllocatorTraits<A>::pointer; -template <typename A> -using ConstPointer = typename AllocatorTraits<A>::const_pointer; -template <typename A> -using SizeType = typename AllocatorTraits<A>::size_type; -template <typename A> -using DifferenceType = typename AllocatorTraits<A>::difference_type; -template <typename A> -using Reference = ValueType<A>&; -template <typename A> -using ConstReference = const ValueType<A>&; -template <typename A> -using Iterator = Pointer<A>; -template <typename A> -using ConstIterator = ConstPointer<A>; -template <typename A> -using ReverseIterator = typename std::reverse_iterator<Iterator<A>>; -template <typename A> -using ConstReverseIterator = typename std::reverse_iterator<ConstIterator<A>>; -template <typename A> -using MoveIterator = typename std::move_iterator<Iterator<A>>; - +template <typename A> +using AllocatorTraits = std::allocator_traits<A>; +template <typename A> +using ValueType = typename AllocatorTraits<A>::value_type; +template <typename A> +using SizeType = typename AllocatorTraits<A>::size_type; +template <typename A> +using Pointer = typename AllocatorTraits<A>::pointer; +template <typename A> +using ConstPointer = typename AllocatorTraits<A>::const_pointer; +template <typename A> +using SizeType = typename AllocatorTraits<A>::size_type; +template <typename A> +using DifferenceType = typename AllocatorTraits<A>::difference_type; +template <typename A> +using Reference = ValueType<A>&; +template <typename A> +using ConstReference = const ValueType<A>&; +template <typename A> +using Iterator = Pointer<A>; +template <typename A> +using ConstIterator = ConstPointer<A>; +template <typename A> +using ReverseIterator = typename std::reverse_iterator<Iterator<A>>; +template <typename A> +using ConstReverseIterator = typename std::reverse_iterator<ConstIterator<A>>; +template <typename A> +using MoveIterator = typename std::move_iterator<Iterator<A>>; + template <typename Iterator> using IsAtLeastForwardIterator = std::is_convertible< typename std::iterator_traits<Iterator>::iterator_category, std::forward_iterator_tag>; -template <typename A> +template <typename A> using IsMemcpyOk = - y_absl::conjunction<std::is_same<A, std::allocator<ValueType<A>>>, - y_absl::is_trivially_copy_constructible<ValueType<A>>, - y_absl::is_trivially_copy_assignable<ValueType<A>>, - y_absl::is_trivially_destructible<ValueType<A>>>; - -template <typename T> -struct TypeIdentity { - using type = T; -}; - -// Used for function arguments in template functions to prevent ADL by forcing -// callers to explicitly specify the template parameter. -template <typename T> -using NoTypeDeduction = typename TypeIdentity<T>::type; - -template <typename A> -void DestroyElements(NoTypeDeduction<A>& allocator, Pointer<A> destroy_first, - SizeType<A> destroy_size) { + y_absl::conjunction<std::is_same<A, std::allocator<ValueType<A>>>, + y_absl::is_trivially_copy_constructible<ValueType<A>>, + y_absl::is_trivially_copy_assignable<ValueType<A>>, + y_absl::is_trivially_destructible<ValueType<A>>>; + +template <typename T> +struct TypeIdentity { + using type = T; +}; + +// Used for function arguments in template functions to prevent ADL by forcing +// callers to explicitly specify the template parameter. +template <typename T> +using NoTypeDeduction = typename TypeIdentity<T>::type; + +template <typename A> +void DestroyElements(NoTypeDeduction<A>& allocator, Pointer<A> destroy_first, + SizeType<A> destroy_size) { if (destroy_first != nullptr) { - for (SizeType<A> i = destroy_size; i != 0;) { + for (SizeType<A> i = destroy_size; i != 0;) { --i; - AllocatorTraits<A>::destroy(allocator, destroy_first + i); + AllocatorTraits<A>::destroy(allocator, destroy_first + i); } } } -template <typename A> -struct Allocation { - Pointer<A> data; - SizeType<A> capacity; -}; - -template <typename A, - bool IsOverAligned = - (alignof(ValueType<A>) > ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT)> -struct MallocAdapter { - static Allocation<A> Allocate(A& allocator, SizeType<A> requested_capacity) { - return {AllocatorTraits<A>::allocate(allocator, requested_capacity), - requested_capacity}; - } - - static void Deallocate(A& allocator, Pointer<A> pointer, - SizeType<A> capacity) { - AllocatorTraits<A>::deallocate(allocator, pointer, capacity); - } -}; - -template <typename A, typename ValueAdapter> -void ConstructElements(NoTypeDeduction<A>& allocator, - Pointer<A> construct_first, ValueAdapter& values, - SizeType<A> construct_size) { - for (SizeType<A> i = 0; i < construct_size; ++i) { - ABSL_INTERNAL_TRY { values.ConstructNext(allocator, construct_first + i); } +template <typename A> +struct Allocation { + Pointer<A> data; + SizeType<A> capacity; +}; + +template <typename A, + bool IsOverAligned = + (alignof(ValueType<A>) > ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT)> +struct MallocAdapter { + static Allocation<A> Allocate(A& allocator, SizeType<A> requested_capacity) { + return {AllocatorTraits<A>::allocate(allocator, requested_capacity), + requested_capacity}; + } + + static void Deallocate(A& allocator, Pointer<A> pointer, + SizeType<A> capacity) { + AllocatorTraits<A>::deallocate(allocator, pointer, capacity); + } +}; + +template <typename A, typename ValueAdapter> +void ConstructElements(NoTypeDeduction<A>& allocator, + Pointer<A> construct_first, ValueAdapter& values, + SizeType<A> construct_size) { + for (SizeType<A> i = 0; i < construct_size; ++i) { + ABSL_INTERNAL_TRY { values.ConstructNext(allocator, construct_first + i); } ABSL_INTERNAL_CATCH_ANY { - DestroyElements<A>(allocator, construct_first, i); + DestroyElements<A>(allocator, construct_first, i); ABSL_INTERNAL_RETHROW; } } } -template <typename A, typename ValueAdapter> -void AssignElements(Pointer<A> assign_first, ValueAdapter& values, - SizeType<A> assign_size) { - for (SizeType<A> i = 0; i < assign_size; ++i) { - values.AssignNext(assign_first + i); +template <typename A, typename ValueAdapter> +void AssignElements(Pointer<A> assign_first, ValueAdapter& values, + SizeType<A> assign_size) { + for (SizeType<A> i = 0; i < assign_size; ++i) { + values.AssignNext(assign_first + i); } } -template <typename A> +template <typename A> struct StorageView { - Pointer<A> data; - SizeType<A> size; - SizeType<A> capacity; + Pointer<A> data; + SizeType<A> size; + SizeType<A> capacity; }; -template <typename A, typename Iterator> +template <typename A, typename Iterator> class IteratorValueAdapter { public: explicit IteratorValueAdapter(const Iterator& it) : it_(it) {} - void ConstructNext(A& allocator, Pointer<A> construct_at) { - AllocatorTraits<A>::construct(allocator, construct_at, *it_); + void ConstructNext(A& allocator, Pointer<A> construct_at) { + AllocatorTraits<A>::construct(allocator, construct_at, *it_); ++it_; } - void AssignNext(Pointer<A> assign_at) { + void AssignNext(Pointer<A> assign_at) { *assign_at = *it_; ++it_; } @@ -173,123 +173,123 @@ class IteratorValueAdapter { Iterator it_; }; -template <typename A> +template <typename A> class CopyValueAdapter { public: - explicit CopyValueAdapter(ConstPointer<A> p) : ptr_(p) {} + explicit CopyValueAdapter(ConstPointer<A> p) : ptr_(p) {} - void ConstructNext(A& allocator, Pointer<A> construct_at) { - AllocatorTraits<A>::construct(allocator, construct_at, *ptr_); + void ConstructNext(A& allocator, Pointer<A> construct_at) { + AllocatorTraits<A>::construct(allocator, construct_at, *ptr_); } - void AssignNext(Pointer<A> assign_at) { *assign_at = *ptr_; } + void AssignNext(Pointer<A> assign_at) { *assign_at = *ptr_; } private: - ConstPointer<A> ptr_; + ConstPointer<A> ptr_; }; -template <typename A> +template <typename A> class DefaultValueAdapter { public: explicit DefaultValueAdapter() {} - void ConstructNext(A& allocator, Pointer<A> construct_at) { - AllocatorTraits<A>::construct(allocator, construct_at); + void ConstructNext(A& allocator, Pointer<A> construct_at) { + AllocatorTraits<A>::construct(allocator, construct_at); } - void AssignNext(Pointer<A> assign_at) { *assign_at = ValueType<A>(); } + void AssignNext(Pointer<A> assign_at) { *assign_at = ValueType<A>(); } }; -template <typename A> +template <typename A> class AllocationTransaction { public: - explicit AllocationTransaction(A& allocator) - : allocator_data_(allocator, nullptr), capacity_(0) {} + explicit AllocationTransaction(A& allocator) + : allocator_data_(allocator, nullptr), capacity_(0) {} ~AllocationTransaction() { if (DidAllocate()) { - MallocAdapter<A>::Deallocate(GetAllocator(), GetData(), GetCapacity()); + MallocAdapter<A>::Deallocate(GetAllocator(), GetData(), GetCapacity()); } } AllocationTransaction(const AllocationTransaction&) = delete; void operator=(const AllocationTransaction&) = delete; - A& GetAllocator() { return allocator_data_.template get<0>(); } - Pointer<A>& GetData() { return allocator_data_.template get<1>(); } - SizeType<A>& GetCapacity() { return capacity_; } + A& GetAllocator() { return allocator_data_.template get<0>(); } + Pointer<A>& GetData() { return allocator_data_.template get<1>(); } + SizeType<A>& GetCapacity() { return capacity_; } bool DidAllocate() { return GetData() != nullptr; } - - Pointer<A> Allocate(SizeType<A> requested_capacity) { - Allocation<A> result = - MallocAdapter<A>::Allocate(GetAllocator(), requested_capacity); - GetData() = result.data; - GetCapacity() = result.capacity; - return result.data; - } - - ABSL_MUST_USE_RESULT Allocation<A> Release() && { - Allocation<A> result = {GetData(), GetCapacity()}; - Reset(); - return result; - } - - private: + + Pointer<A> Allocate(SizeType<A> requested_capacity) { + Allocation<A> result = + MallocAdapter<A>::Allocate(GetAllocator(), requested_capacity); + GetData() = result.data; + GetCapacity() = result.capacity; + return result.data; + } + + ABSL_MUST_USE_RESULT Allocation<A> Release() && { + Allocation<A> result = {GetData(), GetCapacity()}; + Reset(); + return result; + } + + private: void Reset() { GetData() = nullptr; GetCapacity() = 0; } - container_internal::CompressedTuple<A, Pointer<A>> allocator_data_; - SizeType<A> capacity_; + container_internal::CompressedTuple<A, Pointer<A>> allocator_data_; + SizeType<A> capacity_; }; -template <typename A> +template <typename A> class ConstructionTransaction { public: - explicit ConstructionTransaction(A& allocator) - : allocator_data_(allocator, nullptr), size_(0) {} + explicit ConstructionTransaction(A& allocator) + : allocator_data_(allocator, nullptr), size_(0) {} ~ConstructionTransaction() { if (DidConstruct()) { - DestroyElements<A>(GetAllocator(), GetData(), GetSize()); + DestroyElements<A>(GetAllocator(), GetData(), GetSize()); } } ConstructionTransaction(const ConstructionTransaction&) = delete; void operator=(const ConstructionTransaction&) = delete; - A& GetAllocator() { return allocator_data_.template get<0>(); } - Pointer<A>& GetData() { return allocator_data_.template get<1>(); } - SizeType<A>& GetSize() { return size_; } + A& GetAllocator() { return allocator_data_.template get<0>(); } + Pointer<A>& GetData() { return allocator_data_.template get<1>(); } + SizeType<A>& GetSize() { return size_; } bool DidConstruct() { return GetData() != nullptr; } template <typename ValueAdapter> - void Construct(Pointer<A> data, ValueAdapter& values, SizeType<A> size) { - ConstructElements<A>(GetAllocator(), data, values, size); + void Construct(Pointer<A> data, ValueAdapter& values, SizeType<A> size) { + ConstructElements<A>(GetAllocator(), data, values, size); GetData() = data; GetSize() = size; } - void Commit() && { + void Commit() && { GetData() = nullptr; GetSize() = 0; } private: - container_internal::CompressedTuple<A, Pointer<A>> allocator_data_; - SizeType<A> size_; + container_internal::CompressedTuple<A, Pointer<A>> allocator_data_; + SizeType<A> size_; }; template <typename T, size_t N, typename A> class Storage { public: - static SizeType<A> NextCapacity(SizeType<A> current_capacity) { + static SizeType<A> NextCapacity(SizeType<A> current_capacity) { return current_capacity * 2; } - static SizeType<A> ComputeCapacity(SizeType<A> current_capacity, - SizeType<A> requested_capacity) { + static SizeType<A> ComputeCapacity(SizeType<A> current_capacity, + SizeType<A> requested_capacity) { return (std::max)(NextCapacity(current_capacity), requested_capacity); } @@ -297,15 +297,15 @@ class Storage { // Storage Constructors and Destructor // --------------------------------------------------------------------------- - Storage() : metadata_(A(), /* size and is_allocated */ 0) {} + Storage() : metadata_(A(), /* size and is_allocated */ 0) {} - explicit Storage(const A& allocator) - : metadata_(allocator, /* size and is_allocated */ 0) {} + explicit Storage(const A& allocator) + : metadata_(allocator, /* size and is_allocated */ 0) {} ~Storage() { if (GetSizeAndIsAllocated() == 0) { // Empty and not allocated; nothing to do. - } else if (IsMemcpyOk<A>::value) { + } else if (IsMemcpyOk<A>::value) { // No destructors need to be run; just deallocate if necessary. DeallocateIfAllocated(); } else { @@ -317,48 +317,48 @@ class Storage { // Storage Member Accessors // --------------------------------------------------------------------------- - SizeType<A>& GetSizeAndIsAllocated() { return metadata_.template get<1>(); } + SizeType<A>& GetSizeAndIsAllocated() { return metadata_.template get<1>(); } - const SizeType<A>& GetSizeAndIsAllocated() const { + const SizeType<A>& GetSizeAndIsAllocated() const { return metadata_.template get<1>(); } - SizeType<A> GetSize() const { return GetSizeAndIsAllocated() >> 1; } + SizeType<A> GetSize() const { return GetSizeAndIsAllocated() >> 1; } bool GetIsAllocated() const { return GetSizeAndIsAllocated() & 1; } - Pointer<A> GetAllocatedData() { return data_.allocated.allocated_data; } + Pointer<A> GetAllocatedData() { return data_.allocated.allocated_data; } - ConstPointer<A> GetAllocatedData() const { + ConstPointer<A> GetAllocatedData() const { return data_.allocated.allocated_data; } - Pointer<A> GetInlinedData() { - return reinterpret_cast<Pointer<A>>( + Pointer<A> GetInlinedData() { + return reinterpret_cast<Pointer<A>>( std::addressof(data_.inlined.inlined_data[0])); } - ConstPointer<A> GetInlinedData() const { - return reinterpret_cast<ConstPointer<A>>( + ConstPointer<A> GetInlinedData() const { + return reinterpret_cast<ConstPointer<A>>( std::addressof(data_.inlined.inlined_data[0])); } - SizeType<A> GetAllocatedCapacity() const { + SizeType<A> GetAllocatedCapacity() const { return data_.allocated.allocated_capacity; } - SizeType<A> GetInlinedCapacity() const { return static_cast<SizeType<A>>(N); } + SizeType<A> GetInlinedCapacity() const { return static_cast<SizeType<A>>(N); } - StorageView<A> MakeStorageView() { - return GetIsAllocated() ? StorageView<A>{GetAllocatedData(), GetSize(), - GetAllocatedCapacity()} - : StorageView<A>{GetInlinedData(), GetSize(), - GetInlinedCapacity()}; + StorageView<A> MakeStorageView() { + return GetIsAllocated() ? StorageView<A>{GetAllocatedData(), GetSize(), + GetAllocatedCapacity()} + : StorageView<A>{GetInlinedData(), GetSize(), + GetInlinedCapacity()}; } - A& GetAllocator() { return metadata_.template get<0>(); } + A& GetAllocator() { return metadata_.template get<0>(); } - const A& GetAllocator() const { return metadata_.template get<0>(); } + const A& GetAllocator() const { return metadata_.template get<0>(); } // --------------------------------------------------------------------------- // Storage Member Mutators @@ -367,67 +367,67 @@ class Storage { ABSL_ATTRIBUTE_NOINLINE void InitFrom(const Storage& other); template <typename ValueAdapter> - void Initialize(ValueAdapter values, SizeType<A> new_size); + void Initialize(ValueAdapter values, SizeType<A> new_size); template <typename ValueAdapter> - void Assign(ValueAdapter values, SizeType<A> new_size); + void Assign(ValueAdapter values, SizeType<A> new_size); template <typename ValueAdapter> - void Resize(ValueAdapter values, SizeType<A> new_size); + void Resize(ValueAdapter values, SizeType<A> new_size); template <typename ValueAdapter> - Iterator<A> Insert(ConstIterator<A> pos, ValueAdapter values, - SizeType<A> insert_count); + Iterator<A> Insert(ConstIterator<A> pos, ValueAdapter values, + SizeType<A> insert_count); template <typename... Args> - Reference<A> EmplaceBack(Args&&... args); + Reference<A> EmplaceBack(Args&&... args); - Iterator<A> Erase(ConstIterator<A> from, ConstIterator<A> to); + Iterator<A> Erase(ConstIterator<A> from, ConstIterator<A> to); - void Reserve(SizeType<A> requested_capacity); + void Reserve(SizeType<A> requested_capacity); void ShrinkToFit(); void Swap(Storage* other_storage_ptr); void SetIsAllocated() { - GetSizeAndIsAllocated() |= static_cast<SizeType<A>>(1); + GetSizeAndIsAllocated() |= static_cast<SizeType<A>>(1); } void UnsetIsAllocated() { - GetSizeAndIsAllocated() &= ((std::numeric_limits<SizeType<A>>::max)() - 1); + GetSizeAndIsAllocated() &= ((std::numeric_limits<SizeType<A>>::max)() - 1); } - void SetSize(SizeType<A> size) { + void SetSize(SizeType<A> size) { GetSizeAndIsAllocated() = - (size << 1) | static_cast<SizeType<A>>(GetIsAllocated()); + (size << 1) | static_cast<SizeType<A>>(GetIsAllocated()); } - void SetAllocatedSize(SizeType<A> size) { - GetSizeAndIsAllocated() = (size << 1) | static_cast<SizeType<A>>(1); + void SetAllocatedSize(SizeType<A> size) { + GetSizeAndIsAllocated() = (size << 1) | static_cast<SizeType<A>>(1); } - void SetInlinedSize(SizeType<A> size) { - GetSizeAndIsAllocated() = size << static_cast<SizeType<A>>(1); + void SetInlinedSize(SizeType<A> size) { + GetSizeAndIsAllocated() = size << static_cast<SizeType<A>>(1); } - void AddSize(SizeType<A> count) { - GetSizeAndIsAllocated() += count << static_cast<SizeType<A>>(1); + void AddSize(SizeType<A> count) { + GetSizeAndIsAllocated() += count << static_cast<SizeType<A>>(1); } - void SubtractSize(SizeType<A> count) { + void SubtractSize(SizeType<A> count) { assert(count <= GetSize()); - GetSizeAndIsAllocated() -= count << static_cast<SizeType<A>>(1); + GetSizeAndIsAllocated() -= count << static_cast<SizeType<A>>(1); } - void SetAllocation(Allocation<A> allocation) { - data_.allocated.allocated_data = allocation.data; - data_.allocated.allocated_capacity = allocation.capacity; + void SetAllocation(Allocation<A> allocation) { + data_.allocated.allocated_data = allocation.data; + data_.allocated.allocated_capacity = allocation.capacity; } void MemcpyFrom(const Storage& other_storage) { - assert(IsMemcpyOk<A>::value || other_storage.GetIsAllocated()); + assert(IsMemcpyOk<A>::value || other_storage.GetIsAllocated()); GetSizeAndIsAllocated() = other_storage.GetSizeAndIsAllocated(); data_ = other_storage.data_; @@ -435,23 +435,23 @@ class Storage { void DeallocateIfAllocated() { if (GetIsAllocated()) { - MallocAdapter<A>::Deallocate(GetAllocator(), GetAllocatedData(), - GetAllocatedCapacity()); + MallocAdapter<A>::Deallocate(GetAllocator(), GetAllocatedData(), + GetAllocatedCapacity()); } } private: ABSL_ATTRIBUTE_NOINLINE void DestroyContents(); - using Metadata = container_internal::CompressedTuple<A, SizeType<A>>; + using Metadata = container_internal::CompressedTuple<A, SizeType<A>>; struct Allocated { - Pointer<A> allocated_data; - SizeType<A> allocated_capacity; + Pointer<A> allocated_data; + SizeType<A> allocated_capacity; }; struct Inlined { - alignas(ValueType<A>) char inlined_data[sizeof(ValueType<A>[N])]; + alignas(ValueType<A>) char inlined_data[sizeof(ValueType<A>[N])]; }; union Data { @@ -460,7 +460,7 @@ class Storage { }; template <typename... Args> - ABSL_ATTRIBUTE_NOINLINE Reference<A> EmplaceBackSlow(Args&&... args); + ABSL_ATTRIBUTE_NOINLINE Reference<A> EmplaceBackSlow(Args&&... args); Metadata metadata_; Data data_; @@ -468,17 +468,17 @@ class Storage { template <typename T, size_t N, typename A> void Storage<T, N, A>::DestroyContents() { - Pointer<A> data = GetIsAllocated() ? GetAllocatedData() : GetInlinedData(); - DestroyElements<A>(GetAllocator(), data, GetSize()); + Pointer<A> data = GetIsAllocated() ? GetAllocatedData() : GetInlinedData(); + DestroyElements<A>(GetAllocator(), data, GetSize()); DeallocateIfAllocated(); } template <typename T, size_t N, typename A> void Storage<T, N, A>::InitFrom(const Storage& other) { - const SizeType<A> n = other.GetSize(); + const SizeType<A> n = other.GetSize(); assert(n > 0); // Empty sources handled handled in caller. - ConstPointer<A> src; - Pointer<A> dst; + ConstPointer<A> src; + Pointer<A> dst; if (!other.GetIsAllocated()) { dst = GetInlinedData(); src = other.GetInlinedData(); @@ -486,48 +486,48 @@ void Storage<T, N, A>::InitFrom(const Storage& other) { // Because this is only called from the `InlinedVector` constructors, it's // safe to take on the allocation with size `0`. If `ConstructElements(...)` // throws, deallocation will be automatically handled by `~Storage()`. - SizeType<A> requested_capacity = ComputeCapacity(GetInlinedCapacity(), n); - Allocation<A> allocation = - MallocAdapter<A>::Allocate(GetAllocator(), requested_capacity); - SetAllocation(allocation); - dst = allocation.data; + SizeType<A> requested_capacity = ComputeCapacity(GetInlinedCapacity(), n); + Allocation<A> allocation = + MallocAdapter<A>::Allocate(GetAllocator(), requested_capacity); + SetAllocation(allocation); + dst = allocation.data; src = other.GetAllocatedData(); } - if (IsMemcpyOk<A>::value) { - std::memcpy(reinterpret_cast<char*>(dst), - reinterpret_cast<const char*>(src), n * sizeof(ValueType<A>)); + if (IsMemcpyOk<A>::value) { + std::memcpy(reinterpret_cast<char*>(dst), + reinterpret_cast<const char*>(src), n * sizeof(ValueType<A>)); } else { - auto values = IteratorValueAdapter<A, ConstPointer<A>>(src); - ConstructElements<A>(GetAllocator(), dst, values, n); + auto values = IteratorValueAdapter<A, ConstPointer<A>>(src); + ConstructElements<A>(GetAllocator(), dst, values, n); } GetSizeAndIsAllocated() = other.GetSizeAndIsAllocated(); } template <typename T, size_t N, typename A> template <typename ValueAdapter> -auto Storage<T, N, A>::Initialize(ValueAdapter values, SizeType<A> new_size) +auto Storage<T, N, A>::Initialize(ValueAdapter values, SizeType<A> new_size) -> void { // Only callable from constructors! assert(!GetIsAllocated()); assert(GetSize() == 0); - Pointer<A> construct_data; + Pointer<A> construct_data; if (new_size > GetInlinedCapacity()) { // Because this is only called from the `InlinedVector` constructors, it's // safe to take on the allocation with size `0`. If `ConstructElements(...)` // throws, deallocation will be automatically handled by `~Storage()`. - SizeType<A> requested_capacity = - ComputeCapacity(GetInlinedCapacity(), new_size); - Allocation<A> allocation = - MallocAdapter<A>::Allocate(GetAllocator(), requested_capacity); - construct_data = allocation.data; - SetAllocation(allocation); + SizeType<A> requested_capacity = + ComputeCapacity(GetInlinedCapacity(), new_size); + Allocation<A> allocation = + MallocAdapter<A>::Allocate(GetAllocator(), requested_capacity); + construct_data = allocation.data; + SetAllocation(allocation); SetIsAllocated(); } else { construct_data = GetInlinedData(); } - ConstructElements<A>(GetAllocator(), construct_data, values, new_size); + ConstructElements<A>(GetAllocator(), construct_data, values, new_size); // Since the initial size was guaranteed to be `0` and the allocated bit is // already correct for either case, *adding* `new_size` gives us the correct @@ -537,20 +537,20 @@ auto Storage<T, N, A>::Initialize(ValueAdapter values, SizeType<A> new_size) template <typename T, size_t N, typename A> template <typename ValueAdapter> -auto Storage<T, N, A>::Assign(ValueAdapter values, SizeType<A> new_size) - -> void { - StorageView<A> storage_view = MakeStorageView(); +auto Storage<T, N, A>::Assign(ValueAdapter values, SizeType<A> new_size) + -> void { + StorageView<A> storage_view = MakeStorageView(); - AllocationTransaction<A> allocation_tx(GetAllocator()); + AllocationTransaction<A> allocation_tx(GetAllocator()); - y_absl::Span<ValueType<A>> assign_loop; - y_absl::Span<ValueType<A>> construct_loop; - y_absl::Span<ValueType<A>> destroy_loop; + y_absl::Span<ValueType<A>> assign_loop; + y_absl::Span<ValueType<A>> construct_loop; + y_absl::Span<ValueType<A>> destroy_loop; if (new_size > storage_view.capacity) { - SizeType<A> requested_capacity = - ComputeCapacity(storage_view.capacity, new_size); - construct_loop = {allocation_tx.Allocate(requested_capacity), new_size}; + SizeType<A> requested_capacity = + ComputeCapacity(storage_view.capacity, new_size); + construct_loop = {allocation_tx.Allocate(requested_capacity), new_size}; destroy_loop = {storage_view.data, storage_view.size}; } else if (new_size > storage_view.size) { assign_loop = {storage_view.data, storage_view.size}; @@ -561,16 +561,16 @@ auto Storage<T, N, A>::Assign(ValueAdapter values, SizeType<A> new_size) destroy_loop = {storage_view.data + new_size, storage_view.size - new_size}; } - AssignElements<A>(assign_loop.data(), values, assign_loop.size()); + AssignElements<A>(assign_loop.data(), values, assign_loop.size()); - ConstructElements<A>(GetAllocator(), construct_loop.data(), values, - construct_loop.size()); + ConstructElements<A>(GetAllocator(), construct_loop.data(), values, + construct_loop.size()); - DestroyElements<A>(GetAllocator(), destroy_loop.data(), destroy_loop.size()); + DestroyElements<A>(GetAllocator(), destroy_loop.data(), destroy_loop.size()); if (allocation_tx.DidAllocate()) { DeallocateIfAllocated(); - SetAllocation(std::move(allocation_tx).Release()); + SetAllocation(std::move(allocation_tx).Release()); SetIsAllocated(); } @@ -579,18 +579,18 @@ auto Storage<T, N, A>::Assign(ValueAdapter values, SizeType<A> new_size) template <typename T, size_t N, typename A> template <typename ValueAdapter> -auto Storage<T, N, A>::Resize(ValueAdapter values, SizeType<A> new_size) - -> void { - StorageView<A> storage_view = MakeStorageView(); - Pointer<A> const base = storage_view.data; - const SizeType<A> size = storage_view.size; - A& alloc = GetAllocator(); +auto Storage<T, N, A>::Resize(ValueAdapter values, SizeType<A> new_size) + -> void { + StorageView<A> storage_view = MakeStorageView(); + Pointer<A> const base = storage_view.data; + const SizeType<A> size = storage_view.size; + A& alloc = GetAllocator(); if (new_size <= size) { // Destroy extra old elements. - DestroyElements<A>(alloc, base + new_size, size - new_size); + DestroyElements<A>(alloc, base + new_size, size - new_size); } else if (new_size <= storage_view.capacity) { // Construct new elements in place. - ConstructElements<A>(alloc, base + size, values, new_size - size); + ConstructElements<A>(alloc, base + size, values, new_size - size); } else { // Steps: // a. Allocate new backing store. @@ -599,22 +599,22 @@ auto Storage<T, N, A>::Resize(ValueAdapter values, SizeType<A> new_size) // d. Destroy all elements in old backing store. // Use transactional wrappers for the first two steps so we can roll // back if necessary due to exceptions. - AllocationTransaction<A> allocation_tx(alloc); - SizeType<A> requested_capacity = - ComputeCapacity(storage_view.capacity, new_size); - Pointer<A> new_data = allocation_tx.Allocate(requested_capacity); + AllocationTransaction<A> allocation_tx(alloc); + SizeType<A> requested_capacity = + ComputeCapacity(storage_view.capacity, new_size); + Pointer<A> new_data = allocation_tx.Allocate(requested_capacity); - ConstructionTransaction<A> construction_tx(alloc); - construction_tx.Construct(new_data + size, values, new_size - size); + ConstructionTransaction<A> construction_tx(alloc); + construction_tx.Construct(new_data + size, values, new_size - size); - IteratorValueAdapter<A, MoveIterator<A>> move_values( - (MoveIterator<A>(base))); - ConstructElements<A>(alloc, new_data, move_values, size); + IteratorValueAdapter<A, MoveIterator<A>> move_values( + (MoveIterator<A>(base))); + ConstructElements<A>(alloc, new_data, move_values, size); - DestroyElements<A>(alloc, base, size); - std::move(construction_tx).Commit(); + DestroyElements<A>(alloc, base, size); + std::move(construction_tx).Commit(); DeallocateIfAllocated(); - SetAllocation(std::move(allocation_tx).Release()); + SetAllocation(std::move(allocation_tx).Release()); SetIsAllocated(); } SetSize(new_size); @@ -622,76 +622,76 @@ auto Storage<T, N, A>::Resize(ValueAdapter values, SizeType<A> new_size) template <typename T, size_t N, typename A> template <typename ValueAdapter> -auto Storage<T, N, A>::Insert(ConstIterator<A> pos, ValueAdapter values, - SizeType<A> insert_count) -> Iterator<A> { - StorageView<A> storage_view = MakeStorageView(); +auto Storage<T, N, A>::Insert(ConstIterator<A> pos, ValueAdapter values, + SizeType<A> insert_count) -> Iterator<A> { + StorageView<A> storage_view = MakeStorageView(); - SizeType<A> insert_index = - std::distance(ConstIterator<A>(storage_view.data), pos); - SizeType<A> insert_end_index = insert_index + insert_count; - SizeType<A> new_size = storage_view.size + insert_count; + SizeType<A> insert_index = + std::distance(ConstIterator<A>(storage_view.data), pos); + SizeType<A> insert_end_index = insert_index + insert_count; + SizeType<A> new_size = storage_view.size + insert_count; if (new_size > storage_view.capacity) { - AllocationTransaction<A> allocation_tx(GetAllocator()); - ConstructionTransaction<A> construction_tx(GetAllocator()); - ConstructionTransaction<A> move_construction_tx(GetAllocator()); + AllocationTransaction<A> allocation_tx(GetAllocator()); + ConstructionTransaction<A> construction_tx(GetAllocator()); + ConstructionTransaction<A> move_construction_tx(GetAllocator()); - IteratorValueAdapter<A, MoveIterator<A>> move_values( - MoveIterator<A>(storage_view.data)); + IteratorValueAdapter<A, MoveIterator<A>> move_values( + MoveIterator<A>(storage_view.data)); - SizeType<A> requested_capacity = - ComputeCapacity(storage_view.capacity, new_size); - Pointer<A> new_data = allocation_tx.Allocate(requested_capacity); + SizeType<A> requested_capacity = + ComputeCapacity(storage_view.capacity, new_size); + Pointer<A> new_data = allocation_tx.Allocate(requested_capacity); - construction_tx.Construct(new_data + insert_index, values, insert_count); + construction_tx.Construct(new_data + insert_index, values, insert_count); - move_construction_tx.Construct(new_data, move_values, insert_index); + move_construction_tx.Construct(new_data, move_values, insert_index); - ConstructElements<A>(GetAllocator(), new_data + insert_end_index, - move_values, storage_view.size - insert_index); + ConstructElements<A>(GetAllocator(), new_data + insert_end_index, + move_values, storage_view.size - insert_index); - DestroyElements<A>(GetAllocator(), storage_view.data, storage_view.size); + DestroyElements<A>(GetAllocator(), storage_view.data, storage_view.size); - std::move(construction_tx).Commit(); - std::move(move_construction_tx).Commit(); + std::move(construction_tx).Commit(); + std::move(move_construction_tx).Commit(); DeallocateIfAllocated(); - SetAllocation(std::move(allocation_tx).Release()); + SetAllocation(std::move(allocation_tx).Release()); SetAllocatedSize(new_size); - return Iterator<A>(new_data + insert_index); + return Iterator<A>(new_data + insert_index); } else { - SizeType<A> move_construction_destination_index = + SizeType<A> move_construction_destination_index = (std::max)(insert_end_index, storage_view.size); - ConstructionTransaction<A> move_construction_tx(GetAllocator()); + ConstructionTransaction<A> move_construction_tx(GetAllocator()); - IteratorValueAdapter<A, MoveIterator<A>> move_construction_values( - MoveIterator<A>(storage_view.data + - (move_construction_destination_index - insert_count))); - y_absl::Span<ValueType<A>> move_construction = { + IteratorValueAdapter<A, MoveIterator<A>> move_construction_values( + MoveIterator<A>(storage_view.data + + (move_construction_destination_index - insert_count))); + y_absl::Span<ValueType<A>> move_construction = { storage_view.data + move_construction_destination_index, new_size - move_construction_destination_index}; - Pointer<A> move_assignment_values = storage_view.data + insert_index; - y_absl::Span<ValueType<A>> move_assignment = { + Pointer<A> move_assignment_values = storage_view.data + insert_index; + y_absl::Span<ValueType<A>> move_assignment = { storage_view.data + insert_end_index, move_construction_destination_index - insert_end_index}; - y_absl::Span<ValueType<A>> insert_assignment = {move_assignment_values, - move_construction.size()}; + y_absl::Span<ValueType<A>> insert_assignment = {move_assignment_values, + move_construction.size()}; - y_absl::Span<ValueType<A>> insert_construction = { + y_absl::Span<ValueType<A>> insert_construction = { insert_assignment.data() + insert_assignment.size(), insert_count - insert_assignment.size()}; move_construction_tx.Construct(move_construction.data(), - move_construction_values, + move_construction_values, move_construction.size()); - for (Pointer<A> - destination = move_assignment.data() + move_assignment.size(), - last_destination = move_assignment.data(), - source = move_assignment_values + move_assignment.size(); + for (Pointer<A> + destination = move_assignment.data() + move_assignment.size(), + last_destination = move_assignment.data(), + source = move_assignment_values + move_assignment.size(); ;) { --destination; --source; @@ -699,29 +699,29 @@ auto Storage<T, N, A>::Insert(ConstIterator<A> pos, ValueAdapter values, *destination = std::move(*source); } - AssignElements<A>(insert_assignment.data(), values, - insert_assignment.size()); + AssignElements<A>(insert_assignment.data(), values, + insert_assignment.size()); - ConstructElements<A>(GetAllocator(), insert_construction.data(), values, - insert_construction.size()); + ConstructElements<A>(GetAllocator(), insert_construction.data(), values, + insert_construction.size()); - std::move(move_construction_tx).Commit(); + std::move(move_construction_tx).Commit(); AddSize(insert_count); - return Iterator<A>(storage_view.data + insert_index); + return Iterator<A>(storage_view.data + insert_index); } } template <typename T, size_t N, typename A> template <typename... Args> -auto Storage<T, N, A>::EmplaceBack(Args&&... args) -> Reference<A> { - StorageView<A> storage_view = MakeStorageView(); - const SizeType<A> n = storage_view.size; +auto Storage<T, N, A>::EmplaceBack(Args&&... args) -> Reference<A> { + StorageView<A> storage_view = MakeStorageView(); + const SizeType<A> n = storage_view.size; if (ABSL_PREDICT_TRUE(n != storage_view.capacity)) { // Fast path; new element fits. - Pointer<A> last_ptr = storage_view.data + n; - AllocatorTraits<A>::construct(GetAllocator(), last_ptr, - std::forward<Args>(args)...); + Pointer<A> last_ptr = storage_view.data + n; + AllocatorTraits<A>::construct(GetAllocator(), last_ptr, + std::forward<Args>(args)...); AddSize(1); return *last_ptr; } @@ -731,83 +731,83 @@ auto Storage<T, N, A>::EmplaceBack(Args&&... args) -> Reference<A> { template <typename T, size_t N, typename A> template <typename... Args> -auto Storage<T, N, A>::EmplaceBackSlow(Args&&... args) -> Reference<A> { - StorageView<A> storage_view = MakeStorageView(); - AllocationTransaction<A> allocation_tx(GetAllocator()); - IteratorValueAdapter<A, MoveIterator<A>> move_values( - MoveIterator<A>(storage_view.data)); - SizeType<A> requested_capacity = NextCapacity(storage_view.capacity); - Pointer<A> construct_data = allocation_tx.Allocate(requested_capacity); - Pointer<A> last_ptr = construct_data + storage_view.size; +auto Storage<T, N, A>::EmplaceBackSlow(Args&&... args) -> Reference<A> { + StorageView<A> storage_view = MakeStorageView(); + AllocationTransaction<A> allocation_tx(GetAllocator()); + IteratorValueAdapter<A, MoveIterator<A>> move_values( + MoveIterator<A>(storage_view.data)); + SizeType<A> requested_capacity = NextCapacity(storage_view.capacity); + Pointer<A> construct_data = allocation_tx.Allocate(requested_capacity); + Pointer<A> last_ptr = construct_data + storage_view.size; // Construct new element. - AllocatorTraits<A>::construct(GetAllocator(), last_ptr, - std::forward<Args>(args)...); + AllocatorTraits<A>::construct(GetAllocator(), last_ptr, + std::forward<Args>(args)...); // Move elements from old backing store to new backing store. ABSL_INTERNAL_TRY { - ConstructElements<A>(GetAllocator(), allocation_tx.GetData(), move_values, - storage_view.size); + ConstructElements<A>(GetAllocator(), allocation_tx.GetData(), move_values, + storage_view.size); } ABSL_INTERNAL_CATCH_ANY { - AllocatorTraits<A>::destroy(GetAllocator(), last_ptr); + AllocatorTraits<A>::destroy(GetAllocator(), last_ptr); ABSL_INTERNAL_RETHROW; } // Destroy elements in old backing store. - DestroyElements<A>(GetAllocator(), storage_view.data, storage_view.size); + DestroyElements<A>(GetAllocator(), storage_view.data, storage_view.size); DeallocateIfAllocated(); - SetAllocation(std::move(allocation_tx).Release()); + SetAllocation(std::move(allocation_tx).Release()); SetIsAllocated(); AddSize(1); return *last_ptr; } template <typename T, size_t N, typename A> -auto Storage<T, N, A>::Erase(ConstIterator<A> from, ConstIterator<A> to) - -> Iterator<A> { - StorageView<A> storage_view = MakeStorageView(); +auto Storage<T, N, A>::Erase(ConstIterator<A> from, ConstIterator<A> to) + -> Iterator<A> { + StorageView<A> storage_view = MakeStorageView(); - SizeType<A> erase_size = std::distance(from, to); - SizeType<A> erase_index = - std::distance(ConstIterator<A>(storage_view.data), from); - SizeType<A> erase_end_index = erase_index + erase_size; + SizeType<A> erase_size = std::distance(from, to); + SizeType<A> erase_index = + std::distance(ConstIterator<A>(storage_view.data), from); + SizeType<A> erase_end_index = erase_index + erase_size; - IteratorValueAdapter<A, MoveIterator<A>> move_values( - MoveIterator<A>(storage_view.data + erase_end_index)); + IteratorValueAdapter<A, MoveIterator<A>> move_values( + MoveIterator<A>(storage_view.data + erase_end_index)); - AssignElements<A>(storage_view.data + erase_index, move_values, - storage_view.size - erase_end_index); + AssignElements<A>(storage_view.data + erase_index, move_values, + storage_view.size - erase_end_index); - DestroyElements<A>(GetAllocator(), - storage_view.data + (storage_view.size - erase_size), - erase_size); + DestroyElements<A>(GetAllocator(), + storage_view.data + (storage_view.size - erase_size), + erase_size); SubtractSize(erase_size); - return Iterator<A>(storage_view.data + erase_index); + return Iterator<A>(storage_view.data + erase_index); } template <typename T, size_t N, typename A> -auto Storage<T, N, A>::Reserve(SizeType<A> requested_capacity) -> void { - StorageView<A> storage_view = MakeStorageView(); +auto Storage<T, N, A>::Reserve(SizeType<A> requested_capacity) -> void { + StorageView<A> storage_view = MakeStorageView(); if (ABSL_PREDICT_FALSE(requested_capacity <= storage_view.capacity)) return; - AllocationTransaction<A> allocation_tx(GetAllocator()); + AllocationTransaction<A> allocation_tx(GetAllocator()); - IteratorValueAdapter<A, MoveIterator<A>> move_values( - MoveIterator<A>(storage_view.data)); + IteratorValueAdapter<A, MoveIterator<A>> move_values( + MoveIterator<A>(storage_view.data)); - SizeType<A> new_requested_capacity = + SizeType<A> new_requested_capacity = ComputeCapacity(storage_view.capacity, requested_capacity); - Pointer<A> new_data = allocation_tx.Allocate(new_requested_capacity); + Pointer<A> new_data = allocation_tx.Allocate(new_requested_capacity); - ConstructElements<A>(GetAllocator(), new_data, move_values, - storage_view.size); + ConstructElements<A>(GetAllocator(), new_data, move_values, + storage_view.size); - DestroyElements<A>(GetAllocator(), storage_view.data, storage_view.size); + DestroyElements<A>(GetAllocator(), storage_view.data, storage_view.size); DeallocateIfAllocated(); - SetAllocation(std::move(allocation_tx).Release()); + SetAllocation(std::move(allocation_tx).Release()); SetIsAllocated(); } @@ -816,44 +816,44 @@ auto Storage<T, N, A>::ShrinkToFit() -> void { // May only be called on allocated instances! assert(GetIsAllocated()); - StorageView<A> storage_view{GetAllocatedData(), GetSize(), - GetAllocatedCapacity()}; + StorageView<A> storage_view{GetAllocatedData(), GetSize(), + GetAllocatedCapacity()}; if (ABSL_PREDICT_FALSE(storage_view.size == storage_view.capacity)) return; - AllocationTransaction<A> allocation_tx(GetAllocator()); + AllocationTransaction<A> allocation_tx(GetAllocator()); - IteratorValueAdapter<A, MoveIterator<A>> move_values( - MoveIterator<A>(storage_view.data)); + IteratorValueAdapter<A, MoveIterator<A>> move_values( + MoveIterator<A>(storage_view.data)); - Pointer<A> construct_data; + Pointer<A> construct_data; if (storage_view.size > GetInlinedCapacity()) { - SizeType<A> requested_capacity = storage_view.size; - construct_data = allocation_tx.Allocate(requested_capacity); - if (allocation_tx.GetCapacity() >= storage_view.capacity) { - // Already using the smallest available heap allocation. - return; - } + SizeType<A> requested_capacity = storage_view.size; + construct_data = allocation_tx.Allocate(requested_capacity); + if (allocation_tx.GetCapacity() >= storage_view.capacity) { + // Already using the smallest available heap allocation. + return; + } } else { construct_data = GetInlinedData(); } ABSL_INTERNAL_TRY { - ConstructElements<A>(GetAllocator(), construct_data, move_values, - storage_view.size); + ConstructElements<A>(GetAllocator(), construct_data, move_values, + storage_view.size); } ABSL_INTERNAL_CATCH_ANY { - SetAllocation({storage_view.data, storage_view.capacity}); + SetAllocation({storage_view.data, storage_view.capacity}); ABSL_INTERNAL_RETHROW; } - DestroyElements<A>(GetAllocator(), storage_view.data, storage_view.size); + DestroyElements<A>(GetAllocator(), storage_view.data, storage_view.size); - MallocAdapter<A>::Deallocate(GetAllocator(), storage_view.data, - storage_view.capacity); + MallocAdapter<A>::Deallocate(GetAllocator(), storage_view.data, + storage_view.capacity); if (allocation_tx.DidAllocate()) { - SetAllocation(std::move(allocation_tx).Release()); + SetAllocation(std::move(allocation_tx).Release()); } else { UnsetIsAllocated(); } @@ -871,56 +871,56 @@ auto Storage<T, N, A>::Swap(Storage* other_storage_ptr) -> void { Storage* large_ptr = other_storage_ptr; if (small_ptr->GetSize() > large_ptr->GetSize()) swap(small_ptr, large_ptr); - for (SizeType<A> i = 0; i < small_ptr->GetSize(); ++i) { + for (SizeType<A> i = 0; i < small_ptr->GetSize(); ++i) { swap(small_ptr->GetInlinedData()[i], large_ptr->GetInlinedData()[i]); } - IteratorValueAdapter<A, MoveIterator<A>> move_values( - MoveIterator<A>(large_ptr->GetInlinedData() + small_ptr->GetSize())); + IteratorValueAdapter<A, MoveIterator<A>> move_values( + MoveIterator<A>(large_ptr->GetInlinedData() + small_ptr->GetSize())); - ConstructElements<A>(large_ptr->GetAllocator(), - small_ptr->GetInlinedData() + small_ptr->GetSize(), - move_values, - large_ptr->GetSize() - small_ptr->GetSize()); + ConstructElements<A>(large_ptr->GetAllocator(), + small_ptr->GetInlinedData() + small_ptr->GetSize(), + move_values, + large_ptr->GetSize() - small_ptr->GetSize()); - DestroyElements<A>(large_ptr->GetAllocator(), - large_ptr->GetInlinedData() + small_ptr->GetSize(), - large_ptr->GetSize() - small_ptr->GetSize()); + DestroyElements<A>(large_ptr->GetAllocator(), + large_ptr->GetInlinedData() + small_ptr->GetSize(), + large_ptr->GetSize() - small_ptr->GetSize()); } else { Storage* allocated_ptr = this; Storage* inlined_ptr = other_storage_ptr; if (!allocated_ptr->GetIsAllocated()) swap(allocated_ptr, inlined_ptr); - StorageView<A> allocated_storage_view{ - allocated_ptr->GetAllocatedData(), allocated_ptr->GetSize(), - allocated_ptr->GetAllocatedCapacity()}; + StorageView<A> allocated_storage_view{ + allocated_ptr->GetAllocatedData(), allocated_ptr->GetSize(), + allocated_ptr->GetAllocatedCapacity()}; - IteratorValueAdapter<A, MoveIterator<A>> move_values( - MoveIterator<A>(inlined_ptr->GetInlinedData())); + IteratorValueAdapter<A, MoveIterator<A>> move_values( + MoveIterator<A>(inlined_ptr->GetInlinedData())); ABSL_INTERNAL_TRY { - ConstructElements<A>(inlined_ptr->GetAllocator(), - allocated_ptr->GetInlinedData(), move_values, - inlined_ptr->GetSize()); + ConstructElements<A>(inlined_ptr->GetAllocator(), + allocated_ptr->GetInlinedData(), move_values, + inlined_ptr->GetSize()); } ABSL_INTERNAL_CATCH_ANY { - allocated_ptr->SetAllocation( - Allocation<A>{allocated_storage_view.data, allocated_storage_view.capacity}); + allocated_ptr->SetAllocation( + Allocation<A>{allocated_storage_view.data, allocated_storage_view.capacity}); ABSL_INTERNAL_RETHROW; } - DestroyElements<A>(inlined_ptr->GetAllocator(), - inlined_ptr->GetInlinedData(), inlined_ptr->GetSize()); + DestroyElements<A>(inlined_ptr->GetAllocator(), + inlined_ptr->GetInlinedData(), inlined_ptr->GetSize()); - inlined_ptr->SetAllocation( - Allocation<A>{allocated_storage_view.data, allocated_storage_view.capacity}); + inlined_ptr->SetAllocation( + Allocation<A>{allocated_storage_view.data, allocated_storage_view.capacity}); } swap(GetSizeAndIsAllocated(), other_storage_ptr->GetSizeAndIsAllocated()); - swap(GetAllocator(), other_storage_ptr->GetAllocator()); + swap(GetAllocator(), other_storage_ptr->GetAllocator()); } -// End ignore "array-bounds" and "maybe-uninitialized" +// End ignore "array-bounds" and "maybe-uninitialized" #if !defined(__clang__) && defined(__GNUC__) #pragma GCC diagnostic pop #endif diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/raw_hash_map.h b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/raw_hash_map.h index 8a0591f581..cc366b54e6 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/raw_hash_map.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/raw_hash_map.h @@ -51,9 +51,9 @@ class raw_hash_map : public raw_hash_set<Policy, Hash, Eq, Alloc> { using key_arg = typename KeyArgImpl::template type<K, key_type>; static_assert(!std::is_reference<key_type>::value, ""); - - // TODO(b/187807849): Evaluate whether to support reference mapped_type and - // remove this assertion if/when it is supported. + + // TODO(b/187807849): Evaluate whether to support reference mapped_type and + // remove this assertion if/when it is supported. static_assert(!std::is_reference<mapped_type>::value, ""); using iterator = typename raw_hash_map::raw_hash_set::iterator; diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/raw_hash_set.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/raw_hash_set.cc index bf2a15a678..3d2cb3a32b 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/raw_hash_set.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/raw_hash_set.cc @@ -23,12 +23,12 @@ namespace y_absl { ABSL_NAMESPACE_BEGIN namespace container_internal { -alignas(16) ABSL_CONST_INIT ABSL_DLL const ctrl_t kEmptyGroup[16] = { - ctrl_t::kSentinel, ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, - ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, - ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, - ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty}; - +alignas(16) ABSL_CONST_INIT ABSL_DLL const ctrl_t kEmptyGroup[16] = { + ctrl_t::kSentinel, ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, + ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, + ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, + ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty}; + constexpr size_t Group::kWidth; // Returns "random" seed. @@ -43,24 +43,24 @@ inline size_t RandomSeed() { return value ^ static_cast<size_t>(reinterpret_cast<uintptr_t>(&counter)); } -bool ShouldInsertBackwards(size_t hash, const ctrl_t* ctrl) { +bool ShouldInsertBackwards(size_t hash, const ctrl_t* ctrl) { // To avoid problems with weak hashes and single bit tests, we use % 13. // TODO(kfm,sbenza): revisit after we do unconditional mixing return (H1(hash, ctrl) ^ RandomSeed()) % 13 > 6; } -void ConvertDeletedToEmptyAndFullToDeleted(ctrl_t* ctrl, size_t capacity) { - assert(ctrl[capacity] == ctrl_t::kSentinel); +void ConvertDeletedToEmptyAndFullToDeleted(ctrl_t* ctrl, size_t capacity) { + assert(ctrl[capacity] == ctrl_t::kSentinel); assert(IsValidCapacity(capacity)); - for (ctrl_t* pos = ctrl; pos < ctrl + capacity; pos += Group::kWidth) { + for (ctrl_t* pos = ctrl; pos < ctrl + capacity; pos += Group::kWidth) { Group{pos}.ConvertSpecialToEmptyAndFullToDeleted(pos); } // Copy the cloned ctrl bytes. - std::memcpy(ctrl + capacity + 1, ctrl, NumClonedBytes()); - ctrl[capacity] = ctrl_t::kSentinel; + std::memcpy(ctrl + capacity + 1, ctrl, NumClonedBytes()); + ctrl[capacity] = ctrl_t::kSentinel; } -// Extern template instantiotion for inline function. -template FindInfo find_first_non_full(const ctrl_t*, size_t, size_t); +// Extern template instantiotion for inline function. +template FindInfo find_first_non_full(const ctrl_t*, size_t, size_t); } // namespace container_internal ABSL_NAMESPACE_END diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/raw_hash_set.h b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/raw_hash_set.h index 8f45559b31..bb0ae86329 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/raw_hash_set.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/raw_hash_set.h @@ -87,17 +87,17 @@ // // This probing function guarantees that after N probes, all the groups of the // table will be probed exactly once. -// -// The control state and slot array are stored contiguously in a shared heap -// allocation. The layout of this allocation is: `capacity()` control bytes, -// one sentinel control byte, `Group::kWidth - 1` cloned control bytes, -// <possible padding>, `capacity()` slots. The sentinel control byte is used in -// iteration so we know when we reach the end of the table. The cloned control -// bytes at the end of the table are cloned from the beginning of the table so -// groups that begin near the end of the table can see a full group. In cases in -// which there are more than `capacity()` cloned control bytes, the extra bytes -// are `kEmpty`, and these ensure that we always see at least one empty slot and -// can stop an unsuccessful search. +// +// The control state and slot array are stored contiguously in a shared heap +// allocation. The layout of this allocation is: `capacity()` control bytes, +// one sentinel control byte, `Group::kWidth - 1` cloned control bytes, +// <possible padding>, `capacity()` slots. The sentinel control byte is used in +// iteration so we know when we reach the end of the table. The cloned control +// bytes at the end of the table are cloned from the beginning of the table so +// groups that begin near the end of the table can see a full group. In cases in +// which there are more than `capacity()` cloned control bytes, the extra bytes +// are `kEmpty`, and these ensure that we always see at least one empty slot and +// can stop an unsuccessful search. #ifndef ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_ #define ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_ @@ -265,50 +265,50 @@ class BitMask { using h2_t = uint8_t; // The values here are selected for maximum performance. See the static asserts -// below for details. We use an enum class so that when strict aliasing is -// enabled, the compiler knows ctrl_t doesn't alias other types. -enum class ctrl_t : int8_t { +// below for details. We use an enum class so that when strict aliasing is +// enabled, the compiler knows ctrl_t doesn't alias other types. +enum class ctrl_t : int8_t { kEmpty = -128, // 0b10000000 kDeleted = -2, // 0b11111110 kSentinel = -1, // 0b11111111 }; static_assert( - (static_cast<int8_t>(ctrl_t::kEmpty) & - static_cast<int8_t>(ctrl_t::kDeleted) & - static_cast<int8_t>(ctrl_t::kSentinel) & 0x80) != 0, + (static_cast<int8_t>(ctrl_t::kEmpty) & + static_cast<int8_t>(ctrl_t::kDeleted) & + static_cast<int8_t>(ctrl_t::kSentinel) & 0x80) != 0, "Special markers need to have the MSB to make checking for them efficient"); -static_assert( - ctrl_t::kEmpty < ctrl_t::kSentinel && ctrl_t::kDeleted < ctrl_t::kSentinel, - "ctrl_t::kEmpty and ctrl_t::kDeleted must be smaller than " - "ctrl_t::kSentinel to make the SIMD test of IsEmptyOrDeleted() efficient"); -static_assert( - ctrl_t::kSentinel == static_cast<ctrl_t>(-1), - "ctrl_t::kSentinel must be -1 to elide loading it from memory into SIMD " - "registers (pcmpeqd xmm, xmm)"); -static_assert(ctrl_t::kEmpty == static_cast<ctrl_t>(-128), - "ctrl_t::kEmpty must be -128 to make the SIMD check for its " +static_assert( + ctrl_t::kEmpty < ctrl_t::kSentinel && ctrl_t::kDeleted < ctrl_t::kSentinel, + "ctrl_t::kEmpty and ctrl_t::kDeleted must be smaller than " + "ctrl_t::kSentinel to make the SIMD test of IsEmptyOrDeleted() efficient"); +static_assert( + ctrl_t::kSentinel == static_cast<ctrl_t>(-1), + "ctrl_t::kSentinel must be -1 to elide loading it from memory into SIMD " + "registers (pcmpeqd xmm, xmm)"); +static_assert(ctrl_t::kEmpty == static_cast<ctrl_t>(-128), + "ctrl_t::kEmpty must be -128 to make the SIMD check for its " "existence efficient (psignb xmm, xmm)"); -static_assert( - (~static_cast<int8_t>(ctrl_t::kEmpty) & - ~static_cast<int8_t>(ctrl_t::kDeleted) & - static_cast<int8_t>(ctrl_t::kSentinel) & 0x7F) != 0, - "ctrl_t::kEmpty and ctrl_t::kDeleted must share an unset bit that is not " - "shared by ctrl_t::kSentinel to make the scalar test for " - "MatchEmptyOrDeleted() efficient"); -static_assert(ctrl_t::kDeleted == static_cast<ctrl_t>(-2), - "ctrl_t::kDeleted must be -2 to make the implementation of " +static_assert( + (~static_cast<int8_t>(ctrl_t::kEmpty) & + ~static_cast<int8_t>(ctrl_t::kDeleted) & + static_cast<int8_t>(ctrl_t::kSentinel) & 0x7F) != 0, + "ctrl_t::kEmpty and ctrl_t::kDeleted must share an unset bit that is not " + "shared by ctrl_t::kSentinel to make the scalar test for " + "MatchEmptyOrDeleted() efficient"); +static_assert(ctrl_t::kDeleted == static_cast<ctrl_t>(-2), + "ctrl_t::kDeleted must be -2 to make the implementation of " "ConvertSpecialToEmptyAndFullToDeleted efficient"); // A single block of empty control bytes for tables without any slots allocated. // This enables removing a branch in the hot path of find(). -ABSL_DLL extern const ctrl_t kEmptyGroup[16]; +ABSL_DLL extern const ctrl_t kEmptyGroup[16]; inline ctrl_t* EmptyGroup() { - return const_cast<ctrl_t*>(kEmptyGroup); + return const_cast<ctrl_t*>(kEmptyGroup); } // Mixes a randomly generated per-process seed with `hash` and `ctrl` to // randomize insertion order within groups. -bool ShouldInsertBackwards(size_t hash, const ctrl_t* ctrl); +bool ShouldInsertBackwards(size_t hash, const ctrl_t* ctrl); // Returns a hash seed. // @@ -324,12 +324,12 @@ inline size_t HashSeed(const ctrl_t* ctrl) { inline size_t H1(size_t hash, const ctrl_t* ctrl) { return (hash >> 7) ^ HashSeed(ctrl); } -inline h2_t H2(size_t hash) { return hash & 0x7F; } +inline h2_t H2(size_t hash) { return hash & 0x7F; } -inline bool IsEmpty(ctrl_t c) { return c == ctrl_t::kEmpty; } -inline bool IsFull(ctrl_t c) { return c >= static_cast<ctrl_t>(0); } -inline bool IsDeleted(ctrl_t c) { return c == ctrl_t::kDeleted; } -inline bool IsEmptyOrDeleted(ctrl_t c) { return c < ctrl_t::kSentinel; } +inline bool IsEmpty(ctrl_t c) { return c == ctrl_t::kEmpty; } +inline bool IsFull(ctrl_t c) { return c >= static_cast<ctrl_t>(0); } +inline bool IsDeleted(ctrl_t c) { return c == ctrl_t::kDeleted; } +inline bool IsEmptyOrDeleted(ctrl_t c) { return c < ctrl_t::kSentinel; } #if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 @@ -366,24 +366,24 @@ struct GroupSse2Impl { // Returns a bitmask representing the positions of empty slots. BitMask<uint32_t, kWidth> MatchEmpty() const { #if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 - // This only works because ctrl_t::kEmpty is -128. + // This only works because ctrl_t::kEmpty is -128. return BitMask<uint32_t, kWidth>( _mm_movemask_epi8(_mm_sign_epi8(ctrl, ctrl))); #else - return Match(static_cast<h2_t>(ctrl_t::kEmpty)); + return Match(static_cast<h2_t>(ctrl_t::kEmpty)); #endif } // Returns a bitmask representing the positions of empty or deleted slots. BitMask<uint32_t, kWidth> MatchEmptyOrDeleted() const { - auto special = _mm_set1_epi8(static_cast<int8_t>(ctrl_t::kSentinel)); + auto special = _mm_set1_epi8(static_cast<int8_t>(ctrl_t::kSentinel)); return BitMask<uint32_t, kWidth>( _mm_movemask_epi8(_mm_cmpgt_epi8_fixed(special, ctrl))); } // Returns the number of trailing empty or deleted elements in the group. uint32_t CountLeadingEmptyOrDeleted() const { - auto special = _mm_set1_epi8(static_cast<int8_t>(ctrl_t::kSentinel)); + auto special = _mm_set1_epi8(static_cast<int8_t>(ctrl_t::kSentinel)); return TrailingZeros(static_cast<uint32_t>( _mm_movemask_epi8(_mm_cmpgt_epi8_fixed(special, ctrl)) + 1)); } @@ -418,7 +418,7 @@ struct GroupPortableImpl { // // Caveat: there are false positives but: // - they only occur if there is a real match - // - they never occur on ctrl_t::kEmpty, ctrl_t::kDeleted, ctrl_t::kSentinel + // - they never occur on ctrl_t::kEmpty, ctrl_t::kDeleted, ctrl_t::kSentinel // - they will be handled gracefully by subsequent checks in code // // Example: @@ -463,10 +463,10 @@ using Group = GroupSse2Impl; using Group = GroupPortableImpl; #endif -// The number of cloned control bytes that we copy from the beginning to the -// end of the control bytes array. -constexpr size_t NumClonedBytes() { return Group::kWidth - 1; } - +// The number of cloned control bytes that we copy from the beginning to the +// end of the control bytes array. +constexpr size_t NumClonedBytes() { return Group::kWidth - 1; } + template <class Policy, class Hash, class Eq, class Alloc> class raw_hash_set; @@ -474,8 +474,8 @@ inline bool IsValidCapacity(size_t n) { return ((n + 1) & n) == 0 && n > 0; } // PRECONDITION: // IsValidCapacity(capacity) -// ctrl[capacity] == ctrl_t::kSentinel -// ctrl[i] != ctrl_t::kSentinel for all i < capacity +// ctrl[capacity] == ctrl_t::kSentinel +// ctrl[i] != ctrl_t::kSentinel for all i < capacity // Applies mapping for every byte in ctrl: // DELETED -> EMPTY // EMPTY -> EMPTY @@ -517,22 +517,22 @@ inline size_t GrowthToLowerboundCapacity(size_t growth) { return growth + static_cast<size_t>((static_cast<int64_t>(growth) - 1) / 7); } -template <class InputIter> -size_t SelectBucketCountForIterRange(InputIter first, InputIter last, - size_t bucket_count) { - if (bucket_count != 0) { - return bucket_count; - } - using InputIterCategory = - typename std::iterator_traits<InputIter>::iterator_category; - if (std::is_base_of<std::random_access_iterator_tag, - InputIterCategory>::value) { - return GrowthToLowerboundCapacity( - static_cast<size_t>(std::distance(first, last))); - } - return 0; -} - +template <class InputIter> +size_t SelectBucketCountForIterRange(InputIter first, InputIter last, + size_t bucket_count) { + if (bucket_count != 0) { + return bucket_count; + } + using InputIterCategory = + typename std::iterator_traits<InputIter>::iterator_category; + if (std::is_base_of<std::random_access_iterator_tag, + InputIterCategory>::value) { + return GrowthToLowerboundCapacity( + static_cast<size_t>(std::distance(first, last))); + } + return 0; +} + inline void AssertIsFull(ctrl_t* ctrl) { ABSL_HARDENING_ASSERT((ctrl != nullptr && IsFull(*ctrl)) && "Invalid operation on iterator. The element might have " @@ -560,29 +560,29 @@ struct FindInfo { // This is important to make 1 a valid capacity. // // - In small mode only the first `capacity()` control bytes after the -// sentinel are valid. The rest contain dummy ctrl_t::kEmpty values that do not +// sentinel are valid. The rest contain dummy ctrl_t::kEmpty values that do not // represent a real slot. This is important to take into account on // find_first_non_full(), where we never try ShouldInsertBackwards() for // small tables. inline bool is_small(size_t capacity) { return capacity < Group::kWidth - 1; } -inline probe_seq<Group::kWidth> probe(const ctrl_t* ctrl, size_t hash, +inline probe_seq<Group::kWidth> probe(const ctrl_t* ctrl, size_t hash, size_t capacity) { return probe_seq<Group::kWidth>(H1(hash, ctrl), capacity); } // Probes the raw_hash_set with the probe sequence for hash and returns the // pointer to the first empty or deleted slot. -// NOTE: this function must work with tables having both ctrl_t::kEmpty and -// ctrl_t::kDeleted in one group. Such tables appears during -// drop_deletes_without_resize. +// NOTE: this function must work with tables having both ctrl_t::kEmpty and +// ctrl_t::kDeleted in one group. Such tables appears during +// drop_deletes_without_resize. // // This function is very useful when insertions happen and: // - the input is already a set // - there are enough slots // - the element with the hash is not in the table -template <typename = void> -inline FindInfo find_first_non_full(const ctrl_t* ctrl, size_t hash, +template <typename = void> +inline FindInfo find_first_non_full(const ctrl_t* ctrl, size_t hash, size_t capacity) { auto seq = probe(ctrl, hash, capacity); while (true) { @@ -601,60 +601,60 @@ inline FindInfo find_first_non_full(const ctrl_t* ctrl, size_t hash, return {seq.offset(mask.LowestBitSet()), seq.index()}; } seq.next(); - assert(seq.index() <= capacity && "full table!"); - } -} - -// Extern template for inline function keep possibility of inlining. -// When compiler decided to not inline, no symbols will be added to the -// corresponding translation unit. -extern template FindInfo find_first_non_full(const ctrl_t*, size_t, size_t); - -// Reset all ctrl bytes back to ctrl_t::kEmpty, except the sentinel. -inline void ResetCtrl(size_t capacity, ctrl_t* ctrl, const void* slot, - size_t slot_size) { - std::memset(ctrl, static_cast<int8_t>(ctrl_t::kEmpty), - capacity + 1 + NumClonedBytes()); - ctrl[capacity] = ctrl_t::kSentinel; - SanitizerPoisonMemoryRegion(slot, slot_size * capacity); -} - -// Sets the control byte, and if `i < NumClonedBytes()`, set the cloned byte -// at the end too. -inline void SetCtrl(size_t i, ctrl_t h, size_t capacity, ctrl_t* ctrl, - const void* slot, size_t slot_size) { - assert(i < capacity); - - auto* slot_i = static_cast<const char*>(slot) + i * slot_size; - if (IsFull(h)) { - SanitizerUnpoisonMemoryRegion(slot_i, slot_size); - } else { - SanitizerPoisonMemoryRegion(slot_i, slot_size); + assert(seq.index() <= capacity && "full table!"); } - - ctrl[i] = h; - ctrl[((i - NumClonedBytes()) & capacity) + (NumClonedBytes() & capacity)] = h; -} - -inline void SetCtrl(size_t i, h2_t h, size_t capacity, ctrl_t* ctrl, - const void* slot, size_t slot_size) { - SetCtrl(i, static_cast<ctrl_t>(h), capacity, ctrl, slot, slot_size); -} - -// The allocated block consists of `capacity + 1 + NumClonedBytes()` control -// bytes followed by `capacity` slots, which must be aligned to `slot_align`. -// SlotOffset returns the offset of the slots into the allocated block. -inline size_t SlotOffset(size_t capacity, size_t slot_align) { - assert(IsValidCapacity(capacity)); - const size_t num_control_bytes = capacity + 1 + NumClonedBytes(); - return (num_control_bytes + slot_align - 1) & (~slot_align + 1); -} - -// Returns the size of the allocated block. See also above comment. -inline size_t AllocSize(size_t capacity, size_t slot_size, size_t slot_align) { - return SlotOffset(capacity, slot_align) + capacity * slot_size; } +// Extern template for inline function keep possibility of inlining. +// When compiler decided to not inline, no symbols will be added to the +// corresponding translation unit. +extern template FindInfo find_first_non_full(const ctrl_t*, size_t, size_t); + +// Reset all ctrl bytes back to ctrl_t::kEmpty, except the sentinel. +inline void ResetCtrl(size_t capacity, ctrl_t* ctrl, const void* slot, + size_t slot_size) { + std::memset(ctrl, static_cast<int8_t>(ctrl_t::kEmpty), + capacity + 1 + NumClonedBytes()); + ctrl[capacity] = ctrl_t::kSentinel; + SanitizerPoisonMemoryRegion(slot, slot_size * capacity); +} + +// Sets the control byte, and if `i < NumClonedBytes()`, set the cloned byte +// at the end too. +inline void SetCtrl(size_t i, ctrl_t h, size_t capacity, ctrl_t* ctrl, + const void* slot, size_t slot_size) { + assert(i < capacity); + + auto* slot_i = static_cast<const char*>(slot) + i * slot_size; + if (IsFull(h)) { + SanitizerUnpoisonMemoryRegion(slot_i, slot_size); + } else { + SanitizerPoisonMemoryRegion(slot_i, slot_size); + } + + ctrl[i] = h; + ctrl[((i - NumClonedBytes()) & capacity) + (NumClonedBytes() & capacity)] = h; +} + +inline void SetCtrl(size_t i, h2_t h, size_t capacity, ctrl_t* ctrl, + const void* slot, size_t slot_size) { + SetCtrl(i, static_cast<ctrl_t>(h), capacity, ctrl, slot, slot_size); +} + +// The allocated block consists of `capacity + 1 + NumClonedBytes()` control +// bytes followed by `capacity` slots, which must be aligned to `slot_align`. +// SlotOffset returns the offset of the slots into the allocated block. +inline size_t SlotOffset(size_t capacity, size_t slot_align) { + assert(IsValidCapacity(capacity)); + const size_t num_control_bytes = capacity + 1 + NumClonedBytes(); + return (num_control_bytes + slot_align - 1) & (~slot_align + 1); +} + +// Returns the size of the allocated block. See also above comment. +inline size_t AllocSize(size_t capacity, size_t slot_size, size_t slot_align) { + return SlotOffset(capacity, slot_align) + capacity * slot_size; +} + // Policy: a policy defines how to perform different operations on // the slots of the hashtable (see hash_policy_traits.h for the full interface // of policy). @@ -813,7 +813,7 @@ class raw_hash_set { ctrl_ += shift; slot_ += shift; } - if (ABSL_PREDICT_FALSE(*ctrl_ == ctrl_t::kSentinel)) ctrl_ = nullptr; + if (ABSL_PREDICT_FALSE(*ctrl_ == ctrl_t::kSentinel)) ctrl_ = nullptr; } ctrl_t* ctrl_ = nullptr; @@ -894,8 +894,8 @@ class raw_hash_set { raw_hash_set(InputIter first, InputIter last, size_t bucket_count = 0, const hasher& hash = hasher(), const key_equal& eq = key_equal(), const allocator_type& alloc = allocator_type()) - : raw_hash_set(SelectBucketCountForIterRange(first, last, bucket_count), - hash, eq, alloc) { + : raw_hash_set(SelectBucketCountForIterRange(first, last, bucket_count), + hash, eq, alloc) { insert(first, last); } @@ -983,8 +983,8 @@ class raw_hash_set { for (const auto& v : that) { const size_t hash = PolicyTraits::apply(HashElement{hash_ref()}, v); auto target = find_first_non_full(ctrl_, hash, capacity_); - SetCtrl(target.offset, H2(hash), capacity_, ctrl_, slots_, - sizeof(slot_type)); + SetCtrl(target.offset, H2(hash), capacity_, ctrl_, slots_, + sizeof(slot_type)); emplace_at(target.offset, v); infoz().RecordInsert(hash, target.probe_length); } @@ -1080,8 +1080,8 @@ class raw_hash_set { // past that we simply deallocate the array. if (capacity_ > 127) { destroy_slots(); - - infoz().RecordClearedReservation(); + + infoz().RecordClearedReservation(); } else if (capacity_) { for (size_t i = 0; i != capacity_; ++i) { if (IsFull(ctrl_[i])) { @@ -1089,7 +1089,7 @@ class raw_hash_set { } } size_ = 0; - ResetCtrl(capacity_, ctrl_, slots_, sizeof(slot_type)); + ResetCtrl(capacity_, ctrl_, slots_, sizeof(slot_type)); reset_growth_left(); } assert(empty()); @@ -1395,31 +1395,31 @@ class raw_hash_set { if (n == 0 && size_ == 0) { destroy_slots(); infoz().RecordStorageChanged(0, 0); - infoz().RecordClearedReservation(); + infoz().RecordClearedReservation(); return; } - + // bitor is a faster way of doing `max` here. We will round up to the next // power-of-2-minus-1, so bitor is good enough. auto m = NormalizeCapacity(n | GrowthToLowerboundCapacity(size())); // n == 0 unconditionally rehashes as per the standard. if (n == 0 || m > capacity_) { resize(m); - - // This is after resize, to ensure that we have completed the allocation - // and have potentially sampled the hashtable. - infoz().RecordReservation(n); + + // This is after resize, to ensure that we have completed the allocation + // and have potentially sampled the hashtable. + infoz().RecordReservation(n); } } void reserve(size_t n) { - if (n > size() + growth_left()) { - size_t m = GrowthToLowerboundCapacity(n); + if (n > size() + growth_left()) { + size_t m = GrowthToLowerboundCapacity(n); resize(NormalizeCapacity(m)); - - // This is after resize, to ensure that we have completed the allocation - // and have potentially sampled the hashtable. - infoz().RecordReservation(n); + + // This is after resize, to ensure that we have completed the allocation + // and have potentially sampled the hashtable. + infoz().RecordReservation(n); } } @@ -1446,7 +1446,7 @@ class raw_hash_set { void prefetch(const key_arg<K>& key) const { (void)key; #if defined(__GNUC__) - prefetch_heap_block(); + prefetch_heap_block(); auto seq = probe(ctrl_, hash_ref()(key), capacity_); __builtin_prefetch(static_cast<const void*>(ctrl_ + seq.offset())); __builtin_prefetch(static_cast<const void*>(slots_ + seq.offset())); @@ -1473,12 +1473,12 @@ class raw_hash_set { } if (ABSL_PREDICT_TRUE(g.MatchEmpty())) return end(); seq.next(); - assert(seq.index() <= capacity_ && "full table!"); + assert(seq.index() <= capacity_ && "full table!"); } } template <class K = key_type> iterator find(const key_arg<K>& key) { - prefetch_heap_block(); + prefetch_heap_block(); return find(key, hash_ref()(key)); } @@ -1488,7 +1488,7 @@ class raw_hash_set { } template <class K = key_type> const_iterator find(const key_arg<K>& key) const { - prefetch_heap_block(); + prefetch_heap_block(); return find(key, hash_ref()(key)); } @@ -1623,8 +1623,8 @@ class raw_hash_set { static_cast<size_t>(empty_after.TrailingZeros() + empty_before.LeadingZeros()) < Group::kWidth; - SetCtrl(index, was_never_full ? ctrl_t::kEmpty : ctrl_t::kDeleted, - capacity_, ctrl_, slots_, sizeof(slot_type)); + SetCtrl(index, was_never_full ? ctrl_t::kEmpty : ctrl_t::kDeleted, + capacity_, ctrl_, slots_, sizeof(slot_type)); growth_left() += was_never_full; infoz().RecordErase(); } @@ -1643,16 +1643,16 @@ class raw_hash_set { // bound more carefully. if (std::is_same<SlotAlloc, std::allocator<slot_type>>::value && slots_ == nullptr) { - infoz() = Sample(sizeof(slot_type)); + infoz() = Sample(sizeof(slot_type)); } - char* mem = static_cast<char*>(Allocate<alignof(slot_type)>( - &alloc_ref(), - AllocSize(capacity_, sizeof(slot_type), alignof(slot_type)))); - ctrl_ = reinterpret_cast<ctrl_t*>(mem); - slots_ = reinterpret_cast<slot_type*>( - mem + SlotOffset(capacity_, alignof(slot_type))); - ResetCtrl(capacity_, ctrl_, slots_, sizeof(slot_type)); + char* mem = static_cast<char*>(Allocate<alignof(slot_type)>( + &alloc_ref(), + AllocSize(capacity_, sizeof(slot_type), alignof(slot_type)))); + ctrl_ = reinterpret_cast<ctrl_t*>(mem); + slots_ = reinterpret_cast<slot_type*>( + mem + SlotOffset(capacity_, alignof(slot_type))); + ResetCtrl(capacity_, ctrl_, slots_, sizeof(slot_type)); reset_growth_left(); infoz().RecordStorageChanged(size_, capacity_); } @@ -1664,12 +1664,12 @@ class raw_hash_set { PolicyTraits::destroy(&alloc_ref(), slots_ + i); } } - + // Unpoison before returning the memory to the allocator. SanitizerUnpoisonMemoryRegion(slots_, sizeof(slot_type) * capacity_); - Deallocate<alignof(slot_type)>( - &alloc_ref(), ctrl_, - AllocSize(capacity_, sizeof(slot_type), alignof(slot_type))); + Deallocate<alignof(slot_type)>( + &alloc_ref(), ctrl_, + AllocSize(capacity_, sizeof(slot_type), alignof(slot_type))); ctrl_ = EmptyGroup(); slots_ = nullptr; size_ = 0; @@ -1693,16 +1693,16 @@ class raw_hash_set { auto target = find_first_non_full(ctrl_, hash, capacity_); size_t new_i = target.offset; total_probe_length += target.probe_length; - SetCtrl(new_i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type)); + SetCtrl(new_i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type)); PolicyTraits::transfer(&alloc_ref(), slots_ + new_i, old_slots + i); } } if (old_capacity) { SanitizerUnpoisonMemoryRegion(old_slots, sizeof(slot_type) * old_capacity); - Deallocate<alignof(slot_type)>( - &alloc_ref(), old_ctrl, - AllocSize(old_capacity, sizeof(slot_type), alignof(slot_type))); + Deallocate<alignof(slot_type)>( + &alloc_ref(), old_ctrl, + AllocSize(old_capacity, sizeof(slot_type), alignof(slot_type))); } infoz().RecordRehash(total_probe_length); } @@ -1732,35 +1732,35 @@ class raw_hash_set { slot_type* slot = reinterpret_cast<slot_type*>(&raw); for (size_t i = 0; i != capacity_; ++i) { if (!IsDeleted(ctrl_[i])) continue; - const size_t hash = PolicyTraits::apply( - HashElement{hash_ref()}, PolicyTraits::element(slots_ + i)); - const FindInfo target = find_first_non_full(ctrl_, hash, capacity_); - const size_t new_i = target.offset; + const size_t hash = PolicyTraits::apply( + HashElement{hash_ref()}, PolicyTraits::element(slots_ + i)); + const FindInfo target = find_first_non_full(ctrl_, hash, capacity_); + const size_t new_i = target.offset; total_probe_length += target.probe_length; // Verify if the old and new i fall within the same group wrt the hash. // If they do, we don't need to move the object as it falls already in the // best probe we can. - const size_t probe_offset = probe(ctrl_, hash, capacity_).offset(); - const auto probe_index = [probe_offset, this](size_t pos) { - return ((pos - probe_offset) & capacity_) / Group::kWidth; + const size_t probe_offset = probe(ctrl_, hash, capacity_).offset(); + const auto probe_index = [probe_offset, this](size_t pos) { + return ((pos - probe_offset) & capacity_) / Group::kWidth; }; // Element doesn't move. if (ABSL_PREDICT_TRUE(probe_index(new_i) == probe_index(i))) { - SetCtrl(i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type)); + SetCtrl(i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type)); continue; } if (IsEmpty(ctrl_[new_i])) { // Transfer element to the empty spot. - // SetCtrl poisons/unpoisons the slots so we have to call it at the + // SetCtrl poisons/unpoisons the slots so we have to call it at the // right time. - SetCtrl(new_i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type)); + SetCtrl(new_i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type)); PolicyTraits::transfer(&alloc_ref(), slots_ + new_i, slots_ + i); - SetCtrl(i, ctrl_t::kEmpty, capacity_, ctrl_, slots_, sizeof(slot_type)); + SetCtrl(i, ctrl_t::kEmpty, capacity_, ctrl_, slots_, sizeof(slot_type)); } else { assert(IsDeleted(ctrl_[new_i])); - SetCtrl(new_i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type)); + SetCtrl(new_i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type)); // Until we are done rehashing, DELETED marks previously FULL slots. // Swap i and new_i elements. PolicyTraits::transfer(&alloc_ref(), slot, slots_ + i); @@ -1776,50 +1776,50 @@ class raw_hash_set { void rehash_and_grow_if_necessary() { if (capacity_ == 0) { resize(1); - } else if (capacity_ > Group::kWidth && - // Do these calcuations in 64-bit to avoid overflow. - size() * uint64_t{32} <= capacity_ * uint64_t{25}) { + } else if (capacity_ > Group::kWidth && + // Do these calcuations in 64-bit to avoid overflow. + size() * uint64_t{32} <= capacity_ * uint64_t{25}) { // Squash DELETED without growing if there is enough capacity. - // - // Rehash in place if the current size is <= 25/32 of capacity_. - // Rationale for such a high factor: 1) drop_deletes_without_resize() is - // faster than resize, and 2) it takes quite a bit of work to add - // tombstones. In the worst case, seems to take approximately 4 - // insert/erase pairs to create a single tombstone and so if we are - // rehashing because of tombstones, we can afford to rehash-in-place as - // long as we are reclaiming at least 1/8 the capacity without doing more - // than 2X the work. (Where "work" is defined to be size() for rehashing - // or rehashing in place, and 1 for an insert or erase.) But rehashing in - // place is faster per operation than inserting or even doubling the size - // of the table, so we actually afford to reclaim even less space from a - // resize-in-place. The decision is to rehash in place if we can reclaim - // at about 1/8th of the usable capacity (specifically 3/28 of the - // capacity) which means that the total cost of rehashing will be a small - // fraction of the total work. - // - // Here is output of an experiment using the BM_CacheInSteadyState - // benchmark running the old case (where we rehash-in-place only if we can - // reclaim at least 7/16*capacity_) vs. this code (which rehashes in place - // if we can recover 3/32*capacity_). - // - // Note that although in the worst-case number of rehashes jumped up from - // 15 to 190, but the number of operations per second is almost the same. - // - // Abridged output of running BM_CacheInSteadyState benchmark from - // raw_hash_set_benchmark. N is the number of insert/erase operations. - // - // | OLD (recover >= 7/16 | NEW (recover >= 3/32) - // size | N/s LoadFactor NRehashes | N/s LoadFactor NRehashes - // 448 | 145284 0.44 18 | 140118 0.44 19 - // 493 | 152546 0.24 11 | 151417 0.48 28 - // 538 | 151439 0.26 11 | 151152 0.53 38 - // 583 | 151765 0.28 11 | 150572 0.57 50 - // 628 | 150241 0.31 11 | 150853 0.61 66 - // 672 | 149602 0.33 12 | 150110 0.66 90 - // 717 | 149998 0.35 12 | 149531 0.70 129 - // 762 | 149836 0.37 13 | 148559 0.74 190 - // 807 | 149736 0.39 14 | 151107 0.39 14 - // 852 | 150204 0.42 15 | 151019 0.42 15 + // + // Rehash in place if the current size is <= 25/32 of capacity_. + // Rationale for such a high factor: 1) drop_deletes_without_resize() is + // faster than resize, and 2) it takes quite a bit of work to add + // tombstones. In the worst case, seems to take approximately 4 + // insert/erase pairs to create a single tombstone and so if we are + // rehashing because of tombstones, we can afford to rehash-in-place as + // long as we are reclaiming at least 1/8 the capacity without doing more + // than 2X the work. (Where "work" is defined to be size() for rehashing + // or rehashing in place, and 1 for an insert or erase.) But rehashing in + // place is faster per operation than inserting or even doubling the size + // of the table, so we actually afford to reclaim even less space from a + // resize-in-place. The decision is to rehash in place if we can reclaim + // at about 1/8th of the usable capacity (specifically 3/28 of the + // capacity) which means that the total cost of rehashing will be a small + // fraction of the total work. + // + // Here is output of an experiment using the BM_CacheInSteadyState + // benchmark running the old case (where we rehash-in-place only if we can + // reclaim at least 7/16*capacity_) vs. this code (which rehashes in place + // if we can recover 3/32*capacity_). + // + // Note that although in the worst-case number of rehashes jumped up from + // 15 to 190, but the number of operations per second is almost the same. + // + // Abridged output of running BM_CacheInSteadyState benchmark from + // raw_hash_set_benchmark. N is the number of insert/erase operations. + // + // | OLD (recover >= 7/16 | NEW (recover >= 3/32) + // size | N/s LoadFactor NRehashes | N/s LoadFactor NRehashes + // 448 | 145284 0.44 18 | 140118 0.44 19 + // 493 | 152546 0.24 11 | 151417 0.48 28 + // 538 | 151439 0.26 11 | 151152 0.53 38 + // 583 | 151765 0.28 11 | 150572 0.57 50 + // 628 | 150241 0.31 11 | 150853 0.61 66 + // 672 | 149602 0.33 12 | 150110 0.66 90 + // 717 | 149998 0.35 12 | 149531 0.70 129 + // 762 | 149836 0.37 13 | 148559 0.74 190 + // 807 | 149736 0.39 14 | 151107 0.39 14 + // 852 | 150204 0.42 15 | 151019 0.42 15 drop_deletes_without_resize(); } else { // Otherwise grow the container. @@ -1839,7 +1839,7 @@ class raw_hash_set { } if (ABSL_PREDICT_TRUE(g.MatchEmpty())) return false; seq.next(); - assert(seq.index() <= capacity_ && "full table!"); + assert(seq.index() <= capacity_ && "full table!"); } return false; } @@ -1859,7 +1859,7 @@ class raw_hash_set { protected: template <class K> std::pair<size_t, bool> find_or_prepare_insert(const K& key) { - prefetch_heap_block(); + prefetch_heap_block(); auto hash = hash_ref()(key); auto seq = probe(ctrl_, hash, capacity_); while (true) { @@ -1872,7 +1872,7 @@ class raw_hash_set { } if (ABSL_PREDICT_TRUE(g.MatchEmpty())) break; seq.next(); - assert(seq.index() <= capacity_ && "full table!"); + assert(seq.index() <= capacity_ && "full table!"); } return {prepare_insert(hash), true}; } @@ -1886,8 +1886,8 @@ class raw_hash_set { } ++size_; growth_left() -= IsEmpty(ctrl_[target.offset]); - SetCtrl(target.offset, H2(hash), capacity_, ctrl_, slots_, - sizeof(slot_type)); + SetCtrl(target.offset, H2(hash), capacity_, ctrl_, slots_, + sizeof(slot_type)); infoz().RecordInsert(hash, target.probe_length); return target.offset; } @@ -1920,15 +1920,15 @@ class raw_hash_set { growth_left() = CapacityToGrowth(capacity()) - size_; } - size_t& growth_left() { return settings_.template get<0>(); } + size_t& growth_left() { return settings_.template get<0>(); } - void prefetch_heap_block() const { - // Prefetch the heap-allocated memory region to resolve potential TLB - // misses. This is intended to overlap with execution of calculating the - // hash for a key. -#if defined(__GNUC__) - __builtin_prefetch(static_cast<const void*>(ctrl_), 0, 1); -#endif // __GNUC__ + void prefetch_heap_block() const { + // Prefetch the heap-allocated memory region to resolve potential TLB + // misses. This is intended to overlap with execution of calculating the + // hash for a key. +#if defined(__GNUC__) + __builtin_prefetch(static_cast<const void*>(ctrl_), 0, 1); +#endif // __GNUC__ } HashtablezInfoHandle& infoz() { return settings_.template get<1>(); } @@ -1945,10 +1945,10 @@ class raw_hash_set { // TODO(alkis): Investigate removing some of these fields: // - ctrl/slots can be derived from each other // - size can be moved into the slot array - ctrl_t* ctrl_ = EmptyGroup(); // [(capacity + 1 + NumClonedBytes()) * ctrl_t] - slot_type* slots_ = nullptr; // [capacity * slot_type] - size_t size_ = 0; // number of full slots - size_t capacity_ = 0; // total number of slots + ctrl_t* ctrl_ = EmptyGroup(); // [(capacity + 1 + NumClonedBytes()) * ctrl_t] + slot_type* slots_ = nullptr; // [capacity * slot_type] + size_t size_ = 0; // number of full slots + size_t capacity_ = 0; // total number of slots y_absl::container_internal::CompressedTuple<size_t /* growth_left */, HashtablezInfoHandle, hasher, key_equal, allocator_type> @@ -1958,12 +1958,12 @@ class raw_hash_set { // Erases all elements that satisfy the predicate `pred` from the container `c`. template <typename P, typename H, typename E, typename A, typename Predicate> -void EraseIf(Predicate& pred, raw_hash_set<P, H, E, A>* c) { +void EraseIf(Predicate& pred, raw_hash_set<P, H, E, A>* c) { for (auto it = c->begin(), last = c->end(); it != last;) { - if (pred(*it)) { - c->erase(it++); - } else { - ++it; + if (pred(*it)) { + c->erase(it++); + } else { + ++it; } } } @@ -1998,7 +1998,7 @@ struct HashtableDebugAccess<Set, y_absl::void_t<typename Set::raw_hash_set>> { static size_t AllocatedByteSize(const Set& c) { size_t capacity = c.capacity_; if (capacity == 0) return 0; - size_t m = AllocSize(capacity, sizeof(Slot), alignof(Slot)); + size_t m = AllocSize(capacity, sizeof(Slot), alignof(Slot)); size_t per_slot = Traits::space_used(static_cast<const Slot*>(nullptr)); if (per_slot != ~size_t{}) { @@ -2016,8 +2016,8 @@ struct HashtableDebugAccess<Set, y_absl::void_t<typename Set::raw_hash_set>> { static size_t LowerBoundAllocatedByteSize(size_t size) { size_t capacity = GrowthToLowerboundCapacity(size); if (capacity == 0) return 0; - size_t m = - AllocSize(NormalizeCapacity(capacity), sizeof(Slot), alignof(Slot)); + size_t m = + AllocSize(NormalizeCapacity(capacity), sizeof(Slot), alignof(Slot)); size_t per_slot = Traits::space_used(static_cast<const Slot*>(nullptr)); if (per_slot != ~size_t{}) { m += per_slot * size; diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/raw_hash_set/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/raw_hash_set/ya.make index d636929b87..67a9a309d6 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/raw_hash_set/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/raw_hash_set/ya.make @@ -18,23 +18,23 @@ PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/throw_delegate contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity - contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/absl_hashtablez_sampler + contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/absl_hashtablez_sampler contrib/restricted/abseil-cpp-tstring/y_absl/debugging contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize contrib/restricted/abseil-cpp-tstring/y_absl/demangle - contrib/restricted/abseil-cpp-tstring/y_absl/hash + contrib/restricted/abseil-cpp-tstring/y_absl/hash contrib/restricted/abseil-cpp-tstring/y_absl/numeric - contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased contrib/restricted/abseil-cpp-tstring/y_absl/strings - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal contrib/restricted/abseil-cpp-tstring/y_absl/synchronization contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal contrib/restricted/abseil-cpp-tstring/y_absl/time contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_optional_access - contrib/restricted/abseil-cpp-tstring/y_absl/types + contrib/restricted/abseil-cpp-tstring/y_absl/types ) ADDINCL( @@ -43,10 +43,10 @@ ADDINCL( NO_COMPILER_WARNINGS() -SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/container/internal) +SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/container/internal) SRCS( - raw_hash_set.cc + raw_hash_set.cc ) END() diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/unordered_map_constructor_test.h b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/unordered_map_constructor_test.h index f55d6293ae..41db4da981 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/unordered_map_constructor_test.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/unordered_map_constructor_test.h @@ -179,7 +179,7 @@ TYPED_TEST_P(ConstructorTest, InputIteratorBucketHashEqualAlloc) { A alloc(0); std::vector<T> values; std::generate_n(std::back_inserter(values), 10, - hash_internal::UniqueGenerator<T>()); + hash_internal::UniqueGenerator<T>()); TypeParam m(values.begin(), values.end(), 123, hasher, equal, alloc); EXPECT_EQ(m.hash_function(), hasher); EXPECT_EQ(m.key_eq(), equal); @@ -198,7 +198,7 @@ void InputIteratorBucketAllocTest(std::true_type) { A alloc(0); std::vector<T> values; std::generate_n(std::back_inserter(values), 10, - hash_internal::UniqueGenerator<T>()); + hash_internal::UniqueGenerator<T>()); TypeParam m(values.begin(), values.end(), 123, alloc); EXPECT_EQ(m.get_allocator(), alloc); EXPECT_THAT(items(m), ::testing::UnorderedElementsAreArray(values)); @@ -221,7 +221,7 @@ void InputIteratorBucketHashAllocTest(std::true_type) { A alloc(0); std::vector<T> values; std::generate_n(std::back_inserter(values), 10, - hash_internal::UniqueGenerator<T>()); + hash_internal::UniqueGenerator<T>()); TypeParam m(values.begin(), values.end(), 123, hasher, alloc); EXPECT_EQ(m.hash_function(), hasher); EXPECT_EQ(m.get_allocator(), alloc); @@ -241,9 +241,9 @@ TYPED_TEST_P(ConstructorTest, CopyConstructor) { H hasher; E equal; A alloc(0); - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; TypeParam m(123, hasher, equal, alloc); - for (size_t i = 0; i != 10; ++i) m.insert(gen()); + for (size_t i = 0; i != 10; ++i) m.insert(gen()); TypeParam n(m); EXPECT_EQ(m.hash_function(), n.hash_function()); EXPECT_EQ(m.key_eq(), n.key_eq()); @@ -263,9 +263,9 @@ void CopyConstructorAllocTest(std::true_type) { H hasher; E equal; A alloc(0); - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; TypeParam m(123, hasher, equal, alloc); - for (size_t i = 0; i != 10; ++i) m.insert(gen()); + for (size_t i = 0; i != 10; ++i) m.insert(gen()); TypeParam n(m, A(11)); EXPECT_EQ(m.hash_function(), n.hash_function()); EXPECT_EQ(m.key_eq(), n.key_eq()); @@ -287,9 +287,9 @@ TYPED_TEST_P(ConstructorTest, MoveConstructor) { H hasher; E equal; A alloc(0); - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; TypeParam m(123, hasher, equal, alloc); - for (size_t i = 0; i != 10; ++i) m.insert(gen()); + for (size_t i = 0; i != 10; ++i) m.insert(gen()); TypeParam t(m); TypeParam n(std::move(t)); EXPECT_EQ(m.hash_function(), n.hash_function()); @@ -310,9 +310,9 @@ void MoveConstructorAllocTest(std::true_type) { H hasher; E equal; A alloc(0); - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; TypeParam m(123, hasher, equal, alloc); - for (size_t i = 0; i != 10; ++i) m.insert(gen()); + for (size_t i = 0; i != 10; ++i) m.insert(gen()); TypeParam t(m); TypeParam n(std::move(t), A(1)); EXPECT_EQ(m.hash_function(), n.hash_function()); @@ -329,7 +329,7 @@ TYPED_TEST_P(ConstructorTest, MoveConstructorAlloc) { TYPED_TEST_P(ConstructorTest, InitializerListBucketHashEqualAlloc) { using T = hash_internal::GeneratedType<TypeParam>; - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()}; using H = typename TypeParam::hasher; using E = typename TypeParam::key_equal; @@ -352,7 +352,7 @@ template <typename TypeParam> void InitializerListBucketAllocTest(std::true_type) { using T = hash_internal::GeneratedType<TypeParam>; using A = typename TypeParam::allocator_type; - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()}; A alloc(0); TypeParam m(values, 123, alloc); @@ -375,7 +375,7 @@ void InitializerListBucketHashAllocTest(std::true_type) { using A = typename TypeParam::allocator_type; H hasher; A alloc(0); - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()}; TypeParam m(values, 123, hasher, alloc); EXPECT_EQ(m.hash_function(), hasher); @@ -396,7 +396,7 @@ TYPED_TEST_P(ConstructorTest, Assignment) { H hasher; E equal; A alloc(0); - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; TypeParam m({gen(), gen(), gen()}, 123, hasher, equal, alloc); TypeParam n; n = m; @@ -416,7 +416,7 @@ TYPED_TEST_P(ConstructorTest, MoveAssignment) { H hasher; E equal; A alloc(0); - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; TypeParam m({gen(), gen(), gen()}, 123, hasher, equal, alloc); TypeParam t(m); TypeParam n; @@ -428,7 +428,7 @@ TYPED_TEST_P(ConstructorTest, MoveAssignment) { TYPED_TEST_P(ConstructorTest, AssignmentFromInitializerList) { using T = hash_internal::GeneratedType<TypeParam>; - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()}; TypeParam m; m = values; @@ -437,7 +437,7 @@ TYPED_TEST_P(ConstructorTest, AssignmentFromInitializerList) { TYPED_TEST_P(ConstructorTest, AssignmentOverwritesExisting) { using T = hash_internal::GeneratedType<TypeParam>; - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; TypeParam m({gen(), gen(), gen()}); TypeParam n({gen()}); n = m; @@ -446,7 +446,7 @@ TYPED_TEST_P(ConstructorTest, AssignmentOverwritesExisting) { TYPED_TEST_P(ConstructorTest, MoveAssignmentOverwritesExisting) { using T = hash_internal::GeneratedType<TypeParam>; - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; TypeParam m({gen(), gen(), gen()}); TypeParam t(m); TypeParam n({gen()}); @@ -456,7 +456,7 @@ TYPED_TEST_P(ConstructorTest, MoveAssignmentOverwritesExisting) { TYPED_TEST_P(ConstructorTest, AssignmentFromInitializerListOverwritesExisting) { using T = hash_internal::GeneratedType<TypeParam>; - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()}; TypeParam m; m = values; @@ -465,7 +465,7 @@ TYPED_TEST_P(ConstructorTest, AssignmentFromInitializerListOverwritesExisting) { TYPED_TEST_P(ConstructorTest, AssignmentOnSelf) { using T = hash_internal::GeneratedType<TypeParam>; - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()}; TypeParam m(values); m = *&m; // Avoid -Wself-assign diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/unordered_map_modifiers_test.h b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/unordered_map_modifiers_test.h index 725cfdc345..4f87496181 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/unordered_map_modifiers_test.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/unordered_map_modifiers_test.h @@ -81,38 +81,38 @@ TYPED_TEST_P(ModifiersTest, InsertRange) { ASSERT_THAT(items(m), ::testing::UnorderedElementsAreArray(values)); } -TYPED_TEST_P(ModifiersTest, InsertWithinCapacity) { - using T = hash_internal::GeneratedType<TypeParam>; - using V = typename TypeParam::mapped_type; - T val = hash_internal::Generator<T>()(); - TypeParam m; - m.reserve(10); - const size_t original_capacity = m.bucket_count(); - m.insert(val); - EXPECT_EQ(m.bucket_count(), original_capacity); - T val2 = {val.first, hash_internal::Generator<V>()()}; - m.insert(val2); - EXPECT_EQ(m.bucket_count(), original_capacity); -} - -TYPED_TEST_P(ModifiersTest, InsertRangeWithinCapacity) { -#if !defined(__GLIBCXX__) - using T = hash_internal::GeneratedType<TypeParam>; - std::vector<T> base_values; - std::generate_n(std::back_inserter(base_values), 10, - hash_internal::Generator<T>()); - std::vector<T> values; - while (values.size() != 100) { - std::copy_n(base_values.begin(), 10, std::back_inserter(values)); - } - TypeParam m; - m.reserve(10); - const size_t original_capacity = m.bucket_count(); - m.insert(values.begin(), values.end()); - EXPECT_EQ(m.bucket_count(), original_capacity); -#endif -} - +TYPED_TEST_P(ModifiersTest, InsertWithinCapacity) { + using T = hash_internal::GeneratedType<TypeParam>; + using V = typename TypeParam::mapped_type; + T val = hash_internal::Generator<T>()(); + TypeParam m; + m.reserve(10); + const size_t original_capacity = m.bucket_count(); + m.insert(val); + EXPECT_EQ(m.bucket_count(), original_capacity); + T val2 = {val.first, hash_internal::Generator<V>()()}; + m.insert(val2); + EXPECT_EQ(m.bucket_count(), original_capacity); +} + +TYPED_TEST_P(ModifiersTest, InsertRangeWithinCapacity) { +#if !defined(__GLIBCXX__) + using T = hash_internal::GeneratedType<TypeParam>; + std::vector<T> base_values; + std::generate_n(std::back_inserter(base_values), 10, + hash_internal::Generator<T>()); + std::vector<T> values; + while (values.size() != 100) { + std::copy_n(base_values.begin(), 10, std::back_inserter(values)); + } + TypeParam m; + m.reserve(10); + const size_t original_capacity = m.bucket_count(); + m.insert(values.begin(), values.end()); + EXPECT_EQ(m.bucket_count(), original_capacity); +#endif +} + TYPED_TEST_P(ModifiersTest, InsertOrAssign) { #ifdef UNORDERED_MAP_CXX17 using std::get; @@ -298,10 +298,10 @@ TYPED_TEST_P(ModifiersTest, Swap) { // TODO(alkis): Write tests for merge. REGISTER_TYPED_TEST_CASE_P(ModifiersTest, Clear, Insert, InsertHint, - InsertRange, InsertWithinCapacity, - InsertRangeWithinCapacity, InsertOrAssign, - InsertOrAssignHint, Emplace, EmplaceHint, TryEmplace, - TryEmplaceHint, Erase, EraseRange, EraseKey, Swap); + InsertRange, InsertWithinCapacity, + InsertRangeWithinCapacity, InsertOrAssign, + InsertOrAssignHint, Emplace, EmplaceHint, TryEmplace, + TryEmplaceHint, Erase, EraseRange, EraseKey, Swap); template <typename Type> struct is_unique_ptr : std::false_type {}; diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/unordered_set_modifiers_test.h b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/unordered_set_modifiers_test.h index 2f96a0197b..6b2ac56e22 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/unordered_set_modifiers_test.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/container/internal/unordered_set_modifiers_test.h @@ -74,36 +74,36 @@ TYPED_TEST_P(ModifiersTest, InsertRange) { ASSERT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values)); } -TYPED_TEST_P(ModifiersTest, InsertWithinCapacity) { - using T = hash_internal::GeneratedType<TypeParam>; - T val = hash_internal::Generator<T>()(); - TypeParam m; - m.reserve(10); - const size_t original_capacity = m.bucket_count(); - m.insert(val); - EXPECT_EQ(m.bucket_count(), original_capacity); - m.insert(val); - EXPECT_EQ(m.bucket_count(), original_capacity); -} - -TYPED_TEST_P(ModifiersTest, InsertRangeWithinCapacity) { -#if !defined(__GLIBCXX__) - using T = hash_internal::GeneratedType<TypeParam>; - std::vector<T> base_values; - std::generate_n(std::back_inserter(base_values), 10, - hash_internal::Generator<T>()); - std::vector<T> values; - while (values.size() != 100) { - values.insert(values.end(), base_values.begin(), base_values.end()); - } - TypeParam m; - m.reserve(10); - const size_t original_capacity = m.bucket_count(); - m.insert(values.begin(), values.end()); - EXPECT_EQ(m.bucket_count(), original_capacity); -#endif -} - +TYPED_TEST_P(ModifiersTest, InsertWithinCapacity) { + using T = hash_internal::GeneratedType<TypeParam>; + T val = hash_internal::Generator<T>()(); + TypeParam m; + m.reserve(10); + const size_t original_capacity = m.bucket_count(); + m.insert(val); + EXPECT_EQ(m.bucket_count(), original_capacity); + m.insert(val); + EXPECT_EQ(m.bucket_count(), original_capacity); +} + +TYPED_TEST_P(ModifiersTest, InsertRangeWithinCapacity) { +#if !defined(__GLIBCXX__) + using T = hash_internal::GeneratedType<TypeParam>; + std::vector<T> base_values; + std::generate_n(std::back_inserter(base_values), 10, + hash_internal::Generator<T>()); + std::vector<T> values; + while (values.size() != 100) { + values.insert(values.end(), base_values.begin(), base_values.end()); + } + TypeParam m; + m.reserve(10); + const size_t original_capacity = m.bucket_count(); + m.insert(values.begin(), values.end()); + EXPECT_EQ(m.bucket_count(), original_capacity); +#endif +} + TYPED_TEST_P(ModifiersTest, Emplace) { using T = hash_internal::GeneratedType<TypeParam>; T val = hash_internal::Generator<T>()(); @@ -210,9 +210,9 @@ TYPED_TEST_P(ModifiersTest, Swap) { // TODO(alkis): Write tests for merge. REGISTER_TYPED_TEST_CASE_P(ModifiersTest, Clear, Insert, InsertHint, - InsertRange, InsertWithinCapacity, - InsertRangeWithinCapacity, Emplace, EmplaceHint, - Erase, EraseRange, EraseKey, Swap); + InsertRange, InsertWithinCapacity, + InsertRangeWithinCapacity, Emplace, EmplaceHint, + Erase, EraseRange, EraseKey, Swap); } // namespace container_internal ABSL_NAMESPACE_END diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/failure_signal_handler.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/failure_signal_handler.cc index fa6e30f935..8ba76c7f25 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/failure_signal_handler.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/failure_signal_handler.cc @@ -367,7 +367,7 @@ static void AbslFailureSignalHandler(int signo, siginfo_t*, void* ucontext) { // goes after this point. if (fsh_options.writerfn != nullptr) { WriteFailureInfo(signo, ucontext, my_cpu, fsh_options.writerfn); - fsh_options.writerfn(nullptr); + fsh_options.writerfn(nullptr); } if (fsh_options.call_previous_handler) { diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/failure_signal_handler.h b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/failure_signal_handler.h index 879df3c434..3d3e14aefd 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/failure_signal_handler.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/failure_signal_handler.h @@ -90,7 +90,7 @@ struct FailureSignalHandlerOptions { // If non-null, indicates a pointer to a callback function that will be called // upon failure, with a string argument containing failure data. This function // may be used as a hook to write failure data to a secondary location, such - // as a log file. This function will also be called with null data, as a hint + // as a log file. This function will also be called with null data, as a hint // to flush any buffered data before the program may be terminated. Consider // flushing any buffered data in all calls to this function. // diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/failure_signal_handler/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/failure_signal_handler/ya.make index 0c71cb5547..683a22996f 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/failure_signal_handler/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/failure_signal_handler/ya.make @@ -13,19 +13,19 @@ LICENSE(Apache-2.0) PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/base - contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/low_level_alloc contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/raw_logging contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/throw_delegate contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity - contrib/restricted/abseil-cpp-tstring/y_absl/debugging - contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal - contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace - contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize - contrib/restricted/abseil-cpp-tstring/y_absl/demangle + contrib/restricted/abseil-cpp-tstring/y_absl/debugging + contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal + contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace + contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize + contrib/restricted/abseil-cpp-tstring/y_absl/demangle contrib/restricted/abseil-cpp-tstring/y_absl/numeric contrib/restricted/abseil-cpp-tstring/y_absl/strings - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal ) ADDINCL( @@ -34,10 +34,10 @@ ADDINCL( NO_COMPILER_WARNINGS() -SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/debugging) +SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/debugging) SRCS( - failure_signal_handler.cc + failure_signal_handler.cc ) END() diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/.yandex_meta/licenses.list.txt b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/.yandex_meta/licenses.list.txt index aac6c71d05..68f928b27c 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/.yandex_meta/licenses.list.txt +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/.yandex_meta/licenses.list.txt @@ -1,18 +1,18 @@ ====================Apache-2.0==================== - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - - -====================Apache-2.0==================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + + +====================Apache-2.0==================== // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/demangle.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/demangle.cc index 0a4daa2f5c..622460ebb1 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/demangle.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/demangle.cc @@ -1617,7 +1617,7 @@ static bool ParseUnresolvedName(State *state) { // ::= <2-ary operator-name> <expression> <expression> // ::= <3-ary operator-name> <expression> <expression> <expression> // ::= cl <expression>+ E -// ::= cp <simple-id> <expression>* E # Clang-specific. +// ::= cp <simple-id> <expression>* E # Clang-specific. // ::= cv <type> <expression> # type (expression) // ::= cv <type> _ <expression>* E # type (expr-list) // ::= st <type> @@ -1640,8 +1640,8 @@ static bool ParseExpression(State *state) { return true; } - ParseState copy = state->parse_state; - + ParseState copy = state->parse_state; + // Object/function call expression. if (ParseTwoCharToken(state, "cl") && OneOrMore(ParseExpression, state) && ParseOneCharToken(state, 'E')) { @@ -1649,14 +1649,14 @@ static bool ParseExpression(State *state) { } state->parse_state = copy; - // Clang-specific "cp <simple-id> <expression>* E" - // https://clang.llvm.org/doxygen/ItaniumMangle_8cpp_source.html#l04338 - if (ParseTwoCharToken(state, "cp") && ParseSimpleId(state) && - ZeroOrMore(ParseExpression, state) && ParseOneCharToken(state, 'E')) { - return true; - } - state->parse_state = copy; - + // Clang-specific "cp <simple-id> <expression>* E" + // https://clang.llvm.org/doxygen/ItaniumMangle_8cpp_source.html#l04338 + if (ParseTwoCharToken(state, "cp") && ParseSimpleId(state) && + ZeroOrMore(ParseExpression, state) && ParseOneCharToken(state, 'E')) { + return true; + } + state->parse_state = copy; + // Function-param expression (level 0). if (ParseTwoCharToken(state, "fp") && Optional(ParseCVQualifiers(state)) && Optional(ParseNumber(state, nullptr)) && ParseOneCharToken(state, '_')) { diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/elf_mem_image.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/elf_mem_image.cc index ba4bbc3855..1db568e3a4 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/elf_mem_image.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/elf_mem_image.cc @@ -22,7 +22,7 @@ #include <string.h> #include <cassert> #include <cstddef> -#include "y_absl/base/config.h" +#include "y_absl/base/config.h" #include "y_absl/base/internal/raw_logging.h" // From binutils/include/elf/common.h (this doesn't appear to be documented @@ -44,11 +44,11 @@ namespace debugging_internal { namespace { -#if __SIZEOF_POINTER__ == 4 +#if __SIZEOF_POINTER__ == 4 const int kElfClass = ELFCLASS32; int ElfBind(const ElfW(Sym) *symbol) { return ELF32_ST_BIND(symbol->st_info); } int ElfType(const ElfW(Sym) *symbol) { return ELF32_ST_TYPE(symbol->st_info); } -#elif __SIZEOF_POINTER__ == 8 +#elif __SIZEOF_POINTER__ == 8 const int kElfClass = ELFCLASS64; int ElfBind(const ElfW(Sym) *symbol) { return ELF64_ST_BIND(symbol->st_info); } int ElfType(const ElfW(Sym) *symbol) { return ELF64_ST_TYPE(symbol->st_info); } @@ -176,17 +176,17 @@ void ElfMemImage::Init(const void *base) { } switch (base_as_char[EI_DATA]) { case ELFDATA2LSB: { -#ifndef ABSL_IS_LITTLE_ENDIAN - assert(false); - return; -#endif +#ifndef ABSL_IS_LITTLE_ENDIAN + assert(false); + return; +#endif break; } case ELFDATA2MSB: { -#ifndef ABSL_IS_BIG_ENDIAN - assert(false); - return; -#endif +#ifndef ABSL_IS_BIG_ENDIAN + assert(false); + return; +#endif break; } default: { @@ -222,7 +222,7 @@ void ElfMemImage::Init(const void *base) { reinterpret_cast<ElfW(Dyn) *>(dynamic_program_header->p_vaddr + relocation); for (; dynamic_entry->d_tag != DT_NULL; ++dynamic_entry) { - const auto value = dynamic_entry->d_un.d_val + relocation; + const auto value = dynamic_entry->d_un.d_val + relocation; switch (dynamic_entry->d_tag) { case DT_HASH: hash_ = reinterpret_cast<ElfW(Word) *>(value); diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/elf_mem_image.h b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/elf_mem_image.h index 13a6b2e664..c7a189e95f 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/elf_mem_image.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/elf_mem_image.h @@ -31,8 +31,8 @@ #error ABSL_HAVE_ELF_MEM_IMAGE cannot be directly set #endif -#if defined(__ELF__) && !defined(__native_client__) && !defined(__asmjs__) && \ - !defined(__wasm__) +#if defined(__ELF__) && !defined(__native_client__) && !defined(__asmjs__) && \ + !defined(__wasm__) #define ABSL_HAVE_ELF_MEM_IMAGE 1 #endif @@ -40,10 +40,10 @@ #include <link.h> // for ElfW -#if defined(__FreeBSD__) && !defined(ElfW) -#define ElfW(x) __ElfN(x) -#endif - +#if defined(__FreeBSD__) && !defined(ElfW) +#define ElfW(x) __ElfN(x) +#endif + namespace y_absl { ABSL_NAMESPACE_BEGIN namespace debugging_internal { diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/stack_consumption.h b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/stack_consumption.h index 80137ad0eb..846c1b9ced 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/stack_consumption.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/stack_consumption.h @@ -26,7 +26,7 @@ #error ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION cannot be set directly #elif !defined(__APPLE__) && !defined(_WIN32) && \ (defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || \ - defined(__aarch64__) || defined(__riscv)) + defined(__aarch64__) || defined(__riscv)) #define ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION 1 namespace y_absl { diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/stacktrace_config.h b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/stacktrace_config.h index 7ba212ab03..83705649d4 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/stacktrace_config.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/stacktrace_config.h @@ -35,12 +35,12 @@ // Thread local support required for UnwindImpl. #define ABSL_STACKTRACE_INL_HEADER \ "y_absl/debugging/internal/stacktrace_generic-inl.inc" -#endif // defined(ABSL_HAVE_THREAD_LOCAL) - -#elif defined(__EMSCRIPTEN__) -#define ABSL_STACKTRACE_INL_HEADER \ - "y_absl/debugging/internal/stacktrace_emscripten-inl.inc" +#endif // defined(ABSL_HAVE_THREAD_LOCAL) +#elif defined(__EMSCRIPTEN__) +#define ABSL_STACKTRACE_INL_HEADER \ + "y_absl/debugging/internal/stacktrace_emscripten-inl.inc" + #elif defined(__linux__) && !defined(__ANDROID__) #if defined(NO_FRAME_POINTER) && \ @@ -55,7 +55,7 @@ // Note: When using glibc this may require -funwind-tables to function properly. #define ABSL_STACKTRACE_INL_HEADER \ "y_absl/debugging/internal/stacktrace_generic-inl.inc" -#endif // __has_include(<execinfo.h>) +#endif // __has_include(<execinfo.h>) #elif defined(__i386__) || defined(__x86_64__) #define ABSL_STACKTRACE_INL_HEADER \ "y_absl/debugging/internal/stacktrace_x86-inl.inc" @@ -65,18 +65,18 @@ #elif defined(__aarch64__) #define ABSL_STACKTRACE_INL_HEADER \ "y_absl/debugging/internal/stacktrace_aarch64-inl.inc" -#elif defined(__riscv) -#define ABSL_STACKTRACE_INL_HEADER \ - "y_absl/debugging/internal/stacktrace_riscv-inl.inc" +#elif defined(__riscv) +#define ABSL_STACKTRACE_INL_HEADER \ + "y_absl/debugging/internal/stacktrace_riscv-inl.inc" #elif defined(__has_include) #if __has_include(<execinfo.h>) // Note: When using glibc this may require -funwind-tables to function properly. #define ABSL_STACKTRACE_INL_HEADER \ "y_absl/debugging/internal/stacktrace_generic-inl.inc" -#endif // __has_include(<execinfo.h>) -#endif // defined(__has_include) +#endif // __has_include(<execinfo.h>) +#endif // defined(__has_include) -#endif // defined(__linux__) && !defined(__ANDROID__) +#endif // defined(__linux__) && !defined(__ANDROID__) // Fallback to the empty implementation. #if !defined(ABSL_STACKTRACE_INL_HEADER) diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/stacktrace_emscripten-inl.inc b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/stacktrace_emscripten-inl.inc index cdb5557134..6d9a9a1ee7 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/stacktrace_emscripten-inl.inc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/stacktrace_emscripten-inl.inc @@ -1,110 +1,110 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Portable implementation - just use glibc -// -// Note: The glibc implementation may cause a call to malloc. -// This can cause a deadlock in HeapProfiler. - -#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_EMSCRIPTEN_INL_H_ -#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_EMSCRIPTEN_INL_H_ - -#error #include <emscripten.h> - -#include <atomic> -#include <cstring> - -#include "y_absl/base/attributes.h" -#include "y_absl/debugging/stacktrace.h" - -extern "C" { -uintptr_t emscripten_stack_snapshot(); -uint32_t emscripten_stack_unwind_buffer(uintptr_t pc, void *buffer, - uint32_t depth); -} - -// Sometimes, we can try to get a stack trace from within a stack -// trace, which can cause a self-deadlock. -// Protect against such reentrant call by failing to get a stack trace. -// -// We use __thread here because the code here is extremely low level -- it is -// called while collecting stack traces from within malloc and mmap, and thus -// can not call anything which might call malloc or mmap itself. -static __thread int recursive = 0; - -// The stack trace function might be invoked very early in the program's -// execution (e.g. from the very first malloc). -// As such, we suppress usage of backtrace during this early stage of execution. -static std::atomic<bool> disable_stacktraces(true); // Disabled until healthy. -// Waiting until static initializers run seems to be late enough. -// This file is included into stacktrace.cc so this will only run once. -ABSL_ATTRIBUTE_UNUSED static int stacktraces_enabler = []() { - // Check if we can even create stacktraces. If not, bail early and leave - // disable_stacktraces set as-is. - // clang-format off - if (!EM_ASM_INT({ return (typeof wasmOffsetConverter !== 'undefined'); })) { - return 0; - } - // clang-format on - disable_stacktraces.store(false, std::memory_order_relaxed); - return 0; -}(); - -template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> -static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count, - const void *ucp, int *min_dropped_frames) { - if (recursive || disable_stacktraces.load(std::memory_order_relaxed)) { - return 0; - } - ++recursive; - - static_cast<void>(ucp); // Unused. - constexpr int kStackLength = 64; - void *stack[kStackLength]; - - int size; - uintptr_t pc = emscripten_stack_snapshot(); - size = emscripten_stack_unwind_buffer(pc, stack, kStackLength); - - int result_count = size - skip_count; - if (result_count < 0) result_count = 0; - if (result_count > max_depth) result_count = max_depth; - for (int i = 0; i < result_count; i++) result[i] = stack[i + skip_count]; - - if (IS_STACK_FRAMES) { - // No implementation for finding out the stack frame sizes yet. - memset(sizes, 0, sizeof(*sizes) * result_count); - } - if (min_dropped_frames != nullptr) { - if (size - skip_count - max_depth > 0) { - *min_dropped_frames = size - skip_count - max_depth; - } else { - *min_dropped_frames = 0; - } - } - - --recursive; - - return result_count; -} - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace debugging_internal { -bool StackTraceWorksForTest() { return true; } -} // namespace debugging_internal -ABSL_NAMESPACE_END -} // namespace y_absl - -#endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_EMSCRIPTEN_INL_H_ +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Portable implementation - just use glibc +// +// Note: The glibc implementation may cause a call to malloc. +// This can cause a deadlock in HeapProfiler. + +#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_EMSCRIPTEN_INL_H_ +#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_EMSCRIPTEN_INL_H_ + +#error #include <emscripten.h> + +#include <atomic> +#include <cstring> + +#include "y_absl/base/attributes.h" +#include "y_absl/debugging/stacktrace.h" + +extern "C" { +uintptr_t emscripten_stack_snapshot(); +uint32_t emscripten_stack_unwind_buffer(uintptr_t pc, void *buffer, + uint32_t depth); +} + +// Sometimes, we can try to get a stack trace from within a stack +// trace, which can cause a self-deadlock. +// Protect against such reentrant call by failing to get a stack trace. +// +// We use __thread here because the code here is extremely low level -- it is +// called while collecting stack traces from within malloc and mmap, and thus +// can not call anything which might call malloc or mmap itself. +static __thread int recursive = 0; + +// The stack trace function might be invoked very early in the program's +// execution (e.g. from the very first malloc). +// As such, we suppress usage of backtrace during this early stage of execution. +static std::atomic<bool> disable_stacktraces(true); // Disabled until healthy. +// Waiting until static initializers run seems to be late enough. +// This file is included into stacktrace.cc so this will only run once. +ABSL_ATTRIBUTE_UNUSED static int stacktraces_enabler = []() { + // Check if we can even create stacktraces. If not, bail early and leave + // disable_stacktraces set as-is. + // clang-format off + if (!EM_ASM_INT({ return (typeof wasmOffsetConverter !== 'undefined'); })) { + return 0; + } + // clang-format on + disable_stacktraces.store(false, std::memory_order_relaxed); + return 0; +}(); + +template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> +static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count, + const void *ucp, int *min_dropped_frames) { + if (recursive || disable_stacktraces.load(std::memory_order_relaxed)) { + return 0; + } + ++recursive; + + static_cast<void>(ucp); // Unused. + constexpr int kStackLength = 64; + void *stack[kStackLength]; + + int size; + uintptr_t pc = emscripten_stack_snapshot(); + size = emscripten_stack_unwind_buffer(pc, stack, kStackLength); + + int result_count = size - skip_count; + if (result_count < 0) result_count = 0; + if (result_count > max_depth) result_count = max_depth; + for (int i = 0; i < result_count; i++) result[i] = stack[i + skip_count]; + + if (IS_STACK_FRAMES) { + // No implementation for finding out the stack frame sizes yet. + memset(sizes, 0, sizeof(*sizes) * result_count); + } + if (min_dropped_frames != nullptr) { + if (size - skip_count - max_depth > 0) { + *min_dropped_frames = size - skip_count - max_depth; + } else { + *min_dropped_frames = 0; + } + } + + --recursive; + + return result_count; +} + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace debugging_internal { +bool StackTraceWorksForTest() { return true; } +} // namespace debugging_internal +ABSL_NAMESPACE_END +} // namespace y_absl + +#endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_EMSCRIPTEN_INL_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/stacktrace_riscv-inl.inc b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/stacktrace_riscv-inl.inc index 8571c8cbfd..f65ea7f507 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/stacktrace_riscv-inl.inc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/stacktrace_riscv-inl.inc @@ -1,234 +1,234 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_RISCV_INL_H_ -#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_RISCV_INL_H_ - -// Generate stack trace for riscv - -#include <sys/ucontext.h> - -#include "y_absl/base/config.h" -#if defined(__linux__) -#include <sys/mman.h> -#include <ucontext.h> -#include <unistd.h> -#endif - -#include <atomic> -#include <cassert> -#include <cstdint> -#include <iostream> - -#include "y_absl/base/attributes.h" -#include "y_absl/debugging/internal/address_is_readable.h" -#include "y_absl/debugging/internal/vdso_support.h" -#include "y_absl/debugging/stacktrace.h" - -static const uintptr_t kUnknownFrameSize = 0; - -#if defined(__linux__) -// Returns the address of the VDSO __kernel_rt_sigreturn function, if present. -static const unsigned char *GetKernelRtSigreturnAddress() { - constexpr uintptr_t kImpossibleAddress = 0; - ABSL_CONST_INIT static std::atomic<uintptr_t> memoized(kImpossibleAddress); - uintptr_t address = memoized.load(std::memory_order_relaxed); - if (address != kImpossibleAddress) { - return reinterpret_cast<const unsigned char *>(address); - } - - address = reinterpret_cast<uintptr_t>(nullptr); - -#if ABSL_HAVE_VDSO_SUPPORT - y_absl::debugging_internal::VDSOSupport vdso; - if (vdso.IsPresent()) { - y_absl::debugging_internal::VDSOSupport::SymbolInfo symbol_info; - // Symbol versioning pulled from arch/riscv/kernel/vdso/vdso.lds at v5.10. - auto lookup = [&](int type) { - return vdso.LookupSymbol("__kernel_rt_sigreturn", "LINUX_4.15", type, - &symbol_info); - }; - if ((!lookup(STT_FUNC) && !lookup(STT_NOTYPE)) || - symbol_info.address == nullptr) { - // Unexpected: VDSO is present, yet the expected symbol is missing or - // null. - assert(false && "VDSO is present, but doesn't have expected symbol"); - } else { - if (reinterpret_cast<uintptr_t>(symbol_info.address) != - kImpossibleAddress) { - address = reinterpret_cast<uintptr_t>(symbol_info.address); - } else { - assert(false && "VDSO returned invalid address"); - } - } - } -#endif - - memoized.store(address, std::memory_order_relaxed); - return reinterpret_cast<const unsigned char *>(address); -} -#endif // __linux__ - -// Compute the size of a stack frame in [low..high). We assume that low < high. -// Return size of kUnknownFrameSize. -template <typename T> -static inline uintptr_t ComputeStackFrameSize(const T *low, const T *high) { - const char *low_char_ptr = reinterpret_cast<const char *>(low); - const char *high_char_ptr = reinterpret_cast<const char *>(high); - return low < high ? high_char_ptr - low_char_ptr : kUnknownFrameSize; -} - -// Given a pointer to a stack frame, locate and return the calling stackframe, -// or return null if no stackframe can be found. Perform sanity checks (the -// strictness of which is controlled by the boolean parameter -// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned. -template <bool STRICT_UNWINDING, bool WITH_CONTEXT> -ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack. -ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack. -static void ** NextStackFrame(void **old_frame_pointer, const void *uc) { - // . - // . - // . - // +-> +----------------+ - // | | return address | - // | | previous fp | - // | | ... | - // | +----------------+ <-+ - // | | return address | | - // +---|- previous fp | | - // | ... | | - // $fp ->|----------------+ | - // | return address | | - // | previous fp -|---+ - // $sp ->| ... | - // +----------------+ - void **new_frame_pointer = reinterpret_cast<void **>(old_frame_pointer[-2]); - bool check_frame_size = true; - -#if defined(__linux__) - if (WITH_CONTEXT && uc != nullptr) { - // Check to see if next frame's return address is __kernel_rt_sigreturn. - if (old_frame_pointer[-1] == GetKernelRtSigreturnAddress()) { - const ucontext_t *ucv = static_cast<const ucontext_t *>(uc); - // old_frame_pointer is not suitable for unwinding, look at ucontext to - // discover frame pointer before signal. - // - // RISCV ELF psABI has the frame pointer at x8/fp/s0. - // -- RISCV psABI Table 18.2 - void **const pre_signal_frame_pointer = - reinterpret_cast<void **>(ucv->uc_mcontext.__gregs[8]); - - // Check the alleged frame pointer is actually readable. This is to - // prevent "double fault" in case we hit the first fault due to stack - // corruption. - if (!y_absl::debugging_internal::AddressIsReadable( - pre_signal_frame_pointer)) - return nullptr; - - // Alleged frame pointer is readable, use it for further unwinding. - new_frame_pointer = pre_signal_frame_pointer; - - // Skip frame size check if we return from a signal. We may be using an - // alterate stack for signals. - check_frame_size = false; - } - } -#endif - - // The RISCV ELF psABI mandates that the stack pointer is always 16-byte - // aligned. - // FIXME(abdulras) this doesn't hold for ILP32E which only mandates a 4-byte - // alignment. - if ((reinterpret_cast<uintptr_t>(new_frame_pointer) & 15) != 0) - return nullptr; - - // Check frame size. In strict mode, we assume frames to be under 100,000 - // bytes. In non-strict mode, we relax the limit to 1MB. - if (check_frame_size) { - const uintptr_t max_size = STRICT_UNWINDING ? 100000 : 1000000; - const uintptr_t frame_size = - ComputeStackFrameSize(old_frame_pointer, new_frame_pointer); - if (frame_size == kUnknownFrameSize || frame_size > max_size) - return nullptr; - } - - return new_frame_pointer; -} - -template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> -ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack. -ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack. -static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count, - const void *ucp, int *min_dropped_frames) { -#if defined(__GNUC__) - void **frame_pointer = reinterpret_cast<void **>(__builtin_frame_address(0)); -#else -#error reading stack pointer not yet supported on this platform -#endif - - skip_count++; // Skip the frame for this function. - int n = 0; - - // The `frame_pointer` that is computed here points to the top of the frame. - // The two words preceding the address are the return address and the previous - // frame pointer. To find a PC value associated with the current frame, we - // need to go down a level in the call chain. So we remember the return - // address of the last frame seen. This does not work for the first stack - // frame, which belongs to `UnwindImp()` but we skip the frame for - // `UnwindImp()` anyway. - void *prev_return_address = nullptr; - - while (frame_pointer && n < max_depth) { - // The y_absl::GetStackFrames routine si called when we are in some - // informational context (the failure signal handler for example). Use the - // non-strict unwinding rules to produce a stack trace that is as complete - // as possible (even if it contains a few bogus entries in some rare cases). - void **next_frame_pointer = - NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(frame_pointer, ucp); - - if (skip_count > 0) { - skip_count--; - } else { - result[n] = prev_return_address; - if (IS_STACK_FRAMES) { - sizes[n] = ComputeStackFrameSize(frame_pointer, next_frame_pointer); - } - n++; - } - prev_return_address = frame_pointer[-1]; - frame_pointer = next_frame_pointer; - } - if (min_dropped_frames != nullptr) { - // Implementation detail: we clamp the max of frames we are willing to - // count, so as not to spend too much time in the loop below. - const int kMaxUnwind = 200; - int j = 0; - for (; frame_pointer != nullptr && j < kMaxUnwind; j++) { - frame_pointer = - NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(frame_pointer, ucp); - } - *min_dropped_frames = j; - } - return n; -} - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace debugging_internal { -bool StackTraceWorksForTest() { return true; } -} // namespace debugging_internal -ABSL_NAMESPACE_END -} // namespace y_absl - -#endif +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_RISCV_INL_H_ +#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_RISCV_INL_H_ + +// Generate stack trace for riscv + +#include <sys/ucontext.h> + +#include "y_absl/base/config.h" +#if defined(__linux__) +#include <sys/mman.h> +#include <ucontext.h> +#include <unistd.h> +#endif + +#include <atomic> +#include <cassert> +#include <cstdint> +#include <iostream> + +#include "y_absl/base/attributes.h" +#include "y_absl/debugging/internal/address_is_readable.h" +#include "y_absl/debugging/internal/vdso_support.h" +#include "y_absl/debugging/stacktrace.h" + +static const uintptr_t kUnknownFrameSize = 0; + +#if defined(__linux__) +// Returns the address of the VDSO __kernel_rt_sigreturn function, if present. +static const unsigned char *GetKernelRtSigreturnAddress() { + constexpr uintptr_t kImpossibleAddress = 0; + ABSL_CONST_INIT static std::atomic<uintptr_t> memoized(kImpossibleAddress); + uintptr_t address = memoized.load(std::memory_order_relaxed); + if (address != kImpossibleAddress) { + return reinterpret_cast<const unsigned char *>(address); + } + + address = reinterpret_cast<uintptr_t>(nullptr); + +#if ABSL_HAVE_VDSO_SUPPORT + y_absl::debugging_internal::VDSOSupport vdso; + if (vdso.IsPresent()) { + y_absl::debugging_internal::VDSOSupport::SymbolInfo symbol_info; + // Symbol versioning pulled from arch/riscv/kernel/vdso/vdso.lds at v5.10. + auto lookup = [&](int type) { + return vdso.LookupSymbol("__kernel_rt_sigreturn", "LINUX_4.15", type, + &symbol_info); + }; + if ((!lookup(STT_FUNC) && !lookup(STT_NOTYPE)) || + symbol_info.address == nullptr) { + // Unexpected: VDSO is present, yet the expected symbol is missing or + // null. + assert(false && "VDSO is present, but doesn't have expected symbol"); + } else { + if (reinterpret_cast<uintptr_t>(symbol_info.address) != + kImpossibleAddress) { + address = reinterpret_cast<uintptr_t>(symbol_info.address); + } else { + assert(false && "VDSO returned invalid address"); + } + } + } +#endif + + memoized.store(address, std::memory_order_relaxed); + return reinterpret_cast<const unsigned char *>(address); +} +#endif // __linux__ + +// Compute the size of a stack frame in [low..high). We assume that low < high. +// Return size of kUnknownFrameSize. +template <typename T> +static inline uintptr_t ComputeStackFrameSize(const T *low, const T *high) { + const char *low_char_ptr = reinterpret_cast<const char *>(low); + const char *high_char_ptr = reinterpret_cast<const char *>(high); + return low < high ? high_char_ptr - low_char_ptr : kUnknownFrameSize; +} + +// Given a pointer to a stack frame, locate and return the calling stackframe, +// or return null if no stackframe can be found. Perform sanity checks (the +// strictness of which is controlled by the boolean parameter +// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned. +template <bool STRICT_UNWINDING, bool WITH_CONTEXT> +ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack. +ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack. +static void ** NextStackFrame(void **old_frame_pointer, const void *uc) { + // . + // . + // . + // +-> +----------------+ + // | | return address | + // | | previous fp | + // | | ... | + // | +----------------+ <-+ + // | | return address | | + // +---|- previous fp | | + // | ... | | + // $fp ->|----------------+ | + // | return address | | + // | previous fp -|---+ + // $sp ->| ... | + // +----------------+ + void **new_frame_pointer = reinterpret_cast<void **>(old_frame_pointer[-2]); + bool check_frame_size = true; + +#if defined(__linux__) + if (WITH_CONTEXT && uc != nullptr) { + // Check to see if next frame's return address is __kernel_rt_sigreturn. + if (old_frame_pointer[-1] == GetKernelRtSigreturnAddress()) { + const ucontext_t *ucv = static_cast<const ucontext_t *>(uc); + // old_frame_pointer is not suitable for unwinding, look at ucontext to + // discover frame pointer before signal. + // + // RISCV ELF psABI has the frame pointer at x8/fp/s0. + // -- RISCV psABI Table 18.2 + void **const pre_signal_frame_pointer = + reinterpret_cast<void **>(ucv->uc_mcontext.__gregs[8]); + + // Check the alleged frame pointer is actually readable. This is to + // prevent "double fault" in case we hit the first fault due to stack + // corruption. + if (!y_absl::debugging_internal::AddressIsReadable( + pre_signal_frame_pointer)) + return nullptr; + + // Alleged frame pointer is readable, use it for further unwinding. + new_frame_pointer = pre_signal_frame_pointer; + + // Skip frame size check if we return from a signal. We may be using an + // alterate stack for signals. + check_frame_size = false; + } + } +#endif + + // The RISCV ELF psABI mandates that the stack pointer is always 16-byte + // aligned. + // FIXME(abdulras) this doesn't hold for ILP32E which only mandates a 4-byte + // alignment. + if ((reinterpret_cast<uintptr_t>(new_frame_pointer) & 15) != 0) + return nullptr; + + // Check frame size. In strict mode, we assume frames to be under 100,000 + // bytes. In non-strict mode, we relax the limit to 1MB. + if (check_frame_size) { + const uintptr_t max_size = STRICT_UNWINDING ? 100000 : 1000000; + const uintptr_t frame_size = + ComputeStackFrameSize(old_frame_pointer, new_frame_pointer); + if (frame_size == kUnknownFrameSize || frame_size > max_size) + return nullptr; + } + + return new_frame_pointer; +} + +template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> +ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack. +ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack. +static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count, + const void *ucp, int *min_dropped_frames) { +#if defined(__GNUC__) + void **frame_pointer = reinterpret_cast<void **>(__builtin_frame_address(0)); +#else +#error reading stack pointer not yet supported on this platform +#endif + + skip_count++; // Skip the frame for this function. + int n = 0; + + // The `frame_pointer` that is computed here points to the top of the frame. + // The two words preceding the address are the return address and the previous + // frame pointer. To find a PC value associated with the current frame, we + // need to go down a level in the call chain. So we remember the return + // address of the last frame seen. This does not work for the first stack + // frame, which belongs to `UnwindImp()` but we skip the frame for + // `UnwindImp()` anyway. + void *prev_return_address = nullptr; + + while (frame_pointer && n < max_depth) { + // The y_absl::GetStackFrames routine si called when we are in some + // informational context (the failure signal handler for example). Use the + // non-strict unwinding rules to produce a stack trace that is as complete + // as possible (even if it contains a few bogus entries in some rare cases). + void **next_frame_pointer = + NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(frame_pointer, ucp); + + if (skip_count > 0) { + skip_count--; + } else { + result[n] = prev_return_address; + if (IS_STACK_FRAMES) { + sizes[n] = ComputeStackFrameSize(frame_pointer, next_frame_pointer); + } + n++; + } + prev_return_address = frame_pointer[-1]; + frame_pointer = next_frame_pointer; + } + if (min_dropped_frames != nullptr) { + // Implementation detail: we clamp the max of frames we are willing to + // count, so as not to spend too much time in the loop below. + const int kMaxUnwind = 200; + int j = 0; + for (; frame_pointer != nullptr && j < kMaxUnwind; j++) { + frame_pointer = + NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(frame_pointer, ucp); + } + *min_dropped_frames = j; + } + return n; +} + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace debugging_internal { +bool StackTraceWorksForTest() { return true; } +} // namespace debugging_internal +ABSL_NAMESPACE_END +} // namespace y_absl + +#endif diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/stacktrace_x86-inl.inc b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/stacktrace_x86-inl.inc index 8936f8ca70..9348161a6c 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/stacktrace_x86-inl.inc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/stacktrace_x86-inl.inc @@ -27,7 +27,7 @@ #include <cassert> #include <cstdint> -#include <limits> +#include <limits> #include "y_absl/base/macros.h" #include "y_absl/base/port.h" @@ -133,8 +133,8 @@ static uintptr_t GetFP(const void *vuc) { const uintptr_t bp = 0; const uintptr_t sp = 0; #endif - // Sanity-check that the base pointer is valid. It's possible that some - // code in the process is compiled with --copt=-fomit-frame-pointer or + // Sanity-check that the base pointer is valid. It's possible that some + // code in the process is compiled with --copt=-fomit-frame-pointer or // --copt=-momit-leaf-frame-pointer. // // TODO(bcmills): -momit-leaf-frame-pointer is currently the default @@ -159,8 +159,8 @@ static uintptr_t GetFP(const void *vuc) { template <bool STRICT_UNWINDING, bool WITH_CONTEXT> ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack. ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack. -static void **NextStackFrame(void **old_fp, const void *uc, - size_t stack_low, size_t stack_high) { +static void **NextStackFrame(void **old_fp, const void *uc, + size_t stack_low, size_t stack_high) { void **new_fp = (void **)*old_fp; #if defined(__linux__) && defined(__i386__) @@ -248,7 +248,7 @@ static void **NextStackFrame(void **old_fp, const void *uc, // using an alternate signal stack. // // TODO(bcmills): The GetFP call should be completely unnecessary when - // ENABLE_COMBINED_UNWINDER is set (because we should be back in the thread's + // ENABLE_COMBINED_UNWINDER is set (because we should be back in the thread's // stack by this point), but it is empirically still needed (e.g. when the // stack includes a call to abort). unw_get_reg returns UNW_EBADREG for some // frames. Figure out why GetValidFrameAddr and/or libunwind isn't doing what @@ -259,18 +259,18 @@ static void **NextStackFrame(void **old_fp, const void *uc, // at a greater address that the current one. if (new_fp_u <= old_fp_u) return nullptr; if (new_fp_u - old_fp_u > kMaxFrameBytes) return nullptr; - - if (stack_low < old_fp_u && old_fp_u <= stack_high) { - // Old BP was in the expected stack region... - if (!(stack_low < new_fp_u && new_fp_u <= stack_high)) { - // ... but new BP is outside of expected stack region. - // It is most likely bogus. - return nullptr; - } - } else { - // We may be here if we are executing in a co-routine with a - // separate stack. We can't do safety checks in this case. - } + + if (stack_low < old_fp_u && old_fp_u <= stack_high) { + // Old BP was in the expected stack region... + if (!(stack_low < new_fp_u && new_fp_u <= stack_high)) { + // ... but new BP is outside of expected stack region. + // It is most likely bogus. + return nullptr; + } + } else { + // We may be here if we are executing in a co-routine with a + // separate stack. We can't do safety checks in this case. + } } else { if (new_fp == nullptr) return nullptr; // skip AddressIsReadable() below // In the non-strict mode, allow discontiguous stack frames. @@ -310,17 +310,17 @@ static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count, int n = 0; void **fp = reinterpret_cast<void **>(__builtin_frame_address(0)); - size_t stack_low = getpagesize(); // Assume that the first page is not stack. - size_t stack_high = std::numeric_limits<size_t>::max() - sizeof(void *); - + size_t stack_low = getpagesize(); // Assume that the first page is not stack. + size_t stack_high = std::numeric_limits<size_t>::max() - sizeof(void *); + while (fp && n < max_depth) { if (*(fp + 1) == reinterpret_cast<void *>(0)) { // In 64-bit code, we often see a frame that // points to itself and has a return address of 0. break; } - void **next_fp = NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>( - fp, ucp, stack_low, stack_high); + void **next_fp = NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>( + fp, ucp, stack_low, stack_high); if (skip_count > 0) { skip_count--; } else { @@ -343,8 +343,8 @@ static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count, const int kMaxUnwind = 1000; int j = 0; for (; fp != nullptr && j < kMaxUnwind; j++) { - fp = NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(fp, ucp, stack_low, - stack_high); + fp = NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(fp, ucp, stack_low, + stack_high); } *min_dropped_frames = j; } diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/symbolize.h b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/symbolize.h index e6e2b0724a..b9baf92d1a 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/symbolize.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/symbolize.h @@ -28,8 +28,8 @@ #ifdef ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE #error ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE cannot be directly set -#elif defined(__ELF__) && defined(__GLIBC__) && !defined(__native_client__) \ - && !defined(__asmjs__) && !defined(__wasm__) +#elif defined(__ELF__) && defined(__GLIBC__) && !defined(__native_client__) \ + && !defined(__asmjs__) && !defined(__wasm__) #define ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE 1 #include <elf.h> @@ -68,12 +68,12 @@ ABSL_NAMESPACE_END #define ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE 1 #endif -#ifdef ABSL_INTERNAL_HAVE_EMSCRIPTEN_SYMBOLIZE -#error ABSL_INTERNAL_HAVE_EMSCRIPTEN_SYMBOLIZE cannot be directly set -#elif defined(__EMSCRIPTEN__) -#define ABSL_INTERNAL_HAVE_EMSCRIPTEN_SYMBOLIZE 1 -#endif - +#ifdef ABSL_INTERNAL_HAVE_EMSCRIPTEN_SYMBOLIZE +#error ABSL_INTERNAL_HAVE_EMSCRIPTEN_SYMBOLIZE cannot be directly set +#elif defined(__EMSCRIPTEN__) +#define ABSL_INTERNAL_HAVE_EMSCRIPTEN_SYMBOLIZE 1 +#endif + namespace y_absl { ABSL_NAMESPACE_BEGIN namespace debugging_internal { diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/vdso_support.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/vdso_support.cc index 7905eba32f..451be5fde1 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/vdso_support.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/vdso_support.cc @@ -20,25 +20,25 @@ #ifdef ABSL_HAVE_VDSO_SUPPORT // defined in vdso_support.h -#if !defined(__has_include) -#define __has_include(header) 0 -#endif - +#if !defined(__has_include) +#define __has_include(header) 0 +#endif + #include <errno.h> #include <fcntl.h> -#if __has_include(<syscall.h>) -#include <syscall.h> -#elif __has_include(<sys/syscall.h>) +#if __has_include(<syscall.h>) +#include <syscall.h> +#elif __has_include(<sys/syscall.h>) #include <sys/syscall.h> -#endif +#endif #include <unistd.h> -#if defined(__GLIBC__) && \ - (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 16)) -#define ABSL_HAVE_GETAUXVAL -#endif - -#ifdef ABSL_HAVE_GETAUXVAL +#if defined(__GLIBC__) && \ + (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 16)) +#define ABSL_HAVE_GETAUXVAL +#endif + +#ifdef ABSL_HAVE_GETAUXVAL #include <sys/auxv.h> #endif @@ -50,11 +50,11 @@ #define AT_SYSINFO_EHDR 33 // for crosstoolv10 #endif -#if defined(__FreeBSD__) -using Elf64_auxv_t = Elf64_Auxinfo; -using Elf32_auxv_t = Elf32_Auxinfo; -#endif - +#if defined(__FreeBSD__) +using Elf64_auxv_t = Elf64_Auxinfo; +using Elf32_auxv_t = Elf32_Auxinfo; +#endif + namespace y_absl { ABSL_NAMESPACE_BEGIN namespace debugging_internal { @@ -83,7 +83,7 @@ VDSOSupport::VDSOSupport() // the operation should be idempotent. const void *VDSOSupport::Init() { const auto kInvalidBase = debugging_internal::ElfMemImage::kInvalidBase; -#ifdef ABSL_HAVE_GETAUXVAL +#ifdef ABSL_HAVE_GETAUXVAL if (vdso_base_.load(std::memory_order_relaxed) == kInvalidBase) { errno = 0; const void *const sysinfo_ehdr = @@ -92,7 +92,7 @@ const void *VDSOSupport::Init() { vdso_base_.store(sysinfo_ehdr, std::memory_order_relaxed); } } -#endif // ABSL_HAVE_GETAUXVAL +#endif // ABSL_HAVE_GETAUXVAL if (vdso_base_.load(std::memory_order_relaxed) == kInvalidBase) { int fd = open("/proc/self/auxv", O_RDONLY); if (fd == -1) { diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/ya.make index e07162537b..2fdd0c721e 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/internal/ya.make @@ -9,22 +9,22 @@ OWNER( LICENSE(Apache-2.0) -LICENSE_TEXTS(.yandex_meta/licenses.list.txt) - +LICENSE_TEXTS(.yandex_meta/licenses.list.txt) + PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/base - contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/low_level_alloc contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/raw_logging contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/throw_delegate contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity - contrib/restricted/abseil-cpp-tstring/y_absl/debugging - contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace - contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize - contrib/restricted/abseil-cpp-tstring/y_absl/demangle + contrib/restricted/abseil-cpp-tstring/y_absl/debugging + contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace + contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize + contrib/restricted/abseil-cpp-tstring/y_absl/demangle contrib/restricted/abseil-cpp-tstring/y_absl/numeric contrib/restricted/abseil-cpp-tstring/y_absl/strings - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal ) ADDINCL( @@ -34,7 +34,7 @@ ADDINCL( NO_COMPILER_WARNINGS() SRCS( - examine_stack.cc + examine_stack.cc ) END() diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace.cc index 9263d6a2a8..54ba955564 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace.cc @@ -49,10 +49,10 @@ # include "y_absl/debugging/internal/stacktrace_aarch64-inl.inc" # include "y_absl/debugging/internal/stacktrace_arm-inl.inc" -# include "y_absl/debugging/internal/stacktrace_emscripten-inl.inc" +# include "y_absl/debugging/internal/stacktrace_emscripten-inl.inc" # include "y_absl/debugging/internal/stacktrace_generic-inl.inc" # include "y_absl/debugging/internal/stacktrace_powerpc-inl.inc" -# include "y_absl/debugging/internal/stacktrace_riscv-inl.inc" +# include "y_absl/debugging/internal/stacktrace_riscv-inl.inc" # include "y_absl/debugging/internal/stacktrace_unimplemented-inl.inc" # include "y_absl/debugging/internal/stacktrace_win32-inl.inc" # include "y_absl/debugging/internal/stacktrace_x86-inl.inc" diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize.cc index 88c92a19ea..f275ed06cd 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize.cc @@ -31,8 +31,8 @@ #include "y_absl/debugging/symbolize_win32.inc" #elif defined(__APPLE__) #include "y_absl/debugging/symbolize_darwin.inc" -#elif defined(__EMSCRIPTEN__) -#include "y_absl/debugging/symbolize_emscripten.inc" +#elif defined(__EMSCRIPTEN__) +#include "y_absl/debugging/symbolize_emscripten.inc" #else #include "y_absl/debugging/symbolize_unimplemented.inc" #endif diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize/ya.make index 58f9d70682..0cd2cfe677 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize/ya.make @@ -22,7 +22,7 @@ PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/demangle contrib/restricted/abseil-cpp-tstring/y_absl/numeric contrib/restricted/abseil-cpp-tstring/y_absl/strings - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal ) ADDINCL( diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize_elf.inc b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize_elf.inc index 18297405e3..5a6c988682 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize_elf.inc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize_elf.inc @@ -77,10 +77,10 @@ #include "y_absl/debugging/internal/vdso_support.h" #include "y_absl/strings/string_view.h" -#if defined(__FreeBSD__) && !defined(ElfW) -#define ElfW(x) __ElfN(x) -#endif - +#if defined(__FreeBSD__) && !defined(ElfW) +#define ElfW(x) __ElfN(x) +#endif + namespace y_absl { ABSL_NAMESPACE_BEGIN @@ -705,16 +705,16 @@ static ABSL_ATTRIBUTE_NOINLINE FindSymbolResult FindSymbol( const char *start_address = ComputeOffset(original_start_address, relocation); -#ifdef __arm__ - // ARM functions are always aligned to multiples of two bytes; the - // lowest-order bit in start_address is ignored by the CPU and indicates - // whether the function contains ARM (0) or Thumb (1) code. We don't care - // about what encoding is being used; we just want the real start address - // of the function. - start_address = reinterpret_cast<const char *>( - reinterpret_cast<uintptr_t>(start_address) & ~1); -#endif - +#ifdef __arm__ + // ARM functions are always aligned to multiples of two bytes; the + // lowest-order bit in start_address is ignored by the CPU and indicates + // whether the function contains ARM (0) or Thumb (1) code. We don't care + // about what encoding is being used; we just want the real start address + // of the function. + start_address = reinterpret_cast<const char *>( + reinterpret_cast<uintptr_t>(start_address) & ~1); +#endif + if (deref_function_descriptor_pointer && InSection(original_start_address, opd)) { // The opd section is mapped into memory. Just dereference diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize_emscripten.inc b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize_emscripten.inc index 6ddb5b4a7f..6d06ebdbb5 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize_emscripten.inc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize_emscripten.inc @@ -1,72 +1,72 @@ -// Copyright 2020 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <cxxabi.h> -#error #include <emscripten.h> - -#include <algorithm> -#include <cstring> - -#include "y_absl/base/internal/raw_logging.h" -#include "y_absl/debugging/internal/demangle.h" -#include "y_absl/strings/numbers.h" -#include "y_absl/strings/str_cat.h" -#include "y_absl/strings/string_view.h" - -extern "C" { -const char* emscripten_pc_get_function(const void* pc); -} - -// clang-format off -EM_JS(bool, HaveOffsetConverter, (), - { return typeof wasmOffsetConverter !== 'undefined'; }); -// clang-format on - -namespace y_absl { -ABSL_NAMESPACE_BEGIN - -void InitializeSymbolizer(const char*) { - if (!HaveOffsetConverter()) { - ABSL_RAW_LOG(INFO, - "Symbolization unavailable. Rebuild with -sWASM=1 " - "and -sUSE_OFFSET_CONVERTER=1."); - } -} - -bool Symbolize(const void* pc, char* out, int out_size) { - // Check if we have the offset converter necessary for pc_get_function. - // Without it, the program will abort(). - if (!HaveOffsetConverter()) { - return false; - } - const char* func_name = emscripten_pc_get_function(pc); - if (func_name == nullptr) { - return false; - } - - strncpy(out, func_name, out_size); - - if (out[out_size - 1] != '\0') { - // strncpy() does not '\0' terminate when it truncates. - static constexpr char kEllipsis[] = "..."; - int ellipsis_size = std::min<int>(sizeof(kEllipsis) - 1, out_size - 1); - memcpy(out + out_size - ellipsis_size - 1, kEllipsis, ellipsis_size); - out[out_size - 1] = '\0'; - } - - return true; -} - -ABSL_NAMESPACE_END -} // namespace y_absl +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <cxxabi.h> +#error #include <emscripten.h> + +#include <algorithm> +#include <cstring> + +#include "y_absl/base/internal/raw_logging.h" +#include "y_absl/debugging/internal/demangle.h" +#include "y_absl/strings/numbers.h" +#include "y_absl/strings/str_cat.h" +#include "y_absl/strings/string_view.h" + +extern "C" { +const char* emscripten_pc_get_function(const void* pc); +} + +// clang-format off +EM_JS(bool, HaveOffsetConverter, (), + { return typeof wasmOffsetConverter !== 'undefined'; }); +// clang-format on + +namespace y_absl { +ABSL_NAMESPACE_BEGIN + +void InitializeSymbolizer(const char*) { + if (!HaveOffsetConverter()) { + ABSL_RAW_LOG(INFO, + "Symbolization unavailable. Rebuild with -sWASM=1 " + "and -sUSE_OFFSET_CONVERTER=1."); + } +} + +bool Symbolize(const void* pc, char* out, int out_size) { + // Check if we have the offset converter necessary for pc_get_function. + // Without it, the program will abort(). + if (!HaveOffsetConverter()) { + return false; + } + const char* func_name = emscripten_pc_get_function(pc); + if (func_name == nullptr) { + return false; + } + + strncpy(out, func_name, out_size); + + if (out[out_size - 1] != '\0') { + // strncpy() does not '\0' terminate when it truncates. + static constexpr char kEllipsis[] = "..."; + int ellipsis_size = std::min<int>(sizeof(kEllipsis) - 1, out_size - 1); + memcpy(out + out_size - ellipsis_size - 1, kEllipsis, ellipsis_size); + out[out_size - 1] = '\0'; + } + + return true; +} + +ABSL_NAMESPACE_END +} // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/functional/function_ref.h b/contrib/restricted/abseil-cpp-tstring/y_absl/functional/function_ref.h index 6ae4c63c9e..332ac01916 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/functional/function_ref.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/functional/function_ref.h @@ -50,7 +50,7 @@ #include <functional> #include <type_traits> -#include "y_absl/base/attributes.h" +#include "y_absl/base/attributes.h" #include "y_absl/functional/internal/function_ref.h" #include "y_absl/meta/type_traits.h" @@ -99,8 +99,8 @@ class FunctionRef<R(Args...)> { public: // Constructs a FunctionRef from any invokable type. template <typename F, typename = EnableIfCompatible<const F&>> - // NOLINTNEXTLINE(runtime/explicit) - FunctionRef(const F& f ABSL_ATTRIBUTE_LIFETIME_BOUND) + // NOLINTNEXTLINE(runtime/explicit) + FunctionRef(const F& f ABSL_ATTRIBUTE_LIFETIME_BOUND) : invoker_(&y_absl::functional_internal::InvokeObject<F, R, Args...>) { y_absl::functional_internal::AssertNonNull(f); ptr_.obj = &f; @@ -124,7 +124,7 @@ class FunctionRef<R(Args...)> { // To help prevent subtle lifetime bugs, FunctionRef is not assignable. // Typically, it should only be used as an argument type. FunctionRef& operator=(const FunctionRef& rhs) = delete; - FunctionRef(const FunctionRef& rhs) = default; + FunctionRef(const FunctionRef& rhs) = default; // Call the underlying object. R operator()(Args... args) const { diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/hash.h b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/hash.h index 1e93ee96d9..80e6efd0e6 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/hash.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/hash.h @@ -73,8 +73,8 @@ #ifndef ABSL_HASH_HASH_H_ #define ABSL_HASH_HASH_H_ -#include <tuple> - +#include <tuple> + #include "y_absl/hash/internal/hash.h" namespace y_absl { @@ -216,26 +216,26 @@ ABSL_NAMESPACE_BEGIN template <typename T> using Hash = y_absl::hash_internal::Hash<T>; -// HashOf -// -// y_absl::HashOf() is a helper that generates a hash from the values of its -// arguments. It dispatches to y_absl::Hash directly, as follows: -// * HashOf(t) == y_absl::Hash<T>{}(t) -// * HashOf(a, b, c) == HashOf(std::make_tuple(a, b, c)) -// -// HashOf(a1, a2, ...) == HashOf(b1, b2, ...) is guaranteed when -// * The argument lists have pairwise identical C++ types -// * a1 == b1 && a2 == b2 && ... -// -// The requirement that the arguments match in both type and value is critical. -// It means that `a == b` does not necessarily imply `HashOf(a) == HashOf(b)` if -// `a` and `b` have different types. For example, `HashOf(2) != HashOf(2.0)`. -template <int&... ExplicitArgumentBarrier, typename... Types> -size_t HashOf(const Types&... values) { - auto tuple = std::tie(values...); - return y_absl::Hash<decltype(tuple)>{}(tuple); -} - +// HashOf +// +// y_absl::HashOf() is a helper that generates a hash from the values of its +// arguments. It dispatches to y_absl::Hash directly, as follows: +// * HashOf(t) == y_absl::Hash<T>{}(t) +// * HashOf(a, b, c) == HashOf(std::make_tuple(a, b, c)) +// +// HashOf(a1, a2, ...) == HashOf(b1, b2, ...) is guaranteed when +// * The argument lists have pairwise identical C++ types +// * a1 == b1 && a2 == b2 && ... +// +// The requirement that the arguments match in both type and value is critical. +// It means that `a == b` does not necessarily imply `HashOf(a) == HashOf(b)` if +// `a` and `b` have different types. For example, `HashOf(2) != HashOf(2.0)`. +template <int&... ExplicitArgumentBarrier, typename... Types> +size_t HashOf(const Types&... values) { + auto tuple = std::tie(values...); + return y_absl::Hash<decltype(tuple)>{}(tuple); +} + // HashState // // A type erased version of the hash state concept, for use in user-defined diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/hash.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/hash.cc index fe075de43a..0c9894f54d 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/hash.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/hash.cc @@ -18,12 +18,12 @@ namespace y_absl { ABSL_NAMESPACE_BEGIN namespace hash_internal { -uint64_t MixingHashState::CombineLargeContiguousImpl32( - uint64_t state, const unsigned char* first, size_t len) { +uint64_t MixingHashState::CombineLargeContiguousImpl32( + uint64_t state, const unsigned char* first, size_t len) { while (len >= PiecewiseChunkSize()) { - state = Mix(state, - hash_internal::CityHash32(reinterpret_cast<const char*>(first), - PiecewiseChunkSize())); + state = Mix(state, + hash_internal::CityHash32(reinterpret_cast<const char*>(first), + PiecewiseChunkSize())); len -= PiecewiseChunkSize(); first += PiecewiseChunkSize(); } @@ -32,8 +32,8 @@ uint64_t MixingHashState::CombineLargeContiguousImpl32( std::integral_constant<int, 4>{}); } -uint64_t MixingHashState::CombineLargeContiguousImpl64( - uint64_t state, const unsigned char* first, size_t len) { +uint64_t MixingHashState::CombineLargeContiguousImpl64( + uint64_t state, const unsigned char* first, size_t len) { while (len >= PiecewiseChunkSize()) { state = Mix(state, Hash64(first, PiecewiseChunkSize())); len -= PiecewiseChunkSize(); @@ -44,24 +44,24 @@ uint64_t MixingHashState::CombineLargeContiguousImpl64( std::integral_constant<int, 8>{}); } -ABSL_CONST_INIT const void* const MixingHashState::kSeed = &kSeed; +ABSL_CONST_INIT const void* const MixingHashState::kSeed = &kSeed; -// The salt array used by LowLevelHash. This array is NOT the mechanism used to -// make y_absl::Hash non-deterministic between program invocations. See `Seed()` -// for that mechanism. +// The salt array used by LowLevelHash. This array is NOT the mechanism used to +// make y_absl::Hash non-deterministic between program invocations. See `Seed()` +// for that mechanism. // // Any random values are fine. These values are just digits from the decimal // part of pi. // https://en.wikipedia.org/wiki/Nothing-up-my-sleeve_number -constexpr uint64_t kHashSalt[5] = { +constexpr uint64_t kHashSalt[5] = { uint64_t{0x243F6A8885A308D3}, uint64_t{0x13198A2E03707344}, uint64_t{0xA4093822299F31D0}, uint64_t{0x082EFA98EC4E6C89}, uint64_t{0x452821E638D01377}, }; -uint64_t MixingHashState::LowLevelHashImpl(const unsigned char* data, - size_t len) { - return LowLevelHash(data, len, Seed(), kHashSalt); +uint64_t MixingHashState::LowLevelHashImpl(const unsigned char* data, + size_t len) { + return LowLevelHash(data, len, Seed(), kHashSalt); } } // namespace hash_internal diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/hash.h b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/hash.h index fcbe43accd..32cbbbb27a 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/hash.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/hash.h @@ -21,7 +21,7 @@ #include <algorithm> #include <array> -#include <bitset> +#include <bitset> #include <cmath> #include <cstring> #include <deque> @@ -43,8 +43,8 @@ #include "y_absl/base/internal/unaligned_access.h" #include "y_absl/base/port.h" #include "y_absl/container/fixed_array.h" -#include "y_absl/hash/internal/city.h" -#include "y_absl/hash/internal/low_level_hash.h" +#include "y_absl/hash/internal/city.h" +#include "y_absl/hash/internal/low_level_hash.h" #include "y_absl/meta/type_traits.h" #include "y_absl/numeric/int128.h" #include "y_absl/strings/string_view.h" @@ -380,7 +380,7 @@ template <typename H, typename... Ts> // This SFINAE gets MSVC confused under some conditions. Let's just disable it // for now. H -#else // _MSC_VER +#else // _MSC_VER typename std::enable_if<y_absl::conjunction<is_hashable<Ts>...>::value, H>::type #endif // _MSC_VER AbslHashValue(H hash_state, const std::tuple<Ts...>& t) { @@ -490,9 +490,9 @@ typename std::enable_if<is_hashable<T>::value, H>::type AbslHashValue( // AbslHashValue for hashing std::vector // -// Do not use this for vector<bool> on platforms that have a working -// implementation of std::hash. It does not have a .data(), and a fallback for -// std::hash<> is most likely faster. +// Do not use this for vector<bool> on platforms that have a working +// implementation of std::hash. It does not have a .data(), and a fallback for +// std::hash<> is most likely faster. template <typename H, typename T, typename Allocator> typename std::enable_if<is_hashable<T>::value && !std::is_same<T, bool>::value, H>::type @@ -502,27 +502,27 @@ AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) { vector.size()); } -#if defined(ABSL_IS_BIG_ENDIAN) && \ - (defined(__GLIBCXX__) || defined(__GLIBCPP__)) -// AbslHashValue for hashing std::vector<bool> -// -// std::hash in libstdc++ does not work correctly with vector<bool> on Big -// Endian platforms therefore we need to implement a custom AbslHashValue for -// it. More details on the bug: -// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102531 -template <typename H, typename T, typename Allocator> -typename std::enable_if<is_hashable<T>::value && std::is_same<T, bool>::value, - H>::type -AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) { - typename H::AbslInternalPiecewiseCombiner combiner; - for (const auto& i : vector) { - unsigned char c = static_cast<unsigned char>(i); - hash_state = combiner.add_buffer(std::move(hash_state), &c, sizeof(c)); - } - return H::combine(combiner.finalize(std::move(hash_state)), vector.size()); -} -#endif - +#if defined(ABSL_IS_BIG_ENDIAN) && \ + (defined(__GLIBCXX__) || defined(__GLIBCPP__)) +// AbslHashValue for hashing std::vector<bool> +// +// std::hash in libstdc++ does not work correctly with vector<bool> on Big +// Endian platforms therefore we need to implement a custom AbslHashValue for +// it. More details on the bug: +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102531 +template <typename H, typename T, typename Allocator> +typename std::enable_if<is_hashable<T>::value && std::is_same<T, bool>::value, + H>::type +AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) { + typename H::AbslInternalPiecewiseCombiner combiner; + for (const auto& i : vector) { + unsigned char c = static_cast<unsigned char>(i); + hash_state = combiner.add_buffer(std::move(hash_state), &c, sizeof(c)); + } + return H::combine(combiner.finalize(std::move(hash_state)), vector.size()); +} +#endif + // ----------------------------------------------------------------------------- // AbslHashValue for Ordered Associative Containers // ----------------------------------------------------------------------------- @@ -615,29 +615,29 @@ AbslHashValue(H hash_state, const y_absl::variant<T...>& v) { // AbslHashValue for Other Types // ----------------------------------------------------------------------------- -// AbslHashValue for hashing std::bitset is not defined on Little Endian -// platforms, for the same reason as for vector<bool> (see std::vector above): -// It does not expose the raw bytes, and a fallback to std::hash<> is most -// likely faster. - -#if defined(ABSL_IS_BIG_ENDIAN) && \ - (defined(__GLIBCXX__) || defined(__GLIBCPP__)) -// AbslHashValue for hashing std::bitset -// -// std::hash in libstdc++ does not work correctly with std::bitset on Big Endian -// platforms therefore we need to implement a custom AbslHashValue for it. More -// details on the bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102531 -template <typename H, size_t N> -H AbslHashValue(H hash_state, const std::bitset<N>& set) { - typename H::AbslInternalPiecewiseCombiner combiner; - for (int i = 0; i < N; i++) { - unsigned char c = static_cast<unsigned char>(set[i]); - hash_state = combiner.add_buffer(std::move(hash_state), &c, sizeof(c)); - } - return H::combine(combiner.finalize(std::move(hash_state)), N); -} -#endif - +// AbslHashValue for hashing std::bitset is not defined on Little Endian +// platforms, for the same reason as for vector<bool> (see std::vector above): +// It does not expose the raw bytes, and a fallback to std::hash<> is most +// likely faster. + +#if defined(ABSL_IS_BIG_ENDIAN) && \ + (defined(__GLIBCXX__) || defined(__GLIBCPP__)) +// AbslHashValue for hashing std::bitset +// +// std::hash in libstdc++ does not work correctly with std::bitset on Big Endian +// platforms therefore we need to implement a custom AbslHashValue for it. More +// details on the bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102531 +template <typename H, size_t N> +H AbslHashValue(H hash_state, const std::bitset<N>& set) { + typename H::AbslInternalPiecewiseCombiner combiner; + for (int i = 0; i < N; i++) { + unsigned char c = static_cast<unsigned char>(set[i]); + hash_state = combiner.add_buffer(std::move(hash_state), &c, sizeof(c)); + } + return H::combine(combiner.finalize(std::move(hash_state)), N); +} +#endif + // ----------------------------------------------------------------------------- // hash_range_or_bytes() @@ -756,8 +756,8 @@ template <typename T> struct is_hashable : std::integral_constant<bool, HashSelect::template Apply<T>::value> {}; -// MixingHashState -class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> { +// MixingHashState +class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> { // y_absl::uint128 is not an alias or a thin wrapper around the intrinsic. // We use the intrinsic when available to improve performance. #ifdef ABSL_HAVE_INTRINSIC_INT128 @@ -776,23 +776,23 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> { public: // Move only - MixingHashState(MixingHashState&&) = default; - MixingHashState& operator=(MixingHashState&&) = default; + MixingHashState(MixingHashState&&) = default; + MixingHashState& operator=(MixingHashState&&) = default; - // MixingHashState::combine_contiguous() + // MixingHashState::combine_contiguous() // // Fundamental base case for hash recursion: mixes the given range of bytes // into the hash state. - static MixingHashState combine_contiguous(MixingHashState hash_state, - const unsigned char* first, - size_t size) { - return MixingHashState( + static MixingHashState combine_contiguous(MixingHashState hash_state, + const unsigned char* first, + size_t size) { + return MixingHashState( CombineContiguousImpl(hash_state.state_, first, size, std::integral_constant<int, sizeof(size_t)>{})); } - using MixingHashState::HashStateBase::combine_contiguous; + using MixingHashState::HashStateBase::combine_contiguous; - // MixingHashState::hash() + // MixingHashState::hash() // // For performance reasons in non-opt mode, we specialize this for // integral types. @@ -804,24 +804,24 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> { return static_cast<size_t>(Mix(Seed(), static_cast<uint64_t>(value))); } - // Overload of MixingHashState::hash() + // Overload of MixingHashState::hash() template <typename T, y_absl::enable_if_t<!IntegralFastPath<T>::value, int> = 0> static size_t hash(const T& value) { - return static_cast<size_t>(combine(MixingHashState{}, value).state_); + return static_cast<size_t>(combine(MixingHashState{}, value).state_); } private: // Invoked only once for a given argument; that plus the fact that this is // move-only ensures that there is only one non-moved-from object. - MixingHashState() : state_(Seed()) {} + MixingHashState() : state_(Seed()) {} // Workaround for MSVC bug. // We make the type copyable to fix the calling convention, even though we // never actually copy it. Keep it private to not affect the public API of the // type. - MixingHashState(const MixingHashState&) = default; + MixingHashState(const MixingHashState&) = default; - explicit MixingHashState(uint64_t state) : state_(state) {} + explicit MixingHashState(uint64_t state) : state_(state) {} // Implementation of the base case for combine_contiguous where we actually // mix the bytes into the state. @@ -898,15 +898,15 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> { } ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t Mix(uint64_t state, uint64_t v) { -#if defined(__aarch64__) - // On AArch64, calculating a 128-bit product is inefficient, because it - // requires a sequence of two instructions to calculate the upper and lower - // halves of the result. - using MultType = uint64_t; -#else +#if defined(__aarch64__) + // On AArch64, calculating a 128-bit product is inefficient, because it + // requires a sequence of two instructions to calculate the upper and lower + // halves of the result. + using MultType = uint64_t; +#else using MultType = y_absl::conditional_t<sizeof(size_t) == 4, uint64_t, uint128>; -#endif +#endif // We do the addition in 64-bit space to make sure the 128-bit // multiplication is fast. If we were to do it as MultType the compiler has // to assume that the high word is non-zero and needs to perform 2 @@ -916,16 +916,16 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> { return static_cast<uint64_t>(m ^ (m >> (sizeof(m) * 8 / 2))); } - // An extern to avoid bloat on a direct call to LowLevelHash() with fixed - // values for both the seed and salt parameters. - static uint64_t LowLevelHashImpl(const unsigned char* data, size_t len); + // An extern to avoid bloat on a direct call to LowLevelHash() with fixed + // values for both the seed and salt parameters. + static uint64_t LowLevelHashImpl(const unsigned char* data, size_t len); ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t Hash64(const unsigned char* data, size_t len) { #ifdef ABSL_HAVE_INTRINSIC_INT128 - return LowLevelHashImpl(data, len); + return LowLevelHashImpl(data, len); #else - return hash_internal::CityHash64(reinterpret_cast<const char*>(data), len); + return hash_internal::CityHash64(reinterpret_cast<const char*>(data), len); #endif } @@ -960,8 +960,8 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> { uint64_t state_; }; -// MixingHashState::CombineContiguousImpl() -inline uint64_t MixingHashState::CombineContiguousImpl( +// MixingHashState::CombineContiguousImpl() +inline uint64_t MixingHashState::CombineContiguousImpl( uint64_t state, const unsigned char* first, size_t len, std::integral_constant<int, 4> /* sizeof_size_t */) { // For large values we use CityHash, for small ones we just use a @@ -971,7 +971,7 @@ inline uint64_t MixingHashState::CombineContiguousImpl( if (ABSL_PREDICT_FALSE(len > PiecewiseChunkSize())) { return CombineLargeContiguousImpl32(state, first, len); } - v = hash_internal::CityHash32(reinterpret_cast<const char*>(first), len); + v = hash_internal::CityHash32(reinterpret_cast<const char*>(first), len); } else if (len >= 4) { v = Read4To8(first, len); } else if (len > 0) { @@ -983,12 +983,12 @@ inline uint64_t MixingHashState::CombineContiguousImpl( return Mix(state, v); } -// Overload of MixingHashState::CombineContiguousImpl() -inline uint64_t MixingHashState::CombineContiguousImpl( +// Overload of MixingHashState::CombineContiguousImpl() +inline uint64_t MixingHashState::CombineContiguousImpl( uint64_t state, const unsigned char* first, size_t len, std::integral_constant<int, 8> /* sizeof_size_t */) { - // For large values we use LowLevelHash or CityHash depending on the platform, - // for small ones we just use a multiplicative hash. + // For large values we use LowLevelHash or CityHash depending on the platform, + // for small ones we just use a multiplicative hash. uint64_t v; if (len > 16) { if (ABSL_PREDICT_FALSE(len > PiecewiseChunkSize())) { @@ -1025,9 +1025,9 @@ struct PoisonedHash : private AggregateBarrier { template <typename T> struct HashImpl { - size_t operator()(const T& value) const { - return MixingHashState::hash(value); - } + size_t operator()(const T& value) const { + return MixingHashState::hash(value); + } }; template <typename T> diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/low_level_hash.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/low_level_hash.cc index 08b6dd85d4..e1f309d045 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/low_level_hash.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/low_level_hash.cc @@ -12,35 +12,35 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "y_absl/hash/internal/low_level_hash.h" +#include "y_absl/hash/internal/low_level_hash.h" #include "y_absl/base/internal/unaligned_access.h" -#include "y_absl/numeric/bits.h" +#include "y_absl/numeric/bits.h" #include "y_absl/numeric/int128.h" namespace y_absl { ABSL_NAMESPACE_BEGIN namespace hash_internal { -static uint64_t Mix(uint64_t v0, uint64_t v1) { -#if !defined(__aarch64__) - // The default bit-mixer uses 64x64->128-bit multiplication. +static uint64_t Mix(uint64_t v0, uint64_t v1) { +#if !defined(__aarch64__) + // The default bit-mixer uses 64x64->128-bit multiplication. y_absl::uint128 p = v0; p *= v1; return y_absl::Uint128Low64(p) ^ y_absl::Uint128High64(p); -#else - // The default bit-mixer above would perform poorly on some ARM microarchs, - // where calculating a 128-bit product requires a sequence of two - // instructions with a high combined latency and poor throughput. - // Instead, we mix bits using only 64-bit arithmetic, which is faster. - uint64_t p = v0 ^ y_absl::rotl(v1, 40); - p *= v1 ^ y_absl::rotl(v0, 39); - return p ^ (p >> 11); -#endif +#else + // The default bit-mixer above would perform poorly on some ARM microarchs, + // where calculating a 128-bit product requires a sequence of two + // instructions with a high combined latency and poor throughput. + // Instead, we mix bits using only 64-bit arithmetic, which is faster. + uint64_t p = v0 ^ y_absl::rotl(v1, 40); + p *= v1 ^ y_absl::rotl(v0, 39); + return p ^ (p >> 11); +#endif } -uint64_t LowLevelHash(const void* data, size_t len, uint64_t seed, - const uint64_t salt[]) { +uint64_t LowLevelHash(const void* data, size_t len, uint64_t seed, + const uint64_t salt[]) { const uint8_t* ptr = static_cast<const uint8_t*>(data); uint64_t starting_length = static_cast<uint64_t>(len); uint64_t current_state = seed ^ salt[0]; @@ -61,12 +61,12 @@ uint64_t LowLevelHash(const void* data, size_t len, uint64_t seed, uint64_t g = y_absl::base_internal::UnalignedLoad64(ptr + 48); uint64_t h = y_absl::base_internal::UnalignedLoad64(ptr + 56); - uint64_t cs0 = Mix(a ^ salt[1], b ^ current_state); - uint64_t cs1 = Mix(c ^ salt[2], d ^ current_state); + uint64_t cs0 = Mix(a ^ salt[1], b ^ current_state); + uint64_t cs1 = Mix(c ^ salt[2], d ^ current_state); current_state = (cs0 ^ cs1); - uint64_t ds0 = Mix(e ^ salt[3], f ^ duplicated_state); - uint64_t ds1 = Mix(g ^ salt[4], h ^ duplicated_state); + uint64_t ds0 = Mix(e ^ salt[3], f ^ duplicated_state); + uint64_t ds1 = Mix(g ^ salt[4], h ^ duplicated_state); duplicated_state = (ds0 ^ ds1); ptr += 64; @@ -82,7 +82,7 @@ uint64_t LowLevelHash(const void* data, size_t len, uint64_t seed, uint64_t a = y_absl::base_internal::UnalignedLoad64(ptr); uint64_t b = y_absl::base_internal::UnalignedLoad64(ptr + 8); - current_state = Mix(a ^ salt[1], b ^ current_state); + current_state = Mix(a ^ salt[1], b ^ current_state); ptr += 16; len -= 16; @@ -113,9 +113,9 @@ uint64_t LowLevelHash(const void* data, size_t len, uint64_t seed, b = 0; } - uint64_t w = Mix(a ^ salt[1], b ^ current_state); + uint64_t w = Mix(a ^ salt[1], b ^ current_state); uint64_t z = salt[1] ^ starting_length; - return Mix(w, z); + return Mix(w, z); } } // namespace hash_internal diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/low_level_hash.h b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/low_level_hash.h index 4a71ab9418..ce25edf5d0 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/low_level_hash.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/low_level_hash.h @@ -12,18 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// This file provides the Google-internal implementation of LowLevelHash. +// This file provides the Google-internal implementation of LowLevelHash. // -// LowLevelHash is a fast hash function for hash tables, the fastest we've -// currently (late 2020) found that passes the SMHasher tests. The algorithm -// relies on intrinsic 128-bit multiplication for speed. This is not meant to be -// secure - just fast. -// -// It is closely based on a version of wyhash, but does not maintain or -// guarantee future compatibility with it. +// LowLevelHash is a fast hash function for hash tables, the fastest we've +// currently (late 2020) found that passes the SMHasher tests. The algorithm +// relies on intrinsic 128-bit multiplication for speed. This is not meant to be +// secure - just fast. +// +// It is closely based on a version of wyhash, but does not maintain or +// guarantee future compatibility with it. -#ifndef ABSL_HASH_INTERNAL_LOW_LEVEL_HASH_H_ -#define ABSL_HASH_INTERNAL_LOW_LEVEL_HASH_H_ +#ifndef ABSL_HASH_INTERNAL_LOW_LEVEL_HASH_H_ +#define ABSL_HASH_INTERNAL_LOW_LEVEL_HASH_H_ #include <stdint.h> #include <stdlib.h> @@ -38,13 +38,13 @@ namespace hash_internal { // integers are hashed into the result. // // To allow all hashable types (including string_view and Span) to depend on -// this algorithm, we keep the API low-level, with as few dependencies as +// this algorithm, we keep the API low-level, with as few dependencies as // possible. -uint64_t LowLevelHash(const void* data, size_t len, uint64_t seed, - const uint64_t salt[5]); +uint64_t LowLevelHash(const void* data, size_t len, uint64_t seed, + const uint64_t salt[5]); } // namespace hash_internal ABSL_NAMESPACE_END } // namespace y_absl -#endif // ABSL_HASH_INTERNAL_LOW_LEVEL_HASH_H_ +#endif // ABSL_HASH_INTERNAL_LOW_LEVEL_HASH_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/ya.make index 7f3aae3751..f04389ca52 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal/ya.make @@ -26,7 +26,7 @@ ADDINCL( NO_COMPILER_WARNINGS() SRCS( - low_level_hash.cc + low_level_hash.cc ) END() diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/ya.make index 576811ee62..e9419e6061 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/hash/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/hash/ya.make @@ -9,23 +9,23 @@ OWNER( LICENSE(Apache-2.0) -LICENSE_TEXTS(.yandex_meta/licenses.list.txt) - +LICENSE_TEXTS(.yandex_meta/licenses.list.txt) + PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/base contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/raw_logging contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/throw_delegate contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity - contrib/restricted/abseil-cpp-tstring/y_absl/city - contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal + contrib/restricted/abseil-cpp-tstring/y_absl/city + contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal contrib/restricted/abseil-cpp-tstring/y_absl/numeric contrib/restricted/abseil-cpp-tstring/y_absl/strings - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_optional_access - contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_variant_access + contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_variant_access contrib/restricted/abseil-cpp-tstring/y_absl/types - contrib/restricted/abseil-cpp-tstring/y_absl/types/internal + contrib/restricted/abseil-cpp-tstring/y_absl/types/internal ) ADDINCL( @@ -35,7 +35,7 @@ ADDINCL( NO_COMPILER_WARNINGS() SRCS( - internal/hash.cc + internal/hash.cc ) END() diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/memory/memory.h b/contrib/restricted/abseil-cpp-tstring/y_absl/memory/memory.h index 134a614b33..44bb7e8ac7 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/memory/memory.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/memory/memory.h @@ -97,7 +97,7 @@ struct MakeUniqueResult<T[N]> { // define make_unique. Other supported compilers either just define __cplusplus // as 201103 but have make_unique (msvc), or have make_unique whenever // __cplusplus > 201103 (clang). -#if defined(__cpp_lib_make_unique) +#if defined(__cpp_lib_make_unique) using std::make_unique; #else // ----------------------------------------------------------------------------- @@ -419,7 +419,7 @@ struct pointer_traits<T*> { // // A C++11 compatible implementation of C++17's std::allocator_traits. // -#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) using std::allocator_traits; #else // __cplusplus >= 201703L template <typename Alloc> diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/meta/type_traits.h b/contrib/restricted/abseil-cpp-tstring/y_absl/meta/type_traits.h index eb9649060b..e0e85a5fcc 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/meta/type_traits.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/meta/type_traits.h @@ -35,7 +35,7 @@ #ifndef ABSL_META_TYPE_TRAITS_H_ #define ABSL_META_TYPE_TRAITS_H_ -#include <cstddef> +#include <cstddef> #include <functional> #include <type_traits> @@ -47,14 +47,14 @@ #define ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION 1 #endif -// Defines the default alignment. `__STDCPP_DEFAULT_NEW_ALIGNMENT__` is a C++17 -// feature. -#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) -#define ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT __STDCPP_DEFAULT_NEW_ALIGNMENT__ -#else // defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) -#define ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT alignof(std::max_align_t) -#endif // defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) - +// Defines the default alignment. `__STDCPP_DEFAULT_NEW_ALIGNMENT__` is a C++17 +// feature. +#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) +#define ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT __STDCPP_DEFAULT_NEW_ALIGNMENT__ +#else // defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) +#define ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT alignof(std::max_align_t) +#endif // defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) + namespace y_absl { ABSL_NAMESPACE_BEGIN @@ -507,27 +507,27 @@ struct is_trivially_copy_assignable #endif // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE }; -#if defined(__cpp_lib_remove_cvref) && __cpp_lib_remove_cvref >= 201711L -template <typename T> -using remove_cvref = std::remove_cvref<T>; - -template <typename T> -using remove_cvref_t = typename std::remove_cvref<T>::type; -#else -// remove_cvref() -// -// C++11 compatible implementation of std::remove_cvref which was added in -// C++20. -template <typename T> -struct remove_cvref { - using type = - typename std::remove_cv<typename std::remove_reference<T>::type>::type; -}; - -template <typename T> -using remove_cvref_t = typename remove_cvref<T>::type; -#endif - +#if defined(__cpp_lib_remove_cvref) && __cpp_lib_remove_cvref >= 201711L +template <typename T> +using remove_cvref = std::remove_cvref<T>; + +template <typename T> +using remove_cvref_t = typename std::remove_cvref<T>::type; +#else +// remove_cvref() +// +// C++11 compatible implementation of std::remove_cvref which was added in +// C++20. +template <typename T> +struct remove_cvref { + using type = + typename std::remove_cv<typename std::remove_reference<T>::type>::type; +}; + +template <typename T> +using remove_cvref_t = typename remove_cvref<T>::type; +#endif + namespace type_traits_internal { // is_trivially_copyable() // @@ -642,8 +642,8 @@ using underlying_type_t = typename std::underlying_type<T>::type; namespace type_traits_internal { -#if (defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703L) || \ - (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +#if (defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703L) || \ + (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) // std::result_of is deprecated (C++17) or removed (C++20) template<typename> struct result_of; template<typename F, typename... Args> diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/numeric/int128.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/numeric/int128.cc index 6172372d75..5732514380 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/numeric/int128.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/numeric/int128.cc @@ -138,21 +138,21 @@ uint128::uint128(float v) : uint128(MakeUint128FromFloat(v)) {} uint128::uint128(double v) : uint128(MakeUint128FromFloat(v)) {} uint128::uint128(long double v) : uint128(MakeUint128FromFloat(v)) {} -#if !defined(ABSL_HAVE_INTRINSIC_INT128) +#if !defined(ABSL_HAVE_INTRINSIC_INT128) uint128 operator/(uint128 lhs, uint128 rhs) { uint128 quotient = 0; uint128 remainder = 0; DivModImpl(lhs, rhs, "ient, &remainder); return quotient; } - + uint128 operator%(uint128 lhs, uint128 rhs) { uint128 quotient = 0; uint128 remainder = 0; DivModImpl(lhs, rhs, "ient, &remainder); return remainder; } -#endif // !defined(ABSL_HAVE_INTRINSIC_INT128) +#endif // !defined(ABSL_HAVE_INTRINSIC_INT128) namespace { diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/numeric/int128.h b/contrib/restricted/abseil-cpp-tstring/y_absl/numeric/int128.h index b54d614ce9..d91c26f625 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/numeric/int128.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/numeric/int128.h @@ -18,10 +18,10 @@ // ----------------------------------------------------------------------------- // // This header file defines 128-bit integer types, `uint128` and `int128`. -// -// TODO(y_absl-team): This module is inconsistent as many inline `uint128` methods -// are defined in this file, while many inline `int128` methods are defined in -// the `int128_*_intrinsic.inc` files. +// +// TODO(y_absl-team): This module is inconsistent as many inline `uint128` methods +// are defined in this file, while many inline `int128` methods are defined in +// the `int128_*_intrinsic.inc` files. #ifndef ABSL_NUMERIC_INT128_H_ #define ABSL_NUMERIC_INT128_H_ @@ -586,10 +586,10 @@ inline uint128& uint128::operator=(int128 v) { // Arithmetic operators. -constexpr uint128 operator<<(uint128 lhs, int amount); -constexpr uint128 operator>>(uint128 lhs, int amount); -constexpr uint128 operator+(uint128 lhs, uint128 rhs); -constexpr uint128 operator-(uint128 lhs, uint128 rhs); +constexpr uint128 operator<<(uint128 lhs, int amount); +constexpr uint128 operator>>(uint128 lhs, int amount); +constexpr uint128 operator+(uint128 lhs, uint128 rhs); +constexpr uint128 operator-(uint128 lhs, uint128 rhs); uint128 operator*(uint128 lhs, uint128 rhs); uint128 operator/(uint128 lhs, uint128 rhs); uint128 operator%(uint128 lhs, uint128 rhs); @@ -786,19 +786,19 @@ inline uint128::operator long double() const { // Comparison operators. -constexpr bool operator==(uint128 lhs, uint128 rhs) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return static_cast<unsigned __int128>(lhs) == - static_cast<unsigned __int128>(rhs); -#else +constexpr bool operator==(uint128 lhs, uint128 rhs) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return static_cast<unsigned __int128>(lhs) == + static_cast<unsigned __int128>(rhs); +#else return (Uint128Low64(lhs) == Uint128Low64(rhs) && Uint128High64(lhs) == Uint128High64(rhs)); -#endif +#endif } -constexpr bool operator!=(uint128 lhs, uint128 rhs) { return !(lhs == rhs); } +constexpr bool operator!=(uint128 lhs, uint128 rhs) { return !(lhs == rhs); } -constexpr bool operator<(uint128 lhs, uint128 rhs) { +constexpr bool operator<(uint128 lhs, uint128 rhs) { #ifdef ABSL_HAVE_INTRINSIC_INT128 return static_cast<unsigned __int128>(lhs) < static_cast<unsigned __int128>(rhs); @@ -809,171 +809,171 @@ constexpr bool operator<(uint128 lhs, uint128 rhs) { #endif } -constexpr bool operator>(uint128 lhs, uint128 rhs) { return rhs < lhs; } +constexpr bool operator>(uint128 lhs, uint128 rhs) { return rhs < lhs; } -constexpr bool operator<=(uint128 lhs, uint128 rhs) { return !(rhs < lhs); } +constexpr bool operator<=(uint128 lhs, uint128 rhs) { return !(rhs < lhs); } -constexpr bool operator>=(uint128 lhs, uint128 rhs) { return !(lhs < rhs); } +constexpr bool operator>=(uint128 lhs, uint128 rhs) { return !(lhs < rhs); } // Unary operators. -constexpr inline uint128 operator+(uint128 val) { - return val; -} - -constexpr inline int128 operator+(int128 val) { - return val; -} - -constexpr uint128 operator-(uint128 val) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return -static_cast<unsigned __int128>(val); -#else - return MakeUint128( - ~Uint128High64(val) + static_cast<unsigned long>(Uint128Low64(val) == 0), - ~Uint128Low64(val) + 1); -#endif -} - -constexpr inline bool operator!(uint128 val) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return !static_cast<unsigned __int128>(val); -#else +constexpr inline uint128 operator+(uint128 val) { + return val; +} + +constexpr inline int128 operator+(int128 val) { + return val; +} + +constexpr uint128 operator-(uint128 val) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return -static_cast<unsigned __int128>(val); +#else + return MakeUint128( + ~Uint128High64(val) + static_cast<unsigned long>(Uint128Low64(val) == 0), + ~Uint128Low64(val) + 1); +#endif +} + +constexpr inline bool operator!(uint128 val) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return !static_cast<unsigned __int128>(val); +#else return !Uint128High64(val) && !Uint128Low64(val); -#endif +#endif } // Logical operators. -constexpr inline uint128 operator~(uint128 val) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return ~static_cast<unsigned __int128>(val); -#else +constexpr inline uint128 operator~(uint128 val) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return ~static_cast<unsigned __int128>(val); +#else return MakeUint128(~Uint128High64(val), ~Uint128Low64(val)); -#endif +#endif } -constexpr inline uint128 operator|(uint128 lhs, uint128 rhs) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return static_cast<unsigned __int128>(lhs) | - static_cast<unsigned __int128>(rhs); -#else +constexpr inline uint128 operator|(uint128 lhs, uint128 rhs) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return static_cast<unsigned __int128>(lhs) | + static_cast<unsigned __int128>(rhs); +#else return MakeUint128(Uint128High64(lhs) | Uint128High64(rhs), - Uint128Low64(lhs) | Uint128Low64(rhs)); -#endif + Uint128Low64(lhs) | Uint128Low64(rhs)); +#endif } -constexpr inline uint128 operator&(uint128 lhs, uint128 rhs) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return static_cast<unsigned __int128>(lhs) & - static_cast<unsigned __int128>(rhs); -#else +constexpr inline uint128 operator&(uint128 lhs, uint128 rhs) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return static_cast<unsigned __int128>(lhs) & + static_cast<unsigned __int128>(rhs); +#else return MakeUint128(Uint128High64(lhs) & Uint128High64(rhs), - Uint128Low64(lhs) & Uint128Low64(rhs)); -#endif + Uint128Low64(lhs) & Uint128Low64(rhs)); +#endif } -constexpr inline uint128 operator^(uint128 lhs, uint128 rhs) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return static_cast<unsigned __int128>(lhs) ^ - static_cast<unsigned __int128>(rhs); -#else +constexpr inline uint128 operator^(uint128 lhs, uint128 rhs) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return static_cast<unsigned __int128>(lhs) ^ + static_cast<unsigned __int128>(rhs); +#else return MakeUint128(Uint128High64(lhs) ^ Uint128High64(rhs), - Uint128Low64(lhs) ^ Uint128Low64(rhs)); -#endif + Uint128Low64(lhs) ^ Uint128Low64(rhs)); +#endif } inline uint128& uint128::operator|=(uint128 other) { - *this = *this | other; + *this = *this | other; return *this; } inline uint128& uint128::operator&=(uint128 other) { - *this = *this & other; + *this = *this & other; return *this; } inline uint128& uint128::operator^=(uint128 other) { - *this = *this ^ other; + *this = *this ^ other; return *this; } // Arithmetic operators. -constexpr uint128 operator<<(uint128 lhs, int amount) { +constexpr uint128 operator<<(uint128 lhs, int amount) { #ifdef ABSL_HAVE_INTRINSIC_INT128 return static_cast<unsigned __int128>(lhs) << amount; #else // uint64_t shifts of >= 64 are undefined, so we will need some // special-casing. - return amount >= 64 ? MakeUint128(Uint128Low64(lhs) << (amount - 64), 0) - : amount == 0 ? lhs - : MakeUint128((Uint128High64(lhs) << amount) | - (Uint128Low64(lhs) >> (64 - amount)), - Uint128Low64(lhs) << amount); + return amount >= 64 ? MakeUint128(Uint128Low64(lhs) << (amount - 64), 0) + : amount == 0 ? lhs + : MakeUint128((Uint128High64(lhs) << amount) | + (Uint128Low64(lhs) >> (64 - amount)), + Uint128Low64(lhs) << amount); #endif } -constexpr uint128 operator>>(uint128 lhs, int amount) { +constexpr uint128 operator>>(uint128 lhs, int amount) { #ifdef ABSL_HAVE_INTRINSIC_INT128 return static_cast<unsigned __int128>(lhs) >> amount; #else // uint64_t shifts of >= 64 are undefined, so we will need some // special-casing. - return amount >= 64 ? MakeUint128(0, Uint128High64(lhs) >> (amount - 64)) - : amount == 0 ? lhs - : MakeUint128(Uint128High64(lhs) >> amount, - (Uint128Low64(lhs) >> amount) | - (Uint128High64(lhs) << (64 - amount))); -#endif -} - -#if !defined(ABSL_HAVE_INTRINSIC_INT128) -namespace int128_internal { -constexpr uint128 AddResult(uint128 result, uint128 lhs) { - // check for carry - return (Uint128Low64(result) < Uint128Low64(lhs)) - ? MakeUint128(Uint128High64(result) + 1, Uint128Low64(result)) - : result; -} -} // namespace int128_internal -#endif - -constexpr uint128 operator+(uint128 lhs, uint128 rhs) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return static_cast<unsigned __int128>(lhs) + - static_cast<unsigned __int128>(rhs); -#else - return int128_internal::AddResult( - MakeUint128(Uint128High64(lhs) + Uint128High64(rhs), - Uint128Low64(lhs) + Uint128Low64(rhs)), - lhs); -#endif -} - -#if !defined(ABSL_HAVE_INTRINSIC_INT128) -namespace int128_internal { -constexpr uint128 SubstructResult(uint128 result, uint128 lhs, uint128 rhs) { - // check for carry - return (Uint128Low64(lhs) < Uint128Low64(rhs)) - ? MakeUint128(Uint128High64(result) - 1, Uint128Low64(result)) - : result; -} -} // namespace int128_internal -#endif - -constexpr uint128 operator-(uint128 lhs, uint128 rhs) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return static_cast<unsigned __int128>(lhs) - - static_cast<unsigned __int128>(rhs); -#else - return int128_internal::SubstructResult( - MakeUint128(Uint128High64(lhs) - Uint128High64(rhs), - Uint128Low64(lhs) - Uint128Low64(rhs)), - lhs, rhs); + return amount >= 64 ? MakeUint128(0, Uint128High64(lhs) >> (amount - 64)) + : amount == 0 ? lhs + : MakeUint128(Uint128High64(lhs) >> amount, + (Uint128Low64(lhs) >> amount) | + (Uint128High64(lhs) << (64 - amount))); #endif } +#if !defined(ABSL_HAVE_INTRINSIC_INT128) +namespace int128_internal { +constexpr uint128 AddResult(uint128 result, uint128 lhs) { + // check for carry + return (Uint128Low64(result) < Uint128Low64(lhs)) + ? MakeUint128(Uint128High64(result) + 1, Uint128Low64(result)) + : result; +} +} // namespace int128_internal +#endif + +constexpr uint128 operator+(uint128 lhs, uint128 rhs) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return static_cast<unsigned __int128>(lhs) + + static_cast<unsigned __int128>(rhs); +#else + return int128_internal::AddResult( + MakeUint128(Uint128High64(lhs) + Uint128High64(rhs), + Uint128Low64(lhs) + Uint128Low64(rhs)), + lhs); +#endif +} + +#if !defined(ABSL_HAVE_INTRINSIC_INT128) +namespace int128_internal { +constexpr uint128 SubstructResult(uint128 result, uint128 lhs, uint128 rhs) { + // check for carry + return (Uint128Low64(lhs) < Uint128Low64(rhs)) + ? MakeUint128(Uint128High64(result) - 1, Uint128Low64(result)) + : result; +} +} // namespace int128_internal +#endif + +constexpr uint128 operator-(uint128 lhs, uint128 rhs) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return static_cast<unsigned __int128>(lhs) - + static_cast<unsigned __int128>(rhs); +#else + return int128_internal::SubstructResult( + MakeUint128(Uint128High64(lhs) - Uint128High64(rhs), + Uint128Low64(lhs) - Uint128Low64(rhs)), + lhs, rhs); +#endif +} + inline uint128 operator*(uint128 lhs, uint128 rhs) { #if defined(ABSL_HAVE_INTRINSIC_INT128) // TODO(strel) Remove once alignment issues are resolved and unsigned __int128 @@ -1001,18 +1001,18 @@ inline uint128 operator*(uint128 lhs, uint128 rhs) { #endif // ABSL_HAVE_INTRINSIC128 } -#if defined(ABSL_HAVE_INTRINSIC_INT128) -inline uint128 operator/(uint128 lhs, uint128 rhs) { - return static_cast<unsigned __int128>(lhs) / - static_cast<unsigned __int128>(rhs); -} - -inline uint128 operator%(uint128 lhs, uint128 rhs) { - return static_cast<unsigned __int128>(lhs) % - static_cast<unsigned __int128>(rhs); -} -#endif - +#if defined(ABSL_HAVE_INTRINSIC_INT128) +inline uint128 operator/(uint128 lhs, uint128 rhs) { + return static_cast<unsigned __int128>(lhs) / + static_cast<unsigned __int128>(rhs); +} + +inline uint128 operator%(uint128 lhs, uint128 rhs) { + return static_cast<unsigned __int128>(lhs) % + static_cast<unsigned __int128>(rhs); +} +#endif + // Increment/decrement operators. inline uint128 uint128::operator++(int) { @@ -1070,17 +1070,17 @@ inline int128& int128::operator=(unsigned long long v) { } // Arithmetic operators. -constexpr int128 operator-(int128 v); -constexpr int128 operator+(int128 lhs, int128 rhs); -constexpr int128 operator-(int128 lhs, int128 rhs); +constexpr int128 operator-(int128 v); +constexpr int128 operator+(int128 lhs, int128 rhs); +constexpr int128 operator-(int128 lhs, int128 rhs); int128 operator*(int128 lhs, int128 rhs); int128 operator/(int128 lhs, int128 rhs); int128 operator%(int128 lhs, int128 rhs); -constexpr int128 operator|(int128 lhs, int128 rhs); -constexpr int128 operator&(int128 lhs, int128 rhs); -constexpr int128 operator^(int128 lhs, int128 rhs); -constexpr int128 operator<<(int128 lhs, int amount); -constexpr int128 operator>>(int128 lhs, int amount); +constexpr int128 operator|(int128 lhs, int128 rhs); +constexpr int128 operator&(int128 lhs, int128 rhs); +constexpr int128 operator^(int128 lhs, int128 rhs); +constexpr int128 operator<<(int128 lhs, int amount); +constexpr int128 operator>>(int128 lhs, int amount); inline int128& int128::operator+=(int128 other) { *this = *this + other; @@ -1132,9 +1132,9 @@ inline int128& int128::operator>>=(int amount) { return *this; } -// Forward declaration for comparison operators. -constexpr bool operator!=(int128 lhs, int128 rhs); - +// Forward declaration for comparison operators. +constexpr bool operator!=(int128 lhs, int128 rhs); + namespace int128_internal { // Casts from unsigned to signed while preserving the underlying binary diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/numeric/int128_have_intrinsic.inc b/contrib/restricted/abseil-cpp-tstring/y_absl/numeric/int128_have_intrinsic.inc index 3945fa2983..b6e31f8fa5 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/numeric/int128_have_intrinsic.inc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/numeric/int128_have_intrinsic.inc @@ -155,7 +155,7 @@ constexpr int128::operator unsigned __int128() const { #if defined(__clang__) && !defined(__ppc64__) inline int128::operator float() const { return static_cast<float>(v_); } -inline int128::operator double() const { return static_cast<double>(v_); } +inline int128::operator double() const { return static_cast<double>(v_); } inline int128::operator long double() const { return static_cast<long double>(v_); @@ -163,8 +163,8 @@ inline int128::operator long double() const { #else // Clang on PowerPC // Forward declaration for conversion operators to floating point types. -constexpr int128 operator-(int128 v); -constexpr bool operator!=(int128 lhs, int128 rhs); +constexpr int128 operator-(int128 v); +constexpr bool operator!=(int128 lhs, int128 rhs); inline int128::operator float() const { // We must convert the absolute value and then negate as needed, because @@ -199,45 +199,45 @@ inline int128::operator long double() const { // Comparison operators. -constexpr bool operator==(int128 lhs, int128 rhs) { +constexpr bool operator==(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) == static_cast<__int128>(rhs); } -constexpr bool operator!=(int128 lhs, int128 rhs) { +constexpr bool operator!=(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) != static_cast<__int128>(rhs); } -constexpr bool operator<(int128 lhs, int128 rhs) { +constexpr bool operator<(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) < static_cast<__int128>(rhs); } -constexpr bool operator>(int128 lhs, int128 rhs) { +constexpr bool operator>(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) > static_cast<__int128>(rhs); } -constexpr bool operator<=(int128 lhs, int128 rhs) { +constexpr bool operator<=(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) <= static_cast<__int128>(rhs); } -constexpr bool operator>=(int128 lhs, int128 rhs) { +constexpr bool operator>=(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) >= static_cast<__int128>(rhs); } // Unary operators. -constexpr int128 operator-(int128 v) { return -static_cast<__int128>(v); } +constexpr int128 operator-(int128 v) { return -static_cast<__int128>(v); } -constexpr bool operator!(int128 v) { return !static_cast<__int128>(v); } +constexpr bool operator!(int128 v) { return !static_cast<__int128>(v); } -constexpr int128 operator~(int128 val) { return ~static_cast<__int128>(val); } +constexpr int128 operator~(int128 val) { return ~static_cast<__int128>(val); } // Arithmetic operators. -constexpr int128 operator+(int128 lhs, int128 rhs) { +constexpr int128 operator+(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) + static_cast<__int128>(rhs); } -constexpr int128 operator-(int128 lhs, int128 rhs) { +constexpr int128 operator-(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) - static_cast<__int128>(rhs); } @@ -275,22 +275,22 @@ inline int128& int128::operator--() { return *this; } -constexpr int128 operator|(int128 lhs, int128 rhs) { +constexpr int128 operator|(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) | static_cast<__int128>(rhs); } -constexpr int128 operator&(int128 lhs, int128 rhs) { +constexpr int128 operator&(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) & static_cast<__int128>(rhs); } -constexpr int128 operator^(int128 lhs, int128 rhs) { +constexpr int128 operator^(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) ^ static_cast<__int128>(rhs); } -constexpr int128 operator<<(int128 lhs, int amount) { +constexpr int128 operator<<(int128 lhs, int amount) { return static_cast<__int128>(lhs) << amount; } -constexpr int128 operator>>(int128 lhs, int amount) { +constexpr int128 operator>>(int128 lhs, int amount) { return static_cast<__int128>(lhs) >> amount; } diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/numeric/int128_no_intrinsic.inc b/contrib/restricted/abseil-cpp-tstring/y_absl/numeric/int128_no_intrinsic.inc index 8834804cec..deb1c31c36 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/numeric/int128_no_intrinsic.inc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/numeric/int128_no_intrinsic.inc @@ -165,80 +165,80 @@ inline int128::operator long double() const { // Comparison operators. -constexpr bool operator==(int128 lhs, int128 rhs) { +constexpr bool operator==(int128 lhs, int128 rhs) { return (Int128Low64(lhs) == Int128Low64(rhs) && Int128High64(lhs) == Int128High64(rhs)); } -constexpr bool operator!=(int128 lhs, int128 rhs) { return !(lhs == rhs); } +constexpr bool operator!=(int128 lhs, int128 rhs) { return !(lhs == rhs); } -constexpr bool operator<(int128 lhs, int128 rhs) { +constexpr bool operator<(int128 lhs, int128 rhs) { return (Int128High64(lhs) == Int128High64(rhs)) ? (Int128Low64(lhs) < Int128Low64(rhs)) : (Int128High64(lhs) < Int128High64(rhs)); } -constexpr bool operator>(int128 lhs, int128 rhs) { +constexpr bool operator>(int128 lhs, int128 rhs) { return (Int128High64(lhs) == Int128High64(rhs)) ? (Int128Low64(lhs) > Int128Low64(rhs)) : (Int128High64(lhs) > Int128High64(rhs)); } -constexpr bool operator<=(int128 lhs, int128 rhs) { return !(lhs > rhs); } +constexpr bool operator<=(int128 lhs, int128 rhs) { return !(lhs > rhs); } -constexpr bool operator>=(int128 lhs, int128 rhs) { return !(lhs < rhs); } +constexpr bool operator>=(int128 lhs, int128 rhs) { return !(lhs < rhs); } // Unary operators. -constexpr int128 operator-(int128 v) { - return MakeInt128(~Int128High64(v) + (Int128Low64(v) == 0), - ~Int128Low64(v) + 1); +constexpr int128 operator-(int128 v) { + return MakeInt128(~Int128High64(v) + (Int128Low64(v) == 0), + ~Int128Low64(v) + 1); } -constexpr bool operator!(int128 v) { +constexpr bool operator!(int128 v) { return !Int128Low64(v) && !Int128High64(v); } -constexpr int128 operator~(int128 val) { +constexpr int128 operator~(int128 val) { return MakeInt128(~Int128High64(val), ~Int128Low64(val)); } // Arithmetic operators. -namespace int128_internal { -constexpr int128 SignedAddResult(int128 result, int128 lhs) { - // check for carry - return (Int128Low64(result) < Int128Low64(lhs)) - ? MakeInt128(Int128High64(result) + 1, Int128Low64(result)) - : result; -} -} // namespace int128_internal -constexpr int128 operator+(int128 lhs, int128 rhs) { - return int128_internal::SignedAddResult( - MakeInt128(Int128High64(lhs) + Int128High64(rhs), - Int128Low64(lhs) + Int128Low64(rhs)), - lhs); -} - -namespace int128_internal { -constexpr int128 SignedSubstructResult(int128 result, int128 lhs, int128 rhs) { - // check for carry - return (Int128Low64(lhs) < Int128Low64(rhs)) - ? MakeInt128(Int128High64(result) - 1, Int128Low64(result)) - : result; -} -} // namespace int128_internal -constexpr int128 operator-(int128 lhs, int128 rhs) { - return int128_internal::SignedSubstructResult( - MakeInt128(Int128High64(lhs) - Int128High64(rhs), - Int128Low64(lhs) - Int128Low64(rhs)), - lhs, rhs); -} +namespace int128_internal { +constexpr int128 SignedAddResult(int128 result, int128 lhs) { + // check for carry + return (Int128Low64(result) < Int128Low64(lhs)) + ? MakeInt128(Int128High64(result) + 1, Int128Low64(result)) + : result; +} +} // namespace int128_internal +constexpr int128 operator+(int128 lhs, int128 rhs) { + return int128_internal::SignedAddResult( + MakeInt128(Int128High64(lhs) + Int128High64(rhs), + Int128Low64(lhs) + Int128Low64(rhs)), + lhs); +} + +namespace int128_internal { +constexpr int128 SignedSubstructResult(int128 result, int128 lhs, int128 rhs) { + // check for carry + return (Int128Low64(lhs) < Int128Low64(rhs)) + ? MakeInt128(Int128High64(result) - 1, Int128Low64(result)) + : result; +} +} // namespace int128_internal +constexpr int128 operator-(int128 lhs, int128 rhs) { + return int128_internal::SignedSubstructResult( + MakeInt128(Int128High64(lhs) - Int128High64(rhs), + Int128Low64(lhs) - Int128Low64(rhs)), + lhs, rhs); +} inline int128 operator*(int128 lhs, int128 rhs) { - return MakeInt128( - int128_internal::BitCastToSigned(Uint128High64(uint128(lhs) * rhs)), - Uint128Low64(uint128(lhs) * rhs)); + return MakeInt128( + int128_internal::BitCastToSigned(Uint128High64(uint128(lhs) * rhs)), + Uint128Low64(uint128(lhs) * rhs)); } inline int128 int128::operator++(int) { @@ -263,49 +263,49 @@ inline int128& int128::operator--() { return *this; } -constexpr int128 operator|(int128 lhs, int128 rhs) { +constexpr int128 operator|(int128 lhs, int128 rhs) { return MakeInt128(Int128High64(lhs) | Int128High64(rhs), Int128Low64(lhs) | Int128Low64(rhs)); } -constexpr int128 operator&(int128 lhs, int128 rhs) { +constexpr int128 operator&(int128 lhs, int128 rhs) { return MakeInt128(Int128High64(lhs) & Int128High64(rhs), Int128Low64(lhs) & Int128Low64(rhs)); } -constexpr int128 operator^(int128 lhs, int128 rhs) { +constexpr int128 operator^(int128 lhs, int128 rhs) { return MakeInt128(Int128High64(lhs) ^ Int128High64(rhs), Int128Low64(lhs) ^ Int128Low64(rhs)); } -constexpr int128 operator<<(int128 lhs, int amount) { - // int64_t shifts of >= 64 are undefined, so we need some special-casing. - return amount >= 64 - ? MakeInt128( - static_cast<int64_t>(Int128Low64(lhs) << (amount - 64)), 0) - : amount == 0 - ? lhs - : MakeInt128( - (Int128High64(lhs) << amount) | - static_cast<int64_t>(Int128Low64(lhs) >> (64 - amount)), - Int128Low64(lhs) << amount); -} - -constexpr int128 operator>>(int128 lhs, int amount) { - // int64_t shifts of >= 64 are undefined, so we need some special-casing. - // The (Int128High64(lhs) >> 32) >> 32 "trick" causes the the most significant - // int64 to be inititialized with all zeros or all ones correctly. It takes - // into account whether the number is negative or positive, and whether the - // current architecture does arithmetic or logical right shifts for negative - // numbers. - return amount >= 64 - ? MakeInt128( - (Int128High64(lhs) >> 32) >> 32, - static_cast<uint64_t>(Int128High64(lhs) >> (amount - 64))) - : amount == 0 - ? lhs - : MakeInt128(Int128High64(lhs) >> amount, - (Int128Low64(lhs) >> amount) | - (static_cast<uint64_t>(Int128High64(lhs)) - << (64 - amount))); +constexpr int128 operator<<(int128 lhs, int amount) { + // int64_t shifts of >= 64 are undefined, so we need some special-casing. + return amount >= 64 + ? MakeInt128( + static_cast<int64_t>(Int128Low64(lhs) << (amount - 64)), 0) + : amount == 0 + ? lhs + : MakeInt128( + (Int128High64(lhs) << amount) | + static_cast<int64_t>(Int128Low64(lhs) >> (64 - amount)), + Int128Low64(lhs) << amount); +} + +constexpr int128 operator>>(int128 lhs, int amount) { + // int64_t shifts of >= 64 are undefined, so we need some special-casing. + // The (Int128High64(lhs) >> 32) >> 32 "trick" causes the the most significant + // int64 to be inititialized with all zeros or all ones correctly. It takes + // into account whether the number is negative or positive, and whether the + // current architecture does arithmetic or logical right shifts for negative + // numbers. + return amount >= 64 + ? MakeInt128( + (Int128High64(lhs) >> 32) >> 32, + static_cast<uint64_t>(Int128High64(lhs) >> (amount - 64))) + : amount == 0 + ? lhs + : MakeInt128(Int128High64(lhs) >> amount, + (Int128Low64(lhs) >> amount) | + (static_cast<uint64_t>(Int128High64(lhs)) + << (64 - amount))); } diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased.cc index 02f5dfd9da..87bbe49eff 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "y_absl/profiling/internal/exponential_biased.h" +#include "y_absl/profiling/internal/exponential_biased.h" #include <stdint.h> @@ -26,7 +26,7 @@ namespace y_absl { ABSL_NAMESPACE_BEGIN -namespace profiling_internal { +namespace profiling_internal { // The algorithm generates a random number between 0 and 1 and applies the // inverse cumulative distribution function for an exponential. Specifically: @@ -64,7 +64,7 @@ int64_t ExponentialBiased::GetSkipCount(int64_t mean) { // Assume huge values are bias neutral, retain bias for next call. return std::numeric_limits<int64_t>::max() / 2; } - double value = std::rint(interval); + double value = std::rint(interval); bias_ = interval - value; return value; } @@ -88,6 +88,6 @@ void ExponentialBiased::Initialize() { initialized_ = true; } -} // namespace profiling_internal +} // namespace profiling_internal ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased.h b/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased.h index ee7954a535..65351fdc32 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef ABSL_PROFILING_INTERNAL_EXPONENTIAL_BIASED_H_ -#define ABSL_PROFILING_INTERNAL_EXPONENTIAL_BIASED_H_ +#ifndef ABSL_PROFILING_INTERNAL_EXPONENTIAL_BIASED_H_ +#define ABSL_PROFILING_INTERNAL_EXPONENTIAL_BIASED_H_ #include <stdint.h> @@ -22,7 +22,7 @@ namespace y_absl { ABSL_NAMESPACE_BEGIN -namespace profiling_internal { +namespace profiling_internal { // ExponentialBiased provides a small and fast random number generator for a // rounded exponential distribution. This generator manages very little state, @@ -66,7 +66,7 @@ namespace profiling_internal { // Adjusting with rounding bias is relatively trivial: // // double value = bias_ + exponential_distribution(mean)(); -// double rounded_value = std::rint(value); +// double rounded_value = std::rint(value); // bias_ = value - rounded_value; // return rounded_value; // @@ -123,8 +123,8 @@ inline uint64_t ExponentialBiased::NextRandom(uint64_t rnd) { return (prng_mult * rnd + prng_add) & prng_mod_mask; } -} // namespace profiling_internal +} // namespace profiling_internal ABSL_NAMESPACE_END } // namespace y_absl -#endif // ABSL_PROFILING_INTERNAL_EXPONENTIAL_BIASED_H_ +#endif // ABSL_PROFILING_INTERNAL_EXPONENTIAL_BIASED_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased/ya.make index ddfe147041..735cc27bc8 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased/ya.make @@ -17,7 +17,7 @@ ADDINCL( NO_COMPILER_WARNINGS() -SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal) +SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal) SRCS( exponential_biased.cc diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/periodic_sampler.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/periodic_sampler.cc index 39fb3660f0..8595e5d23a 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/periodic_sampler.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/periodic_sampler.cc @@ -12,15 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "y_absl/profiling/internal/periodic_sampler.h" +#include "y_absl/profiling/internal/periodic_sampler.h" #include <atomic> -#include "y_absl/profiling/internal/exponential_biased.h" +#include "y_absl/profiling/internal/exponential_biased.h" namespace y_absl { ABSL_NAMESPACE_BEGIN -namespace profiling_internal { +namespace profiling_internal { int64_t PeriodicSamplerBase::GetExponentialBiased(int period) noexcept { return rng_.GetStride(period); @@ -48,6 +48,6 @@ bool PeriodicSamplerBase::SubtleConfirmSample() noexcept { return true; } -} // namespace profiling_internal +} // namespace profiling_internal ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/periodic_sampler.h b/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/periodic_sampler.h index 37796a9e00..690842ce13 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/periodic_sampler.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/periodic_sampler.h @@ -12,19 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef ABSL_PROFILING_INTERNAL_PERIODIC_SAMPLER_H_ -#define ABSL_PROFILING_INTERNAL_PERIODIC_SAMPLER_H_ +#ifndef ABSL_PROFILING_INTERNAL_PERIODIC_SAMPLER_H_ +#define ABSL_PROFILING_INTERNAL_PERIODIC_SAMPLER_H_ #include <stdint.h> #include <atomic> #include "y_absl/base/optimization.h" -#include "y_absl/profiling/internal/exponential_biased.h" +#include "y_absl/profiling/internal/exponential_biased.h" namespace y_absl { ABSL_NAMESPACE_BEGIN -namespace profiling_internal { +namespace profiling_internal { // PeriodicSamplerBase provides the basic period sampler implementation. // @@ -149,7 +149,7 @@ class PeriodicSamplerBase { // ICC x64 (OK) : https://gcc.godbolt.org/z/ptTNfD // MSVC x64 (OK) : https://gcc.godbolt.org/z/76j4-5 uint64_t stride_ = 0; - y_absl::profiling_internal::ExponentialBiased rng_; + y_absl::profiling_internal::ExponentialBiased rng_; }; inline bool PeriodicSamplerBase::SubtleMaybeSample() noexcept { @@ -204,8 +204,8 @@ class PeriodicSampler final : public PeriodicSamplerBase { template <typename Tag, int default_period> std::atomic<int> PeriodicSampler<Tag, default_period>::period_(default_period); -} // namespace profiling_internal +} // namespace profiling_internal ABSL_NAMESPACE_END } // namespace y_absl -#endif // ABSL_PROFILING_INTERNAL_PERIODIC_SAMPLER_H_ +#endif // ABSL_PROFILING_INTERNAL_PERIODIC_SAMPLER_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/sample_recorder.h b/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/sample_recorder.h index 449d17a76d..dfc37e9e03 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/sample_recorder.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/sample_recorder.h @@ -1,230 +1,230 @@ -// Copyright 2018 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ----------------------------------------------------------------------------- -// File: sample_recorder.h -// ----------------------------------------------------------------------------- -// -// This header file defines a lock-free linked list for recording samples -// collected from a random/stochastic process. -// -// This utility is internal-only. Use at your own risk. - -#ifndef ABSL_PROFILING_INTERNAL_SAMPLE_RECORDER_H_ -#define ABSL_PROFILING_INTERNAL_SAMPLE_RECORDER_H_ - -#include <atomic> -#include <cstddef> -#include <functional> - -#include "y_absl/base/config.h" -#include "y_absl/base/thread_annotations.h" -#include "y_absl/synchronization/mutex.h" -#include "y_absl/time/time.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace profiling_internal { - -// Sample<T> that has members required for linking samples in the linked list of -// samples maintained by the SampleRecorder. Type T defines the sampled data. -template <typename T> -struct Sample { - // Guards the ability to restore the sample to a pristine state. This - // prevents races with sampling and resurrecting an object. - y_absl::Mutex init_mu; - T* next = nullptr; - T* dead ABSL_GUARDED_BY(init_mu) = nullptr; -}; - -// Holds samples and their associated stack traces with a soft limit of -// `SetHashtablezMaxSamples()`. -// -// Thread safe. -template <typename T> -class SampleRecorder { - public: - SampleRecorder(); - ~SampleRecorder(); - - // Registers for sampling. Returns an opaque registration info. - T* Register(); - - // Unregisters the sample. - void Unregister(T* sample); - - // The dispose callback will be called on all samples the moment they are - // being unregistered. Only affects samples that are unregistered after the - // callback has been set. - // Returns the previous callback. - using DisposeCallback = void (*)(const T&); - DisposeCallback SetDisposeCallback(DisposeCallback f); - - // Iterates over all the registered `StackInfo`s. Returning the number of - // samples that have been dropped. - int64_t Iterate(const std::function<void(const T& stack)>& f); - - void SetMaxSamples(int32_t max); - - private: - void PushNew(T* sample); - void PushDead(T* sample); - T* PopDead(); - - std::atomic<size_t> dropped_samples_; - std::atomic<size_t> size_estimate_; - std::atomic<int32_t> max_samples_{1 << 20}; - - // Intrusive lock free linked lists for tracking samples. - // - // `all_` records all samples (they are never removed from this list) and is - // terminated with a `nullptr`. - // - // `graveyard_.dead` is a circular linked list. When it is empty, - // `graveyard_.dead == &graveyard`. The list is circular so that - // every item on it (even the last) has a non-null dead pointer. This allows - // `Iterate` to determine if a given sample is live or dead using only - // information on the sample itself. - // - // For example, nodes [A, B, C, D, E] with [A, C, E] alive and [B, D] dead - // looks like this (G is the Graveyard): - // - // +---+ +---+ +---+ +---+ +---+ - // all -->| A |--->| B |--->| C |--->| D |--->| E | - // | | | | | | | | | | - // +---+ | | +->| |-+ | | +->| |-+ | | - // | G | +---+ | +---+ | +---+ | +---+ | +---+ - // | | | | | | - // | | --------+ +--------+ | - // +---+ | - // ^ | - // +--------------------------------------+ - // - std::atomic<T*> all_; - T graveyard_; - - std::atomic<DisposeCallback> dispose_; -}; - -template <typename T> -typename SampleRecorder<T>::DisposeCallback -SampleRecorder<T>::SetDisposeCallback(DisposeCallback f) { - return dispose_.exchange(f, std::memory_order_relaxed); -} - -template <typename T> -SampleRecorder<T>::SampleRecorder() - : dropped_samples_(0), size_estimate_(0), all_(nullptr), dispose_(nullptr) { - y_absl::MutexLock l(&graveyard_.init_mu); - graveyard_.dead = &graveyard_; -} - -template <typename T> -SampleRecorder<T>::~SampleRecorder() { - T* s = all_.load(std::memory_order_acquire); - while (s != nullptr) { - T* next = s->next; - delete s; - s = next; - } -} - -template <typename T> -void SampleRecorder<T>::PushNew(T* sample) { - sample->next = all_.load(std::memory_order_relaxed); - while (!all_.compare_exchange_weak(sample->next, sample, - std::memory_order_release, - std::memory_order_relaxed)) { - } -} - -template <typename T> -void SampleRecorder<T>::PushDead(T* sample) { - if (auto* dispose = dispose_.load(std::memory_order_relaxed)) { - dispose(*sample); - } - - y_absl::MutexLock graveyard_lock(&graveyard_.init_mu); - y_absl::MutexLock sample_lock(&sample->init_mu); - sample->dead = graveyard_.dead; - graveyard_.dead = sample; -} - -template <typename T> -T* SampleRecorder<T>::PopDead() { - y_absl::MutexLock graveyard_lock(&graveyard_.init_mu); - - // The list is circular, so eventually it collapses down to - // graveyard_.dead == &graveyard_ - // when it is empty. - T* sample = graveyard_.dead; - if (sample == &graveyard_) return nullptr; - - y_absl::MutexLock sample_lock(&sample->init_mu); - graveyard_.dead = sample->dead; - sample->dead = nullptr; - sample->PrepareForSampling(); - return sample; -} - -template <typename T> -T* SampleRecorder<T>::Register() { - int64_t size = size_estimate_.fetch_add(1, std::memory_order_relaxed); - if (size > max_samples_.load(std::memory_order_relaxed)) { - size_estimate_.fetch_sub(1, std::memory_order_relaxed); - dropped_samples_.fetch_add(1, std::memory_order_relaxed); - return nullptr; - } - - T* sample = PopDead(); - if (sample == nullptr) { - // Resurrection failed. Hire a new warlock. - sample = new T(); - PushNew(sample); - } - - return sample; -} - -template <typename T> -void SampleRecorder<T>::Unregister(T* sample) { - PushDead(sample); - size_estimate_.fetch_sub(1, std::memory_order_relaxed); -} - -template <typename T> -int64_t SampleRecorder<T>::Iterate( - const std::function<void(const T& stack)>& f) { - T* s = all_.load(std::memory_order_acquire); - while (s != nullptr) { - y_absl::MutexLock l(&s->init_mu); - if (s->dead == nullptr) { - f(*s); - } - s = s->next; - } - - return dropped_samples_.load(std::memory_order_relaxed); -} - -template <typename T> -void SampleRecorder<T>::SetMaxSamples(int32_t max) { - max_samples_.store(max, std::memory_order_release); -} - -} // namespace profiling_internal -ABSL_NAMESPACE_END -} // namespace y_absl - -#endif // ABSL_PROFILING_INTERNAL_SAMPLE_RECORDER_H_ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ----------------------------------------------------------------------------- +// File: sample_recorder.h +// ----------------------------------------------------------------------------- +// +// This header file defines a lock-free linked list for recording samples +// collected from a random/stochastic process. +// +// This utility is internal-only. Use at your own risk. + +#ifndef ABSL_PROFILING_INTERNAL_SAMPLE_RECORDER_H_ +#define ABSL_PROFILING_INTERNAL_SAMPLE_RECORDER_H_ + +#include <atomic> +#include <cstddef> +#include <functional> + +#include "y_absl/base/config.h" +#include "y_absl/base/thread_annotations.h" +#include "y_absl/synchronization/mutex.h" +#include "y_absl/time/time.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace profiling_internal { + +// Sample<T> that has members required for linking samples in the linked list of +// samples maintained by the SampleRecorder. Type T defines the sampled data. +template <typename T> +struct Sample { + // Guards the ability to restore the sample to a pristine state. This + // prevents races with sampling and resurrecting an object. + y_absl::Mutex init_mu; + T* next = nullptr; + T* dead ABSL_GUARDED_BY(init_mu) = nullptr; +}; + +// Holds samples and their associated stack traces with a soft limit of +// `SetHashtablezMaxSamples()`. +// +// Thread safe. +template <typename T> +class SampleRecorder { + public: + SampleRecorder(); + ~SampleRecorder(); + + // Registers for sampling. Returns an opaque registration info. + T* Register(); + + // Unregisters the sample. + void Unregister(T* sample); + + // The dispose callback will be called on all samples the moment they are + // being unregistered. Only affects samples that are unregistered after the + // callback has been set. + // Returns the previous callback. + using DisposeCallback = void (*)(const T&); + DisposeCallback SetDisposeCallback(DisposeCallback f); + + // Iterates over all the registered `StackInfo`s. Returning the number of + // samples that have been dropped. + int64_t Iterate(const std::function<void(const T& stack)>& f); + + void SetMaxSamples(int32_t max); + + private: + void PushNew(T* sample); + void PushDead(T* sample); + T* PopDead(); + + std::atomic<size_t> dropped_samples_; + std::atomic<size_t> size_estimate_; + std::atomic<int32_t> max_samples_{1 << 20}; + + // Intrusive lock free linked lists for tracking samples. + // + // `all_` records all samples (they are never removed from this list) and is + // terminated with a `nullptr`. + // + // `graveyard_.dead` is a circular linked list. When it is empty, + // `graveyard_.dead == &graveyard`. The list is circular so that + // every item on it (even the last) has a non-null dead pointer. This allows + // `Iterate` to determine if a given sample is live or dead using only + // information on the sample itself. + // + // For example, nodes [A, B, C, D, E] with [A, C, E] alive and [B, D] dead + // looks like this (G is the Graveyard): + // + // +---+ +---+ +---+ +---+ +---+ + // all -->| A |--->| B |--->| C |--->| D |--->| E | + // | | | | | | | | | | + // +---+ | | +->| |-+ | | +->| |-+ | | + // | G | +---+ | +---+ | +---+ | +---+ | +---+ + // | | | | | | + // | | --------+ +--------+ | + // +---+ | + // ^ | + // +--------------------------------------+ + // + std::atomic<T*> all_; + T graveyard_; + + std::atomic<DisposeCallback> dispose_; +}; + +template <typename T> +typename SampleRecorder<T>::DisposeCallback +SampleRecorder<T>::SetDisposeCallback(DisposeCallback f) { + return dispose_.exchange(f, std::memory_order_relaxed); +} + +template <typename T> +SampleRecorder<T>::SampleRecorder() + : dropped_samples_(0), size_estimate_(0), all_(nullptr), dispose_(nullptr) { + y_absl::MutexLock l(&graveyard_.init_mu); + graveyard_.dead = &graveyard_; +} + +template <typename T> +SampleRecorder<T>::~SampleRecorder() { + T* s = all_.load(std::memory_order_acquire); + while (s != nullptr) { + T* next = s->next; + delete s; + s = next; + } +} + +template <typename T> +void SampleRecorder<T>::PushNew(T* sample) { + sample->next = all_.load(std::memory_order_relaxed); + while (!all_.compare_exchange_weak(sample->next, sample, + std::memory_order_release, + std::memory_order_relaxed)) { + } +} + +template <typename T> +void SampleRecorder<T>::PushDead(T* sample) { + if (auto* dispose = dispose_.load(std::memory_order_relaxed)) { + dispose(*sample); + } + + y_absl::MutexLock graveyard_lock(&graveyard_.init_mu); + y_absl::MutexLock sample_lock(&sample->init_mu); + sample->dead = graveyard_.dead; + graveyard_.dead = sample; +} + +template <typename T> +T* SampleRecorder<T>::PopDead() { + y_absl::MutexLock graveyard_lock(&graveyard_.init_mu); + + // The list is circular, so eventually it collapses down to + // graveyard_.dead == &graveyard_ + // when it is empty. + T* sample = graveyard_.dead; + if (sample == &graveyard_) return nullptr; + + y_absl::MutexLock sample_lock(&sample->init_mu); + graveyard_.dead = sample->dead; + sample->dead = nullptr; + sample->PrepareForSampling(); + return sample; +} + +template <typename T> +T* SampleRecorder<T>::Register() { + int64_t size = size_estimate_.fetch_add(1, std::memory_order_relaxed); + if (size > max_samples_.load(std::memory_order_relaxed)) { + size_estimate_.fetch_sub(1, std::memory_order_relaxed); + dropped_samples_.fetch_add(1, std::memory_order_relaxed); + return nullptr; + } + + T* sample = PopDead(); + if (sample == nullptr) { + // Resurrection failed. Hire a new warlock. + sample = new T(); + PushNew(sample); + } + + return sample; +} + +template <typename T> +void SampleRecorder<T>::Unregister(T* sample) { + PushDead(sample); + size_estimate_.fetch_sub(1, std::memory_order_relaxed); +} + +template <typename T> +int64_t SampleRecorder<T>::Iterate( + const std::function<void(const T& stack)>& f) { + T* s = all_.load(std::memory_order_acquire); + while (s != nullptr) { + y_absl::MutexLock l(&s->init_mu); + if (s->dead == nullptr) { + f(*s); + } + s = s->next; + } + + return dropped_samples_.load(std::memory_order_relaxed); +} + +template <typename T> +void SampleRecorder<T>::SetMaxSamples(int32_t max) { + max_samples_.store(max, std::memory_order_release); +} + +} // namespace profiling_internal +ABSL_NAMESPACE_END +} // namespace y_absl + +#endif // ABSL_PROFILING_INTERNAL_SAMPLE_RECORDER_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/status/internal/status_internal.h b/contrib/restricted/abseil-cpp-tstring/y_absl/status/internal/status_internal.h index 6754d7d518..4289e5f8fa 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/status/internal/status_internal.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/status/internal/status_internal.h @@ -47,12 +47,12 @@ using Payloads = y_absl::InlinedVector<Payload, 1>; // Reference-counted representation of Status data. struct StatusRep { - StatusRep(y_absl::StatusCode code_arg, y_absl::string_view message_arg, - std::unique_ptr<status_internal::Payloads> payloads_arg) + StatusRep(y_absl::StatusCode code_arg, y_absl::string_view message_arg, + std::unique_ptr<status_internal::Payloads> payloads_arg) : ref(int32_t{1}), - code(code_arg), - message(message_arg), - payloads(std::move(payloads_arg)) {} + code(code_arg), + message(message_arg), + payloads(std::move(payloads_arg)) {} std::atomic<int32_t> ref; y_absl::StatusCode code; diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/status/status.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/status/status.cc index 3b7fe28e08..68eeb69645 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/status/status.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/status/status.cc @@ -161,7 +161,7 @@ bool Status::ErasePayload(y_absl::string_view type_url) { } void Status::ForEachPayload( - y_absl::FunctionRef<void(y_absl::string_view, const y_absl::Cord&)> visitor) + y_absl::FunctionRef<void(y_absl::string_view, const y_absl::Cord&)> visitor) const { if (auto* payloads = GetPayloads()) { bool in_reverse = @@ -210,7 +210,7 @@ void Status::UnrefNonInlined(uintptr_t rep) { Status::Status(y_absl::StatusCode code, y_absl::string_view msg) : rep_(CodeToInlinedRep(code)) { if (code != y_absl::StatusCode::kOk && !msg.empty()) { - rep_ = PointerToRep(new status_internal::StatusRep(code, msg, nullptr)); + rep_ = PointerToRep(new status_internal::StatusRep(code, msg, nullptr)); } } @@ -229,9 +229,9 @@ y_absl::StatusCode Status::code() const { void Status::PrepareToModify() { ABSL_RAW_CHECK(!ok(), "PrepareToModify shouldn't be called on OK status."); if (IsInlined(rep_)) { - rep_ = PointerToRep(new status_internal::StatusRep( - static_cast<y_absl::StatusCode>(raw_code()), y_absl::string_view(), - nullptr)); + rep_ = PointerToRep(new status_internal::StatusRep( + static_cast<y_absl::StatusCode>(raw_code()), y_absl::string_view(), + nullptr)); return; } @@ -242,9 +242,9 @@ void Status::PrepareToModify() { if (rep->payloads) { payloads = y_absl::make_unique<status_internal::Payloads>(*rep->payloads); } - status_internal::StatusRep* const new_rep = new status_internal::StatusRep( - rep->code, message(), std::move(payloads)); - rep_ = PointerToRep(new_rep); + status_internal::StatusRep* const new_rep = new status_internal::StatusRep( + rep->code, message(), std::move(payloads)); + rep_ = PointerToRep(new_rep); UnrefNonInlined(rep_i); } } @@ -308,7 +308,7 @@ TString Status::ToStringSlow(StatusToStringMode mode) const { } std::ostream& operator<<(std::ostream& os, const Status& x) { - os << x.ToString(StatusToStringMode::kWithEverything); + os << x.ToString(StatusToStringMode::kWithEverything); return os; } diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/status/status.h b/contrib/restricted/abseil-cpp-tstring/y_absl/status/status.h index fa461e9f76..db12703600 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/status/status.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/status/status.h @@ -55,7 +55,7 @@ #include <util/generic/string.h> #include "y_absl/container/inlined_vector.h" -#include "y_absl/functional/function_ref.h" +#include "y_absl/functional/function_ref.h" #include "y_absl/status/internal/status_internal.h" #include "y_absl/strings/cord.h" #include "y_absl/strings/string_view.h" @@ -81,7 +81,7 @@ ABSL_NAMESPACE_BEGIN // `kFailedPrecondition` if both codes apply. Similarly prefer `kNotFound` or // `kAlreadyExists` over `kFailedPrecondition`. // -// Because these errors may cross RPC boundaries, these codes are tied to the +// Because these errors may cross RPC boundaries, these codes are tied to the // `google.rpc.Code` definitions within // https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto // The string value of these RPC codes is denoted within each enum below. @@ -115,10 +115,10 @@ enum class StatusCode : int { // StatusCode::kInvalidArgument // // kInvalidArgument (gRPC code "INVALID_ARGUMENT") indicates the caller - // specified an invalid argument, such as a malformed filename. Note that use - // of such errors should be narrowly limited to indicate the invalid nature of - // the arguments themselves. Errors with validly formed arguments that may - // cause errors with the state of the receiving system should be denoted with + // specified an invalid argument, such as a malformed filename. Note that use + // of such errors should be narrowly limited to indicate the invalid nature of + // the arguments themselves. Errors with validly formed arguments that may + // cause errors with the state of the receiving system should be denoted with // `kFailedPrecondition` instead. kInvalidArgument = 3, @@ -138,15 +138,15 @@ enum class StatusCode : int { // // `kNotFound` is useful if a request should be denied for an entire class of // users, such as during a gradual feature rollout or undocumented allow list. - // If a request should be denied for specific sets of users, such as through - // user-based access control, use `kPermissionDenied` instead. + // If a request should be denied for specific sets of users, such as through + // user-based access control, use `kPermissionDenied` instead. kNotFound = 5, // StatusCode::kAlreadyExists // - // kAlreadyExists (gRPC code "ALREADY_EXISTS") indicates that the entity a - // caller attempted to create (such as a file or directory) is already - // present. + // kAlreadyExists (gRPC code "ALREADY_EXISTS") indicates that the entity a + // caller attempted to create (such as a file or directory) is already + // present. kAlreadyExists = 6, // StatusCode::kPermissionDenied @@ -185,7 +185,7 @@ enum class StatusCode : int { // level (such as when a client-specified test-and-set fails, indicating // the client should restart a read-modify-write sequence). // (c) Use `kFailedPrecondition` if the client should not retry until - // the system state has been explicitly fixed. For example, if a "rmdir" + // the system state has been explicitly fixed. For example, if a "rmdir" // fails because the directory is non-empty, `kFailedPrecondition` // should be returned since the client should not retry unless // the files are deleted from the directory. @@ -285,7 +285,7 @@ std::ostream& operator<<(std::ostream& os, StatusCode code); // y_absl::StatusToStringMode // // An `y_absl::StatusToStringMode` is an enumerated type indicating how -// `y_absl::Status::ToString()` should construct the output string for a non-ok +// `y_absl::Status::ToString()` should construct the output string for a non-ok // status. enum class StatusToStringMode : int { // ToString will not contain any extra data (such as payloads). It will only @@ -295,8 +295,8 @@ enum class StatusToStringMode : int { kWithPayload = 1 << 0, // ToString will include all the extra data this Status has. kWithEverything = ~kWithNoExtraData, - // Default mode used by ToString. Its exact value might change in the future. - kDefault = kWithPayload, + // Default mode used by ToString. Its exact value might change in the future. + kDefault = kWithPayload, }; // y_absl::StatusToStringMode is specified as a bitmask type, which means the @@ -347,7 +347,7 @@ inline StatusToStringMode& operator^=(StatusToStringMode& lhs, // API developers should construct their functions to return `y_absl::OkStatus()` // upon success, or an `y_absl::StatusCode` upon another type of error (e.g // an `y_absl::StatusCode::kInvalidArgument` error). The API provides convenience -// functions to construct each status code. +// functions to construct each status code. // // Example: // @@ -495,7 +495,7 @@ class Status final { // Returns the error message associated with this error code, if available. // Note that this message rarely describes the error code. It is not unusual // for the error message to be the empty string. As a result, prefer - // `operator<<` or `Status::ToString()` for debug logging. + // `operator<<` or `Status::ToString()` for debug logging. y_absl::string_view message() const; friend bool operator==(const Status&, const Status&); @@ -513,7 +513,7 @@ class Status final { // result, and the payloads to be printed use the status payload printer // mechanism (which is internal). TString ToString( - StatusToStringMode mode = StatusToStringMode::kDefault) const; + StatusToStringMode mode = StatusToStringMode::kDefault) const; // Status::IgnoreError() // @@ -591,7 +591,7 @@ class Status final { // NOTE: Any mutation on the same 'y_absl::Status' object during visitation is // forbidden and could result in undefined behavior. void ForEachPayload( - y_absl::FunctionRef<void(y_absl::string_view, const y_absl::Cord&)> visitor) + y_absl::FunctionRef<void(y_absl::string_view, const y_absl::Cord&)> visitor) const; private: diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/status/statusor.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/status/statusor.cc index 03e6d1cec4..a40e65fa3f 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/status/statusor.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/status/statusor.cc @@ -16,7 +16,7 @@ #include <cstdlib> #include <utility> -#include "y_absl/base/call_once.h" +#include "y_absl/base/call_once.h" #include "y_absl/base/internal/raw_logging.h" #include "y_absl/status/status.h" #include "y_absl/strings/str_cat.h" @@ -27,44 +27,44 @@ ABSL_NAMESPACE_BEGIN BadStatusOrAccess::BadStatusOrAccess(y_absl::Status status) : status_(std::move(status)) {} -BadStatusOrAccess::BadStatusOrAccess(const BadStatusOrAccess& other) - : status_(other.status_) {} - -BadStatusOrAccess& BadStatusOrAccess::operator=( - const BadStatusOrAccess& other) { - // Ensure assignment is correct regardless of whether this->InitWhat() has - // already been called. - other.InitWhat(); - status_ = other.status_; - what_ = other.what_; - return *this; -} - -BadStatusOrAccess& BadStatusOrAccess::operator=(BadStatusOrAccess&& other) { - // Ensure assignment is correct regardless of whether this->InitWhat() has - // already been called. - other.InitWhat(); - status_ = std::move(other.status_); - what_ = std::move(other.what_); - return *this; -} - -BadStatusOrAccess::BadStatusOrAccess(BadStatusOrAccess&& other) - : status_(std::move(other.status_)) {} - +BadStatusOrAccess::BadStatusOrAccess(const BadStatusOrAccess& other) + : status_(other.status_) {} + +BadStatusOrAccess& BadStatusOrAccess::operator=( + const BadStatusOrAccess& other) { + // Ensure assignment is correct regardless of whether this->InitWhat() has + // already been called. + other.InitWhat(); + status_ = other.status_; + what_ = other.what_; + return *this; +} + +BadStatusOrAccess& BadStatusOrAccess::operator=(BadStatusOrAccess&& other) { + // Ensure assignment is correct regardless of whether this->InitWhat() has + // already been called. + other.InitWhat(); + status_ = std::move(other.status_); + what_ = std::move(other.what_); + return *this; +} + +BadStatusOrAccess::BadStatusOrAccess(BadStatusOrAccess&& other) + : status_(std::move(other.status_)) {} + const char* BadStatusOrAccess::what() const noexcept { - InitWhat(); - return what_.c_str(); + InitWhat(); + return what_.c_str(); } const y_absl::Status& BadStatusOrAccess::status() const { return status_; } -void BadStatusOrAccess::InitWhat() const { - y_absl::call_once(init_what_, [this] { - what_ = y_absl::StrCat("Bad StatusOr access: ", status_.ToString()); - }); -} - +void BadStatusOrAccess::InitWhat() const { + y_absl::call_once(init_what_, [this] { + what_ = y_absl::StrCat("Bad StatusOr access: ", status_.ToString()); + }); +} + namespace internal_statusor { void Helper::HandleInvalidStatusCtorArg(y_absl::Status* status) { diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/status/statusor.h b/contrib/restricted/abseil-cpp-tstring/y_absl/status/statusor.h index 23e1b8a6e4..90f5f83700 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/status/statusor.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/status/statusor.h @@ -44,7 +44,7 @@ #include <utility> #include "y_absl/base/attributes.h" -#include "y_absl/base/call_once.h" +#include "y_absl/base/call_once.h" #include "y_absl/meta/type_traits.h" #include "y_absl/status/internal/statusor_internal.h" #include "y_absl/status/status.h" @@ -73,18 +73,18 @@ ABSL_NAMESPACE_BEGIN class BadStatusOrAccess : public std::exception { public: explicit BadStatusOrAccess(y_absl::Status status); - ~BadStatusOrAccess() override = default; - - BadStatusOrAccess(const BadStatusOrAccess& other); - BadStatusOrAccess& operator=(const BadStatusOrAccess& other); - BadStatusOrAccess(BadStatusOrAccess&& other); - BadStatusOrAccess& operator=(BadStatusOrAccess&& other); + ~BadStatusOrAccess() override = default; + BadStatusOrAccess(const BadStatusOrAccess& other); + BadStatusOrAccess& operator=(const BadStatusOrAccess& other); + BadStatusOrAccess(BadStatusOrAccess&& other); + BadStatusOrAccess& operator=(BadStatusOrAccess&& other); + // BadStatusOrAccess::what() // // Returns the associated explanatory string of the `y_absl::StatusOr<T>` - // object's error code. This function contains information about the failing - // status, but its exact formatting may change and should not be depended on. + // object's error code. This function contains information about the failing + // status, but its exact formatting may change and should not be depended on. // // The pointer of this string is guaranteed to be valid until any non-const // function is invoked on the exception object. @@ -97,11 +97,11 @@ class BadStatusOrAccess : public std::exception { const y_absl::Status& status() const; private: - void InitWhat() const; - + void InitWhat() const; + y_absl::Status status_; - mutable y_absl::once_flag init_what_; - mutable TString what_; + mutable y_absl::once_flag init_what_; + mutable TString what_; }; // Returned StatusOr objects may not be ignored. @@ -429,8 +429,8 @@ class StatusOr : private internal_statusor::StatusOrData<T>, // if `T` can be constructed from a `U`. Can accept move or copy constructors. // // This constructor is explicit if `U` is not convertible to `T`. To avoid - // ambiguity, this constructor is disabled if `U` is a `StatusOr<J>`, where - // `J` is convertible to `T`. + // ambiguity, this constructor is disabled if `U` is a `StatusOr<J>`, where + // `J` is convertible to `T`. template < typename U = T, y_absl::enable_if_t< @@ -447,7 +447,7 @@ class StatusOr : private internal_statusor::StatusOrData<T>, T, U&&>>>>>::value, int> = 0> StatusOr(U&& u) // NOLINT - : StatusOr(y_absl::in_place, std::forward<U>(u)) {} + : StatusOr(y_absl::in_place, std::forward<U>(u)) {} template < typename U = T, @@ -466,7 +466,7 @@ class StatusOr : private internal_statusor::StatusOrData<T>, y_absl::negation<std::is_convertible<U&&, T>>>::value, int> = 0> explicit StatusOr(U&& u) // NOLINT - : StatusOr(y_absl::in_place, std::forward<U>(u)) {} + : StatusOr(y_absl::in_place, std::forward<U>(u)) {} // StatusOr<T>::ok() // @@ -489,7 +489,7 @@ class StatusOr : private internal_statusor::StatusOrData<T>, // Returns a reference to the current `y_absl::Status` contained within the // `y_absl::StatusOr<T>`. If `y_absl::StatusOr<T>` contains a `T`, then this // function returns `y_absl::OkStatus()`. - const Status& status() const&; + const Status& status() const&; Status status() &&; // StatusOr<T>::value() @@ -518,10 +518,10 @@ class StatusOr : private internal_statusor::StatusOrData<T>, // // The `std::move` on statusor instead of on the whole expression enables // warnings about possible uses of the statusor object after the move. - const T& value() const& ABSL_ATTRIBUTE_LIFETIME_BOUND; - T& value() & ABSL_ATTRIBUTE_LIFETIME_BOUND; - const T&& value() const&& ABSL_ATTRIBUTE_LIFETIME_BOUND; - T&& value() && ABSL_ATTRIBUTE_LIFETIME_BOUND; + const T& value() const& ABSL_ATTRIBUTE_LIFETIME_BOUND; + T& value() & ABSL_ATTRIBUTE_LIFETIME_BOUND; + const T&& value() const&& ABSL_ATTRIBUTE_LIFETIME_BOUND; + T&& value() && ABSL_ATTRIBUTE_LIFETIME_BOUND; // StatusOr<T>:: operator*() // @@ -533,10 +533,10 @@ class StatusOr : private internal_statusor::StatusOrData<T>, // `y_absl::StatusOr<T>`. Alternatively, see the `value()` member function for a // similar API that guarantees crashing or throwing an exception if there is // no current value. - const T& operator*() const& ABSL_ATTRIBUTE_LIFETIME_BOUND; - T& operator*() & ABSL_ATTRIBUTE_LIFETIME_BOUND; - const T&& operator*() const&& ABSL_ATTRIBUTE_LIFETIME_BOUND; - T&& operator*() && ABSL_ATTRIBUTE_LIFETIME_BOUND; + const T& operator*() const& ABSL_ATTRIBUTE_LIFETIME_BOUND; + T& operator*() & ABSL_ATTRIBUTE_LIFETIME_BOUND; + const T&& operator*() const&& ABSL_ATTRIBUTE_LIFETIME_BOUND; + T&& operator*() && ABSL_ATTRIBUTE_LIFETIME_BOUND; // StatusOr<T>::operator->() // @@ -545,8 +545,8 @@ class StatusOr : private internal_statusor::StatusOrData<T>, // REQUIRES: `this->ok() == true`, otherwise the behavior is undefined. // // Use `this->ok()` to verify that there is a current value. - const T* operator->() const ABSL_ATTRIBUTE_LIFETIME_BOUND; - T* operator->() ABSL_ATTRIBUTE_LIFETIME_BOUND; + const T* operator->() const ABSL_ATTRIBUTE_LIFETIME_BOUND; + T* operator->() ABSL_ATTRIBUTE_LIFETIME_BOUND; // StatusOr<T>::value_or() // @@ -669,9 +669,9 @@ StatusOr<T>::StatusOr(y_absl::in_place_t, std::initializer_list<U> ilist, : Base(y_absl::in_place, ilist, std::forward<Args>(args)...) {} template <typename T> -const Status& StatusOr<T>::status() const& { - return this->status_; -} +const Status& StatusOr<T>::status() const& { + return this->status_; +} template <typename T> Status StatusOr<T>::status() && { return ok() ? OkStatus() : std::move(this->status_); diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/status/statusor/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/status/statusor/ya.make index a29c7ae5b3..1155fc0de9 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/status/statusor/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/status/statusor/ya.make @@ -13,33 +13,33 @@ LICENSE(Apache-2.0) PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/base - contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/low_level_alloc contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/raw_logging contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/throw_delegate contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity - contrib/restricted/abseil-cpp-tstring/y_absl/debugging - contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace - contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize - contrib/restricted/abseil-cpp-tstring/y_absl/demangle + contrib/restricted/abseil-cpp-tstring/y_absl/debugging + contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace + contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize + contrib/restricted/abseil-cpp-tstring/y_absl/demangle contrib/restricted/abseil-cpp-tstring/y_absl/numeric - contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased - contrib/restricted/abseil-cpp-tstring/y_absl/status + contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp-tstring/y_absl/status contrib/restricted/abseil-cpp-tstring/y_absl/strings - contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_cord_internal - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format - contrib/restricted/abseil-cpp-tstring/y_absl/synchronization - contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal - contrib/restricted/abseil-cpp-tstring/y_absl/time - contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time - contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone + contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_cord_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format + contrib/restricted/abseil-cpp-tstring/y_absl/synchronization + contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal + contrib/restricted/abseil-cpp-tstring/y_absl/time + contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time + contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_optional_access - contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_variant_access + contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_variant_access ) ADDINCL( @@ -48,10 +48,10 @@ ADDINCL( NO_COMPILER_WARNINGS() -SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/status) +SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/status) SRCS( - statusor.cc + statusor.cc ) END() diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/status/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/status/ya.make index 9414dfc26b..d9718ddb9b 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/status/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/status/ya.make @@ -23,20 +23,20 @@ PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize contrib/restricted/abseil-cpp-tstring/y_absl/demangle contrib/restricted/abseil-cpp-tstring/y_absl/numeric - contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased contrib/restricted/abseil-cpp-tstring/y_absl/strings - contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_cord_internal - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info + contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_cord_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format - contrib/restricted/abseil-cpp-tstring/y_absl/synchronization - contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal - contrib/restricted/abseil-cpp-tstring/y_absl/time - contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time - contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone + contrib/restricted/abseil-cpp-tstring/y_absl/synchronization + contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal + contrib/restricted/abseil-cpp-tstring/y_absl/time + contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time + contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_optional_access ) diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/.yandex_meta/licenses.list.txt b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/.yandex_meta/licenses.list.txt index 9d8552c68c..dd78f940d1 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/.yandex_meta/licenses.list.txt +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/.yandex_meta/licenses.list.txt @@ -35,10 +35,10 @@ ====================COPYRIGHT==================== -// Copyright 2019 The Abseil Authors. - - -====================COPYRIGHT==================== +// Copyright 2019 The Abseil Authors. + + +====================COPYRIGHT==================== // Copyright 2020 The Abseil Authors. diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/charconv.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/charconv.cc index 9515ca24dd..d876d82b79 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/charconv.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/charconv.cc @@ -111,7 +111,7 @@ struct FloatTraits<double> { return sign ? -ldexp(mantissa, exponent) : ldexp(mantissa, exponent); #else constexpr uint64_t kMantissaMask = - (uint64_t{1} << (kTargetMantissaBits - 1)) - 1; + (uint64_t{1} << (kTargetMantissaBits - 1)) - 1; uint64_t dbl = static_cast<uint64_t>(sign) << 63; if (mantissa > kMantissaMask) { // Normal value. @@ -151,7 +151,7 @@ struct FloatTraits<float> { return sign ? -ldexpf(mantissa, exponent) : ldexpf(mantissa, exponent); #else constexpr uint32_t kMantissaMask = - (uint32_t{1} << (kTargetMantissaBits - 1)) - 1; + (uint32_t{1} << (kTargetMantissaBits - 1)) - 1; uint32_t flt = static_cast<uint32_t>(sign) << 31; if (mantissa > kMantissaMask) { // Normal value. @@ -499,7 +499,7 @@ bool MustRoundUp(uint64_t guess_mantissa, int guess_exponent, template <typename FloatType> CalculatedFloat CalculatedFloatFromRawValues(uint64_t mantissa, int exponent) { CalculatedFloat result; - if (mantissa == uint64_t{1} << FloatTraits<FloatType>::kTargetMantissaBits) { + if (mantissa == uint64_t{1} << FloatTraits<FloatType>::kTargetMantissaBits) { mantissa >>= 1; exponent += 1; } diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/charconv.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/charconv.h index 1a115aa251..c989bd1299 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/charconv.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/charconv.h @@ -64,9 +64,9 @@ struct from_chars_result { // the result in `value`. // // The matching pattern format is almost the same as that of strtod(), except -// that (1) C locale is not respected, (2) an initial '+' character in the -// input range will never be matched, and (3) leading whitespaces are not -// ignored. +// that (1) C locale is not respected, (2) an initial '+' character in the +// input range will never be matched, and (3) leading whitespaces are not +// ignored. // // If `fmt` is set, it must be one of the enumerator values of the chars_format. // (This is despite the fact that chars_format is a bitmask type.) If set to diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord.cc index 0de4ea1b3c..65411ff5ec 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord.cc @@ -36,11 +36,11 @@ #include "y_absl/container/inlined_vector.h" #include "y_absl/strings/escaping.h" #include "y_absl/strings/internal/cord_internal.h" -#include "y_absl/strings/internal/cord_rep_btree.h" +#include "y_absl/strings/internal/cord_rep_btree.h" #include "y_absl/strings/internal/cord_rep_flat.h" -#include "y_absl/strings/internal/cordz_statistics.h" -#include "y_absl/strings/internal/cordz_update_scope.h" -#include "y_absl/strings/internal/cordz_update_tracker.h" +#include "y_absl/strings/internal/cordz_statistics.h" +#include "y_absl/strings/internal/cordz_update_scope.h" +#include "y_absl/strings/internal/cordz_update_tracker.h" #include "y_absl/strings/internal/resize_uninitialized.h" #include "y_absl/strings/str_cat.h" #include "y_absl/strings/str_format.h" @@ -51,14 +51,14 @@ namespace y_absl { ABSL_NAMESPACE_BEGIN using ::y_absl::cord_internal::CordRep; -using ::y_absl::cord_internal::CordRepBtree; +using ::y_absl::cord_internal::CordRepBtree; using ::y_absl::cord_internal::CordRepConcat; using ::y_absl::cord_internal::CordRepExternal; using ::y_absl::cord_internal::CordRepFlat; using ::y_absl::cord_internal::CordRepSubstring; -using ::y_absl::cord_internal::CordzUpdateTracker; -using ::y_absl::cord_internal::InlineData; -using ::y_absl::cord_internal::kMaxFlatLength; +using ::y_absl::cord_internal::CordzUpdateTracker; +using ::y_absl::cord_internal::InlineData; +using ::y_absl::cord_internal::kMaxFlatLength; using ::y_absl::cord_internal::kMinFlatLength; using ::y_absl::cord_internal::kInlinedVectorSize; @@ -94,13 +94,13 @@ static constexpr uint64_t min_length[] = { static const int kMinLengthSize = ABSL_ARRAYSIZE(min_length); -static inline bool btree_enabled() { - return cord_internal::cord_btree_enabled.load( +static inline bool btree_enabled() { + return cord_internal::cord_btree_enabled.load( std::memory_order_relaxed); } static inline bool IsRootBalanced(CordRep* node) { - if (!node->IsConcat()) { + if (!node->IsConcat()) { return true; } else if (node->concat()->depth() <= 15) { return true; @@ -137,7 +137,7 @@ static inline CordRep* VerifyTree(CordRep* node) { // Return the depth of a node static int Depth(const CordRep* rep) { - if (rep->IsConcat()) { + if (rep->IsConcat()) { return rep->concat()->depth(); } else { return 0; @@ -170,7 +170,7 @@ static CordRep* RawConcat(CordRep* left, CordRep* right) { } CordRepConcat* rep = new CordRepConcat(); - rep->tag = cord_internal::CONCAT; + rep->tag = cord_internal::CONCAT; SetConcatChildren(rep, left, right); return rep; @@ -205,32 +205,32 @@ static CordRep* MakeBalancedTree(CordRep** reps, size_t n) { } static CordRepFlat* CreateFlat(const char* data, size_t length, - size_t alloc_hint) { + size_t alloc_hint) { CordRepFlat* flat = CordRepFlat::New(length + alloc_hint); flat->length = length; memcpy(flat->Data(), data, length); return flat; } -// Creates a new flat or Btree out of the specified array. +// Creates a new flat or Btree out of the specified array. // The returned node has a refcount of 1. -static CordRep* NewBtree(const char* data, size_t length, size_t alloc_hint) { +static CordRep* NewBtree(const char* data, size_t length, size_t alloc_hint) { if (length <= kMaxFlatLength) { return CreateFlat(data, length, alloc_hint); } CordRepFlat* flat = CreateFlat(data, kMaxFlatLength, 0); data += kMaxFlatLength; length -= kMaxFlatLength; - auto* root = CordRepBtree::Create(flat); - return CordRepBtree::Append(root, {data, length}, alloc_hint); + auto* root = CordRepBtree::Create(flat); + return CordRepBtree::Append(root, {data, length}, alloc_hint); } // Create a new tree out of the specified array. // The returned node has a refcount of 1. -static CordRep* NewTree(const char* data, size_t length, size_t alloc_hint) { +static CordRep* NewTree(const char* data, size_t length, size_t alloc_hint) { if (length == 0) return nullptr; - if (btree_enabled()) { - return NewBtree(data, length, alloc_hint); + if (btree_enabled()) { + return NewBtree(data, length, alloc_hint); } y_absl::FixedArray<CordRep*> reps((length - 1) / kMaxFlatLength + 1); size_t n = 0; @@ -267,42 +267,42 @@ static CordRep* NewSubstring(CordRep* child, size_t offset, size_t length) { CordRepSubstring* rep = new CordRepSubstring(); assert((offset + length) <= child->length); rep->length = length; - rep->tag = cord_internal::SUBSTRING; + rep->tag = cord_internal::SUBSTRING; rep->start = offset; rep->child = child; return VerifyTree(rep); } } -// Creates a CordRep from the provided string. If the string is large enough, -// and not wasteful, we move the string into an external cord rep, preserving -// the already allocated string contents. -// Requires the provided string length to be larger than `kMaxInline`. -static CordRep* CordRepFromString(TString&& src) { - assert(src.length() > cord_internal::kMaxInline); - if ( - // String is short: copy data to avoid external block overhead. - src.size() <= kMaxBytesToCopy || - // String is wasteful: copy data to avoid pinning too much unused memory. - src.size() < src.capacity() / 2 - ) { - return NewTree(src.data(), src.size(), 0); - } - - struct StringReleaser { - void operator()(y_absl::string_view /* data */) {} - TString data; - }; - const y_absl::string_view original_data = src; - auto* rep = - static_cast<::y_absl::cord_internal::CordRepExternalImpl<StringReleaser>*>( - y_absl::cord_internal::NewExternalRep(original_data, - StringReleaser{std::move(src)})); - // Moving src may have invalidated its data pointer, so adjust it. - rep->base = rep->template get<0>().data.data(); - return rep; -} - +// Creates a CordRep from the provided string. If the string is large enough, +// and not wasteful, we move the string into an external cord rep, preserving +// the already allocated string contents. +// Requires the provided string length to be larger than `kMaxInline`. +static CordRep* CordRepFromString(TString&& src) { + assert(src.length() > cord_internal::kMaxInline); + if ( + // String is short: copy data to avoid external block overhead. + src.size() <= kMaxBytesToCopy || + // String is wasteful: copy data to avoid pinning too much unused memory. + src.size() < src.capacity() / 2 + ) { + return NewTree(src.data(), src.size(), 0); + } + + struct StringReleaser { + void operator()(y_absl::string_view /* data */) {} + TString data; + }; + const y_absl::string_view original_data = src; + auto* rep = + static_cast<::y_absl::cord_internal::CordRepExternalImpl<StringReleaser>*>( + y_absl::cord_internal::NewExternalRep(original_data, + StringReleaser{std::move(src)})); + // Moving src may have invalidated its data pointer, so adjust it. + rep->base = rep->template get<0>().data.data(); + return rep; +} + // -------------------------------------------------------------------- // Cord::InlineRep functions @@ -338,78 +338,78 @@ inline void Cord::InlineRep::remove_prefix(size_t n) { reduce_size(n); } -// Returns `rep` converted into a CordRepBtree. -// Directly returns `rep` if `rep` is already a CordRepBtree. -static CordRepBtree* ForceBtree(CordRep* rep) { - return rep->IsBtree() ? rep->btree() : CordRepBtree::Create(rep); -} - -void Cord::InlineRep::AppendTreeToInlined(CordRep* tree, - MethodIdentifier method) { - assert(!is_tree()); - if (!data_.is_empty()) { - CordRepFlat* flat = MakeFlatWithExtraCapacity(0); - if (btree_enabled()) { - tree = CordRepBtree::Append(CordRepBtree::Create(flat), tree); - } else { - tree = Concat(flat, tree); - } - } - EmplaceTree(tree, method); -} - -void Cord::InlineRep::AppendTreeToTree(CordRep* tree, MethodIdentifier method) { - assert(is_tree()); - const CordzUpdateScope scope(data_.cordz_info(), method); - if (btree_enabled()) { - tree = CordRepBtree::Append(ForceBtree(data_.as_tree()), tree); - } else { - tree = Concat(data_.as_tree(), tree); - } - SetTree(tree, scope); -} - -void Cord::InlineRep::AppendTree(CordRep* tree, MethodIdentifier method) { +// Returns `rep` converted into a CordRepBtree. +// Directly returns `rep` if `rep` is already a CordRepBtree. +static CordRepBtree* ForceBtree(CordRep* rep) { + return rep->IsBtree() ? rep->btree() : CordRepBtree::Create(rep); +} + +void Cord::InlineRep::AppendTreeToInlined(CordRep* tree, + MethodIdentifier method) { + assert(!is_tree()); + if (!data_.is_empty()) { + CordRepFlat* flat = MakeFlatWithExtraCapacity(0); + if (btree_enabled()) { + tree = CordRepBtree::Append(CordRepBtree::Create(flat), tree); + } else { + tree = Concat(flat, tree); + } + } + EmplaceTree(tree, method); +} + +void Cord::InlineRep::AppendTreeToTree(CordRep* tree, MethodIdentifier method) { + assert(is_tree()); + const CordzUpdateScope scope(data_.cordz_info(), method); + if (btree_enabled()) { + tree = CordRepBtree::Append(ForceBtree(data_.as_tree()), tree); + } else { + tree = Concat(data_.as_tree(), tree); + } + SetTree(tree, scope); +} + +void Cord::InlineRep::AppendTree(CordRep* tree, MethodIdentifier method) { if (tree == nullptr) return; - if (data_.is_tree()) { - AppendTreeToTree(tree, method); - } else { - AppendTreeToInlined(tree, method); - } -} - -void Cord::InlineRep::PrependTreeToInlined(CordRep* tree, - MethodIdentifier method) { - assert(!is_tree()); - if (!data_.is_empty()) { - CordRepFlat* flat = MakeFlatWithExtraCapacity(0); - if (btree_enabled()) { - tree = CordRepBtree::Prepend(CordRepBtree::Create(flat), tree); - } else { - tree = Concat(tree, flat); - } - } - EmplaceTree(tree, method); -} - -void Cord::InlineRep::PrependTreeToTree(CordRep* tree, - MethodIdentifier method) { - assert(is_tree()); - const CordzUpdateScope scope(data_.cordz_info(), method); - if (btree_enabled()) { - tree = CordRepBtree::Prepend(ForceBtree(data_.as_tree()), tree); + if (data_.is_tree()) { + AppendTreeToTree(tree, method); } else { - tree = Concat(tree, data_.as_tree()); - } - SetTree(tree, scope); -} - -void Cord::InlineRep::PrependTree(CordRep* tree, MethodIdentifier method) { + AppendTreeToInlined(tree, method); + } +} + +void Cord::InlineRep::PrependTreeToInlined(CordRep* tree, + MethodIdentifier method) { + assert(!is_tree()); + if (!data_.is_empty()) { + CordRepFlat* flat = MakeFlatWithExtraCapacity(0); + if (btree_enabled()) { + tree = CordRepBtree::Prepend(CordRepBtree::Create(flat), tree); + } else { + tree = Concat(tree, flat); + } + } + EmplaceTree(tree, method); +} + +void Cord::InlineRep::PrependTreeToTree(CordRep* tree, + MethodIdentifier method) { + assert(is_tree()); + const CordzUpdateScope scope(data_.cordz_info(), method); + if (btree_enabled()) { + tree = CordRepBtree::Prepend(ForceBtree(data_.as_tree()), tree); + } else { + tree = Concat(tree, data_.as_tree()); + } + SetTree(tree, scope); +} + +void Cord::InlineRep::PrependTree(CordRep* tree, MethodIdentifier method) { assert(tree != nullptr); - if (data_.is_tree()) { - PrependTreeToTree(tree, method); + if (data_.is_tree()) { + PrependTreeToTree(tree, method); } else { - PrependTreeToInlined(tree, method); + PrependTreeToInlined(tree, method); } } @@ -419,8 +419,8 @@ void Cord::InlineRep::PrependTree(CordRep* tree, MethodIdentifier method) { // written to region and the actual size increase will be written to size. static inline bool PrepareAppendRegion(CordRep* root, char** region, size_t* size, size_t max_length) { - if (root->IsBtree() && root->refcount.IsMutable()) { - Span<char> span = root->btree()->GetAppendBuffer(max_length); + if (root->IsBtree() && root->refcount.IsMutable()) { + Span<char> span = root->btree()->GetAppendBuffer(max_length); if (!span.empty()) { *region = span.data(); *size = span.size(); @@ -430,11 +430,11 @@ static inline bool PrepareAppendRegion(CordRep* root, char** region, // Search down the right-hand path for a non-full FLAT node. CordRep* dst = root; - while (dst->IsConcat() && dst->refcount.IsMutable()) { + while (dst->IsConcat() && dst->refcount.IsMutable()) { dst = dst->concat()->right; } - if (!dst->IsFlat() || !dst->refcount.IsMutable()) { + if (!dst->IsFlat() || !dst->refcount.IsMutable()) { *region = nullptr; *size = 0; return false; @@ -461,115 +461,115 @@ static inline bool PrepareAppendRegion(CordRep* root, char** region, return true; } -template <bool has_length> +template <bool has_length> void Cord::InlineRep::GetAppendRegion(char** region, size_t* size, - size_t length) { - auto constexpr method = CordzUpdateTracker::kGetAppendRegion; - - CordRep* root = tree(); - size_t sz = root ? root->length : inline_size(); - if (root == nullptr) { - size_t available = kMaxInline - sz; - if (available >= (has_length ? length : 1)) { - *region = data_.as_chars() + sz; - *size = has_length ? length : available; - set_inline_size(has_length ? sz + length : kMaxInline); + size_t length) { + auto constexpr method = CordzUpdateTracker::kGetAppendRegion; + + CordRep* root = tree(); + size_t sz = root ? root->length : inline_size(); + if (root == nullptr) { + size_t available = kMaxInline - sz; + if (available >= (has_length ? length : 1)) { + *region = data_.as_chars() + sz; + *size = has_length ? length : available; + set_inline_size(has_length ? sz + length : kMaxInline); return; } } - size_t extra = has_length ? length : (std::max)(sz, kMinFlatLength); - CordRep* rep = root ? root : MakeFlatWithExtraCapacity(extra); - CordzUpdateScope scope(root ? data_.cordz_info() : nullptr, method); - if (PrepareAppendRegion(rep, region, size, length)) { - CommitTree(root, rep, scope, method); + size_t extra = has_length ? length : (std::max)(sz, kMinFlatLength); + CordRep* rep = root ? root : MakeFlatWithExtraCapacity(extra); + CordzUpdateScope scope(root ? data_.cordz_info() : nullptr, method); + if (PrepareAppendRegion(rep, region, size, length)) { + CommitTree(root, rep, scope, method); return; } // Allocate new node. - CordRepFlat* new_node = CordRepFlat::New(extra); - new_node->length = std::min(new_node->Capacity(), length); + CordRepFlat* new_node = CordRepFlat::New(extra); + new_node->length = std::min(new_node->Capacity(), length); *region = new_node->Data(); *size = new_node->length; - if (btree_enabled()) { - rep = CordRepBtree::Append(ForceBtree(rep), new_node); - } else { - rep = Concat(rep, new_node); + if (btree_enabled()) { + rep = CordRepBtree::Append(ForceBtree(rep), new_node); + } else { + rep = Concat(rep, new_node); } - CommitTree(root, rep, scope, method); + CommitTree(root, rep, scope, method); } -// Computes the memory side of the provided edge which must be a valid data edge -// for a btrtee, i.e., a FLAT, EXTERNAL or SUBSTRING of a FLAT or EXTERNAL node. -static bool RepMemoryUsageDataEdge(const CordRep* rep, - size_t* total_mem_usage) { - size_t maybe_sub_size = 0; - if (ABSL_PREDICT_FALSE(rep->IsSubstring())) { - maybe_sub_size = sizeof(cord_internal::CordRepSubstring); - rep = rep->substring()->child; +// Computes the memory side of the provided edge which must be a valid data edge +// for a btrtee, i.e., a FLAT, EXTERNAL or SUBSTRING of a FLAT or EXTERNAL node. +static bool RepMemoryUsageDataEdge(const CordRep* rep, + size_t* total_mem_usage) { + size_t maybe_sub_size = 0; + if (ABSL_PREDICT_FALSE(rep->IsSubstring())) { + maybe_sub_size = sizeof(cord_internal::CordRepSubstring); + rep = rep->substring()->child; } - if (rep->IsFlat()) { - *total_mem_usage += maybe_sub_size + rep->flat()->AllocatedSize(); - return true; + if (rep->IsFlat()) { + *total_mem_usage += maybe_sub_size + rep->flat()->AllocatedSize(); + return true; } - if (rep->IsExternal()) { - // We don't know anything about the embedded / bound data, but we can safely - // assume it is 'at least' a word / pointer to data. In the future we may - // choose to use the 'data' byte as a tag to identify the types of some - // well-known externals, such as a TString instance. - *total_mem_usage += maybe_sub_size + - sizeof(cord_internal::CordRepExternalImpl<intptr_t>) + - rep->length; - return true; + if (rep->IsExternal()) { + // We don't know anything about the embedded / bound data, but we can safely + // assume it is 'at least' a word / pointer to data. In the future we may + // choose to use the 'data' byte as a tag to identify the types of some + // well-known externals, such as a TString instance. + *total_mem_usage += maybe_sub_size + + sizeof(cord_internal::CordRepExternalImpl<intptr_t>) + + rep->length; + return true; } - return false; + return false; } // If the rep is a leaf, this will increment the value at total_mem_usage and // will return true. static bool RepMemoryUsageLeaf(const CordRep* rep, size_t* total_mem_usage) { - if (rep->IsFlat()) { + if (rep->IsFlat()) { *total_mem_usage += rep->flat()->AllocatedSize(); return true; } - if (rep->IsExternal()) { - // We don't know anything about the embedded / bound data, but we can safely - // assume it is 'at least' a word / pointer to data. In the future we may - // choose to use the 'data' byte as a tag to identify the types of some - // well-known externals, such as a TString instance. - *total_mem_usage += - sizeof(cord_internal::CordRepExternalImpl<intptr_t>) + rep->length; + if (rep->IsExternal()) { + // We don't know anything about the embedded / bound data, but we can safely + // assume it is 'at least' a word / pointer to data. In the future we may + // choose to use the 'data' byte as a tag to identify the types of some + // well-known externals, such as a TString instance. + *total_mem_usage += + sizeof(cord_internal::CordRepExternalImpl<intptr_t>) + rep->length; return true; } return false; } void Cord::InlineRep::AssignSlow(const Cord::InlineRep& src) { - assert(&src != this); - assert(is_tree() || src.is_tree()); - auto constexpr method = CordzUpdateTracker::kAssignCord; - if (ABSL_PREDICT_TRUE(!is_tree())) { - EmplaceTree(CordRep::Ref(src.as_tree()), src.data_, method); - return; - } - - CordRep* tree = as_tree(); - if (CordRep* src_tree = src.tree()) { - // Leave any existing `cordz_info` in place, and let MaybeTrackCord() - // decide if this cord should be (or remains to be) sampled or not. - data_.set_tree(CordRep::Ref(src_tree)); - CordzInfo::MaybeTrackCord(data_, src.data_, method); - } else { - CordzInfo::MaybeUntrackCord(data_.cordz_info()); - data_ = src.data_; - } - CordRep::Unref(tree); -} - -void Cord::InlineRep::UnrefTree() { + assert(&src != this); + assert(is_tree() || src.is_tree()); + auto constexpr method = CordzUpdateTracker::kAssignCord; + if (ABSL_PREDICT_TRUE(!is_tree())) { + EmplaceTree(CordRep::Ref(src.as_tree()), src.data_, method); + return; + } + + CordRep* tree = as_tree(); + if (CordRep* src_tree = src.tree()) { + // Leave any existing `cordz_info` in place, and let MaybeTrackCord() + // decide if this cord should be (or remains to be) sampled or not. + data_.set_tree(CordRep::Ref(src_tree)); + CordzInfo::MaybeTrackCord(data_, src.data_, method); + } else { + CordzInfo::MaybeUntrackCord(data_.cordz_info()); + data_ = src.data_; + } + CordRep::Unref(tree); +} + +void Cord::InlineRep::UnrefTree() { if (is_tree()) { - CordzInfo::MaybeUntrackCord(data_.cordz_info()); + CordzInfo::MaybeUntrackCord(data_.cordz_info()); CordRep::Unref(tree()); } } @@ -577,24 +577,24 @@ void Cord::InlineRep::UnrefTree() { // -------------------------------------------------------------------- // Constructors and destructors -Cord::Cord(y_absl::string_view src, MethodIdentifier method) - : contents_(InlineData::kDefaultInit) { +Cord::Cord(y_absl::string_view src, MethodIdentifier method) + : contents_(InlineData::kDefaultInit) { const size_t n = src.size(); if (n <= InlineRep::kMaxInline) { - contents_.set_data(src.data(), n, true); + contents_.set_data(src.data(), n, true); } else { - CordRep* rep = NewTree(src.data(), n, 0); - contents_.EmplaceTree(rep, method); + CordRep* rep = NewTree(src.data(), n, 0); + contents_.EmplaceTree(rep, method); } } template <typename T, Cord::EnableIfString<T>> -Cord::Cord(T&& src) : contents_(InlineData::kDefaultInit) { - if (src.size() <= InlineRep::kMaxInline) { - contents_.set_data(src.data(), src.size(), true); +Cord::Cord(T&& src) : contents_(InlineData::kDefaultInit) { + if (src.size() <= InlineRep::kMaxInline) { + contents_.set_data(src.data(), src.size(), true); } else { - CordRep* rep = CordRepFromString(std::forward<T>(src)); - contents_.EmplaceTree(rep, CordzUpdateTracker::kConstructorString); + CordRep* rep = CordRepFromString(std::forward<T>(src)); + contents_.EmplaceTree(rep, CordzUpdateTracker::kConstructorString); } } @@ -603,9 +603,9 @@ template Cord::Cord(TString&& src); // The destruction code is separate so that the compiler can determine // that it does not need to call the destructor on a moved-from Cord. void Cord::DestroyCordSlow() { - assert(contents_.is_tree()); - CordzInfo::MaybeUntrackCord(contents_.cordz_info()); - CordRep::Unref(VerifyTree(contents_.as_tree())); + assert(contents_.is_tree()); + CordzInfo::MaybeUntrackCord(contents_.cordz_info()); + CordRep::Unref(VerifyTree(contents_.as_tree())); } // -------------------------------------------------------------------- @@ -617,116 +617,116 @@ void Cord::Clear() { } } -Cord& Cord::AssignLargeString(TString&& src) { - auto constexpr method = CordzUpdateTracker::kAssignString; - assert(src.size() > kMaxBytesToCopy); - CordRep* rep = CordRepFromString(std::move(src)); - if (CordRep* tree = contents_.tree()) { - CordzUpdateScope scope(contents_.cordz_info(), method); - contents_.SetTree(rep, scope); - CordRep::Unref(tree); - } else { - contents_.EmplaceTree(rep, method); - } - return *this; -} - +Cord& Cord::AssignLargeString(TString&& src) { + auto constexpr method = CordzUpdateTracker::kAssignString; + assert(src.size() > kMaxBytesToCopy); + CordRep* rep = CordRepFromString(std::move(src)); + if (CordRep* tree = contents_.tree()) { + CordzUpdateScope scope(contents_.cordz_info(), method); + contents_.SetTree(rep, scope); + CordRep::Unref(tree); + } else { + contents_.EmplaceTree(rep, method); + } + return *this; +} + Cord& Cord::operator=(y_absl::string_view src) { - auto constexpr method = CordzUpdateTracker::kAssignString; + auto constexpr method = CordzUpdateTracker::kAssignString; const char* data = src.data(); size_t length = src.size(); CordRep* tree = contents_.tree(); if (length <= InlineRep::kMaxInline) { - // Embed into this->contents_, which is somewhat subtle: - // - MaybeUntrackCord must be called before Unref(tree). - // - MaybeUntrackCord must be called before set_data() clobbers cordz_info. - // - set_data() must be called before Unref(tree) as it may reference tree. - if (tree != nullptr) CordzInfo::MaybeUntrackCord(contents_.cordz_info()); + // Embed into this->contents_, which is somewhat subtle: + // - MaybeUntrackCord must be called before Unref(tree). + // - MaybeUntrackCord must be called before set_data() clobbers cordz_info. + // - set_data() must be called before Unref(tree) as it may reference tree. + if (tree != nullptr) CordzInfo::MaybeUntrackCord(contents_.cordz_info()); contents_.set_data(data, length, true); - if (tree != nullptr) CordRep::Unref(tree); + if (tree != nullptr) CordRep::Unref(tree); return *this; } - if (tree != nullptr) { - CordzUpdateScope scope(contents_.cordz_info(), method); - if (tree->IsFlat() && tree->flat()->Capacity() >= length && - tree->refcount.IsMutable()) { - // Copy in place if the existing FLAT node is reusable. - memmove(tree->flat()->Data(), data, length); - tree->length = length; - VerifyTree(tree); - return *this; - } - contents_.SetTree(NewTree(data, length, 0), scope); - CordRep::Unref(tree); + if (tree != nullptr) { + CordzUpdateScope scope(contents_.cordz_info(), method); + if (tree->IsFlat() && tree->flat()->Capacity() >= length && + tree->refcount.IsMutable()) { + // Copy in place if the existing FLAT node is reusable. + memmove(tree->flat()->Data(), data, length); + tree->length = length; + VerifyTree(tree); + return *this; + } + contents_.SetTree(NewTree(data, length, 0), scope); + CordRep::Unref(tree); } else { - contents_.EmplaceTree(NewTree(data, length, 0), method); + contents_.EmplaceTree(NewTree(data, length, 0), method); } return *this; } // TODO(sanjay): Move to Cord::InlineRep section of file. For now, // we keep it here to make diffs easier. -void Cord::InlineRep::AppendArray(y_absl::string_view src, - MethodIdentifier method) { - if (src.empty()) return; // memcpy(_, nullptr, 0) is undefined. +void Cord::InlineRep::AppendArray(y_absl::string_view src, + MethodIdentifier method) { + if (src.empty()) return; // memcpy(_, nullptr, 0) is undefined. size_t appended = 0; - CordRep* rep = tree(); - const CordRep* const root = rep; - CordzUpdateScope scope(root ? cordz_info() : nullptr, method); - if (root != nullptr) { + CordRep* rep = tree(); + const CordRep* const root = rep; + CordzUpdateScope scope(root ? cordz_info() : nullptr, method); + if (root != nullptr) { char* region; - if (PrepareAppendRegion(rep, ®ion, &appended, src.size())) { - memcpy(region, src.data(), appended); + if (PrepareAppendRegion(rep, ®ion, &appended, src.size())) { + memcpy(region, src.data(), appended); } } else { // Try to fit in the inline buffer if possible. size_t inline_length = inline_size(); - if (src.size() <= kMaxInline - inline_length) { + if (src.size() <= kMaxInline - inline_length) { // Append new data to embedded array - memcpy(data_.as_chars() + inline_length, src.data(), src.size()); - set_inline_size(inline_length + src.size()); + memcpy(data_.as_chars() + inline_length, src.data(), src.size()); + set_inline_size(inline_length + src.size()); return; } - // Allocate flat to be a perfect fit on first append exceeding inlined size. - // Subsequent growth will use amortized growth until we reach maximum flat - // size. - rep = CordRepFlat::New(inline_length + src.size()); - appended = std::min(src.size(), rep->flat()->Capacity() - inline_length); - memcpy(rep->flat()->Data(), data_.as_chars(), inline_length); - memcpy(rep->flat()->Data() + inline_length, src.data(), appended); - rep->length = inline_length + appended; + // Allocate flat to be a perfect fit on first append exceeding inlined size. + // Subsequent growth will use amortized growth until we reach maximum flat + // size. + rep = CordRepFlat::New(inline_length + src.size()); + appended = std::min(src.size(), rep->flat()->Capacity() - inline_length); + memcpy(rep->flat()->Data(), data_.as_chars(), inline_length); + memcpy(rep->flat()->Data() + inline_length, src.data(), appended); + rep->length = inline_length + appended; } - src.remove_prefix(appended); - if (src.empty()) { - CommitTree(root, rep, scope, method); + src.remove_prefix(appended); + if (src.empty()) { + CommitTree(root, rep, scope, method); return; } - if (btree_enabled()) { - // TODO(b/192061034): keep legacy 10% growth rate: consider other rates. - rep = ForceBtree(rep); - const size_t min_growth = std::max<size_t>(rep->length / 10, src.size()); - rep = CordRepBtree::Append(rep->btree(), src, min_growth - src.size()); - } else { - // Use new block(s) for any remaining bytes that were not handled above. - // Alloc extra memory only if the right child of the root of the new tree - // is going to be a FLAT node, which will permit further inplace appends. - size_t length = src.size(); - if (src.size() < kMaxFlatLength) { - // The new length is either - // - old size + 10% - // - old_size + src.size() - // This will cause a reasonable conservative step-up in size that is - // still large enough to avoid excessive amounts of small fragments - // being added. - length = std::max<size_t>(rep->length / 10, src.size()); - } - rep = Concat(rep, NewTree(src.data(), src.size(), length - src.size())); - } - CommitTree(root, rep, scope, method); + if (btree_enabled()) { + // TODO(b/192061034): keep legacy 10% growth rate: consider other rates. + rep = ForceBtree(rep); + const size_t min_growth = std::max<size_t>(rep->length / 10, src.size()); + rep = CordRepBtree::Append(rep->btree(), src, min_growth - src.size()); + } else { + // Use new block(s) for any remaining bytes that were not handled above. + // Alloc extra memory only if the right child of the root of the new tree + // is going to be a FLAT node, which will permit further inplace appends. + size_t length = src.size(); + if (src.size() < kMaxFlatLength) { + // The new length is either + // - old size + 10% + // - old_size + src.size() + // This will cause a reasonable conservative step-up in size that is + // still large enough to avoid excessive amounts of small fragments + // being added. + length = std::max<size_t>(rep->length / 10, src.size()); + } + rep = Concat(rep, NewTree(src.data(), src.size(), length - src.size())); + } + CommitTree(root, rep, scope, method); } inline CordRep* Cord::TakeRep() const& { @@ -741,17 +741,17 @@ inline CordRep* Cord::TakeRep() && { template <typename C> inline void Cord::AppendImpl(C&& src) { - auto constexpr method = CordzUpdateTracker::kAppendCord; + auto constexpr method = CordzUpdateTracker::kAppendCord; if (empty()) { - // Since destination is empty, we can avoid allocating a node, - if (src.contents_.is_tree()) { - // by taking the tree directly - CordRep* rep = std::forward<C>(src).TakeRep(); - contents_.EmplaceTree(rep, method); - } else { - // or copying over inline data - contents_.data_ = src.contents_.data_; - } + // Since destination is empty, we can avoid allocating a node, + if (src.contents_.is_tree()) { + // by taking the tree directly + CordRep* rep = std::forward<C>(src).TakeRep(); + contents_.EmplaceTree(rep, method); + } else { + // or copying over inline data + contents_.data_ = src.contents_.data_; + } return; } @@ -761,12 +761,12 @@ inline void Cord::AppendImpl(C&& src) { CordRep* src_tree = src.contents_.tree(); if (src_tree == nullptr) { // src has embedded data. - contents_.AppendArray({src.contents_.data(), src_size}, method); + contents_.AppendArray({src.contents_.data(), src_size}, method); return; } - if (src_tree->IsFlat()) { + if (src_tree->IsFlat()) { // src tree just has one flat node. - contents_.AppendArray({src_tree->flat()->Data(), src_size}, method); + contents_.AppendArray({src_tree->flat()->Data(), src_size}, method); return; } if (&src == this) { @@ -782,25 +782,25 @@ inline void Cord::AppendImpl(C&& src) { } // Guaranteed to be a tree (kMaxBytesToCopy > kInlinedSize) - CordRep* rep = std::forward<C>(src).TakeRep(); - contents_.AppendTree(rep, CordzUpdateTracker::kAppendCord); + CordRep* rep = std::forward<C>(src).TakeRep(); + contents_.AppendTree(rep, CordzUpdateTracker::kAppendCord); } -void Cord::Append(const Cord& src) { - AppendImpl(src); -} +void Cord::Append(const Cord& src) { + AppendImpl(src); +} -void Cord::Append(Cord&& src) { - AppendImpl(std::move(src)); -} +void Cord::Append(Cord&& src) { + AppendImpl(std::move(src)); +} template <typename T, Cord::EnableIfString<T>> void Cord::Append(T&& src) { if (src.size() <= kMaxBytesToCopy) { Append(y_absl::string_view(src)); } else { - CordRep* rep = CordRepFromString(std::forward<T>(src)); - contents_.AppendTree(rep, CordzUpdateTracker::kAppendString); + CordRep* rep = CordRepFromString(std::forward<T>(src)); + contents_.AppendTree(rep, CordzUpdateTracker::kAppendString); } } @@ -810,7 +810,7 @@ void Cord::Prepend(const Cord& src) { CordRep* src_tree = src.contents_.tree(); if (src_tree != nullptr) { CordRep::Ref(src_tree); - contents_.PrependTree(src_tree, CordzUpdateTracker::kPrependCord); + contents_.PrependTree(src_tree, CordzUpdateTracker::kPrependCord); return; } @@ -819,7 +819,7 @@ void Cord::Prepend(const Cord& src) { return Prepend(src_contents); } -void Cord::PrependArray(y_absl::string_view src, MethodIdentifier method) { +void Cord::PrependArray(y_absl::string_view src, MethodIdentifier method) { if (src.empty()) return; // memcpy(_, nullptr, 0) is undefined. if (!contents_.is_tree()) { size_t cur_size = contents_.inline_size(); @@ -833,8 +833,8 @@ void Cord::PrependArray(y_absl::string_view src, MethodIdentifier method) { return; } } - CordRep* rep = NewTree(src.data(), src.size(), 0); - contents_.PrependTree(rep, method); + CordRep* rep = NewTree(src.data(), src.size(), 0); + contents_.PrependTree(rep, method); } template <typename T, Cord::EnableIfString<T>> @@ -842,8 +842,8 @@ inline void Cord::Prepend(T&& src) { if (src.size() <= kMaxBytesToCopy) { Prepend(y_absl::string_view(src)); } else { - CordRep* rep = CordRepFromString(std::forward<T>(src)); - contents_.PrependTree(rep, CordzUpdateTracker::kPrependString); + CordRep* rep = CordRepFromString(std::forward<T>(src)); + contents_.PrependTree(rep, CordzUpdateTracker::kPrependString); } } @@ -854,7 +854,7 @@ static CordRep* RemovePrefixFrom(CordRep* node, size_t n) { if (n == 0) return CordRep::Ref(node); y_absl::InlinedVector<CordRep*, kInlinedVectorSize> rhs_stack; - while (node->IsConcat()) { + while (node->IsConcat()) { assert(n <= node->length); if (n < node->concat()->left->length) { // Push right to stack, descend left. @@ -873,7 +873,7 @@ static CordRep* RemovePrefixFrom(CordRep* node, size_t n) { } else { size_t start = n; size_t len = node->length - n; - if (node->IsSubstring()) { + if (node->IsSubstring()) { // Consider in-place update of node, similar to in RemoveSuffixFrom(). start += node->substring()->start; node = node->substring()->child; @@ -894,9 +894,9 @@ static CordRep* RemoveSuffixFrom(CordRep* node, size_t n) { if (n >= node->length) return nullptr; if (n == 0) return CordRep::Ref(node); y_absl::InlinedVector<CordRep*, kInlinedVectorSize> lhs_stack; - bool inplace_ok = node->refcount.IsMutable(); + bool inplace_ok = node->refcount.IsMutable(); - while (node->IsConcat()) { + while (node->IsConcat()) { assert(n <= node->length); if (n < node->concat()->right->length) { // Push left to stack, descend right. @@ -907,13 +907,13 @@ static CordRep* RemoveSuffixFrom(CordRep* node, size_t n) { n -= node->concat()->right->length; node = node->concat()->left; } - inplace_ok = inplace_ok && node->refcount.IsMutable(); + inplace_ok = inplace_ok && node->refcount.IsMutable(); } assert(n <= node->length); if (n == 0) { CordRep::Ref(node); - } else if (inplace_ok && !node->IsExternal()) { + } else if (inplace_ok && !node->IsExternal()) { // Consider making a new buffer if the current node capacity is much // larger than the new length. CordRep::Ref(node); @@ -921,7 +921,7 @@ static CordRep* RemoveSuffixFrom(CordRep* node, size_t n) { } else { size_t start = 0; size_t len = node->length - n; - if (node->IsSubstring()) { + if (node->IsSubstring()) { start = node->substring()->start; node = node->substring()->child; } @@ -942,18 +942,18 @@ void Cord::RemovePrefix(size_t n) { if (tree == nullptr) { contents_.remove_prefix(n); } else { - auto constexpr method = CordzUpdateTracker::kRemovePrefix; - CordzUpdateScope scope(contents_.cordz_info(), method); - if (tree->IsBtree()) { - CordRep* old = tree; - tree = tree->btree()->SubTree(n, tree->length - n); - CordRep::Unref(old); - } else { - CordRep* newrep = RemovePrefixFrom(tree, n); - CordRep::Unref(tree); - tree = VerifyTree(newrep); - } - contents_.SetTreeOrEmpty(tree, scope); + auto constexpr method = CordzUpdateTracker::kRemovePrefix; + CordzUpdateScope scope(contents_.cordz_info(), method); + if (tree->IsBtree()) { + CordRep* old = tree; + tree = tree->btree()->SubTree(n, tree->length - n); + CordRep::Unref(old); + } else { + CordRep* newrep = RemovePrefixFrom(tree, n); + CordRep::Unref(tree); + tree = VerifyTree(newrep); + } + contents_.SetTreeOrEmpty(tree, scope); } } @@ -965,16 +965,16 @@ void Cord::RemoveSuffix(size_t n) { if (tree == nullptr) { contents_.reduce_size(n); } else { - auto constexpr method = CordzUpdateTracker::kRemoveSuffix; - CordzUpdateScope scope(contents_.cordz_info(), method); - if (tree->IsBtree()) { - tree = CordRepBtree::RemoveSuffix(tree->btree(), n); - } else { - CordRep* newrep = RemoveSuffixFrom(tree, n); - CordRep::Unref(tree); - tree = VerifyTree(newrep); - } - contents_.SetTreeOrEmpty(tree, scope); + auto constexpr method = CordzUpdateTracker::kRemoveSuffix; + CordzUpdateScope scope(contents_.cordz_info(), method); + if (tree->IsBtree()) { + tree = CordRepBtree::RemoveSuffix(tree->btree(), n); + } else { + CordRep* newrep = RemoveSuffixFrom(tree, n); + CordRep::Unref(tree); + tree = VerifyTree(newrep); + } + contents_.SetTreeOrEmpty(tree, scope); } } @@ -1007,8 +1007,8 @@ static CordRep* NewSubRange(CordRep* node, size_t pos, size_t n) { results.push_back(Concat(left, right)); } else if (pos == 0 && n == node->length) { results.push_back(CordRep::Ref(node)); - } else if (!node->IsConcat()) { - if (node->IsSubstring()) { + } else if (!node->IsConcat()) { + if (node->IsSubstring()) { pos += node->substring()->start; node = node->substring()->child; } @@ -1034,18 +1034,18 @@ Cord Cord::Subcord(size_t pos, size_t new_size) const { size_t length = size(); if (pos > length) pos = length; if (new_size > length - pos) new_size = length - pos; - if (new_size == 0) return sub_cord; - + if (new_size == 0) return sub_cord; + CordRep* tree = contents_.tree(); if (tree == nullptr) { // sub_cord is newly constructed, no need to re-zero-out the tail of // contents_ memory. sub_cord.contents_.set_data(contents_.data() + pos, new_size, false); - return sub_cord; - } - - if (new_size <= InlineRep::kMaxInline) { - char* dest = sub_cord.contents_.data_.as_chars(); + return sub_cord; + } + + if (new_size <= InlineRep::kMaxInline) { + char* dest = sub_cord.contents_.data_.as_chars(); Cord::ChunkIterator it = chunk_begin(); it.AdvanceBytes(pos); size_t remaining_size = new_size; @@ -1057,16 +1057,16 @@ Cord Cord::Subcord(size_t pos, size_t new_size) const { } cord_internal::SmallMemmove(dest, it->data(), remaining_size); sub_cord.contents_.set_inline_size(new_size); - return sub_cord; - } - - if (tree->IsBtree()) { - tree = tree->btree()->SubTree(pos, new_size); + return sub_cord; + } + + if (tree->IsBtree()) { + tree = tree->btree()->SubTree(pos, new_size); } else { - tree = NewSubRange(tree, pos, new_size); + tree = NewSubRange(tree, pos, new_size); } - sub_cord.contents_.EmplaceTree(tree, contents_.data_, - CordzUpdateTracker::kSubCord); + sub_cord.contents_.EmplaceTree(tree, contents_.data_, + CordzUpdateTracker::kSubCord); return sub_cord; } @@ -1085,7 +1085,7 @@ class CordForest { CordRep* node = pending.back(); pending.pop_back(); CheckNode(node); - if (ABSL_PREDICT_FALSE(!node->IsConcat())) { + if (ABSL_PREDICT_FALSE(!node->IsConcat())) { AddNode(node); continue; } @@ -1179,7 +1179,7 @@ class CordForest { static void CheckNode(CordRep* node) { ABSL_INTERNAL_CHECK(node->length != 0u, ""); - if (node->IsConcat()) { + if (node->IsConcat()) { ABSL_INTERNAL_CHECK(node->concat()->left != nullptr, ""); ABSL_INTERNAL_CHECK(node->concat()->right != nullptr, ""); ABSL_INTERNAL_CHECK(node->length == (node->concat()->left->length + @@ -1199,7 +1199,7 @@ class CordForest { static CordRep* Rebalance(CordRep* node) { VerifyTree(node); - assert(node->IsConcat()); + assert(node->IsConcat()); if (node->length == 0) { return nullptr; @@ -1249,33 +1249,33 @@ bool ComputeCompareResult<bool>(int memcmp_res) { } // namespace -// Helper routine. Locates the first flat or external chunk of the Cord without -// initializing the iterator, and returns a string_view referencing the data. +// Helper routine. Locates the first flat or external chunk of the Cord without +// initializing the iterator, and returns a string_view referencing the data. inline y_absl::string_view Cord::InlineRep::FindFlatStartPiece() const { if (!is_tree()) { return y_absl::string_view(data_.as_chars(), data_.inline_size()); } CordRep* node = tree(); - if (node->IsFlat()) { + if (node->IsFlat()) { return y_absl::string_view(node->flat()->Data(), node->length); } - if (node->IsExternal()) { + if (node->IsExternal()) { return y_absl::string_view(node->external()->base, node->length); } - if (node->IsBtree()) { - CordRepBtree* tree = node->btree(); - int height = tree->height(); - while (--height >= 0) { - tree = tree->Edge(CordRepBtree::kFront)->btree(); - } - return tree->Data(tree->begin()); + if (node->IsBtree()) { + CordRepBtree* tree = node->btree(); + int height = tree->height(); + while (--height >= 0) { + tree = tree->Edge(CordRepBtree::kFront)->btree(); + } + return tree->Data(tree->begin()); } // Walk down the left branches until we hit a non-CONCAT node. - while (node->IsConcat()) { + while (node->IsConcat()) { node = node->concat()->left; } @@ -1284,16 +1284,16 @@ inline y_absl::string_view Cord::InlineRep::FindFlatStartPiece() const { size_t length = node->length; assert(length != 0); - if (node->IsSubstring()) { + if (node->IsSubstring()) { offset = node->substring()->start; node = node->substring()->child; } - if (node->IsFlat()) { + if (node->IsFlat()) { return y_absl::string_view(node->flat()->Data() + offset, length); } - assert(node->IsExternal() && "Expect FLAT or EXTERNAL node here"); + assert(node->IsExternal() && "Expect FLAT or EXTERNAL node here"); return y_absl::string_view(node->external()->base + offset, length); } @@ -1487,7 +1487,7 @@ Cord::ChunkIterator& Cord::ChunkIterator::AdvanceStack() { // Walk down the left branches until we hit a non-CONCAT node. Save the // right children to the stack for subsequent traversal. - while (node->IsConcat()) { + while (node->IsConcat()) { stack_of_right_children.push_back(node->concat()->right); node = node->concat()->left; } @@ -1495,15 +1495,15 @@ Cord::ChunkIterator& Cord::ChunkIterator::AdvanceStack() { // Get the child node if we encounter a SUBSTRING. size_t offset = 0; size_t length = node->length; - if (node->IsSubstring()) { + if (node->IsSubstring()) { offset = node->substring()->start; node = node->substring()->child; } - assert(node->IsExternal() || node->IsFlat()); + assert(node->IsExternal() || node->IsFlat()); assert(length != 0); const char* data = - node->IsExternal() ? node->external()->base : node->flat()->Data(); + node->IsExternal() ? node->external()->base : node->flat()->Data(); current_chunk_ = y_absl::string_view(data + offset, length); current_leaf_ = node; return *this; @@ -1513,7 +1513,7 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) { ABSL_HARDENING_ASSERT(bytes_remaining_ >= n && "Attempted to iterate past `end()`"); Cord subcord; - auto constexpr method = CordzUpdateTracker::kCordReader; + auto constexpr method = CordzUpdateTracker::kCordReader; if (n <= InlineRep::kMaxInline) { // Range to read fits in inline data. Flatten it. @@ -1533,21 +1533,21 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) { return subcord; } - if (btree_reader_) { + if (btree_reader_) { size_t chunk_size = current_chunk_.size(); if (n <= chunk_size && n <= kMaxBytesToCopy) { - subcord = Cord(current_chunk_.substr(0, n), method); - if (n < chunk_size) { - current_chunk_.remove_prefix(n); - } else { - current_chunk_ = btree_reader_.Next(); - } + subcord = Cord(current_chunk_.substr(0, n), method); + if (n < chunk_size) { + current_chunk_.remove_prefix(n); + } else { + current_chunk_ = btree_reader_.Next(); + } } else { - CordRep* rep; - current_chunk_ = btree_reader_.Read(n, chunk_size, rep); - subcord.contents_.EmplaceTree(rep, method); + CordRep* rep; + current_chunk_ = btree_reader_.Read(n, chunk_size, rep); + subcord.contents_.EmplaceTree(rep, method); } - bytes_remaining_ -= n; + bytes_remaining_ -= n; return subcord; } @@ -1556,10 +1556,10 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) { // Range to read is a proper subrange of the current chunk. assert(current_leaf_ != nullptr); CordRep* subnode = CordRep::Ref(current_leaf_); - const char* data = subnode->IsExternal() ? subnode->external()->base - : subnode->flat()->Data(); + const char* data = subnode->IsExternal() ? subnode->external()->base + : subnode->flat()->Data(); subnode = NewSubstring(subnode, current_chunk_.data() - data, n); - subcord.contents_.EmplaceTree(VerifyTree(subnode), method); + subcord.contents_.EmplaceTree(VerifyTree(subnode), method); RemoveChunkPrefix(n); return subcord; } @@ -1569,8 +1569,8 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) { assert(current_leaf_ != nullptr); CordRep* subnode = CordRep::Ref(current_leaf_); if (current_chunk_.size() < subnode->length) { - const char* data = subnode->IsExternal() ? subnode->external()->base - : subnode->flat()->Data(); + const char* data = subnode->IsExternal() ? subnode->external()->base + : subnode->flat()->Data(); subnode = NewSubstring(subnode, current_chunk_.data() - data, current_chunk_.size()); } @@ -1602,13 +1602,13 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) { if (node == nullptr) { // We have reached the end of the Cord. assert(bytes_remaining_ == 0); - subcord.contents_.EmplaceTree(VerifyTree(subnode), method); + subcord.contents_.EmplaceTree(VerifyTree(subnode), method); return subcord; } // Walk down the appropriate branches until we hit a non-CONCAT node. Save the // right children to the stack for subsequent traversal. - while (node->IsConcat()) { + while (node->IsConcat()) { if (node->concat()->left->length > n) { // Push right, descend left. stack_of_right_children.push_back(node->concat()->right); @@ -1625,24 +1625,24 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) { // Get the child node if we encounter a SUBSTRING. size_t offset = 0; size_t length = node->length; - if (node->IsSubstring()) { + if (node->IsSubstring()) { offset = node->substring()->start; node = node->substring()->child; } // Range to read ends with a proper (possibly empty) subrange of the current // chunk. - assert(node->IsExternal() || node->IsFlat()); + assert(node->IsExternal() || node->IsFlat()); assert(length > n); if (n > 0) { subnode = Concat(subnode, NewSubstring(CordRep::Ref(node), offset, n)); } const char* data = - node->IsExternal() ? node->external()->base : node->flat()->Data(); + node->IsExternal() ? node->external()->base : node->flat()->Data(); current_chunk_ = y_absl::string_view(data + offset + n, length - n); current_leaf_ = node; bytes_remaining_ -= n; - subcord.contents_.EmplaceTree(VerifyTree(subnode), method); + subcord.contents_.EmplaceTree(VerifyTree(subnode), method); return subcord; } @@ -1681,7 +1681,7 @@ void Cord::ChunkIterator::AdvanceBytesSlowPath(size_t n) { // Walk down the appropriate branches until we hit a non-CONCAT node. Save the // right children to the stack for subsequent traversal. - while (node->IsConcat()) { + while (node->IsConcat()) { if (node->concat()->left->length > n) { // Push right, descend left. stack_of_right_children.push_back(node->concat()->right); @@ -1697,15 +1697,15 @@ void Cord::ChunkIterator::AdvanceBytesSlowPath(size_t n) { // Get the child node if we encounter a SUBSTRING. size_t offset = 0; size_t length = node->length; - if (node->IsSubstring()) { + if (node->IsSubstring()) { offset = node->substring()->start; node = node->substring()->child; } - assert(node->IsExternal() || node->IsFlat()); + assert(node->IsExternal() || node->IsFlat()); assert(length > n); const char* data = - node->IsExternal() ? node->external()->base : node->flat()->Data(); + node->IsExternal() ? node->external()->base : node->flat()->Data(); current_chunk_ = y_absl::string_view(data + offset + n, length - n); current_leaf_ = node; bytes_remaining_ -= n; @@ -1721,15 +1721,15 @@ char Cord::operator[](size_t i) const { while (true) { assert(rep != nullptr); assert(offset < rep->length); - if (rep->IsFlat()) { + if (rep->IsFlat()) { // Get the "i"th character directly from the flat array. return rep->flat()->Data()[offset]; - } else if (rep->IsBtree()) { - return rep->btree()->GetCharacter(offset); - } else if (rep->IsExternal()) { + } else if (rep->IsBtree()) { + return rep->btree()->GetCharacter(offset); + } else if (rep->IsExternal()) { // Get the "i"th character from the external array. return rep->external()->base[offset]; - } else if (rep->IsConcat()) { + } else if (rep->IsConcat()) { // Recursively branch to the side of the concatenation that the "i"th // character is on. size_t left_length = rep->concat()->left->length; @@ -1741,7 +1741,7 @@ char Cord::operator[](size_t i) const { } } else { // This must be a substring a node, so bypass it to get to the child. - assert(rep->IsSubstring()); + assert(rep->IsSubstring()); offset += rep->substring()->start; rep = rep->substring()->child; } @@ -1749,7 +1749,7 @@ char Cord::operator[](size_t i) const { } y_absl::string_view Cord::FlattenSlowPath() { - assert(contents_.is_tree()); + assert(contents_.is_tree()); size_t total_size = size(); CordRep* new_rep; char* new_buffer; @@ -1770,35 +1770,35 @@ y_absl::string_view Cord::FlattenSlowPath() { s.size()); }); } - CordzUpdateScope scope(contents_.cordz_info(), CordzUpdateTracker::kFlatten); - CordRep::Unref(contents_.as_tree()); - contents_.SetTree(new_rep, scope); + CordzUpdateScope scope(contents_.cordz_info(), CordzUpdateTracker::kFlatten); + CordRep::Unref(contents_.as_tree()); + contents_.SetTree(new_rep, scope); return y_absl::string_view(new_buffer, total_size); } /* static */ bool Cord::GetFlatAux(CordRep* rep, y_absl::string_view* fragment) { assert(rep != nullptr); - if (rep->IsFlat()) { + if (rep->IsFlat()) { *fragment = y_absl::string_view(rep->flat()->Data(), rep->length); return true; - } else if (rep->IsExternal()) { + } else if (rep->IsExternal()) { *fragment = y_absl::string_view(rep->external()->base, rep->length); return true; - } else if (rep->IsBtree()) { - return rep->btree()->IsFlat(fragment); - } else if (rep->IsSubstring()) { + } else if (rep->IsBtree()) { + return rep->btree()->IsFlat(fragment); + } else if (rep->IsSubstring()) { CordRep* child = rep->substring()->child; - if (child->IsFlat()) { + if (child->IsFlat()) { *fragment = y_absl::string_view( child->flat()->Data() + rep->substring()->start, rep->length); return true; - } else if (child->IsExternal()) { + } else if (child->IsExternal()) { *fragment = y_absl::string_view( child->external()->base + rep->substring()->start, rep->length); return true; - } else if (child->IsBtree()) { - return child->btree()->IsFlat(rep->substring()->start, rep->length, - fragment); + } else if (child->IsBtree()) { + return child->btree()->IsFlat(rep->substring()->start, rep->length, + fragment); } } return false; @@ -1807,7 +1807,7 @@ y_absl::string_view Cord::FlattenSlowPath() { /* static */ void Cord::ForEachChunkAux( y_absl::cord_internal::CordRep* rep, y_absl::FunctionRef<void(y_absl::string_view)> callback) { - if (rep->IsBtree()) { + if (rep->IsBtree()) { ChunkIterator it(rep), end; while (it != end) { callback(*it); @@ -1823,7 +1823,7 @@ y_absl::string_view Cord::FlattenSlowPath() { y_absl::cord_internal::CordRep* stack[stack_max]; y_absl::cord_internal::CordRep* current_node = rep; while (true) { - if (current_node->IsConcat()) { + if (current_node->IsConcat()) { if (stack_pos == stack_max) { // There's no more room on our stack array to add another right branch, // and the idea is to avoid allocations, so call this function @@ -1870,29 +1870,29 @@ static void DumpNode(CordRep* rep, bool include_data, std::ostream* os, *os << "]"; *os << " " << (IsRootBalanced(rep) ? 'b' : 'u'); *os << " " << std::setw(indent) << ""; - if (rep->IsConcat()) { + if (rep->IsConcat()) { *os << "CONCAT depth=" << Depth(rep) << "\n"; indent += kIndentStep; indents.push_back(indent); stack.push_back(rep->concat()->right); rep = rep->concat()->left; - } else if (rep->IsSubstring()) { + } else if (rep->IsSubstring()) { *os << "SUBSTRING @ " << rep->substring()->start << "\n"; indent += kIndentStep; rep = rep->substring()->child; } else { // Leaf or ring - if (rep->IsExternal()) { + if (rep->IsExternal()) { *os << "EXTERNAL ["; if (include_data) *os << y_absl::CEscape(TString(rep->external()->base, rep->length)); *os << "]\n"; - } else if (rep->IsFlat()) { - *os << "FLAT cap=" << rep->flat()->Capacity() << " ["; + } else if (rep->IsFlat()) { + *os << "FLAT cap=" << rep->flat()->Capacity() << " ["; if (include_data) *os << y_absl::CEscape(TString(rep->flat()->Data(), rep->length)); *os << "]\n"; } else { - CordRepBtree::Dump(rep, /*label=*/ "", include_data, *os); + CordRepBtree::Dump(rep, /*label=*/ "", include_data, *os); } if (stack.empty()) break; rep = stack.back(); @@ -1924,7 +1924,7 @@ static bool VerifyNode(CordRep* root, CordRep* start_node, ABSL_INTERNAL_CHECK(node->length != 0, ReportError(root, node)); } - if (node->IsConcat()) { + if (node->IsConcat()) { ABSL_INTERNAL_CHECK(node->concat()->left != nullptr, ReportError(root, node)); ABSL_INTERNAL_CHECK(node->concat()->right != nullptr, @@ -1936,13 +1936,13 @@ static bool VerifyNode(CordRep* root, CordRep* start_node, worklist.push_back(node->concat()->right); worklist.push_back(node->concat()->left); } - } else if (node->IsFlat()) { - ABSL_INTERNAL_CHECK(node->length <= node->flat()->Capacity(), - ReportError(root, node)); - } else if (node->IsExternal()) { + } else if (node->IsFlat()) { + ABSL_INTERNAL_CHECK(node->length <= node->flat()->Capacity(), + ReportError(root, node)); + } else if (node->IsExternal()) { ABSL_INTERNAL_CHECK(node->external()->base != nullptr, ReportError(root, node)); - } else if (node->IsSubstring()) { + } else if (node->IsSubstring()) { ABSL_INTERNAL_CHECK( node->substring()->start < node->substring()->child->length, ReportError(root, node)); @@ -1971,7 +1971,7 @@ static bool VerifyNode(CordRep* root, CordRep* start_node, while (true) { const CordRep* next_node = nullptr; - if (cur_node->IsConcat()) { + if (cur_node->IsConcat()) { total_mem_usage += sizeof(CordRepConcat); const CordRep* left = cur_node->concat()->left; if (!RepMemoryUsageLeaf(left, &total_mem_usage)) { @@ -1985,21 +1985,21 @@ static bool VerifyNode(CordRep* root, CordRep* start_node, } next_node = right; } - } else if (cur_node->IsBtree()) { - total_mem_usage += sizeof(CordRepBtree); - const CordRepBtree* node = cur_node->btree(); - if (node->height() == 0) { - for (const CordRep* edge : node->Edges()) { - RepMemoryUsageDataEdge(edge, &total_mem_usage); - } - } else { - for (const CordRep* edge : node->Edges()) { - tree_stack.push_back(edge); - } - } + } else if (cur_node->IsBtree()) { + total_mem_usage += sizeof(CordRepBtree); + const CordRepBtree* node = cur_node->btree(); + if (node->height() == 0) { + for (const CordRep* edge : node->Edges()) { + RepMemoryUsageDataEdge(edge, &total_mem_usage); + } + } else { + for (const CordRep* edge : node->Edges()) { + tree_stack.push_back(edge); + } + } } else { // Since cur_node is not a leaf or a concat node it must be a substring. - assert(cur_node->IsSubstring()); + assert(cur_node->IsSubstring()); total_mem_usage += sizeof(CordRepSubstring); next_node = cur_node->substring()->child; if (RepMemoryUsageLeaf(next_node, &total_mem_usage)) { diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord.h index 62359e0cf8..226f327c6b 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord.h @@ -70,7 +70,7 @@ #include <util/generic/string.h> #include <type_traits> -#include "y_absl/base/config.h" +#include "y_absl/base/config.h" #include "y_absl/base/internal/endian.h" #include "y_absl/base/internal/per_thread_tls.h" #include "y_absl/base/macros.h" @@ -79,14 +79,14 @@ #include "y_absl/functional/function_ref.h" #include "y_absl/meta/type_traits.h" #include "y_absl/strings/internal/cord_internal.h" -#include "y_absl/strings/internal/cord_rep_btree.h" -#include "y_absl/strings/internal/cord_rep_btree_reader.h" +#include "y_absl/strings/internal/cord_rep_btree.h" +#include "y_absl/strings/internal/cord_rep_btree_reader.h" #include "y_absl/strings/internal/cord_rep_ring.h" -#include "y_absl/strings/internal/cordz_functions.h" -#include "y_absl/strings/internal/cordz_info.h" -#include "y_absl/strings/internal/cordz_statistics.h" -#include "y_absl/strings/internal/cordz_update_scope.h" -#include "y_absl/strings/internal/cordz_update_tracker.h" +#include "y_absl/strings/internal/cordz_functions.h" +#include "y_absl/strings/internal/cordz_info.h" +#include "y_absl/strings/internal/cordz_statistics.h" +#include "y_absl/strings/internal/cordz_update_scope.h" +#include "y_absl/strings/internal/cordz_update_tracker.h" #include "y_absl/strings/internal/resize_uninitialized.h" #include "y_absl/strings/internal/string_constant.h" #include "y_absl/strings/string_view.h" @@ -256,7 +256,7 @@ class Cord { // swap() // // Swaps the contents of two Cords. - friend void swap(Cord& x, Cord& y) noexcept { x.swap(y); } + friend void swap(Cord& x, Cord& y) noexcept { x.swap(y); } // Cord::size() // @@ -369,8 +369,8 @@ class Cord { private: using CordRep = y_absl::cord_internal::CordRep; - using CordRepBtree = y_absl::cord_internal::CordRepBtree; - using CordRepBtreeReader = y_absl::cord_internal::CordRepBtreeReader; + using CordRepBtree = y_absl::cord_internal::CordRepBtree; + using CordRepBtreeReader = y_absl::cord_internal::CordRepBtreeReader; // Stack of right children of concat nodes that we have to visit. // Keep this at the end of the structure to avoid cache-thrashing. @@ -396,9 +396,9 @@ class Cord { // Stack specific operator++ ChunkIterator& AdvanceStack(); - // Btree specific operator++ - ChunkIterator& AdvanceBtree(); - void AdvanceBytesBtree(size_t n); + // Btree specific operator++ + ChunkIterator& AdvanceBtree(); + void AdvanceBytesBtree(size_t n); // Iterates `n` bytes, where `n` is expected to be greater than or equal to // `current_chunk_.size()`. @@ -414,8 +414,8 @@ class Cord { // The number of bytes left in the `Cord` over which we are iterating. size_t bytes_remaining_ = 0; - // Cord reader for cord btrees. Empty if not traversing a btree. - CordRepBtreeReader btree_reader_; + // Cord reader for cord btrees. Empty if not traversing a btree. + CordRepBtreeReader btree_reader_; // See 'Stack' alias definition. Stack stack_of_right_children_; @@ -460,16 +460,16 @@ class Cord { // `Cord::chunk_begin()` and `Cord::chunk_end()`. class ChunkRange { public: - // Fulfill minimum c++ container requirements [container.requirements] - // Theses (partial) container type definitions allow ChunkRange to be used - // in various utilities expecting a subset of [container.requirements]. - // For example, the below enables using `::testing::ElementsAre(...)` - using value_type = y_absl::string_view; - using reference = value_type&; - using const_reference = const value_type&; - using iterator = ChunkIterator; - using const_iterator = ChunkIterator; - + // Fulfill minimum c++ container requirements [container.requirements] + // Theses (partial) container type definitions allow ChunkRange to be used + // in various utilities expecting a subset of [container.requirements]. + // For example, the below enables using `::testing::ElementsAre(...)` + using value_type = y_absl::string_view; + using reference = value_type&; + using const_reference = const value_type&; + using iterator = ChunkIterator; + using const_iterator = ChunkIterator; + explicit ChunkRange(const Cord* cord) : cord_(cord) {} ChunkIterator begin() const; @@ -601,16 +601,16 @@ class Cord { // `Cord::char_begin()` and `Cord::char_end()`. class CharRange { public: - // Fulfill minimum c++ container requirements [container.requirements] - // Theses (partial) container type definitions allow CharRange to be used - // in various utilities expecting a subset of [container.requirements]. - // For example, the below enables using `::testing::ElementsAre(...)` - using value_type = char; - using reference = value_type&; - using const_reference = const value_type&; - using iterator = CharIterator; - using const_iterator = CharIterator; - + // Fulfill minimum c++ container requirements [container.requirements] + // Theses (partial) container type definitions allow CharRange to be used + // in various utilities expecting a subset of [container.requirements]. + // For example, the below enables using `::testing::ElementsAre(...)` + using value_type = char; + using reference = value_type&; + using const_reference = const value_type&; + using iterator = CharIterator; + using const_iterator = CharIterator; + explicit CharRange(const Cord* cord) : cord_(cord) {} CharIterator begin() const; @@ -689,24 +689,24 @@ class Cord { explicit constexpr Cord(strings_internal::StringConstant<T>); private: - using CordRep = y_absl::cord_internal::CordRep; - using CordRepFlat = y_absl::cord_internal::CordRepFlat; - using CordzInfo = cord_internal::CordzInfo; - using CordzUpdateScope = cord_internal::CordzUpdateScope; - using CordzUpdateTracker = cord_internal::CordzUpdateTracker; - using InlineData = cord_internal::InlineData; - using MethodIdentifier = CordzUpdateTracker::MethodIdentifier; - - // Creates a cord instance with `method` representing the originating - // public API call causing the cord to be created. - explicit Cord(y_absl::string_view src, MethodIdentifier method); - + using CordRep = y_absl::cord_internal::CordRep; + using CordRepFlat = y_absl::cord_internal::CordRepFlat; + using CordzInfo = cord_internal::CordzInfo; + using CordzUpdateScope = cord_internal::CordzUpdateScope; + using CordzUpdateTracker = cord_internal::CordzUpdateTracker; + using InlineData = cord_internal::InlineData; + using MethodIdentifier = CordzUpdateTracker::MethodIdentifier; + + // Creates a cord instance with `method` representing the originating + // public API call causing the cord to be created. + explicit Cord(y_absl::string_view src, MethodIdentifier method); + friend class CordTestPeer; friend bool operator==(const Cord& lhs, const Cord& rhs); friend bool operator==(const Cord& lhs, y_absl::string_view rhs); - friend const CordzInfo* GetCordzInfoForTesting(const Cord& cord); - + friend const CordzInfo* GetCordzInfoForTesting(const Cord& cord); + // Calls the provided function once for each cord chunk, in order. Unlike // Chunks(), this API will not allocate memory. void ForEachChunk(y_absl::FunctionRef<void(y_absl::string_view)>) const; @@ -726,7 +726,7 @@ class Cord { static_assert(kMaxInline >= sizeof(y_absl::cord_internal::CordRep*), ""); constexpr InlineRep() : data_() {} - explicit InlineRep(InlineData::DefaultInitType init) : data_(init) {} + explicit InlineRep(InlineData::DefaultInitType init) : data_(init) {} InlineRep(const InlineRep& src); InlineRep(InlineRep&& src); InlineRep& operator=(const InlineRep& src); @@ -740,60 +740,60 @@ class Cord { const char* data() const; // Returns nullptr if holding pointer void set_data(const char* data, size_t n, bool nullify_tail); // Discards pointer, if any - char* set_data(size_t n); // Write data to the result + char* set_data(size_t n); // Write data to the result // Returns nullptr if holding bytes y_absl::cord_internal::CordRep* tree() const; y_absl::cord_internal::CordRep* as_tree() const; // Returns non-null iff was holding a pointer y_absl::cord_internal::CordRep* clear(); // Converts to pointer if necessary. - void reduce_size(size_t n); // REQUIRES: holding data + void reduce_size(size_t n); // REQUIRES: holding data void remove_prefix(size_t n); // REQUIRES: holding data - void AppendArray(y_absl::string_view src, MethodIdentifier method); + void AppendArray(y_absl::string_view src, MethodIdentifier method); y_absl::string_view FindFlatStartPiece() const; - - // Creates a CordRepFlat instance from the current inlined data with `extra' - // bytes of desired additional capacity. - CordRepFlat* MakeFlatWithExtraCapacity(size_t extra); - - // Sets the tree value for this instance. `rep` must not be null. - // Requires the current instance to hold a tree, and a lock to be held on - // any CordzInfo referenced by this instance. The latter is enforced through - // the CordzUpdateScope argument. If the current instance is sampled, then - // the CordzInfo instance is updated to reference the new `rep` value. - void SetTree(CordRep* rep, const CordzUpdateScope& scope); - - // Identical to SetTree(), except that `rep` is allowed to be null, in - // which case the current instance is reset to an empty value. - void SetTreeOrEmpty(CordRep* rep, const CordzUpdateScope& scope); - - // Sets the tree value for this instance, and randomly samples this cord. - // This function disregards existing contents in `data_`, and should be - // called when a Cord is 'promoted' from an 'uninitialized' or 'inlined' - // value to a non-inlined (tree / ring) value. - void EmplaceTree(CordRep* rep, MethodIdentifier method); - - // Identical to EmplaceTree, except that it copies the parent stack from - // the provided `parent` data if the parent is sampled. - void EmplaceTree(CordRep* rep, const InlineData& parent, - MethodIdentifier method); - - // Commits the change of a newly created, or updated `rep` root value into - // this cord. `old_rep` indicates the old (inlined or tree) value of the - // cord, and determines if the commit invokes SetTree() or EmplaceTree(). - void CommitTree(const CordRep* old_rep, CordRep* rep, - const CordzUpdateScope& scope, MethodIdentifier method); - - void AppendTreeToInlined(CordRep* tree, MethodIdentifier method); - void AppendTreeToTree(CordRep* tree, MethodIdentifier method); - void AppendTree(CordRep* tree, MethodIdentifier method); - void PrependTreeToInlined(CordRep* tree, MethodIdentifier method); - void PrependTreeToTree(CordRep* tree, MethodIdentifier method); - void PrependTree(CordRep* tree, MethodIdentifier method); - - template <bool has_length> - void GetAppendRegion(char** region, size_t* size, size_t length); - + + // Creates a CordRepFlat instance from the current inlined data with `extra' + // bytes of desired additional capacity. + CordRepFlat* MakeFlatWithExtraCapacity(size_t extra); + + // Sets the tree value for this instance. `rep` must not be null. + // Requires the current instance to hold a tree, and a lock to be held on + // any CordzInfo referenced by this instance. The latter is enforced through + // the CordzUpdateScope argument. If the current instance is sampled, then + // the CordzInfo instance is updated to reference the new `rep` value. + void SetTree(CordRep* rep, const CordzUpdateScope& scope); + + // Identical to SetTree(), except that `rep` is allowed to be null, in + // which case the current instance is reset to an empty value. + void SetTreeOrEmpty(CordRep* rep, const CordzUpdateScope& scope); + + // Sets the tree value for this instance, and randomly samples this cord. + // This function disregards existing contents in `data_`, and should be + // called when a Cord is 'promoted' from an 'uninitialized' or 'inlined' + // value to a non-inlined (tree / ring) value. + void EmplaceTree(CordRep* rep, MethodIdentifier method); + + // Identical to EmplaceTree, except that it copies the parent stack from + // the provided `parent` data if the parent is sampled. + void EmplaceTree(CordRep* rep, const InlineData& parent, + MethodIdentifier method); + + // Commits the change of a newly created, or updated `rep` root value into + // this cord. `old_rep` indicates the old (inlined or tree) value of the + // cord, and determines if the commit invokes SetTree() or EmplaceTree(). + void CommitTree(const CordRep* old_rep, CordRep* rep, + const CordzUpdateScope& scope, MethodIdentifier method); + + void AppendTreeToInlined(CordRep* tree, MethodIdentifier method); + void AppendTreeToTree(CordRep* tree, MethodIdentifier method); + void AppendTree(CordRep* tree, MethodIdentifier method); + void PrependTreeToInlined(CordRep* tree, MethodIdentifier method); + void PrependTreeToTree(CordRep* tree, MethodIdentifier method); + void PrependTree(CordRep* tree, MethodIdentifier method); + + template <bool has_length> + void GetAppendRegion(char** region, size_t* size, size_t length); + bool IsSame(const InlineRep& other) const { return memcmp(&data_, &other.data_, sizeof(data_)) == 0; } @@ -849,8 +849,8 @@ class Cord { friend class Cord; void AssignSlow(const InlineRep& src); - // Unrefs the tree and stops profiling. - void UnrefTree(); + // Unrefs the tree and stops profiling. + void UnrefTree(); void ResetToEmpty() { data_ = {}; } @@ -901,14 +901,14 @@ class Cord { template <typename C> void AppendImpl(C&& src); - // Prepends the provided data to this instance. `method` contains the public - // API method for this action which is tracked for Cordz sampling purposes. - void PrependArray(y_absl::string_view src, MethodIdentifier method); - - // Assigns the value in 'src' to this instance, 'stealing' its contents. - // Requires src.length() > kMaxBytesToCopy. - Cord& AssignLargeString(TString&& src); - + // Prepends the provided data to this instance. `method` contains the public + // API method for this action which is tracked for Cordz sampling purposes. + void PrependArray(y_absl::string_view src, MethodIdentifier method); + + // Assigns the value in 'src' to this instance, 'stealing' its contents. + // Requires src.length() > kMaxBytesToCopy. + Cord& AssignLargeString(TString&& src); + // Helper for AbslHashValue(). template <typename H> H HashFragmented(H hash_state) const { @@ -1011,11 +1011,11 @@ inline CordRep* NewExternalRep(y_absl::string_view data, template <typename Releaser> Cord MakeCordFromExternal(y_absl::string_view data, Releaser&& releaser) { Cord cord; - if (auto* rep = ::y_absl::cord_internal::NewExternalRep( - data, std::forward<Releaser>(releaser))) { - cord.contents_.EmplaceTree(rep, - Cord::MethodIdentifier::kMakeCordFromExternal); - } + if (auto* rep = ::y_absl::cord_internal::NewExternalRep( + data, std::forward<Releaser>(releaser))) { + cord.contents_.EmplaceTree(rep, + Cord::MethodIdentifier::kMakeCordFromExternal); + } return cord; } @@ -1023,16 +1023,16 @@ constexpr Cord::InlineRep::InlineRep(cord_internal::InlineData data) : data_(data) {} inline Cord::InlineRep::InlineRep(const Cord::InlineRep& src) - : data_(InlineData::kDefaultInit) { - if (CordRep* tree = src.tree()) { - EmplaceTree(CordRep::Ref(tree), src.data_, - CordzUpdateTracker::kConstructorCord); - } else { - data_ = src.data_; + : data_(InlineData::kDefaultInit) { + if (CordRep* tree = src.tree()) { + EmplaceTree(CordRep::Ref(tree), src.data_, + CordzUpdateTracker::kConstructorCord); + } else { + data_ = src.data_; } } -inline Cord::InlineRep::InlineRep(Cord::InlineRep&& src) : data_(src.data_) { +inline Cord::InlineRep::InlineRep(Cord::InlineRep&& src) : data_(src.data_) { src.ResetToEmpty(); } @@ -1051,7 +1051,7 @@ inline Cord::InlineRep& Cord::InlineRep::operator=(const Cord::InlineRep& src) { inline Cord::InlineRep& Cord::InlineRep::operator=( Cord::InlineRep&& src) noexcept { if (is_tree()) { - UnrefTree(); + UnrefTree(); } data_ = src.data_; src.ResetToEmpty(); @@ -1088,62 +1088,62 @@ inline size_t Cord::InlineRep::size() const { return is_tree() ? as_tree()->length : inline_size(); } -inline cord_internal::CordRepFlat* Cord::InlineRep::MakeFlatWithExtraCapacity( - size_t extra) { - static_assert(cord_internal::kMinFlatLength >= sizeof(data_), ""); - size_t len = data_.inline_size(); - auto* result = CordRepFlat::New(len + extra); - result->length = len; - memcpy(result->Data(), data_.as_chars(), sizeof(data_)); - return result; -} - -inline void Cord::InlineRep::EmplaceTree(CordRep* rep, - MethodIdentifier method) { - assert(rep); - data_.make_tree(rep); - CordzInfo::MaybeTrackCord(data_, method); -} - -inline void Cord::InlineRep::EmplaceTree(CordRep* rep, const InlineData& parent, - MethodIdentifier method) { - data_.make_tree(rep); - CordzInfo::MaybeTrackCord(data_, parent, method); -} - -inline void Cord::InlineRep::SetTree(CordRep* rep, - const CordzUpdateScope& scope) { - assert(rep); - assert(data_.is_tree()); - data_.set_tree(rep); - scope.SetCordRep(rep); -} - -inline void Cord::InlineRep::SetTreeOrEmpty(CordRep* rep, - const CordzUpdateScope& scope) { - assert(data_.is_tree()); - if (rep) { - data_.set_tree(rep); +inline cord_internal::CordRepFlat* Cord::InlineRep::MakeFlatWithExtraCapacity( + size_t extra) { + static_assert(cord_internal::kMinFlatLength >= sizeof(data_), ""); + size_t len = data_.inline_size(); + auto* result = CordRepFlat::New(len + extra); + result->length = len; + memcpy(result->Data(), data_.as_chars(), sizeof(data_)); + return result; +} + +inline void Cord::InlineRep::EmplaceTree(CordRep* rep, + MethodIdentifier method) { + assert(rep); + data_.make_tree(rep); + CordzInfo::MaybeTrackCord(data_, method); +} + +inline void Cord::InlineRep::EmplaceTree(CordRep* rep, const InlineData& parent, + MethodIdentifier method) { + data_.make_tree(rep); + CordzInfo::MaybeTrackCord(data_, parent, method); +} + +inline void Cord::InlineRep::SetTree(CordRep* rep, + const CordzUpdateScope& scope) { + assert(rep); + assert(data_.is_tree()); + data_.set_tree(rep); + scope.SetCordRep(rep); +} + +inline void Cord::InlineRep::SetTreeOrEmpty(CordRep* rep, + const CordzUpdateScope& scope) { + assert(data_.is_tree()); + if (rep) { + data_.set_tree(rep); } else { - data_ = {}; + data_ = {}; } - scope.SetCordRep(rep); + scope.SetCordRep(rep); } -inline void Cord::InlineRep::CommitTree(const CordRep* old_rep, CordRep* rep, - const CordzUpdateScope& scope, - MethodIdentifier method) { - if (old_rep) { - SetTree(rep, scope); - } else { - EmplaceTree(rep, method); +inline void Cord::InlineRep::CommitTree(const CordRep* old_rep, CordRep* rep, + const CordzUpdateScope& scope, + MethodIdentifier method) { + if (old_rep) { + SetTree(rep, scope); + } else { + EmplaceTree(rep, method); } } inline y_absl::cord_internal::CordRep* Cord::InlineRep::clear() { - if (is_tree()) { - CordzInfo::MaybeUntrackCord(cordz_info()); - } + if (is_tree()) { + CordzInfo::MaybeUntrackCord(cordz_info()); + } y_absl::cord_internal::CordRep* result = tree(); ResetToEmpty(); return result; @@ -1158,9 +1158,9 @@ inline void Cord::InlineRep::CopyToArray(char* dst) const { constexpr inline Cord::Cord() noexcept {} -inline Cord::Cord(y_absl::string_view src) - : Cord(src, CordzUpdateTracker::kConstructorString) {} - +inline Cord::Cord(y_absl::string_view src) + : Cord(src, CordzUpdateTracker::kConstructorString) {} + template <typename T> constexpr Cord::Cord(strings_internal::StringConstant<T>) : contents_(strings_internal::StringConstant<T>::value.size() <= @@ -1176,15 +1176,15 @@ inline Cord& Cord::operator=(const Cord& x) { return *this; } -template <typename T, Cord::EnableIfString<T>> -Cord& Cord::operator=(T&& src) { - if (src.size() <= cord_internal::kMaxBytesToCopy) { - return operator=(y_absl::string_view(src)); - } else { - return AssignLargeString(std::forward<T>(src)); - } -} - +template <typename T, Cord::EnableIfString<T>> +Cord& Cord::operator=(T&& src) { + if (src.size() <= cord_internal::kMaxBytesToCopy) { + return operator=(y_absl::string_view(src)); + } else { + return AssignLargeString(std::forward<T>(src)); + } +} + inline Cord::Cord(const Cord& src) : contents_(src.contents_) {} inline Cord::Cord(Cord&& src) noexcept : contents_(std::move(src.contents_)) {} @@ -1241,13 +1241,13 @@ inline y_absl::string_view Cord::Flatten() { } inline void Cord::Append(y_absl::string_view src) { - contents_.AppendArray(src, CordzUpdateTracker::kAppendString); -} - -inline void Cord::Prepend(y_absl::string_view src) { - PrependArray(src, CordzUpdateTracker::kPrependString); + contents_.AppendArray(src, CordzUpdateTracker::kAppendString); } +inline void Cord::Prepend(y_absl::string_view src) { + PrependArray(src, CordzUpdateTracker::kPrependString); +} + extern template void Cord::Append(TString&& src); extern template void Cord::Prepend(TString&& src); @@ -1274,8 +1274,8 @@ inline bool Cord::StartsWith(y_absl::string_view rhs) const { } inline void Cord::ChunkIterator::InitTree(cord_internal::CordRep* tree) { - if (tree->tag == cord_internal::BTREE) { - current_chunk_ = btree_reader_.Init(tree->btree()); + if (tree->tag == cord_internal::BTREE) { + current_chunk_ = btree_reader_.Init(tree->btree()); return; } @@ -1298,20 +1298,20 @@ inline Cord::ChunkIterator::ChunkIterator(const Cord* cord) } } -inline Cord::ChunkIterator& Cord::ChunkIterator::AdvanceBtree() { - current_chunk_ = btree_reader_.Next(); +inline Cord::ChunkIterator& Cord::ChunkIterator::AdvanceBtree() { + current_chunk_ = btree_reader_.Next(); return *this; } -inline void Cord::ChunkIterator::AdvanceBytesBtree(size_t n) { +inline void Cord::ChunkIterator::AdvanceBytesBtree(size_t n) { assert(n >= current_chunk_.size()); bytes_remaining_ -= n; if (bytes_remaining_) { if (n == current_chunk_.size()) { - current_chunk_ = btree_reader_.Next(); + current_chunk_ = btree_reader_.Next(); } else { - size_t offset = btree_reader_.length() - bytes_remaining_; - current_chunk_ = btree_reader_.Seek(offset); + size_t offset = btree_reader_.length() - bytes_remaining_; + current_chunk_ = btree_reader_.Seek(offset); } } else { current_chunk_ = {}; @@ -1324,7 +1324,7 @@ inline Cord::ChunkIterator& Cord::ChunkIterator::operator++() { assert(bytes_remaining_ >= current_chunk_.size()); bytes_remaining_ -= current_chunk_.size(); if (bytes_remaining_ > 0) { - return btree_reader_ ? AdvanceBtree() : AdvanceStack(); + return btree_reader_ ? AdvanceBtree() : AdvanceStack(); } else { current_chunk_ = {}; } @@ -1366,7 +1366,7 @@ inline void Cord::ChunkIterator::AdvanceBytes(size_t n) { if (ABSL_PREDICT_TRUE(n < current_chunk_.size())) { RemoveChunkPrefix(n); } else if (n != 0) { - btree_reader_ ? AdvanceBytesBtree(n) : AdvanceBytesSlowPath(n); + btree_reader_ ? AdvanceBytesBtree(n) : AdvanceBytesSlowPath(n); } } @@ -1466,8 +1466,8 @@ inline bool operator==(const Cord& lhs, const Cord& rhs) { } inline bool operator!=(const Cord& x, const Cord& y) { return !(x == y); } -inline bool operator<(const Cord& x, const Cord& y) { return x.Compare(y) < 0; } -inline bool operator>(const Cord& x, const Cord& y) { return x.Compare(y) > 0; } +inline bool operator<(const Cord& x, const Cord& y) { return x.Compare(y) < 0; } +inline bool operator>(const Cord& x, const Cord& y) { return x.Compare(y) > 0; } inline bool operator<=(const Cord& x, const Cord& y) { return x.Compare(y) <= 0; } diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord/ya.make index 8f3ec1f20f..8a876e0b0d 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord/ya.make @@ -13,28 +13,28 @@ LICENSE(Apache-2.0) PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/base - contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/low_level_alloc contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/raw_logging contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/throw_delegate contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity - contrib/restricted/abseil-cpp-tstring/y_absl/debugging - contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace - contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize - contrib/restricted/abseil-cpp-tstring/y_absl/demangle + contrib/restricted/abseil-cpp-tstring/y_absl/debugging + contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace + contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize + contrib/restricted/abseil-cpp-tstring/y_absl/demangle contrib/restricted/abseil-cpp-tstring/y_absl/numeric - contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased contrib/restricted/abseil-cpp-tstring/y_absl/strings - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_cord_internal - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info - contrib/restricted/abseil-cpp-tstring/y_absl/synchronization - contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal - contrib/restricted/abseil-cpp-tstring/y_absl/time - contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time - contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_cord_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info + contrib/restricted/abseil-cpp-tstring/y_absl/synchronization + contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal + contrib/restricted/abseil-cpp-tstring/y_absl/time + contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time + contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_optional_access contrib/restricted/abseil-cpp-tstring/y_absl/algorithm contrib/restricted/abseil-cpp-tstring/y_absl/container diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord_test_helpers.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord_test_helpers.h index 8dd7c05751..78aca35e51 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord_test_helpers.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord_test_helpers.h @@ -17,73 +17,73 @@ #ifndef ABSL_STRINGS_CORD_TEST_HELPERS_H_ #define ABSL_STRINGS_CORD_TEST_HELPERS_H_ -#include <cstdint> -#include <iostream> -#include <util/generic/string.h> - -#include "y_absl/base/config.h" +#include <cstdint> +#include <iostream> +#include <util/generic/string.h> + +#include "y_absl/base/config.h" #include "y_absl/strings/cord.h" -#include "y_absl/strings/internal/cord_internal.h" -#include "y_absl/strings/string_view.h" +#include "y_absl/strings/internal/cord_internal.h" +#include "y_absl/strings/string_view.h" namespace y_absl { ABSL_NAMESPACE_BEGIN -// Cord sizes relevant for testing -enum class TestCordSize { - // An empty value - kEmpty = 0, - - // An inlined string value - kInlined = cord_internal::kMaxInline / 2 + 1, - - // 'Well known' SSO lengths (excluding terminating zero). - // libstdcxx has a maximum SSO of 15, libc++ has a maximum SSO of 22. - kStringSso1 = 15, - kStringSso2 = 22, - - // A string value which is too large to fit in inlined data, but small enough - // such that Cord prefers copying the value if possible, i.e.: not stealing - // TString inputs, or referencing existing CordReps on Append, etc. - kSmall = cord_internal::kMaxBytesToCopy / 2 + 1, - - // A string value large enough that Cord prefers to reference or steal from - // existing inputs rather than copying contents of the input. - kMedium = cord_internal::kMaxFlatLength / 2 + 1, - - // A string value large enough to cause it to be stored in mutliple flats. - kLarge = cord_internal::kMaxFlatLength * 4 -}; - -// To string helper -inline y_absl::string_view ToString(TestCordSize size) { - switch (size) { - case TestCordSize::kEmpty: - return "Empty"; - case TestCordSize::kInlined: - return "Inlined"; - case TestCordSize::kSmall: - return "Small"; - case TestCordSize::kStringSso1: - return "StringSso1"; - case TestCordSize::kStringSso2: - return "StringSso2"; - case TestCordSize::kMedium: - return "Medium"; - case TestCordSize::kLarge: - return "Large"; - } - return "???"; -} - -// Returns the length matching the specified size -inline size_t Length(TestCordSize size) { return static_cast<size_t>(size); } - -// Stream output helper -inline std::ostream& operator<<(std::ostream& stream, TestCordSize size) { - return stream << ToString(size); -} - +// Cord sizes relevant for testing +enum class TestCordSize { + // An empty value + kEmpty = 0, + + // An inlined string value + kInlined = cord_internal::kMaxInline / 2 + 1, + + // 'Well known' SSO lengths (excluding terminating zero). + // libstdcxx has a maximum SSO of 15, libc++ has a maximum SSO of 22. + kStringSso1 = 15, + kStringSso2 = 22, + + // A string value which is too large to fit in inlined data, but small enough + // such that Cord prefers copying the value if possible, i.e.: not stealing + // TString inputs, or referencing existing CordReps on Append, etc. + kSmall = cord_internal::kMaxBytesToCopy / 2 + 1, + + // A string value large enough that Cord prefers to reference or steal from + // existing inputs rather than copying contents of the input. + kMedium = cord_internal::kMaxFlatLength / 2 + 1, + + // A string value large enough to cause it to be stored in mutliple flats. + kLarge = cord_internal::kMaxFlatLength * 4 +}; + +// To string helper +inline y_absl::string_view ToString(TestCordSize size) { + switch (size) { + case TestCordSize::kEmpty: + return "Empty"; + case TestCordSize::kInlined: + return "Inlined"; + case TestCordSize::kSmall: + return "Small"; + case TestCordSize::kStringSso1: + return "StringSso1"; + case TestCordSize::kStringSso2: + return "StringSso2"; + case TestCordSize::kMedium: + return "Medium"; + case TestCordSize::kLarge: + return "Large"; + } + return "???"; +} + +// Returns the length matching the specified size +inline size_t Length(TestCordSize size) { return static_cast<size_t>(size); } + +// Stream output helper +inline std::ostream& operator<<(std::ostream& stream, TestCordSize size) { + return stream << ToString(size); +} + // Creates a multi-segment Cord from an iterable container of strings. The // resulting Cord is guaranteed to have one segment for every string in the // container. This allows code to be unit tested with multi-segment Cord diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cordz_test_helpers.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cordz_test_helpers.h index bbb952f073..3adc14ea1f 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cordz_test_helpers.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/cordz_test_helpers.h @@ -1,151 +1,151 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_CORDZ_TEST_HELPERS_H_ -#define ABSL_STRINGS_CORDZ_TEST_HELPERS_H_ - -#include <utility> - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "y_absl/base/config.h" -#include "y_absl/base/macros.h" -#include "y_absl/strings/cord.h" -#include "y_absl/strings/internal/cord_internal.h" -#include "y_absl/strings/internal/cordz_info.h" -#include "y_absl/strings/internal/cordz_sample_token.h" -#include "y_absl/strings/internal/cordz_statistics.h" -#include "y_absl/strings/internal/cordz_update_tracker.h" -#include "y_absl/strings/str_cat.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN - -// Returns the CordzInfo for the cord, or nullptr if the cord is not sampled. -inline const cord_internal::CordzInfo* GetCordzInfoForTesting( - const Cord& cord) { - if (!cord.contents_.is_tree()) return nullptr; - return cord.contents_.cordz_info(); -} - -// Returns true if the provided cordz_info is in the list of sampled cords. -inline bool CordzInfoIsListed(const cord_internal::CordzInfo* cordz_info, - cord_internal::CordzSampleToken token = {}) { - for (const cord_internal::CordzInfo& info : token) { - if (cordz_info == &info) return true; - } - return false; -} - -// Matcher on Cord that verifies all of: -// - the cord is sampled -// - the CordzInfo of the cord is listed / discoverable. -// - the reported CordzStatistics match the cord's actual properties -// - the cord has an (initial) UpdateTracker count of 1 for `method` -MATCHER_P(HasValidCordzInfoOf, method, "CordzInfo matches cord") { - const cord_internal::CordzInfo* cord_info = GetCordzInfoForTesting(arg); - if (cord_info == nullptr) { - *result_listener << "cord is not sampled"; - return false; - } - if (!CordzInfoIsListed(cord_info)) { - *result_listener << "cord is sampled, but not listed"; - return false; - } - cord_internal::CordzStatistics stat = cord_info->GetCordzStatistics(); - if (stat.size != arg.size()) { - *result_listener << "cordz size " << stat.size - << " does not match cord size " << arg.size(); - return false; - } - if (stat.update_tracker.Value(method) != 1) { - *result_listener << "Expected method count 1 for " << method << ", found " - << stat.update_tracker.Value(method); - return false; - } - return true; -} - -// Matcher on Cord that verifies that the cord is sampled and that the CordzInfo -// update tracker has 'method' with a call count of 'n' -MATCHER_P2(CordzMethodCountEq, method, n, - y_absl::StrCat("CordzInfo method count equals ", n)) { - const cord_internal::CordzInfo* cord_info = GetCordzInfoForTesting(arg); - if (cord_info == nullptr) { - *result_listener << "cord is not sampled"; - return false; - } - cord_internal::CordzStatistics stat = cord_info->GetCordzStatistics(); - if (stat.update_tracker.Value(method) != n) { - *result_listener << "Expected method count " << n << " for " << method - << ", found " << stat.update_tracker.Value(method); - return false; - } - return true; -} - -// Cordz will only update with a new rate once the previously scheduled event -// has fired. When we disable Cordz, a long delay takes place where we won't -// consider profiling new Cords. CordzSampleIntervalHelper will burn through -// that interval and allow for testing that assumes that the average sampling -// interval is a particular value. -class CordzSamplingIntervalHelper { - public: - explicit CordzSamplingIntervalHelper(int32_t interval) - : orig_mean_interval_(y_absl::cord_internal::get_cordz_mean_interval()) { - y_absl::cord_internal::set_cordz_mean_interval(interval); - y_absl::cord_internal::cordz_set_next_sample_for_testing(interval); - } - - ~CordzSamplingIntervalHelper() { - y_absl::cord_internal::set_cordz_mean_interval(orig_mean_interval_); - y_absl::cord_internal::cordz_set_next_sample_for_testing(orig_mean_interval_); - } - - private: - int32_t orig_mean_interval_; -}; - -// Wrapper struct managing a small CordRep `rep` -struct TestCordRep { - cord_internal::CordRepFlat* rep; - - TestCordRep() { - rep = cord_internal::CordRepFlat::New(100); - rep->length = 100; - memset(rep->Data(), 1, 100); - } - ~TestCordRep() { cord_internal::CordRep::Unref(rep); } -}; - -// Wrapper struct managing a small CordRep `rep`, and -// an InlineData `data` initialized with that CordRep. -struct TestCordData { - TestCordRep rep; - cord_internal::InlineData data{rep.rep}; -}; - -// Creates a Cord that is not sampled -template <typename... Args> -Cord UnsampledCord(Args... args) { - CordzSamplingIntervalHelper never(9999); - Cord cord(std::forward<Args>(args)...); - ABSL_ASSERT(GetCordzInfoForTesting(cord) == nullptr); - return cord; -} - -ABSL_NAMESPACE_END -} // namespace y_absl - -#endif // ABSL_STRINGS_CORDZ_TEST_HELPERS_H_ +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_CORDZ_TEST_HELPERS_H_ +#define ABSL_STRINGS_CORDZ_TEST_HELPERS_H_ + +#include <utility> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "y_absl/base/config.h" +#include "y_absl/base/macros.h" +#include "y_absl/strings/cord.h" +#include "y_absl/strings/internal/cord_internal.h" +#include "y_absl/strings/internal/cordz_info.h" +#include "y_absl/strings/internal/cordz_sample_token.h" +#include "y_absl/strings/internal/cordz_statistics.h" +#include "y_absl/strings/internal/cordz_update_tracker.h" +#include "y_absl/strings/str_cat.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN + +// Returns the CordzInfo for the cord, or nullptr if the cord is not sampled. +inline const cord_internal::CordzInfo* GetCordzInfoForTesting( + const Cord& cord) { + if (!cord.contents_.is_tree()) return nullptr; + return cord.contents_.cordz_info(); +} + +// Returns true if the provided cordz_info is in the list of sampled cords. +inline bool CordzInfoIsListed(const cord_internal::CordzInfo* cordz_info, + cord_internal::CordzSampleToken token = {}) { + for (const cord_internal::CordzInfo& info : token) { + if (cordz_info == &info) return true; + } + return false; +} + +// Matcher on Cord that verifies all of: +// - the cord is sampled +// - the CordzInfo of the cord is listed / discoverable. +// - the reported CordzStatistics match the cord's actual properties +// - the cord has an (initial) UpdateTracker count of 1 for `method` +MATCHER_P(HasValidCordzInfoOf, method, "CordzInfo matches cord") { + const cord_internal::CordzInfo* cord_info = GetCordzInfoForTesting(arg); + if (cord_info == nullptr) { + *result_listener << "cord is not sampled"; + return false; + } + if (!CordzInfoIsListed(cord_info)) { + *result_listener << "cord is sampled, but not listed"; + return false; + } + cord_internal::CordzStatistics stat = cord_info->GetCordzStatistics(); + if (stat.size != arg.size()) { + *result_listener << "cordz size " << stat.size + << " does not match cord size " << arg.size(); + return false; + } + if (stat.update_tracker.Value(method) != 1) { + *result_listener << "Expected method count 1 for " << method << ", found " + << stat.update_tracker.Value(method); + return false; + } + return true; +} + +// Matcher on Cord that verifies that the cord is sampled and that the CordzInfo +// update tracker has 'method' with a call count of 'n' +MATCHER_P2(CordzMethodCountEq, method, n, + y_absl::StrCat("CordzInfo method count equals ", n)) { + const cord_internal::CordzInfo* cord_info = GetCordzInfoForTesting(arg); + if (cord_info == nullptr) { + *result_listener << "cord is not sampled"; + return false; + } + cord_internal::CordzStatistics stat = cord_info->GetCordzStatistics(); + if (stat.update_tracker.Value(method) != n) { + *result_listener << "Expected method count " << n << " for " << method + << ", found " << stat.update_tracker.Value(method); + return false; + } + return true; +} + +// Cordz will only update with a new rate once the previously scheduled event +// has fired. When we disable Cordz, a long delay takes place where we won't +// consider profiling new Cords. CordzSampleIntervalHelper will burn through +// that interval and allow for testing that assumes that the average sampling +// interval is a particular value. +class CordzSamplingIntervalHelper { + public: + explicit CordzSamplingIntervalHelper(int32_t interval) + : orig_mean_interval_(y_absl::cord_internal::get_cordz_mean_interval()) { + y_absl::cord_internal::set_cordz_mean_interval(interval); + y_absl::cord_internal::cordz_set_next_sample_for_testing(interval); + } + + ~CordzSamplingIntervalHelper() { + y_absl::cord_internal::set_cordz_mean_interval(orig_mean_interval_); + y_absl::cord_internal::cordz_set_next_sample_for_testing(orig_mean_interval_); + } + + private: + int32_t orig_mean_interval_; +}; + +// Wrapper struct managing a small CordRep `rep` +struct TestCordRep { + cord_internal::CordRepFlat* rep; + + TestCordRep() { + rep = cord_internal::CordRepFlat::New(100); + rep->length = 100; + memset(rep->Data(), 1, 100); + } + ~TestCordRep() { cord_internal::CordRep::Unref(rep); } +}; + +// Wrapper struct managing a small CordRep `rep`, and +// an InlineData `data` initialized with that CordRep. +struct TestCordData { + TestCordRep rep; + cord_internal::InlineData data{rep.rep}; +}; + +// Creates a Cord that is not sampled +template <typename... Args> +Cord UnsampledCord(Args... args) { + CordzSamplingIntervalHelper never(9999); + Cord cord(std::forward<Args>(args)...); + ABSL_ASSERT(GetCordzInfoForTesting(cord) == nullptr); + return cord; +} + +ABSL_NAMESPACE_END +} // namespace y_absl + +#endif // ABSL_STRINGS_CORDZ_TEST_HELPERS_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_cord_internal/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_cord_internal/ya.make index 42b7b6cd5e..aa888d4ecd 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_cord_internal/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_cord_internal/ya.make @@ -19,7 +19,7 @@ PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity contrib/restricted/abseil-cpp-tstring/y_absl/numeric contrib/restricted/abseil-cpp-tstring/y_absl/strings - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal ) ADDINCL( @@ -28,15 +28,15 @@ ADDINCL( NO_COMPILER_WARNINGS() -SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal) +SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal) SRCS( - cord_internal.cc - cord_rep_btree.cc - cord_rep_btree_navigator.cc - cord_rep_btree_reader.cc - cord_rep_consume.cc - cord_rep_ring.cc + cord_internal.cc + cord_rep_btree.cc + cord_rep_btree_navigator.cc + cord_rep_btree_reader.cc + cord_rep_consume.cc + cord_rep_ring.cc ) END() diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal/ya.make index 4e57fc75f6..ad0e94f7a6 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal/ya.make @@ -2,8 +2,8 @@ LIBRARY() -WITHOUT_LICENSE_TEXTS() - +WITHOUT_LICENSE_TEXTS() + OWNER( somov g:cpp-contrib @@ -24,8 +24,8 @@ ADDINCL( NO_COMPILER_WARNINGS() -SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal) - +SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal) + SRCS( escaping.cc ostringstream.cc diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/charconv_parse.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/charconv_parse.cc index f0f78eb68c..80ac216750 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/charconv_parse.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/charconv_parse.cc @@ -52,7 +52,7 @@ static_assert(std::numeric_limits<double>::digits == 53, "IEEE double fact"); // The lowest valued 19-digit decimal mantissa we can read still contains // sufficient information to reconstruct a binary mantissa. -static_assert(1000000000000000000u > (uint64_t{1} << (53 + 3)), "(b) above"); +static_assert(1000000000000000000u > (uint64_t{1} << (53 + 3)), "(b) above"); // ParseFloat<16> will read the first 15 significant digits of the mantissa. // diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_internal.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_internal.cc index 6fc39985d8..2a14b0f610 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_internal.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_internal.cc @@ -18,7 +18,7 @@ #include <memory> #include "y_absl/container/inlined_vector.h" -#include "y_absl/strings/internal/cord_rep_btree.h" +#include "y_absl/strings/internal/cord_rep_btree.h" #include "y_absl/strings/internal/cord_rep_flat.h" #include "y_absl/strings/internal/cord_rep_ring.h" @@ -26,12 +26,12 @@ namespace y_absl { ABSL_NAMESPACE_BEGIN namespace cord_internal { -ABSL_CONST_INIT std::atomic<bool> cord_btree_enabled(kCordEnableBtreeDefault); +ABSL_CONST_INIT std::atomic<bool> cord_btree_enabled(kCordEnableBtreeDefault); ABSL_CONST_INIT std::atomic<bool> cord_ring_buffer_enabled( kCordEnableRingBufferDefault); ABSL_CONST_INIT std::atomic<bool> shallow_subcords_enabled( kCordShallowSubcordsDefault); -ABSL_CONST_INIT std::atomic<bool> cord_btree_exhaustive_validation(false); +ABSL_CONST_INIT std::atomic<bool> cord_btree_exhaustive_validation(false); void CordRep::Destroy(CordRep* rep) { assert(rep != nullptr); @@ -52,9 +52,9 @@ void CordRep::Destroy(CordRep* rep) { rep = left; continue; } - } else if (rep->tag == BTREE) { - CordRepBtree::Destroy(rep->btree()); - rep = nullptr; + } else if (rep->tag == BTREE) { + CordRepBtree::Destroy(rep->btree()); + rep = nullptr; } else if (rep->tag == RING) { CordRepRing::Destroy(rep->ring()); rep = nullptr; diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_internal.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_internal.h index 82f5ac7b81..3806497743 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_internal.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_internal.h @@ -37,25 +37,25 @@ class CordzInfo; // Default feature enable states for cord ring buffers enum CordFeatureDefaults { - kCordEnableBtreeDefault = true, + kCordEnableBtreeDefault = true, kCordEnableRingBufferDefault = false, kCordShallowSubcordsDefault = false }; -extern std::atomic<bool> cord_btree_enabled; +extern std::atomic<bool> cord_btree_enabled; extern std::atomic<bool> cord_ring_buffer_enabled; extern std::atomic<bool> shallow_subcords_enabled; -// `cord_btree_exhaustive_validation` can be set to force exhaustive validation -// in debug assertions, and code that calls `IsValid()` explicitly. By default, -// assertions should be relatively cheap and AssertValid() can easily lead to -// O(n^2) complexity as recursive / full tree validation is O(n). -extern std::atomic<bool> cord_btree_exhaustive_validation; - -inline void enable_cord_btree(bool enable) { - cord_btree_enabled.store(enable, std::memory_order_relaxed); -} - +// `cord_btree_exhaustive_validation` can be set to force exhaustive validation +// in debug assertions, and code that calls `IsValid()` explicitly. By default, +// assertions should be relatively cheap and AssertValid() can easily lead to +// O(n^2) complexity as recursive / full tree validation is O(n). +extern std::atomic<bool> cord_btree_exhaustive_validation; + +inline void enable_cord_btree(bool enable) { + cord_btree_enabled.store(enable, std::memory_order_relaxed); +} + inline void enable_cord_ring_buffer(bool enable) { cord_ring_buffer_enabled.store(enable, std::memory_order_relaxed); } @@ -80,16 +80,16 @@ enum Constants { kMaxBytesToCopy = 511 }; -// Compact class for tracking the reference count and state flags for CordRep -// instances. Data is stored in an atomic int32_t for compactness and speed. -class RefcountAndFlags { +// Compact class for tracking the reference count and state flags for CordRep +// instances. Data is stored in an atomic int32_t for compactness and speed. +class RefcountAndFlags { public: - constexpr RefcountAndFlags() : count_{kRefIncrement} {} + constexpr RefcountAndFlags() : count_{kRefIncrement} {} struct Immortal {}; - explicit constexpr RefcountAndFlags(Immortal) : count_(kImmortalFlag) {} - struct WithCrc {}; - explicit constexpr RefcountAndFlags(WithCrc) - : count_(kCrcFlag | kRefIncrement) {} + explicit constexpr RefcountAndFlags(Immortal) : count_(kImmortalFlag) {} + struct WithCrc {}; + explicit constexpr RefcountAndFlags(WithCrc) + : count_(kCrcFlag | kRefIncrement) {} // Increments the reference count. Imposes no memory ordering. inline void Increment() { @@ -102,82 +102,82 @@ class RefcountAndFlags { // Returns false if there are no references outstanding; true otherwise. // Inserts barriers to ensure that state written before this method returns // false will be visible to a thread that just observed this method returning - // false. Always returns false when the immortal bit is set. + // false. Always returns false when the immortal bit is set. inline bool Decrement() { - int32_t refcount = count_.load(std::memory_order_acquire) & kRefcountMask; - assert(refcount > 0 || refcount & kImmortalFlag); + int32_t refcount = count_.load(std::memory_order_acquire) & kRefcountMask; + assert(refcount > 0 || refcount & kImmortalFlag); return refcount != kRefIncrement && - (count_.fetch_sub(kRefIncrement, std::memory_order_acq_rel) & - kRefcountMask) != kRefIncrement; + (count_.fetch_sub(kRefIncrement, std::memory_order_acq_rel) & + kRefcountMask) != kRefIncrement; } // Same as Decrement but expect that refcount is greater than 1. inline bool DecrementExpectHighRefcount() { int32_t refcount = - count_.fetch_sub(kRefIncrement, std::memory_order_acq_rel) & - kRefcountMask; - assert(refcount > 0 || refcount & kImmortalFlag); + count_.fetch_sub(kRefIncrement, std::memory_order_acq_rel) & + kRefcountMask; + assert(refcount > 0 || refcount & kImmortalFlag); return refcount != kRefIncrement; } // Returns the current reference count using acquire semantics. inline int32_t Get() const { - return count_.load(std::memory_order_acquire) >> kNumFlags; - } - - // Returns true if the referenced object carries a CRC value. - bool HasCrc() const { - return (count_.load(std::memory_order_relaxed) & kCrcFlag) != 0; - } - - // Returns true iff the atomic integer is 1 and this node does not store - // a CRC. When both these conditions are met, the current thread owns - // the reference and no other thread shares it, so its contents may be - // safely mutated. - // - // If the referenced item is shared, carries a CRC, or is immortal, - // it should not be modified in-place, and this function returns false. - // - // This call performs the memory barrier needed for the owning thread - // to act on the object, so that if it returns true, it may safely - // assume exclusive access to the object. - inline bool IsMutable() { - return (count_.load(std::memory_order_acquire)) == kRefIncrement; + return count_.load(std::memory_order_acquire) >> kNumFlags; } - // Returns whether the atomic integer is 1. Similar to IsMutable(), - // but does not check for a stored CRC. (An unshared node with a CRC is not - // mutable, because changing its data would invalidate the CRC.) - // - // When this returns true, there are no other references, and data sinks - // may safely adopt the children of the CordRep. + // Returns true if the referenced object carries a CRC value. + bool HasCrc() const { + return (count_.load(std::memory_order_relaxed) & kCrcFlag) != 0; + } + + // Returns true iff the atomic integer is 1 and this node does not store + // a CRC. When both these conditions are met, the current thread owns + // the reference and no other thread shares it, so its contents may be + // safely mutated. + // + // If the referenced item is shared, carries a CRC, or is immortal, + // it should not be modified in-place, and this function returns false. + // + // This call performs the memory barrier needed for the owning thread + // to act on the object, so that if it returns true, it may safely + // assume exclusive access to the object. + inline bool IsMutable() { + return (count_.load(std::memory_order_acquire)) == kRefIncrement; + } + + // Returns whether the atomic integer is 1. Similar to IsMutable(), + // but does not check for a stored CRC. (An unshared node with a CRC is not + // mutable, because changing its data would invalidate the CRC.) + // + // When this returns true, there are no other references, and data sinks + // may safely adopt the children of the CordRep. inline bool IsOne() { - return (count_.load(std::memory_order_acquire) & kRefcountMask) == - kRefIncrement; + return (count_.load(std::memory_order_acquire) & kRefcountMask) == + kRefIncrement; } bool IsImmortal() const { - return (count_.load(std::memory_order_relaxed) & kImmortalFlag) != 0; + return (count_.load(std::memory_order_relaxed) & kImmortalFlag) != 0; } private: - // We reserve the bottom bits for flags. - // kImmortalBit indicates that this entity should never be collected; it is - // used for the StringConstant constructor to avoid collecting immutable - // constant cords. - // kReservedFlag is reserved for future use. + // We reserve the bottom bits for flags. + // kImmortalBit indicates that this entity should never be collected; it is + // used for the StringConstant constructor to avoid collecting immutable + // constant cords. + // kReservedFlag is reserved for future use. enum { - kNumFlags = 2, - - kImmortalFlag = 0x1, - kCrcFlag = 0x2, - kRefIncrement = (1 << kNumFlags), - - // Bitmask to use when checking refcount by equality. This masks out - // all flags except kImmortalFlag, which is part of the refcount for - // purposes of equality. (A refcount of 0 or 1 does not count as 0 or 1 - // if the immortal bit is set.) - kRefcountMask = ~kCrcFlag, + kNumFlags = 2, + + kImmortalFlag = 0x1, + kCrcFlag = 0x2, + kRefIncrement = (1 << kNumFlags), + + // Bitmask to use when checking refcount by equality. This masks out + // all flags except kImmortalFlag, which is part of the refcount for + // purposes of equality. (A refcount of 0 or 1 does not count as 0 or 1 + // if the immortal bit is set.) + kRefcountMask = ~kCrcFlag, }; std::atomic<int32_t> count_; @@ -193,68 +193,68 @@ struct CordRepExternal; struct CordRepFlat; struct CordRepSubstring; class CordRepRing; -class CordRepBtree; +class CordRepBtree; // Various representations that we allow enum CordRepKind { CONCAT = 0, - SUBSTRING = 1, - BTREE = 2, + SUBSTRING = 1, + BTREE = 2, RING = 3, - EXTERNAL = 4, + EXTERNAL = 4, // We have different tags for different sized flat arrays, - // starting with FLAT, and limited to MAX_FLAT_TAG. The 225 value is based on + // starting with FLAT, and limited to MAX_FLAT_TAG. The 225 value is based on // the current 'size to tag' encoding of 8 / 32 bytes. If a new tag is needed // in the future, then 'FLAT' and 'MAX_FLAT_TAG' should be adjusted as well // as the Tag <---> Size logic so that FLAT stil represents the minimum flat // allocation size. (32 bytes as of now). - FLAT = 5, - MAX_FLAT_TAG = 225 + FLAT = 5, + MAX_FLAT_TAG = 225 }; -// There are various locations where we want to check if some rep is a 'plain' -// data edge, i.e. an external or flat rep. By having FLAT == EXTERNAL + 1, we -// can perform this check in a single branch as 'tag >= EXTERNAL' -// Likewise, we have some locations where we check for 'ring or external/flat', -// so likewise align RING to EXTERNAL. -// Note that we can leave this optimization to the compiler. The compiler will -// DTRT when it sees a condition like `tag == EXTERNAL || tag >= FLAT`. -static_assert(RING == BTREE + 1, "BTREE and RING not consecutive"); -static_assert(EXTERNAL == RING + 1, "BTREE and EXTERNAL not consecutive"); -static_assert(FLAT == EXTERNAL + 1, "EXTERNAL and FLAT not consecutive"); - +// There are various locations where we want to check if some rep is a 'plain' +// data edge, i.e. an external or flat rep. By having FLAT == EXTERNAL + 1, we +// can perform this check in a single branch as 'tag >= EXTERNAL' +// Likewise, we have some locations where we check for 'ring or external/flat', +// so likewise align RING to EXTERNAL. +// Note that we can leave this optimization to the compiler. The compiler will +// DTRT when it sees a condition like `tag == EXTERNAL || tag >= FLAT`. +static_assert(RING == BTREE + 1, "BTREE and RING not consecutive"); +static_assert(EXTERNAL == RING + 1, "BTREE and EXTERNAL not consecutive"); +static_assert(FLAT == EXTERNAL + 1, "EXTERNAL and FLAT not consecutive"); + struct CordRep { CordRep() = default; - constexpr CordRep(RefcountAndFlags::Immortal immortal, size_t l) + constexpr CordRep(RefcountAndFlags::Immortal immortal, size_t l) : length(l), refcount(immortal), tag(EXTERNAL), storage{} {} // The following three fields have to be less than 32 bytes since // that is the smallest supported flat node size. size_t length; - RefcountAndFlags refcount; + RefcountAndFlags refcount; // If tag < FLAT, it represents CordRepKind and indicates the type of node. // Otherwise, the node type is CordRepFlat and the tag is the encoded size. uint8_t tag; - // `storage` provides two main purposes: - // - the starting point for FlatCordRep.Data() [flexible-array-member] - // - 3 bytes of additional storage for use by derived classes. - // The latter is used by CordrepConcat and CordRepBtree. CordRepConcat stores - // a 'depth' value in storage[0], and the (future) CordRepBtree class stores - // `height`, `begin` and `end` in the 3 entries. Otherwise we would need to - // allocate room for these in the derived class, as not all compilers reuse - // padding space from the base class (clang and gcc do, MSVC does not, etc) - uint8_t storage[3]; - - // Returns true if this instance's tag matches the requested type. - constexpr bool IsRing() const { return tag == RING; } - constexpr bool IsConcat() const { return tag == CONCAT; } - constexpr bool IsSubstring() const { return tag == SUBSTRING; } - constexpr bool IsExternal() const { return tag == EXTERNAL; } - constexpr bool IsFlat() const { return tag >= FLAT; } - constexpr bool IsBtree() const { return tag == BTREE; } - + // `storage` provides two main purposes: + // - the starting point for FlatCordRep.Data() [flexible-array-member] + // - 3 bytes of additional storage for use by derived classes. + // The latter is used by CordrepConcat and CordRepBtree. CordRepConcat stores + // a 'depth' value in storage[0], and the (future) CordRepBtree class stores + // `height`, `begin` and `end` in the 3 entries. Otherwise we would need to + // allocate room for these in the derived class, as not all compilers reuse + // padding space from the base class (clang and gcc do, MSVC does not, etc) + uint8_t storage[3]; + + // Returns true if this instance's tag matches the requested type. + constexpr bool IsRing() const { return tag == RING; } + constexpr bool IsConcat() const { return tag == CONCAT; } + constexpr bool IsSubstring() const { return tag == SUBSTRING; } + constexpr bool IsExternal() const { return tag == EXTERNAL; } + constexpr bool IsFlat() const { return tag >= FLAT; } + constexpr bool IsBtree() const { return tag == BTREE; } + inline CordRepRing* ring(); inline const CordRepRing* ring() const; inline CordRepConcat* concat(); @@ -265,8 +265,8 @@ struct CordRep { inline const CordRepExternal* external() const; inline CordRepFlat* flat(); inline const CordRepFlat* flat() const; - inline CordRepBtree* btree(); - inline const CordRepBtree* btree() const; + inline CordRepBtree* btree(); + inline const CordRepBtree* btree() const; // -------------------------------------------------------------------- // Memory management @@ -287,8 +287,8 @@ struct CordRepConcat : public CordRep { CordRep* left; CordRep* right; - uint8_t depth() const { return storage[0]; } - void set_depth(uint8_t depth) { storage[0] = depth; } + uint8_t depth() const { return storage[0]; } + void set_depth(uint8_t depth) { storage[0] = depth; } }; struct CordRepSubstring : public CordRep { @@ -306,7 +306,7 @@ using ExternalReleaserInvoker = void (*)(CordRepExternal*); struct CordRepExternal : public CordRep { CordRepExternal() = default; explicit constexpr CordRepExternal(y_absl::string_view str) - : CordRep(RefcountAndFlags::Immortal{}, str.size()), + : CordRep(RefcountAndFlags::Immortal{}, str.size()), base(str.data()), releaser_invoker(nullptr) {} @@ -315,7 +315,7 @@ struct CordRepExternal : public CordRep { ExternalReleaserInvoker releaser_invoker; // Deletes (releases) the external rep. - // Requires rep != nullptr and rep->IsExternal() + // Requires rep != nullptr and rep->IsExternal() static void Delete(CordRep* rep); }; @@ -358,7 +358,7 @@ struct CordRepExternalImpl }; inline void CordRepExternal::Delete(CordRep* rep) { - assert(rep != nullptr && rep->IsExternal()); + assert(rep != nullptr && rep->IsExternal()); auto* rep_external = static_cast<CordRepExternal*>(rep); assert(rep_external->releaser_invoker != nullptr); rep_external->releaser_invoker(rep_external); @@ -404,9 +404,9 @@ static constexpr cordz_info_t BigEndianByte(unsigned char value) { class InlineData { public: - // DefaultInitType forces the use of the default initialization constructor. - enum DefaultInitType { kDefaultInit }; - + // DefaultInitType forces the use of the default initialization constructor. + enum DefaultInitType { kDefaultInit }; + // kNullCordzInfo holds the big endian representation of intptr_t(1) // This is the 'null' / initial value of 'cordz_info'. The null value // is specifically big endian 1 as with 64-bit pointers, the last @@ -414,7 +414,7 @@ class InlineData { static constexpr cordz_info_t kNullCordzInfo = BigEndianByte(1); constexpr InlineData() : as_chars_{0} {} - explicit InlineData(DefaultInitType) {} + explicit InlineData(DefaultInitType) {} explicit constexpr InlineData(CordRep* rep) : as_tree_(rep) {} explicit constexpr InlineData(y_absl::string_view chars) : as_chars_{ @@ -441,16 +441,16 @@ class InlineData { return as_tree_.cordz_info != kNullCordzInfo; } - // Returns true if either of the provided instances hold a cordz_info value. - // This method is more efficient than the equivalent `data1.is_profiled() || - // data2.is_profiled()`. Requires both arguments to hold a tree. - static bool is_either_profiled(const InlineData& data1, - const InlineData& data2) { - assert(data1.is_tree() && data2.is_tree()); - return (data1.as_tree_.cordz_info | data2.as_tree_.cordz_info) != - kNullCordzInfo; - } - + // Returns true if either of the provided instances hold a cordz_info value. + // This method is more efficient than the equivalent `data1.is_profiled() || + // data2.is_profiled()`. Requires both arguments to hold a tree. + static bool is_either_profiled(const InlineData& data1, + const InlineData& data2) { + assert(data1.is_tree() && data2.is_tree()); + return (data1.as_tree_.cordz_info | data2.as_tree_.cordz_info) != + kNullCordzInfo; + } + // Returns the cordz_info sampling instance for this instance, or nullptr // if the current instance is not sampled and does not have CordzInfo data. // Requires the current instance to hold a tree value. @@ -560,7 +560,7 @@ class InlineData { // store the size in the last char of `as_chars_` shifted left + 1. // Else we store it in a tree and store a pointer to that tree in // `as_tree_.rep` and store a tag in `tagged_size`. - union { + union { char as_chars_[kMaxInline + 1]; AsTree as_tree_; }; @@ -569,32 +569,32 @@ class InlineData { static_assert(sizeof(InlineData) == kMaxInline + 1, ""); inline CordRepConcat* CordRep::concat() { - assert(IsConcat()); + assert(IsConcat()); return static_cast<CordRepConcat*>(this); } inline const CordRepConcat* CordRep::concat() const { - assert(IsConcat()); + assert(IsConcat()); return static_cast<const CordRepConcat*>(this); } inline CordRepSubstring* CordRep::substring() { - assert(IsSubstring()); + assert(IsSubstring()); return static_cast<CordRepSubstring*>(this); } inline const CordRepSubstring* CordRep::substring() const { - assert(IsSubstring()); + assert(IsSubstring()); return static_cast<const CordRepSubstring*>(this); } inline CordRepExternal* CordRep::external() { - assert(IsExternal()); + assert(IsExternal()); return static_cast<CordRepExternal*>(this); } inline const CordRepExternal* CordRep::external() const { - assert(IsExternal()); + assert(IsExternal()); return static_cast<const CordRepExternal*>(this); } diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree.cc index 93121c9958..396a40b499 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree.cc @@ -1,1128 +1,1128 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "y_absl/strings/internal/cord_rep_btree.h" - -#include <cassert> -#include <cstdint> -#include <iostream> -#include <util/generic/string.h> - -#include "y_absl/base/attributes.h" -#include "y_absl/base/config.h" -#include "y_absl/base/internal/raw_logging.h" -#include "y_absl/strings/internal/cord_internal.h" -#include "y_absl/strings/internal/cord_rep_consume.h" -#include "y_absl/strings/internal/cord_rep_flat.h" -#include "y_absl/strings/str_cat.h" -#include "y_absl/strings/string_view.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -constexpr size_t CordRepBtree::kMaxCapacity; // NOLINT: needed for c++ < c++17 - -namespace { - -using NodeStack = CordRepBtree * [CordRepBtree::kMaxDepth]; -using EdgeType = CordRepBtree::EdgeType; -using OpResult = CordRepBtree::OpResult; -using CopyResult = CordRepBtree::CopyResult; - -constexpr auto kFront = CordRepBtree::kFront; -constexpr auto kBack = CordRepBtree::kBack; - -inline bool exhaustive_validation() { - return cord_btree_exhaustive_validation.load(std::memory_order_relaxed); -} - -// Implementation of the various 'Dump' functions. -// Prints the entire tree structure or 'rep'. External callers should -// not specify 'depth' and leave it to its default (0) value. -// Rep may be a CordRepBtree tree, or a SUBSTRING / EXTERNAL / FLAT node. -void DumpAll(const CordRep* rep, bool include_contents, std::ostream& stream, - int depth = 0) { - // Allow for full height trees + substring -> flat / external nodes. - assert(depth <= CordRepBtree::kMaxDepth + 2); - TString sharing = const_cast<CordRep*>(rep)->refcount.IsOne() - ? TString("Private") - : y_absl::StrCat("Shared(", rep->refcount.Get(), ")"); - TString sptr = y_absl::StrCat("0x", y_absl::Hex(rep)); - - // Dumps the data contents of `rep` if `include_contents` is true. - // Always emits a new line character. - auto maybe_dump_data = [&stream, include_contents](const CordRep* r) { - if (include_contents) { - // Allow for up to 60 wide display of content data, which with some - // indentation and prefix / labels keeps us within roughly 80-100 wide. - constexpr size_t kMaxDataLength = 60; - stream << ", data = \"" - << CordRepBtree::EdgeData(r).substr(0, kMaxDataLength) - << (r->length > kMaxDataLength ? "\"..." : "\""); - } - stream << '\n'; - }; - - // For each level, we print the 'shared/private' state and the rep pointer, - // indented by two spaces per recursive depth. - stream << TString(depth * 2, ' ') << sharing << " (" << sptr << ") "; - - if (rep->IsBtree()) { - const CordRepBtree* node = rep->btree(); - TString label = - node->height() ? y_absl::StrCat("Node(", node->height(), ")") : "Leaf"; - stream << label << ", len = " << node->length - << ", begin = " << node->begin() << ", end = " << node->end() - << "\n"; - for (CordRep* edge : node->Edges()) { - DumpAll(edge, include_contents, stream, depth + 1); - } - } else if (rep->tag == SUBSTRING) { - const CordRepSubstring* substring = rep->substring(); - stream << "Substring, len = " << rep->length - << ", start = " << substring->start; - maybe_dump_data(rep); - DumpAll(substring->child, include_contents, stream, depth + 1); - } else if (rep->tag >= FLAT) { - stream << "Flat, len = " << rep->length - << ", cap = " << rep->flat()->Capacity(); - maybe_dump_data(rep); - } else if (rep->tag == EXTERNAL) { - stream << "Extn, len = " << rep->length; - maybe_dump_data(rep); - } -} - -// TODO(b/192061034): add 'bytes to copy' logic to avoid large slop on substring -// small data out of large reps, and general efficiency of 'always copy small -// data'. Consider making this a cord rep internal library function. -CordRepSubstring* CreateSubstring(CordRep* rep, size_t offset, size_t n) { - assert(n != 0); - assert(offset + n <= rep->length); - assert(offset != 0 || n != rep->length); - - if (rep->tag == SUBSTRING) { - CordRepSubstring* substring = rep->substring(); - offset += substring->start; - rep = CordRep::Ref(substring->child); - CordRep::Unref(substring); - } - CordRepSubstring* substring = new CordRepSubstring(); - substring->length = n; - substring->tag = SUBSTRING; - substring->start = offset; - substring->child = rep; - return substring; -} - -// TODO(b/192061034): consider making this a cord rep library function. -inline CordRep* MakeSubstring(CordRep* rep, size_t offset, size_t n) { - if (n == rep->length) return rep; - if (n == 0) return CordRep::Unref(rep), nullptr; - return CreateSubstring(rep, offset, n); -} - -// TODO(b/192061034): consider making this a cord rep library function. -inline CordRep* MakeSubstring(CordRep* rep, size_t offset) { - if (offset == 0) return rep; - return CreateSubstring(rep, offset, rep->length - offset); -} - -// Resizes `edge` to the provided `length`. Adopts a reference on `edge`. -// This method directly returns `edge` if `length` equals `edge->length`. -// If `is_mutable` is set to true, this function may return `edge` with -// `edge->length` set to the new length depending on the type and size of -// `edge`. Otherwise, this function returns a new CordRepSubstring value. -// Requires `length > 0 && length <= edge->length`. -CordRep* ResizeEdge(CordRep* edge, size_t length, bool is_mutable) { - assert(length > 0); - assert(length <= edge->length); - assert(CordRepBtree::IsDataEdge(edge)); - if (length >= edge->length) return edge; - - if (is_mutable && (edge->tag >= FLAT || edge->tag == SUBSTRING)) { - edge->length = length; - return edge; - } - - return CreateSubstring(edge, 0, length); -} - -template <EdgeType edge_type> -inline y_absl::string_view Consume(y_absl::string_view s, size_t n) { - return edge_type == kBack ? s.substr(n) : s.substr(0, s.size() - n); -} - -template <EdgeType edge_type> -inline y_absl::string_view Consume(char* dst, y_absl::string_view s, size_t n) { - if (edge_type == kBack) { - memcpy(dst, s.data(), n); - return s.substr(n); - } else { - const size_t offset = s.size() - n; - memcpy(dst, s.data() + offset, n); - return s.substr(0, offset); - } -} - -// Known issue / optimization weirdness: the store associated with the -// decrement introduces traffic between cpus (even if the result of that -// traffic does nothing), making this faster than a single call to -// refcount.Decrement() checking the zero refcount condition. -template <typename R, typename Fn> -inline void FastUnref(R* r, Fn&& fn) { - if (r->refcount.IsOne()) { - fn(r); - } else if (!r->refcount.DecrementExpectHighRefcount()) { - fn(r); - } -} - -// Deletes a leaf node data edge. Requires `rep` to be an EXTERNAL or FLAT -// node, or a SUBSTRING of an EXTERNAL or FLAT node. -void DeleteLeafEdge(CordRep* rep) { - for (;;) { - if (rep->tag >= FLAT) { - CordRepFlat::Delete(rep->flat()); - return; - } - if (rep->tag == EXTERNAL) { - CordRepExternal::Delete(rep->external()); - return; - } - assert(rep->tag == SUBSTRING); - CordRepSubstring* substring = rep->substring(); - rep = substring->child; - assert(rep->tag == EXTERNAL || rep->tag >= FLAT); - delete substring; - if (rep->refcount.Decrement()) return; - } -} - -// StackOperations contains the logic to build a left-most or right-most stack -// (leg) down to the leaf level of a btree, and 'unwind' / 'Finalize' methods to -// propagate node changes up the stack. -template <EdgeType edge_type> -struct StackOperations { - // Returns true if the node at 'depth' is mutable, i.e. has a refcount - // of one, carries no CRC, and all of its parent nodes have a refcount of one. - inline bool owned(int depth) const { return depth < share_depth; } - - // Returns the node at 'depth'. - inline CordRepBtree* node(int depth) const { return stack[depth]; } - - // Builds a `depth` levels deep stack starting at `tree` recording which nodes - // are private in the form of the 'share depth' where nodes are shared. - inline CordRepBtree* BuildStack(CordRepBtree* tree, int depth) { - assert(depth <= tree->height()); - int current_depth = 0; - while (current_depth < depth && tree->refcount.IsMutable()) { - stack[current_depth++] = tree; - tree = tree->Edge(edge_type)->btree(); - } - share_depth = current_depth + (tree->refcount.IsMutable() ? 1 : 0); - while (current_depth < depth) { - stack[current_depth++] = tree; - tree = tree->Edge(edge_type)->btree(); - } - return tree; - } - - // Builds a stack with the invariant that all nodes are private owned / not - // shared and carry no CRC data. This is used in iterative updates where a - // previous propagation guaranteed all nodes have this property. - inline void BuildOwnedStack(CordRepBtree* tree, int height) { - assert(height <= CordRepBtree::kMaxHeight); - int depth = 0; - while (depth < height) { - assert(tree->refcount.IsMutable()); - stack[depth++] = tree; - tree = tree->Edge(edge_type)->btree(); - } - assert(tree->refcount.IsMutable()); - share_depth = depth + 1; - } - - // Processes the final 'top level' result action for the tree. - // See the 'Action' enum for the various action implications. - static inline CordRepBtree* Finalize(CordRepBtree* tree, OpResult result) { - switch (result.action) { - case CordRepBtree::kPopped: - tree = edge_type == kBack ? CordRepBtree::New(tree, result.tree) - : CordRepBtree::New(result.tree, tree); - if (ABSL_PREDICT_FALSE(tree->height() > CordRepBtree::kMaxHeight)) { - tree = CordRepBtree::Rebuild(tree); - ABSL_RAW_CHECK(tree->height() <= CordRepBtree::kMaxHeight, - "Max height exceeded"); - } - return tree; - case CordRepBtree::kCopied: - CordRep::Unref(tree); - ABSL_FALLTHROUGH_INTENDED; - case CordRepBtree::kSelf: - return result.tree; - } - ABSL_INTERNAL_UNREACHABLE; - return result.tree; - } - - // Propagate the action result in 'result' up into all nodes of the stack - // starting at depth 'depth'. 'length' contains the extra length of data that - // was added at the lowest level, and is updated into all nodes of the stack. - // See the 'Action' enum for the various action implications. - // If 'propagate' is true, then any copied node values are updated into the - // stack, which is used for iterative processing on the same stack. - template <bool propagate = false> - inline CordRepBtree* Unwind(CordRepBtree* tree, int depth, size_t length, - OpResult result) { - // TODO(mvels): revisit the below code to check if 3 loops with 3 - // (incremental) conditions is faster than 1 loop with a switch. - // Benchmarking and perf recordings indicate the loop with switch is - // fastest, likely because of indirect jumps on the tight case values and - // dense branches. But it's worth considering 3 loops, as the `action` - // transitions are mono directional. E.g.: - // while (action == kPopped) { - // ... - // } - // while (action == kCopied) { - // ... - // } - // ... - // We also found that an "if () do {}" loop here seems faster, possibly - // because it allows the branch predictor more granular heuristics on - // 'single leaf' (`depth` == 0) and 'single depth' (`depth` == 1) cases - // which appear to be the most common use cases. - if (depth != 0) { - do { - CordRepBtree* node = stack[--depth]; - const bool owned = depth < share_depth; - switch (result.action) { - case CordRepBtree::kPopped: - assert(!propagate); - result = node->AddEdge<edge_type>(owned, result.tree, length); - break; - case CordRepBtree::kCopied: - result = node->SetEdge<edge_type>(owned, result.tree, length); - if (propagate) stack[depth] = result.tree; - break; - case CordRepBtree::kSelf: - node->length += length; - while (depth > 0) { - node = stack[--depth]; - node->length += length; - } - return node; - } - } while (depth > 0); - } - return Finalize(tree, result); - } - - // Invokes `Unwind` with `propagate=true` to update the stack node values. - inline CordRepBtree* Propagate(CordRepBtree* tree, int depth, size_t length, - OpResult result) { - return Unwind</*propagate=*/true>(tree, depth, length, result); - } - - // `share_depth` contains the depth at which the nodes in the stack cannot - // be mutated. I.e., if the top most level is shared (i.e.: - // `!refcount.IsMutable()`), then `share_depth` is 0. If the 2nd node - // is shared (and implicitly all nodes below that) then `share_depth` is 1, - // etc. A `share_depth` greater than the depth of the stack indicates that - // none of the nodes in the stack are shared. - int share_depth; - - NodeStack stack; -}; - -} // namespace - -void CordRepBtree::Dump(const CordRep* rep, y_absl::string_view label, - bool include_contents, std::ostream& stream) { - stream << "===================================\n"; - if (!label.empty()) { - stream << label << '\n'; - stream << "-----------------------------------\n"; - } - if (rep) { - DumpAll(rep, include_contents, stream); - } else { - stream << "NULL\n"; - } -} - -void CordRepBtree::Dump(const CordRep* rep, y_absl::string_view label, - std::ostream& stream) { - Dump(rep, label, false, stream); -} - -void CordRepBtree::Dump(const CordRep* rep, std::ostream& stream) { - Dump(rep, y_absl::string_view(), false, stream); -} - -void CordRepBtree::DestroyLeaf(CordRepBtree* tree, size_t begin, size_t end) { - for (CordRep* edge : tree->Edges(begin, end)) { - FastUnref(edge, DeleteLeafEdge); - } - Delete(tree); -} - -void CordRepBtree::DestroyNonLeaf(CordRepBtree* tree, size_t begin, - size_t end) { - for (CordRep* edge : tree->Edges(begin, end)) { - FastUnref(edge->btree(), Destroy); - } - Delete(tree); -} - -bool CordRepBtree::IsValid(const CordRepBtree* tree, bool shallow) { -#define NODE_CHECK_VALID(x) \ - if (!(x)) { \ - ABSL_RAW_LOG(ERROR, "CordRepBtree::CheckValid() FAILED: %s", #x); \ - return false; \ - } -#define NODE_CHECK_EQ(x, y) \ - if ((x) != (y)) { \ - ABSL_RAW_LOG(ERROR, \ - "CordRepBtree::CheckValid() FAILED: %s != %s (%s vs %s)", #x, \ - #y, y_absl::StrCat(x).c_str(), y_absl::StrCat(y).c_str()); \ - return false; \ - } - - NODE_CHECK_VALID(tree != nullptr); - NODE_CHECK_VALID(tree->IsBtree()); - NODE_CHECK_VALID(tree->height() <= kMaxHeight); - NODE_CHECK_VALID(tree->begin() < tree->capacity()); - NODE_CHECK_VALID(tree->end() <= tree->capacity()); - NODE_CHECK_VALID(tree->begin() <= tree->end()); - size_t child_length = 0; - for (CordRep* edge : tree->Edges()) { - NODE_CHECK_VALID(edge != nullptr); - if (tree->height() > 0) { - NODE_CHECK_VALID(edge->IsBtree()); - NODE_CHECK_VALID(edge->btree()->height() == tree->height() - 1); - } else { - NODE_CHECK_VALID(IsDataEdge(edge)); - } - child_length += edge->length; - } - NODE_CHECK_EQ(child_length, tree->length); - if ((!shallow || exhaustive_validation()) && tree->height() > 0) { - for (CordRep* edge : tree->Edges()) { - if (!IsValid(edge->btree(), shallow)) return false; - } - } - return true; - -#undef NODE_CHECK_VALID -#undef NODE_CHECK_EQ -} - -#ifndef NDEBUG - -CordRepBtree* CordRepBtree::AssertValid(CordRepBtree* tree, bool shallow) { - if (!IsValid(tree, shallow)) { - Dump(tree, "CordRepBtree validation failed:", false, std::cout); - ABSL_RAW_LOG(FATAL, "CordRepBtree::CheckValid() FAILED"); - } - return tree; -} - -const CordRepBtree* CordRepBtree::AssertValid(const CordRepBtree* tree, - bool shallow) { - if (!IsValid(tree, shallow)) { - Dump(tree, "CordRepBtree validation failed:", false, std::cout); - ABSL_RAW_LOG(FATAL, "CordRepBtree::CheckValid() FAILED"); - } - return tree; -} - -#endif // NDEBUG - -template <EdgeType edge_type> -inline OpResult CordRepBtree::AddEdge(bool owned, CordRep* edge, size_t delta) { - if (size() >= kMaxCapacity) return {New(edge), kPopped}; - OpResult result = ToOpResult(owned); - result.tree->Add<edge_type>(edge); - result.tree->length += delta; - return result; -} - -template <EdgeType edge_type> -OpResult CordRepBtree::SetEdge(bool owned, CordRep* edge, size_t delta) { - OpResult result; - const size_t idx = index(edge_type); - if (owned) { - result = {this, kSelf}; - CordRep::Unref(edges_[idx]); - } else { - // Create a copy containing all unchanged edges. Unchanged edges are the - // open interval [begin, back) or [begin + 1, end) depending on `edge_type`. - // We conveniently cover both case using a constexpr `shift` being 0 or 1 - // as `end :== back + 1`. - result = {CopyRaw(), kCopied}; - constexpr int shift = edge_type == kFront ? 1 : 0; - for (CordRep* r : Edges(begin() + shift, back() + shift)) { - CordRep::Ref(r); - } - } - result.tree->edges_[idx] = edge; - result.tree->length += delta; - return result; -} - -template <EdgeType edge_type> -CordRepBtree* CordRepBtree::AddCordRep(CordRepBtree* tree, CordRep* rep) { - const int depth = tree->height(); - const size_t length = rep->length; - StackOperations<edge_type> ops; - CordRepBtree* leaf = ops.BuildStack(tree, depth); - const OpResult result = - leaf->AddEdge<edge_type>(ops.owned(depth), rep, length); - return ops.Unwind(tree, depth, length, result); -} - -template <> -CordRepBtree* CordRepBtree::NewLeaf<kBack>(y_absl::string_view data, - size_t extra) { - CordRepBtree* leaf = CordRepBtree::New(0); - size_t length = 0; - size_t end = 0; - const size_t cap = leaf->capacity(); - while (!data.empty() && end != cap) { - auto* flat = CordRepFlat::New(data.length() + extra); - flat->length = (std::min)(data.length(), flat->Capacity()); - length += flat->length; - leaf->edges_[end++] = flat; - data = Consume<kBack>(flat->Data(), data, flat->length); - } - leaf->length = length; - leaf->set_end(end); - return leaf; -} - -template <> -CordRepBtree* CordRepBtree::NewLeaf<kFront>(y_absl::string_view data, - size_t extra) { - CordRepBtree* leaf = CordRepBtree::New(0); - size_t length = 0; - size_t begin = leaf->capacity(); - leaf->set_end(leaf->capacity()); - while (!data.empty() && begin != 0) { - auto* flat = CordRepFlat::New(data.length() + extra); - flat->length = (std::min)(data.length(), flat->Capacity()); - length += flat->length; - leaf->edges_[--begin] = flat; - data = Consume<kFront>(flat->Data(), data, flat->length); - } - leaf->length = length; - leaf->set_begin(begin); - return leaf; -} - -template <> -y_absl::string_view CordRepBtree::AddData<kBack>(y_absl::string_view data, - size_t extra) { - assert(!data.empty()); - assert(size() < capacity()); - AlignBegin(); - const size_t cap = capacity(); - do { - CordRepFlat* flat = CordRepFlat::New(data.length() + extra); - const size_t n = (std::min)(data.length(), flat->Capacity()); - flat->length = n; - edges_[fetch_add_end(1)] = flat; - data = Consume<kBack>(flat->Data(), data, n); - } while (!data.empty() && end() != cap); - return data; -} - -template <> -y_absl::string_view CordRepBtree::AddData<kFront>(y_absl::string_view data, - size_t extra) { - assert(!data.empty()); - assert(size() < capacity()); - AlignEnd(); - do { - CordRepFlat* flat = CordRepFlat::New(data.length() + extra); - const size_t n = (std::min)(data.length(), flat->Capacity()); - flat->length = n; - edges_[sub_fetch_begin(1)] = flat; - data = Consume<kFront>(flat->Data(), data, n); - } while (!data.empty() && begin() != 0); - return data; -} - -template <EdgeType edge_type> -CordRepBtree* CordRepBtree::AddData(CordRepBtree* tree, y_absl::string_view data, - size_t extra) { - if (ABSL_PREDICT_FALSE(data.empty())) return tree; - - const size_t original_data_size = data.size(); - int depth = tree->height(); - StackOperations<edge_type> ops; - CordRepBtree* leaf = ops.BuildStack(tree, depth); - - // If there is capacity in the last edge, append as much data - // as possible into this last edge. - if (leaf->size() < leaf->capacity()) { - OpResult result = leaf->ToOpResult(ops.owned(depth)); - data = result.tree->AddData<edge_type>(data, extra); - if (data.empty()) { - result.tree->length += original_data_size; - return ops.Unwind(tree, depth, original_data_size, result); - } - - // We added some data into this leaf, but not all. Propagate the added - // length to the top most node, and rebuild the stack with any newly copied - // or updated nodes. From this point on, the path (leg) from the top most - // node to the right-most node towards the leaf node is privately owned. - size_t delta = original_data_size - data.size(); - assert(delta > 0); - result.tree->length += delta; - tree = ops.Propagate(tree, depth, delta, result); - ops.share_depth = depth + 1; - } - - // We were unable to append all data into the existing right-most leaf node. - // This means all remaining data must be put into (a) new leaf node(s) which - // we append to the tree. To make this efficient, we iteratively build full - // leaf nodes from `data` until the created leaf contains all remaining data. - // We utilize the `Unwind` method to merge the created leaf into the first - // level towards root that has capacity. On each iteration with remaining - // data, we rebuild the stack in the knowledge that right-most nodes are - // privately owned after the first `Unwind` completes. - for (;;) { - OpResult result = {CordRepBtree::NewLeaf<edge_type>(data, extra), kPopped}; - if (result.tree->length == data.size()) { - return ops.Unwind(tree, depth, result.tree->length, result); - } - data = Consume<edge_type>(data, result.tree->length); - tree = ops.Unwind(tree, depth, result.tree->length, result); - depth = tree->height(); - ops.BuildOwnedStack(tree, depth); - } -} - -template <EdgeType edge_type> -CordRepBtree* CordRepBtree::Merge(CordRepBtree* dst, CordRepBtree* src) { - assert(dst->height() >= src->height()); - - // Capture source length as we may consume / destroy `src`. - const size_t length = src->length; - - // We attempt to merge `src` at its corresponding height in `dst`. - const int depth = dst->height() - src->height(); - StackOperations<edge_type> ops; - CordRepBtree* merge_node = ops.BuildStack(dst, depth); - - // If there is enough space in `merge_node` for all edges from `src`, add all - // edges to this node, making a fresh copy as needed if not privately owned. - // If `merge_node` does not have capacity for `src`, we rely on `Unwind` and - // `Finalize` to merge `src` into the first level towards `root` where there - // is capacity for another edge, or create a new top level node. - OpResult result; - if (merge_node->size() + src->size() <= kMaxCapacity) { - result = merge_node->ToOpResult(ops.owned(depth)); - result.tree->Add<edge_type>(src->Edges()); - result.tree->length += src->length; - if (src->refcount.IsOne()) { - Delete(src); - } else { - for (CordRep* edge : src->Edges()) CordRep::Ref(edge); - CordRepBtree::Unref(src); - } - } else { - result = {src, kPopped}; - } - - // Unless we merged at the top level (i.e.: src and dst are equal height), - // unwind the result towards the top level, and finalize the result. - if (depth) { - return ops.Unwind(dst, depth, length, result); - } - return ops.Finalize(dst, result); -} - -CopyResult CordRepBtree::CopySuffix(size_t offset) { - assert(offset < this->length); - - // As long as `offset` starts inside the last edge, we can 'drop' the current - // depth. For the most extreme example: if offset references the last data - // edge in the tree, there is only a single edge / path from the top of the - // tree to that last edge, so we can drop all the nodes except that edge. - // The fast path check for this is `back->length >= length - offset`. - int height = this->height(); - CordRepBtree* node = this; - size_t len = node->length - offset; - CordRep* back = node->Edge(kBack); - while (back->length >= len) { - offset = back->length - len; - if (--height < 0) { - return {MakeSubstring(CordRep::Ref(back), offset), height}; - } - node = back->btree(); - back = node->Edge(kBack); - } - if (offset == 0) return {CordRep::Ref(node), height}; - - // Offset does not point into the last edge, so we span at least two edges. - // Find the index of offset with `IndexBeyond` which provides us the edge - // 'beyond' the offset if offset is not a clean starting point of an edge. - Position pos = node->IndexBeyond(offset); - CordRepBtree* sub = node->CopyToEndFrom(pos.index, len); - const CopyResult result = {sub, height}; - - // `pos.n` contains a non zero value if the offset is not an exact starting - // point of an edge. In this case, `pos.n` contains the 'trailing' amount of - // bytes of the edge preceding that in `pos.index`. We need to iteratively - // adjust the preceding edge with the 'broken' offset until we have a perfect - // start of the edge. - while (pos.n != 0) { - assert(pos.index >= 1); - const size_t begin = pos.index - 1; - sub->set_begin(begin); - CordRep* const edge = node->Edge(begin); - - len = pos.n; - offset = edge->length - len; - - if (--height < 0) { - sub->edges_[begin] = MakeSubstring(CordRep::Ref(edge), offset, len); - return result; - } - - node = edge->btree(); - pos = node->IndexBeyond(offset); - - CordRepBtree* nsub = node->CopyToEndFrom(pos.index, len); - sub->edges_[begin] = nsub; - sub = nsub; - } - sub->set_begin(pos.index); - return result; -} - -CopyResult CordRepBtree::CopyPrefix(size_t n, bool allow_folding) { - assert(n > 0); - assert(n <= this->length); - - // As long as `n` does not exceed the length of the first edge, we can 'drop' - // the current depth. For the most extreme example: if we'd copy a 1 byte - // prefix from a tree, there is only a single edge / path from the top of the - // tree to the single data edge containing this byte, so we can drop all the - // nodes except the data node. - int height = this->height(); - CordRepBtree* node = this; - CordRep* front = node->Edge(kFront); - if (allow_folding) { - while (front->length >= n) { - if (--height < 0) return {MakeSubstring(CordRep::Ref(front), 0, n), -1}; - node = front->btree(); - front = node->Edge(kFront); - } - } - if (node->length == n) return {CordRep::Ref(node), height}; - - // `n` spans at least two nodes, find the end point of the span. - Position pos = node->IndexOf(n); - - // Create a partial copy of the node up to `pos.index`, with a defined length - // of `n`. Any 'partial last edge' is added further below as needed. - CordRepBtree* sub = node->CopyBeginTo(pos.index, n); - const CopyResult result = {sub, height}; - - // `pos.n` contains the 'offset inside the edge for IndexOf(n)'. As long as - // this is not zero, we don't have a 'clean cut', so we need to make a - // (partial) copy of that last edge, and repeat this until pos.n is zero. - while (pos.n != 0) { - size_t end = pos.index; - n = pos.n; - - CordRep* edge = node->Edge(pos.index); - if (--height < 0) { - sub->edges_[end++] = MakeSubstring(CordRep::Ref(edge), 0, n); - sub->set_end(end); - AssertValid(result.edge->btree()); - return result; - } - - node = edge->btree(); - pos = node->IndexOf(n); - CordRepBtree* nsub = node->CopyBeginTo(pos.index, n); - sub->edges_[end++] = nsub; - sub->set_end(end); - sub = nsub; - } - sub->set_end(pos.index); - AssertValid(result.edge->btree()); - return result; -} - -CordRep* CordRepBtree::ExtractFront(CordRepBtree* tree) { - CordRep* front = tree->Edge(tree->begin()); - if (tree->refcount.IsMutable()) { - Unref(tree->Edges(tree->begin() + 1, tree->end())); - CordRepBtree::Delete(tree); - } else { - CordRep::Ref(front); - CordRep::Unref(tree); - } - return front; -} - -CordRepBtree* CordRepBtree::ConsumeBeginTo(CordRepBtree* tree, size_t end, - size_t new_length) { - assert(end <= tree->end()); - if (tree->refcount.IsMutable()) { - Unref(tree->Edges(end, tree->end())); - tree->set_end(end); - tree->length = new_length; - } else { - CordRepBtree* old = tree; - tree = tree->CopyBeginTo(end, new_length); - CordRep::Unref(old); - } - return tree; -} - -CordRep* CordRepBtree::RemoveSuffix(CordRepBtree* tree, size_t n) { - // Check input and deal with trivial cases 'Remove all/none' - assert(tree != nullptr); - assert(n <= tree->length); - const size_t len = tree->length; - if (ABSL_PREDICT_FALSE(n == 0)) { - return tree; - } - if (ABSL_PREDICT_FALSE(n >= len)) { - CordRepBtree::Unref(tree); - return nullptr; - } - - size_t length = len - n; - int height = tree->height(); - bool is_mutable = tree->refcount.IsMutable(); - - // Extract all top nodes which are reduced to size = 1 - Position pos = tree->IndexOfLength(length); - while (pos.index == tree->begin()) { - CordRep* edge = ExtractFront(tree); - is_mutable &= edge->refcount.IsMutable(); - if (height-- == 0) return ResizeEdge(edge, length, is_mutable); - tree = edge->btree(); - pos = tree->IndexOfLength(length); - } - - // Repeat the following sequence traversing down the tree: - // - Crop the top node to the 'last remaining edge' adjusting length. - // - Set the length for down edges to the partial length in that last edge. - // - Repeat this until the last edge is 'included in full' - // - If we hit the data edge level, resize and return the last data edge - CordRepBtree* top = tree = ConsumeBeginTo(tree, pos.index + 1, length); - CordRep* edge = tree->Edge(pos.index); - length = pos.n; - while (length != edge->length) { - // ConsumeBeginTo guarantees `tree` is a clean, privately owned copy. - assert(tree->refcount.IsMutable()); - const bool edge_is_mutable = edge->refcount.IsMutable(); - - if (height-- == 0) { - tree->edges_[pos.index] = ResizeEdge(edge, length, edge_is_mutable); - return AssertValid(top); - } - - if (!edge_is_mutable) { - // We can't 'in place' remove any suffixes down this edge. - // Replace this edge with a prefix copy instead. - tree->edges_[pos.index] = edge->btree()->CopyPrefix(length, false).edge; - CordRep::Unref(edge); - return AssertValid(top); - } - - // Move down one level, rinse repeat. - tree = edge->btree(); - pos = tree->IndexOfLength(length); - tree = ConsumeBeginTo(edge->btree(), pos.index + 1, length); - edge = tree->Edge(pos.index); - length = pos.n; - } - - return AssertValid(top); -} - -CordRep* CordRepBtree::SubTree(size_t offset, size_t n) { - assert(n <= this->length); - assert(offset <= this->length - n); - if (ABSL_PREDICT_FALSE(n == 0)) return nullptr; - - CordRepBtree* node = this; - int height = node->height(); - Position front = node->IndexOf(offset); - CordRep* left = node->edges_[front.index]; - while (front.n + n <= left->length) { - if (--height < 0) return MakeSubstring(CordRep::Ref(left), front.n, n); - node = left->btree(); - front = node->IndexOf(front.n); - left = node->edges_[front.index]; - } - - const Position back = node->IndexBefore(front, n); - CordRep* const right = node->edges_[back.index]; - assert(back.index > front.index); - - // Get partial suffix and prefix entries. - CopyResult prefix; - CopyResult suffix; - if (height > 0) { - // Copy prefix and suffix of the boundary nodes. - prefix = left->btree()->CopySuffix(front.n); - suffix = right->btree()->CopyPrefix(back.n); - - // If there is an edge between the prefix and suffix edges, then the tree - // must remain at its previous (full) height. If we have no edges between - // prefix and suffix edges, then the tree must be as high as either the - // suffix or prefix edges (which are collapsed to their minimum heights). - if (front.index + 1 == back.index) { - height = (std::max)(prefix.height, suffix.height) + 1; - } - - // Raise prefix and suffixes to the new tree height. - for (int h = prefix.height + 1; h < height; ++h) { - prefix.edge = CordRepBtree::New(prefix.edge); - } - for (int h = suffix.height + 1; h < height; ++h) { - suffix.edge = CordRepBtree::New(suffix.edge); - } - } else { - // Leaf node, simply take substrings for prefix and suffix. - prefix = CopyResult{MakeSubstring(CordRep::Ref(left), front.n), -1}; - suffix = CopyResult{MakeSubstring(CordRep::Ref(right), 0, back.n), -1}; - } - - // Compose resulting tree. - CordRepBtree* sub = CordRepBtree::New(height); - size_t end = 0; - sub->edges_[end++] = prefix.edge; - for (CordRep* r : node->Edges(front.index + 1, back.index)) { - sub->edges_[end++] = CordRep::Ref(r); - } - sub->edges_[end++] = suffix.edge; - sub->set_end(end); - sub->length = n; - return AssertValid(sub); -} - -CordRepBtree* CordRepBtree::MergeTrees(CordRepBtree* left, - CordRepBtree* right) { - return left->height() >= right->height() ? Merge<kBack>(left, right) - : Merge<kFront>(right, left); -} - -bool CordRepBtree::IsFlat(y_absl::string_view* fragment) const { - if (height() == 0 && size() == 1) { - if (fragment) *fragment = Data(begin()); - return true; - } - return false; -} - -bool CordRepBtree::IsFlat(size_t offset, const size_t n, - y_absl::string_view* fragment) const { - assert(n <= this->length); - assert(offset <= this->length - n); - if (ABSL_PREDICT_FALSE(n == 0)) return false; - int height = this->height(); - const CordRepBtree* node = this; - for (;;) { - const Position front = node->IndexOf(offset); - const CordRep* edge = node->Edge(front.index); - if (edge->length < front.n + n) return false; - if (--height < 0) { - if (fragment) *fragment = EdgeData(edge).substr(front.n, n); - return true; - } - offset = front.n; - node = node->Edge(front.index)->btree(); - } -} - -char CordRepBtree::GetCharacter(size_t offset) const { - assert(offset < length); - const CordRepBtree* node = this; - int height = node->height(); - for (;;) { - Position front = node->IndexOf(offset); - if (--height < 0) return node->Data(front.index)[front.n]; - offset = front.n; - node = node->Edge(front.index)->btree(); - } -} - -Span<char> CordRepBtree::GetAppendBufferSlow(size_t size) { - // The inlined version in `GetAppendBuffer()` deals with all heights <= 3. - assert(height() >= 4); - assert(refcount.IsMutable()); - - // Build a stack of nodes we may potentially need to update if we find a - // non-shared FLAT with capacity at the leaf level. - const int depth = height(); - CordRepBtree* node = this; - CordRepBtree* stack[kMaxDepth]; - for (int i = 0; i < depth; ++i) { - node = node->Edge(kBack)->btree(); - if (!node->refcount.IsMutable()) return {}; - stack[i] = node; - } - - // Must be a privately owned, mutable flat. - CordRep* const edge = node->Edge(kBack); - if (!edge->refcount.IsMutable() || edge->tag < FLAT) return {}; - - // Must have capacity. - const size_t avail = edge->flat()->Capacity() - edge->length; - if (avail == 0) return {}; - - // Build span on remaining capacity. - size_t delta = (std::min)(size, avail); - Span<char> span = {edge->flat()->Data() + edge->length, delta}; - edge->length += delta; - this->length += delta; - for (int i = 0; i < depth; ++i) { - stack[i]->length += delta; - } - return span; -} - -CordRepBtree* CordRepBtree::CreateSlow(CordRep* rep) { - if (rep->IsBtree()) return rep->btree(); - - CordRepBtree* node = nullptr; - auto consume = [&node](CordRep* r, size_t offset, size_t length) { - r = MakeSubstring(r, offset, length); - if (node == nullptr) { - node = New(r); - } else { - node = CordRepBtree::AddCordRep<kBack>(node, r); - } - }; - Consume(rep, consume); - return node; -} - -CordRepBtree* CordRepBtree::AppendSlow(CordRepBtree* tree, CordRep* rep) { - if (ABSL_PREDICT_TRUE(rep->IsBtree())) { - return MergeTrees(tree, rep->btree()); - } - auto consume = [&tree](CordRep* r, size_t offset, size_t length) { - r = MakeSubstring(r, offset, length); - tree = CordRepBtree::AddCordRep<kBack>(tree, r); - }; - Consume(rep, consume); - return tree; -} - -CordRepBtree* CordRepBtree::PrependSlow(CordRepBtree* tree, CordRep* rep) { - if (ABSL_PREDICT_TRUE(rep->IsBtree())) { - return MergeTrees(rep->btree(), tree); - } - auto consume = [&tree](CordRep* r, size_t offset, size_t length) { - r = MakeSubstring(r, offset, length); - tree = CordRepBtree::AddCordRep<kFront>(tree, r); - }; - ReverseConsume(rep, consume); - return tree; -} - -CordRepBtree* CordRepBtree::Append(CordRepBtree* tree, y_absl::string_view data, - size_t extra) { - return CordRepBtree::AddData<kBack>(tree, data, extra); -} - -CordRepBtree* CordRepBtree::Prepend(CordRepBtree* tree, y_absl::string_view data, - size_t extra) { - return CordRepBtree::AddData<kFront>(tree, data, extra); -} - -template CordRepBtree* CordRepBtree::AddCordRep<kFront>(CordRepBtree* tree, - CordRep* rep); -template CordRepBtree* CordRepBtree::AddCordRep<kBack>(CordRepBtree* tree, - CordRep* rep); -template CordRepBtree* CordRepBtree::AddData<kFront>(CordRepBtree* tree, - y_absl::string_view data, - size_t extra); -template CordRepBtree* CordRepBtree::AddData<kBack>(CordRepBtree* tree, - y_absl::string_view data, - size_t extra); - -void CordRepBtree::Rebuild(CordRepBtree** stack, CordRepBtree* tree, - bool consume) { - bool owned = consume && tree->refcount.IsOne(); - if (tree->height() == 0) { - for (CordRep* edge : tree->Edges()) { - if (!owned) edge = CordRep::Ref(edge); - size_t height = 0; - size_t length = edge->length; - CordRepBtree* node = stack[0]; - OpResult result = node->AddEdge<kBack>(true, edge, length); - while (result.action == CordRepBtree::kPopped) { - stack[height] = result.tree; - if (stack[++height] == nullptr) { - result.action = CordRepBtree::kSelf; - stack[height] = CordRepBtree::New(node, result.tree); - } else { - node = stack[height]; - result = node->AddEdge<kBack>(true, result.tree, length); - } - } - while (stack[++height] != nullptr) { - stack[height]->length += length; - } - } - } else { - for (CordRep* rep : tree->Edges()) { - Rebuild(stack, rep->btree(), owned); - } - } - if (consume) { - if (owned) { - CordRepBtree::Delete(tree); - } else { - CordRepBtree::Unref(tree); - } - } -} - -CordRepBtree* CordRepBtree::Rebuild(CordRepBtree* tree) { - // Set up initial stack with empty leaf node. - CordRepBtree* node = CordRepBtree::New(); - CordRepBtree* stack[CordRepBtree::kMaxDepth + 1] = {node}; - - // Recursively build the tree, consuming the input tree. - Rebuild(stack, tree, /* consume reference */ true); - - // Return top most node - for (CordRepBtree* parent : stack) { - if (parent == nullptr) return node; - node = parent; - } - - // Unreachable - assert(false); - return nullptr; -} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace y_absl +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "y_absl/strings/internal/cord_rep_btree.h" + +#include <cassert> +#include <cstdint> +#include <iostream> +#include <util/generic/string.h> + +#include "y_absl/base/attributes.h" +#include "y_absl/base/config.h" +#include "y_absl/base/internal/raw_logging.h" +#include "y_absl/strings/internal/cord_internal.h" +#include "y_absl/strings/internal/cord_rep_consume.h" +#include "y_absl/strings/internal/cord_rep_flat.h" +#include "y_absl/strings/str_cat.h" +#include "y_absl/strings/string_view.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +constexpr size_t CordRepBtree::kMaxCapacity; // NOLINT: needed for c++ < c++17 + +namespace { + +using NodeStack = CordRepBtree * [CordRepBtree::kMaxDepth]; +using EdgeType = CordRepBtree::EdgeType; +using OpResult = CordRepBtree::OpResult; +using CopyResult = CordRepBtree::CopyResult; + +constexpr auto kFront = CordRepBtree::kFront; +constexpr auto kBack = CordRepBtree::kBack; + +inline bool exhaustive_validation() { + return cord_btree_exhaustive_validation.load(std::memory_order_relaxed); +} + +// Implementation of the various 'Dump' functions. +// Prints the entire tree structure or 'rep'. External callers should +// not specify 'depth' and leave it to its default (0) value. +// Rep may be a CordRepBtree tree, or a SUBSTRING / EXTERNAL / FLAT node. +void DumpAll(const CordRep* rep, bool include_contents, std::ostream& stream, + int depth = 0) { + // Allow for full height trees + substring -> flat / external nodes. + assert(depth <= CordRepBtree::kMaxDepth + 2); + TString sharing = const_cast<CordRep*>(rep)->refcount.IsOne() + ? TString("Private") + : y_absl::StrCat("Shared(", rep->refcount.Get(), ")"); + TString sptr = y_absl::StrCat("0x", y_absl::Hex(rep)); + + // Dumps the data contents of `rep` if `include_contents` is true. + // Always emits a new line character. + auto maybe_dump_data = [&stream, include_contents](const CordRep* r) { + if (include_contents) { + // Allow for up to 60 wide display of content data, which with some + // indentation and prefix / labels keeps us within roughly 80-100 wide. + constexpr size_t kMaxDataLength = 60; + stream << ", data = \"" + << CordRepBtree::EdgeData(r).substr(0, kMaxDataLength) + << (r->length > kMaxDataLength ? "\"..." : "\""); + } + stream << '\n'; + }; + + // For each level, we print the 'shared/private' state and the rep pointer, + // indented by two spaces per recursive depth. + stream << TString(depth * 2, ' ') << sharing << " (" << sptr << ") "; + + if (rep->IsBtree()) { + const CordRepBtree* node = rep->btree(); + TString label = + node->height() ? y_absl::StrCat("Node(", node->height(), ")") : "Leaf"; + stream << label << ", len = " << node->length + << ", begin = " << node->begin() << ", end = " << node->end() + << "\n"; + for (CordRep* edge : node->Edges()) { + DumpAll(edge, include_contents, stream, depth + 1); + } + } else if (rep->tag == SUBSTRING) { + const CordRepSubstring* substring = rep->substring(); + stream << "Substring, len = " << rep->length + << ", start = " << substring->start; + maybe_dump_data(rep); + DumpAll(substring->child, include_contents, stream, depth + 1); + } else if (rep->tag >= FLAT) { + stream << "Flat, len = " << rep->length + << ", cap = " << rep->flat()->Capacity(); + maybe_dump_data(rep); + } else if (rep->tag == EXTERNAL) { + stream << "Extn, len = " << rep->length; + maybe_dump_data(rep); + } +} + +// TODO(b/192061034): add 'bytes to copy' logic to avoid large slop on substring +// small data out of large reps, and general efficiency of 'always copy small +// data'. Consider making this a cord rep internal library function. +CordRepSubstring* CreateSubstring(CordRep* rep, size_t offset, size_t n) { + assert(n != 0); + assert(offset + n <= rep->length); + assert(offset != 0 || n != rep->length); + + if (rep->tag == SUBSTRING) { + CordRepSubstring* substring = rep->substring(); + offset += substring->start; + rep = CordRep::Ref(substring->child); + CordRep::Unref(substring); + } + CordRepSubstring* substring = new CordRepSubstring(); + substring->length = n; + substring->tag = SUBSTRING; + substring->start = offset; + substring->child = rep; + return substring; +} + +// TODO(b/192061034): consider making this a cord rep library function. +inline CordRep* MakeSubstring(CordRep* rep, size_t offset, size_t n) { + if (n == rep->length) return rep; + if (n == 0) return CordRep::Unref(rep), nullptr; + return CreateSubstring(rep, offset, n); +} + +// TODO(b/192061034): consider making this a cord rep library function. +inline CordRep* MakeSubstring(CordRep* rep, size_t offset) { + if (offset == 0) return rep; + return CreateSubstring(rep, offset, rep->length - offset); +} + +// Resizes `edge` to the provided `length`. Adopts a reference on `edge`. +// This method directly returns `edge` if `length` equals `edge->length`. +// If `is_mutable` is set to true, this function may return `edge` with +// `edge->length` set to the new length depending on the type and size of +// `edge`. Otherwise, this function returns a new CordRepSubstring value. +// Requires `length > 0 && length <= edge->length`. +CordRep* ResizeEdge(CordRep* edge, size_t length, bool is_mutable) { + assert(length > 0); + assert(length <= edge->length); + assert(CordRepBtree::IsDataEdge(edge)); + if (length >= edge->length) return edge; + + if (is_mutable && (edge->tag >= FLAT || edge->tag == SUBSTRING)) { + edge->length = length; + return edge; + } + + return CreateSubstring(edge, 0, length); +} + +template <EdgeType edge_type> +inline y_absl::string_view Consume(y_absl::string_view s, size_t n) { + return edge_type == kBack ? s.substr(n) : s.substr(0, s.size() - n); +} + +template <EdgeType edge_type> +inline y_absl::string_view Consume(char* dst, y_absl::string_view s, size_t n) { + if (edge_type == kBack) { + memcpy(dst, s.data(), n); + return s.substr(n); + } else { + const size_t offset = s.size() - n; + memcpy(dst, s.data() + offset, n); + return s.substr(0, offset); + } +} + +// Known issue / optimization weirdness: the store associated with the +// decrement introduces traffic between cpus (even if the result of that +// traffic does nothing), making this faster than a single call to +// refcount.Decrement() checking the zero refcount condition. +template <typename R, typename Fn> +inline void FastUnref(R* r, Fn&& fn) { + if (r->refcount.IsOne()) { + fn(r); + } else if (!r->refcount.DecrementExpectHighRefcount()) { + fn(r); + } +} + +// Deletes a leaf node data edge. Requires `rep` to be an EXTERNAL or FLAT +// node, or a SUBSTRING of an EXTERNAL or FLAT node. +void DeleteLeafEdge(CordRep* rep) { + for (;;) { + if (rep->tag >= FLAT) { + CordRepFlat::Delete(rep->flat()); + return; + } + if (rep->tag == EXTERNAL) { + CordRepExternal::Delete(rep->external()); + return; + } + assert(rep->tag == SUBSTRING); + CordRepSubstring* substring = rep->substring(); + rep = substring->child; + assert(rep->tag == EXTERNAL || rep->tag >= FLAT); + delete substring; + if (rep->refcount.Decrement()) return; + } +} + +// StackOperations contains the logic to build a left-most or right-most stack +// (leg) down to the leaf level of a btree, and 'unwind' / 'Finalize' methods to +// propagate node changes up the stack. +template <EdgeType edge_type> +struct StackOperations { + // Returns true if the node at 'depth' is mutable, i.e. has a refcount + // of one, carries no CRC, and all of its parent nodes have a refcount of one. + inline bool owned(int depth) const { return depth < share_depth; } + + // Returns the node at 'depth'. + inline CordRepBtree* node(int depth) const { return stack[depth]; } + + // Builds a `depth` levels deep stack starting at `tree` recording which nodes + // are private in the form of the 'share depth' where nodes are shared. + inline CordRepBtree* BuildStack(CordRepBtree* tree, int depth) { + assert(depth <= tree->height()); + int current_depth = 0; + while (current_depth < depth && tree->refcount.IsMutable()) { + stack[current_depth++] = tree; + tree = tree->Edge(edge_type)->btree(); + } + share_depth = current_depth + (tree->refcount.IsMutable() ? 1 : 0); + while (current_depth < depth) { + stack[current_depth++] = tree; + tree = tree->Edge(edge_type)->btree(); + } + return tree; + } + + // Builds a stack with the invariant that all nodes are private owned / not + // shared and carry no CRC data. This is used in iterative updates where a + // previous propagation guaranteed all nodes have this property. + inline void BuildOwnedStack(CordRepBtree* tree, int height) { + assert(height <= CordRepBtree::kMaxHeight); + int depth = 0; + while (depth < height) { + assert(tree->refcount.IsMutable()); + stack[depth++] = tree; + tree = tree->Edge(edge_type)->btree(); + } + assert(tree->refcount.IsMutable()); + share_depth = depth + 1; + } + + // Processes the final 'top level' result action for the tree. + // See the 'Action' enum for the various action implications. + static inline CordRepBtree* Finalize(CordRepBtree* tree, OpResult result) { + switch (result.action) { + case CordRepBtree::kPopped: + tree = edge_type == kBack ? CordRepBtree::New(tree, result.tree) + : CordRepBtree::New(result.tree, tree); + if (ABSL_PREDICT_FALSE(tree->height() > CordRepBtree::kMaxHeight)) { + tree = CordRepBtree::Rebuild(tree); + ABSL_RAW_CHECK(tree->height() <= CordRepBtree::kMaxHeight, + "Max height exceeded"); + } + return tree; + case CordRepBtree::kCopied: + CordRep::Unref(tree); + ABSL_FALLTHROUGH_INTENDED; + case CordRepBtree::kSelf: + return result.tree; + } + ABSL_INTERNAL_UNREACHABLE; + return result.tree; + } + + // Propagate the action result in 'result' up into all nodes of the stack + // starting at depth 'depth'. 'length' contains the extra length of data that + // was added at the lowest level, and is updated into all nodes of the stack. + // See the 'Action' enum for the various action implications. + // If 'propagate' is true, then any copied node values are updated into the + // stack, which is used for iterative processing on the same stack. + template <bool propagate = false> + inline CordRepBtree* Unwind(CordRepBtree* tree, int depth, size_t length, + OpResult result) { + // TODO(mvels): revisit the below code to check if 3 loops with 3 + // (incremental) conditions is faster than 1 loop with a switch. + // Benchmarking and perf recordings indicate the loop with switch is + // fastest, likely because of indirect jumps on the tight case values and + // dense branches. But it's worth considering 3 loops, as the `action` + // transitions are mono directional. E.g.: + // while (action == kPopped) { + // ... + // } + // while (action == kCopied) { + // ... + // } + // ... + // We also found that an "if () do {}" loop here seems faster, possibly + // because it allows the branch predictor more granular heuristics on + // 'single leaf' (`depth` == 0) and 'single depth' (`depth` == 1) cases + // which appear to be the most common use cases. + if (depth != 0) { + do { + CordRepBtree* node = stack[--depth]; + const bool owned = depth < share_depth; + switch (result.action) { + case CordRepBtree::kPopped: + assert(!propagate); + result = node->AddEdge<edge_type>(owned, result.tree, length); + break; + case CordRepBtree::kCopied: + result = node->SetEdge<edge_type>(owned, result.tree, length); + if (propagate) stack[depth] = result.tree; + break; + case CordRepBtree::kSelf: + node->length += length; + while (depth > 0) { + node = stack[--depth]; + node->length += length; + } + return node; + } + } while (depth > 0); + } + return Finalize(tree, result); + } + + // Invokes `Unwind` with `propagate=true` to update the stack node values. + inline CordRepBtree* Propagate(CordRepBtree* tree, int depth, size_t length, + OpResult result) { + return Unwind</*propagate=*/true>(tree, depth, length, result); + } + + // `share_depth` contains the depth at which the nodes in the stack cannot + // be mutated. I.e., if the top most level is shared (i.e.: + // `!refcount.IsMutable()`), then `share_depth` is 0. If the 2nd node + // is shared (and implicitly all nodes below that) then `share_depth` is 1, + // etc. A `share_depth` greater than the depth of the stack indicates that + // none of the nodes in the stack are shared. + int share_depth; + + NodeStack stack; +}; + +} // namespace + +void CordRepBtree::Dump(const CordRep* rep, y_absl::string_view label, + bool include_contents, std::ostream& stream) { + stream << "===================================\n"; + if (!label.empty()) { + stream << label << '\n'; + stream << "-----------------------------------\n"; + } + if (rep) { + DumpAll(rep, include_contents, stream); + } else { + stream << "NULL\n"; + } +} + +void CordRepBtree::Dump(const CordRep* rep, y_absl::string_view label, + std::ostream& stream) { + Dump(rep, label, false, stream); +} + +void CordRepBtree::Dump(const CordRep* rep, std::ostream& stream) { + Dump(rep, y_absl::string_view(), false, stream); +} + +void CordRepBtree::DestroyLeaf(CordRepBtree* tree, size_t begin, size_t end) { + for (CordRep* edge : tree->Edges(begin, end)) { + FastUnref(edge, DeleteLeafEdge); + } + Delete(tree); +} + +void CordRepBtree::DestroyNonLeaf(CordRepBtree* tree, size_t begin, + size_t end) { + for (CordRep* edge : tree->Edges(begin, end)) { + FastUnref(edge->btree(), Destroy); + } + Delete(tree); +} + +bool CordRepBtree::IsValid(const CordRepBtree* tree, bool shallow) { +#define NODE_CHECK_VALID(x) \ + if (!(x)) { \ + ABSL_RAW_LOG(ERROR, "CordRepBtree::CheckValid() FAILED: %s", #x); \ + return false; \ + } +#define NODE_CHECK_EQ(x, y) \ + if ((x) != (y)) { \ + ABSL_RAW_LOG(ERROR, \ + "CordRepBtree::CheckValid() FAILED: %s != %s (%s vs %s)", #x, \ + #y, y_absl::StrCat(x).c_str(), y_absl::StrCat(y).c_str()); \ + return false; \ + } + + NODE_CHECK_VALID(tree != nullptr); + NODE_CHECK_VALID(tree->IsBtree()); + NODE_CHECK_VALID(tree->height() <= kMaxHeight); + NODE_CHECK_VALID(tree->begin() < tree->capacity()); + NODE_CHECK_VALID(tree->end() <= tree->capacity()); + NODE_CHECK_VALID(tree->begin() <= tree->end()); + size_t child_length = 0; + for (CordRep* edge : tree->Edges()) { + NODE_CHECK_VALID(edge != nullptr); + if (tree->height() > 0) { + NODE_CHECK_VALID(edge->IsBtree()); + NODE_CHECK_VALID(edge->btree()->height() == tree->height() - 1); + } else { + NODE_CHECK_VALID(IsDataEdge(edge)); + } + child_length += edge->length; + } + NODE_CHECK_EQ(child_length, tree->length); + if ((!shallow || exhaustive_validation()) && tree->height() > 0) { + for (CordRep* edge : tree->Edges()) { + if (!IsValid(edge->btree(), shallow)) return false; + } + } + return true; + +#undef NODE_CHECK_VALID +#undef NODE_CHECK_EQ +} + +#ifndef NDEBUG + +CordRepBtree* CordRepBtree::AssertValid(CordRepBtree* tree, bool shallow) { + if (!IsValid(tree, shallow)) { + Dump(tree, "CordRepBtree validation failed:", false, std::cout); + ABSL_RAW_LOG(FATAL, "CordRepBtree::CheckValid() FAILED"); + } + return tree; +} + +const CordRepBtree* CordRepBtree::AssertValid(const CordRepBtree* tree, + bool shallow) { + if (!IsValid(tree, shallow)) { + Dump(tree, "CordRepBtree validation failed:", false, std::cout); + ABSL_RAW_LOG(FATAL, "CordRepBtree::CheckValid() FAILED"); + } + return tree; +} + +#endif // NDEBUG + +template <EdgeType edge_type> +inline OpResult CordRepBtree::AddEdge(bool owned, CordRep* edge, size_t delta) { + if (size() >= kMaxCapacity) return {New(edge), kPopped}; + OpResult result = ToOpResult(owned); + result.tree->Add<edge_type>(edge); + result.tree->length += delta; + return result; +} + +template <EdgeType edge_type> +OpResult CordRepBtree::SetEdge(bool owned, CordRep* edge, size_t delta) { + OpResult result; + const size_t idx = index(edge_type); + if (owned) { + result = {this, kSelf}; + CordRep::Unref(edges_[idx]); + } else { + // Create a copy containing all unchanged edges. Unchanged edges are the + // open interval [begin, back) or [begin + 1, end) depending on `edge_type`. + // We conveniently cover both case using a constexpr `shift` being 0 or 1 + // as `end :== back + 1`. + result = {CopyRaw(), kCopied}; + constexpr int shift = edge_type == kFront ? 1 : 0; + for (CordRep* r : Edges(begin() + shift, back() + shift)) { + CordRep::Ref(r); + } + } + result.tree->edges_[idx] = edge; + result.tree->length += delta; + return result; +} + +template <EdgeType edge_type> +CordRepBtree* CordRepBtree::AddCordRep(CordRepBtree* tree, CordRep* rep) { + const int depth = tree->height(); + const size_t length = rep->length; + StackOperations<edge_type> ops; + CordRepBtree* leaf = ops.BuildStack(tree, depth); + const OpResult result = + leaf->AddEdge<edge_type>(ops.owned(depth), rep, length); + return ops.Unwind(tree, depth, length, result); +} + +template <> +CordRepBtree* CordRepBtree::NewLeaf<kBack>(y_absl::string_view data, + size_t extra) { + CordRepBtree* leaf = CordRepBtree::New(0); + size_t length = 0; + size_t end = 0; + const size_t cap = leaf->capacity(); + while (!data.empty() && end != cap) { + auto* flat = CordRepFlat::New(data.length() + extra); + flat->length = (std::min)(data.length(), flat->Capacity()); + length += flat->length; + leaf->edges_[end++] = flat; + data = Consume<kBack>(flat->Data(), data, flat->length); + } + leaf->length = length; + leaf->set_end(end); + return leaf; +} + +template <> +CordRepBtree* CordRepBtree::NewLeaf<kFront>(y_absl::string_view data, + size_t extra) { + CordRepBtree* leaf = CordRepBtree::New(0); + size_t length = 0; + size_t begin = leaf->capacity(); + leaf->set_end(leaf->capacity()); + while (!data.empty() && begin != 0) { + auto* flat = CordRepFlat::New(data.length() + extra); + flat->length = (std::min)(data.length(), flat->Capacity()); + length += flat->length; + leaf->edges_[--begin] = flat; + data = Consume<kFront>(flat->Data(), data, flat->length); + } + leaf->length = length; + leaf->set_begin(begin); + return leaf; +} + +template <> +y_absl::string_view CordRepBtree::AddData<kBack>(y_absl::string_view data, + size_t extra) { + assert(!data.empty()); + assert(size() < capacity()); + AlignBegin(); + const size_t cap = capacity(); + do { + CordRepFlat* flat = CordRepFlat::New(data.length() + extra); + const size_t n = (std::min)(data.length(), flat->Capacity()); + flat->length = n; + edges_[fetch_add_end(1)] = flat; + data = Consume<kBack>(flat->Data(), data, n); + } while (!data.empty() && end() != cap); + return data; +} + +template <> +y_absl::string_view CordRepBtree::AddData<kFront>(y_absl::string_view data, + size_t extra) { + assert(!data.empty()); + assert(size() < capacity()); + AlignEnd(); + do { + CordRepFlat* flat = CordRepFlat::New(data.length() + extra); + const size_t n = (std::min)(data.length(), flat->Capacity()); + flat->length = n; + edges_[sub_fetch_begin(1)] = flat; + data = Consume<kFront>(flat->Data(), data, n); + } while (!data.empty() && begin() != 0); + return data; +} + +template <EdgeType edge_type> +CordRepBtree* CordRepBtree::AddData(CordRepBtree* tree, y_absl::string_view data, + size_t extra) { + if (ABSL_PREDICT_FALSE(data.empty())) return tree; + + const size_t original_data_size = data.size(); + int depth = tree->height(); + StackOperations<edge_type> ops; + CordRepBtree* leaf = ops.BuildStack(tree, depth); + + // If there is capacity in the last edge, append as much data + // as possible into this last edge. + if (leaf->size() < leaf->capacity()) { + OpResult result = leaf->ToOpResult(ops.owned(depth)); + data = result.tree->AddData<edge_type>(data, extra); + if (data.empty()) { + result.tree->length += original_data_size; + return ops.Unwind(tree, depth, original_data_size, result); + } + + // We added some data into this leaf, but not all. Propagate the added + // length to the top most node, and rebuild the stack with any newly copied + // or updated nodes. From this point on, the path (leg) from the top most + // node to the right-most node towards the leaf node is privately owned. + size_t delta = original_data_size - data.size(); + assert(delta > 0); + result.tree->length += delta; + tree = ops.Propagate(tree, depth, delta, result); + ops.share_depth = depth + 1; + } + + // We were unable to append all data into the existing right-most leaf node. + // This means all remaining data must be put into (a) new leaf node(s) which + // we append to the tree. To make this efficient, we iteratively build full + // leaf nodes from `data` until the created leaf contains all remaining data. + // We utilize the `Unwind` method to merge the created leaf into the first + // level towards root that has capacity. On each iteration with remaining + // data, we rebuild the stack in the knowledge that right-most nodes are + // privately owned after the first `Unwind` completes. + for (;;) { + OpResult result = {CordRepBtree::NewLeaf<edge_type>(data, extra), kPopped}; + if (result.tree->length == data.size()) { + return ops.Unwind(tree, depth, result.tree->length, result); + } + data = Consume<edge_type>(data, result.tree->length); + tree = ops.Unwind(tree, depth, result.tree->length, result); + depth = tree->height(); + ops.BuildOwnedStack(tree, depth); + } +} + +template <EdgeType edge_type> +CordRepBtree* CordRepBtree::Merge(CordRepBtree* dst, CordRepBtree* src) { + assert(dst->height() >= src->height()); + + // Capture source length as we may consume / destroy `src`. + const size_t length = src->length; + + // We attempt to merge `src` at its corresponding height in `dst`. + const int depth = dst->height() - src->height(); + StackOperations<edge_type> ops; + CordRepBtree* merge_node = ops.BuildStack(dst, depth); + + // If there is enough space in `merge_node` for all edges from `src`, add all + // edges to this node, making a fresh copy as needed if not privately owned. + // If `merge_node` does not have capacity for `src`, we rely on `Unwind` and + // `Finalize` to merge `src` into the first level towards `root` where there + // is capacity for another edge, or create a new top level node. + OpResult result; + if (merge_node->size() + src->size() <= kMaxCapacity) { + result = merge_node->ToOpResult(ops.owned(depth)); + result.tree->Add<edge_type>(src->Edges()); + result.tree->length += src->length; + if (src->refcount.IsOne()) { + Delete(src); + } else { + for (CordRep* edge : src->Edges()) CordRep::Ref(edge); + CordRepBtree::Unref(src); + } + } else { + result = {src, kPopped}; + } + + // Unless we merged at the top level (i.e.: src and dst are equal height), + // unwind the result towards the top level, and finalize the result. + if (depth) { + return ops.Unwind(dst, depth, length, result); + } + return ops.Finalize(dst, result); +} + +CopyResult CordRepBtree::CopySuffix(size_t offset) { + assert(offset < this->length); + + // As long as `offset` starts inside the last edge, we can 'drop' the current + // depth. For the most extreme example: if offset references the last data + // edge in the tree, there is only a single edge / path from the top of the + // tree to that last edge, so we can drop all the nodes except that edge. + // The fast path check for this is `back->length >= length - offset`. + int height = this->height(); + CordRepBtree* node = this; + size_t len = node->length - offset; + CordRep* back = node->Edge(kBack); + while (back->length >= len) { + offset = back->length - len; + if (--height < 0) { + return {MakeSubstring(CordRep::Ref(back), offset), height}; + } + node = back->btree(); + back = node->Edge(kBack); + } + if (offset == 0) return {CordRep::Ref(node), height}; + + // Offset does not point into the last edge, so we span at least two edges. + // Find the index of offset with `IndexBeyond` which provides us the edge + // 'beyond' the offset if offset is not a clean starting point of an edge. + Position pos = node->IndexBeyond(offset); + CordRepBtree* sub = node->CopyToEndFrom(pos.index, len); + const CopyResult result = {sub, height}; + + // `pos.n` contains a non zero value if the offset is not an exact starting + // point of an edge. In this case, `pos.n` contains the 'trailing' amount of + // bytes of the edge preceding that in `pos.index`. We need to iteratively + // adjust the preceding edge with the 'broken' offset until we have a perfect + // start of the edge. + while (pos.n != 0) { + assert(pos.index >= 1); + const size_t begin = pos.index - 1; + sub->set_begin(begin); + CordRep* const edge = node->Edge(begin); + + len = pos.n; + offset = edge->length - len; + + if (--height < 0) { + sub->edges_[begin] = MakeSubstring(CordRep::Ref(edge), offset, len); + return result; + } + + node = edge->btree(); + pos = node->IndexBeyond(offset); + + CordRepBtree* nsub = node->CopyToEndFrom(pos.index, len); + sub->edges_[begin] = nsub; + sub = nsub; + } + sub->set_begin(pos.index); + return result; +} + +CopyResult CordRepBtree::CopyPrefix(size_t n, bool allow_folding) { + assert(n > 0); + assert(n <= this->length); + + // As long as `n` does not exceed the length of the first edge, we can 'drop' + // the current depth. For the most extreme example: if we'd copy a 1 byte + // prefix from a tree, there is only a single edge / path from the top of the + // tree to the single data edge containing this byte, so we can drop all the + // nodes except the data node. + int height = this->height(); + CordRepBtree* node = this; + CordRep* front = node->Edge(kFront); + if (allow_folding) { + while (front->length >= n) { + if (--height < 0) return {MakeSubstring(CordRep::Ref(front), 0, n), -1}; + node = front->btree(); + front = node->Edge(kFront); + } + } + if (node->length == n) return {CordRep::Ref(node), height}; + + // `n` spans at least two nodes, find the end point of the span. + Position pos = node->IndexOf(n); + + // Create a partial copy of the node up to `pos.index`, with a defined length + // of `n`. Any 'partial last edge' is added further below as needed. + CordRepBtree* sub = node->CopyBeginTo(pos.index, n); + const CopyResult result = {sub, height}; + + // `pos.n` contains the 'offset inside the edge for IndexOf(n)'. As long as + // this is not zero, we don't have a 'clean cut', so we need to make a + // (partial) copy of that last edge, and repeat this until pos.n is zero. + while (pos.n != 0) { + size_t end = pos.index; + n = pos.n; + + CordRep* edge = node->Edge(pos.index); + if (--height < 0) { + sub->edges_[end++] = MakeSubstring(CordRep::Ref(edge), 0, n); + sub->set_end(end); + AssertValid(result.edge->btree()); + return result; + } + + node = edge->btree(); + pos = node->IndexOf(n); + CordRepBtree* nsub = node->CopyBeginTo(pos.index, n); + sub->edges_[end++] = nsub; + sub->set_end(end); + sub = nsub; + } + sub->set_end(pos.index); + AssertValid(result.edge->btree()); + return result; +} + +CordRep* CordRepBtree::ExtractFront(CordRepBtree* tree) { + CordRep* front = tree->Edge(tree->begin()); + if (tree->refcount.IsMutable()) { + Unref(tree->Edges(tree->begin() + 1, tree->end())); + CordRepBtree::Delete(tree); + } else { + CordRep::Ref(front); + CordRep::Unref(tree); + } + return front; +} + +CordRepBtree* CordRepBtree::ConsumeBeginTo(CordRepBtree* tree, size_t end, + size_t new_length) { + assert(end <= tree->end()); + if (tree->refcount.IsMutable()) { + Unref(tree->Edges(end, tree->end())); + tree->set_end(end); + tree->length = new_length; + } else { + CordRepBtree* old = tree; + tree = tree->CopyBeginTo(end, new_length); + CordRep::Unref(old); + } + return tree; +} + +CordRep* CordRepBtree::RemoveSuffix(CordRepBtree* tree, size_t n) { + // Check input and deal with trivial cases 'Remove all/none' + assert(tree != nullptr); + assert(n <= tree->length); + const size_t len = tree->length; + if (ABSL_PREDICT_FALSE(n == 0)) { + return tree; + } + if (ABSL_PREDICT_FALSE(n >= len)) { + CordRepBtree::Unref(tree); + return nullptr; + } + + size_t length = len - n; + int height = tree->height(); + bool is_mutable = tree->refcount.IsMutable(); + + // Extract all top nodes which are reduced to size = 1 + Position pos = tree->IndexOfLength(length); + while (pos.index == tree->begin()) { + CordRep* edge = ExtractFront(tree); + is_mutable &= edge->refcount.IsMutable(); + if (height-- == 0) return ResizeEdge(edge, length, is_mutable); + tree = edge->btree(); + pos = tree->IndexOfLength(length); + } + + // Repeat the following sequence traversing down the tree: + // - Crop the top node to the 'last remaining edge' adjusting length. + // - Set the length for down edges to the partial length in that last edge. + // - Repeat this until the last edge is 'included in full' + // - If we hit the data edge level, resize and return the last data edge + CordRepBtree* top = tree = ConsumeBeginTo(tree, pos.index + 1, length); + CordRep* edge = tree->Edge(pos.index); + length = pos.n; + while (length != edge->length) { + // ConsumeBeginTo guarantees `tree` is a clean, privately owned copy. + assert(tree->refcount.IsMutable()); + const bool edge_is_mutable = edge->refcount.IsMutable(); + + if (height-- == 0) { + tree->edges_[pos.index] = ResizeEdge(edge, length, edge_is_mutable); + return AssertValid(top); + } + + if (!edge_is_mutable) { + // We can't 'in place' remove any suffixes down this edge. + // Replace this edge with a prefix copy instead. + tree->edges_[pos.index] = edge->btree()->CopyPrefix(length, false).edge; + CordRep::Unref(edge); + return AssertValid(top); + } + + // Move down one level, rinse repeat. + tree = edge->btree(); + pos = tree->IndexOfLength(length); + tree = ConsumeBeginTo(edge->btree(), pos.index + 1, length); + edge = tree->Edge(pos.index); + length = pos.n; + } + + return AssertValid(top); +} + +CordRep* CordRepBtree::SubTree(size_t offset, size_t n) { + assert(n <= this->length); + assert(offset <= this->length - n); + if (ABSL_PREDICT_FALSE(n == 0)) return nullptr; + + CordRepBtree* node = this; + int height = node->height(); + Position front = node->IndexOf(offset); + CordRep* left = node->edges_[front.index]; + while (front.n + n <= left->length) { + if (--height < 0) return MakeSubstring(CordRep::Ref(left), front.n, n); + node = left->btree(); + front = node->IndexOf(front.n); + left = node->edges_[front.index]; + } + + const Position back = node->IndexBefore(front, n); + CordRep* const right = node->edges_[back.index]; + assert(back.index > front.index); + + // Get partial suffix and prefix entries. + CopyResult prefix; + CopyResult suffix; + if (height > 0) { + // Copy prefix and suffix of the boundary nodes. + prefix = left->btree()->CopySuffix(front.n); + suffix = right->btree()->CopyPrefix(back.n); + + // If there is an edge between the prefix and suffix edges, then the tree + // must remain at its previous (full) height. If we have no edges between + // prefix and suffix edges, then the tree must be as high as either the + // suffix or prefix edges (which are collapsed to their minimum heights). + if (front.index + 1 == back.index) { + height = (std::max)(prefix.height, suffix.height) + 1; + } + + // Raise prefix and suffixes to the new tree height. + for (int h = prefix.height + 1; h < height; ++h) { + prefix.edge = CordRepBtree::New(prefix.edge); + } + for (int h = suffix.height + 1; h < height; ++h) { + suffix.edge = CordRepBtree::New(suffix.edge); + } + } else { + // Leaf node, simply take substrings for prefix and suffix. + prefix = CopyResult{MakeSubstring(CordRep::Ref(left), front.n), -1}; + suffix = CopyResult{MakeSubstring(CordRep::Ref(right), 0, back.n), -1}; + } + + // Compose resulting tree. + CordRepBtree* sub = CordRepBtree::New(height); + size_t end = 0; + sub->edges_[end++] = prefix.edge; + for (CordRep* r : node->Edges(front.index + 1, back.index)) { + sub->edges_[end++] = CordRep::Ref(r); + } + sub->edges_[end++] = suffix.edge; + sub->set_end(end); + sub->length = n; + return AssertValid(sub); +} + +CordRepBtree* CordRepBtree::MergeTrees(CordRepBtree* left, + CordRepBtree* right) { + return left->height() >= right->height() ? Merge<kBack>(left, right) + : Merge<kFront>(right, left); +} + +bool CordRepBtree::IsFlat(y_absl::string_view* fragment) const { + if (height() == 0 && size() == 1) { + if (fragment) *fragment = Data(begin()); + return true; + } + return false; +} + +bool CordRepBtree::IsFlat(size_t offset, const size_t n, + y_absl::string_view* fragment) const { + assert(n <= this->length); + assert(offset <= this->length - n); + if (ABSL_PREDICT_FALSE(n == 0)) return false; + int height = this->height(); + const CordRepBtree* node = this; + for (;;) { + const Position front = node->IndexOf(offset); + const CordRep* edge = node->Edge(front.index); + if (edge->length < front.n + n) return false; + if (--height < 0) { + if (fragment) *fragment = EdgeData(edge).substr(front.n, n); + return true; + } + offset = front.n; + node = node->Edge(front.index)->btree(); + } +} + +char CordRepBtree::GetCharacter(size_t offset) const { + assert(offset < length); + const CordRepBtree* node = this; + int height = node->height(); + for (;;) { + Position front = node->IndexOf(offset); + if (--height < 0) return node->Data(front.index)[front.n]; + offset = front.n; + node = node->Edge(front.index)->btree(); + } +} + +Span<char> CordRepBtree::GetAppendBufferSlow(size_t size) { + // The inlined version in `GetAppendBuffer()` deals with all heights <= 3. + assert(height() >= 4); + assert(refcount.IsMutable()); + + // Build a stack of nodes we may potentially need to update if we find a + // non-shared FLAT with capacity at the leaf level. + const int depth = height(); + CordRepBtree* node = this; + CordRepBtree* stack[kMaxDepth]; + for (int i = 0; i < depth; ++i) { + node = node->Edge(kBack)->btree(); + if (!node->refcount.IsMutable()) return {}; + stack[i] = node; + } + + // Must be a privately owned, mutable flat. + CordRep* const edge = node->Edge(kBack); + if (!edge->refcount.IsMutable() || edge->tag < FLAT) return {}; + + // Must have capacity. + const size_t avail = edge->flat()->Capacity() - edge->length; + if (avail == 0) return {}; + + // Build span on remaining capacity. + size_t delta = (std::min)(size, avail); + Span<char> span = {edge->flat()->Data() + edge->length, delta}; + edge->length += delta; + this->length += delta; + for (int i = 0; i < depth; ++i) { + stack[i]->length += delta; + } + return span; +} + +CordRepBtree* CordRepBtree::CreateSlow(CordRep* rep) { + if (rep->IsBtree()) return rep->btree(); + + CordRepBtree* node = nullptr; + auto consume = [&node](CordRep* r, size_t offset, size_t length) { + r = MakeSubstring(r, offset, length); + if (node == nullptr) { + node = New(r); + } else { + node = CordRepBtree::AddCordRep<kBack>(node, r); + } + }; + Consume(rep, consume); + return node; +} + +CordRepBtree* CordRepBtree::AppendSlow(CordRepBtree* tree, CordRep* rep) { + if (ABSL_PREDICT_TRUE(rep->IsBtree())) { + return MergeTrees(tree, rep->btree()); + } + auto consume = [&tree](CordRep* r, size_t offset, size_t length) { + r = MakeSubstring(r, offset, length); + tree = CordRepBtree::AddCordRep<kBack>(tree, r); + }; + Consume(rep, consume); + return tree; +} + +CordRepBtree* CordRepBtree::PrependSlow(CordRepBtree* tree, CordRep* rep) { + if (ABSL_PREDICT_TRUE(rep->IsBtree())) { + return MergeTrees(rep->btree(), tree); + } + auto consume = [&tree](CordRep* r, size_t offset, size_t length) { + r = MakeSubstring(r, offset, length); + tree = CordRepBtree::AddCordRep<kFront>(tree, r); + }; + ReverseConsume(rep, consume); + return tree; +} + +CordRepBtree* CordRepBtree::Append(CordRepBtree* tree, y_absl::string_view data, + size_t extra) { + return CordRepBtree::AddData<kBack>(tree, data, extra); +} + +CordRepBtree* CordRepBtree::Prepend(CordRepBtree* tree, y_absl::string_view data, + size_t extra) { + return CordRepBtree::AddData<kFront>(tree, data, extra); +} + +template CordRepBtree* CordRepBtree::AddCordRep<kFront>(CordRepBtree* tree, + CordRep* rep); +template CordRepBtree* CordRepBtree::AddCordRep<kBack>(CordRepBtree* tree, + CordRep* rep); +template CordRepBtree* CordRepBtree::AddData<kFront>(CordRepBtree* tree, + y_absl::string_view data, + size_t extra); +template CordRepBtree* CordRepBtree::AddData<kBack>(CordRepBtree* tree, + y_absl::string_view data, + size_t extra); + +void CordRepBtree::Rebuild(CordRepBtree** stack, CordRepBtree* tree, + bool consume) { + bool owned = consume && tree->refcount.IsOne(); + if (tree->height() == 0) { + for (CordRep* edge : tree->Edges()) { + if (!owned) edge = CordRep::Ref(edge); + size_t height = 0; + size_t length = edge->length; + CordRepBtree* node = stack[0]; + OpResult result = node->AddEdge<kBack>(true, edge, length); + while (result.action == CordRepBtree::kPopped) { + stack[height] = result.tree; + if (stack[++height] == nullptr) { + result.action = CordRepBtree::kSelf; + stack[height] = CordRepBtree::New(node, result.tree); + } else { + node = stack[height]; + result = node->AddEdge<kBack>(true, result.tree, length); + } + } + while (stack[++height] != nullptr) { + stack[height]->length += length; + } + } + } else { + for (CordRep* rep : tree->Edges()) { + Rebuild(stack, rep->btree(), owned); + } + } + if (consume) { + if (owned) { + CordRepBtree::Delete(tree); + } else { + CordRepBtree::Unref(tree); + } + } +} + +CordRepBtree* CordRepBtree::Rebuild(CordRepBtree* tree) { + // Set up initial stack with empty leaf node. + CordRepBtree* node = CordRepBtree::New(); + CordRepBtree* stack[CordRepBtree::kMaxDepth + 1] = {node}; + + // Recursively build the tree, consuming the input tree. + Rebuild(stack, tree, /* consume reference */ true); + + // Return top most node + for (CordRepBtree* parent : stack) { + if (parent == nullptr) return node; + node = parent; + } + + // Unreachable + assert(false); + return nullptr; +} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree.h index 3ad8097cc8..b60358ab9e 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree.h @@ -1,939 +1,939 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_H_ -#define ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_H_ - -#include <cassert> -#include <cstdint> -#include <iosfwd> - -#include "y_absl/base/config.h" -#include "y_absl/base/internal/raw_logging.h" -#include "y_absl/base/optimization.h" -#include "y_absl/strings/internal/cord_internal.h" -#include "y_absl/strings/internal/cord_rep_flat.h" -#include "y_absl/strings/string_view.h" -#include "y_absl/types/span.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -class CordRepBtreeNavigator; - -// CordRepBtree is as the name implies a btree implementation of a Cordrep tree. -// Data is stored at the leaf level only, non leaf nodes contain down pointers -// only. Allowed types of data edges are FLAT, EXTERNAL and SUBSTRINGs of FLAT -// or EXTERNAL nodes. The implementation allows for data to be added to either -// end of the tree only, it does not provide any 'insert' logic. This has the -// benefit that we can expect good fill ratios: all nodes except the outer -// 'legs' will have 100% fill ratios for trees built using Append/Prepend -// methods. Merged trees will typically have a fill ratio well above 50% as in a -// similar fashion, one side of the merged tree will typically have a 100% fill -// ratio, and the 'open' end will average 50%. All operations are O(log(n)) or -// better, and the tree never needs balancing. -// -// All methods accepting a CordRep* or CordRepBtree* adopt a reference on that -// input unless explicitly stated otherwise. All functions returning a CordRep* -// or CordRepBtree* instance transfer a reference back to the caller. -// Simplified, callers both 'donate' and 'consume' a reference count on each -// call, simplifying the API. An example of building a tree: -// -// CordRepBtree* tree = CordRepBtree::Create(MakeFlat("Hello")); -// tree = CordRepBtree::Append(tree, MakeFlat("world")); -// -// In the above example, all inputs are consumed, making each call affecting -// `tree` reference count neutral. The returned `tree` value can be different -// from the input if the input is shared with other threads, or if the tree -// grows in height, but callers typically never have to concern themselves with -// that and trust that all methods DTRT at all times. -class CordRepBtree : public CordRep { - public: - // EdgeType identifies `front` and `back` enum values. - // Various implementations in CordRepBtree such as `Add` and `Edge` are - // generic and templated on operating on either of the boundary edges. - // For more information on the possible edges contained in a CordRepBtree - // instance see the documentation for `edges_`. - enum class EdgeType { kFront, kBack }; - - // Convenience constants into `EdgeType` - static constexpr EdgeType kFront = EdgeType::kFront; - static constexpr EdgeType kBack = EdgeType::kBack; - - // Maximum number of edges: based on experiments and performance data, we can - // pick suitable values resulting in optimum cacheline aligned values. The - // preferred values are based on 64-bit systems where we aim to align this - // class onto 64 bytes, i.e.: 6 = 64 bytes, 14 = 128 bytes, etc. - // TODO(b/192061034): experiment with alternative sizes. - static constexpr size_t kMaxCapacity = 6; - - // Reasonable maximum height of the btree. We can expect a fill ratio of at - // least 50%: trees are always expanded at the front or back. Concatenating - // trees will then typically fold at the top most node, where the lower nodes - // are at least at capacity on one side of joined inputs. At a lower fill - // rate of 4 edges per node, we have capacity for ~16 million leaf nodes. - // We will fail / abort if an application ever exceeds this height, which - // should be extremely rare (near impossible) and be an indication of an - // application error: we do not assume it reasonable for any application to - // operate correctly with such monster trees. - // Another compelling reason for the number `12` is that any contextual stack - // required for navigation or insertion requires 12 words and 12 bytes, which - // fits inside 2 cache lines with some room to spare, and is reasonable as a - // local stack variable compared to Cord's current near 400 bytes stack use. - // The maximum `height` value of a node is then `kMaxDepth - 1` as node height - // values start with a value of 0 for leaf nodes. - static constexpr int kMaxDepth = 12; - static constexpr int kMaxHeight = kMaxDepth - 1; - - // `Action` defines the action for unwinding changes done at the btree's leaf - // level that need to be propagated up to the parent node(s). Each operation - // on a node has an effect / action defined as follows: - // - kSelf - // The operation (add / update, etc) was performed directly on the node as - // the node is private to the current thread (i.e.: not shared directly or - // indirectly through a refcount > 1). Changes can be propagated directly to - // all parent nodes as all parent nodes are also then private to the current - // thread. - // - kCopied - // The operation (add / update, etc) was performed on a copy of the original - // node, as the node is (potentially) directly or indirectly shared with - // other threads. Changes need to be propagated into the parent nodes where - // the old down pointer must be unreffed and replaced with this new copy. - // Such changes to parent nodes may themselves require a copy if the parent - // node is also shared. A kCopied action can propagate all the way to the - // top node where we then must unref the `tree` input provided by the - // caller, and return the new copy. - // - kPopped - // The operation (typically add) could not be satisfied due to insufficient - // capacity in the targeted node, and a new 'leg' was created that needs to - // be added into the parent node. For example, adding a FLAT inside a leaf - // node that is at capacity will create a new leaf node containing that - // FLAT, that needs to be 'popped' up the btree. Such 'pop' actions can - // cascade up the tree if parent nodes are also at capacity. A 'Popped' - // action propagating all the way to the top of the tree will result in - // the tree becoming one level higher than the current tree through a final - // `CordRepBtree::New(tree, popped)` call, resulting in a new top node - // referencing the old tree and the new (fully popped upwards) 'leg'. - enum Action { kSelf, kCopied, kPopped }; - - // Result of an operation on a node. See the `Action` enum for details. - struct OpResult { - CordRepBtree* tree; - Action action; - }; - - // Return value of the CopyPrefix and CopySuffix methods which can - // return a node or data edge at any height inside the tree. - // A height of 0 defines the lowest (leaf) node, a height of -1 identifies - // `edge` as being a plain data node: EXTERNAL / FLAT or SUBSTRING thereof. - struct CopyResult { - CordRep* edge; - int height; - }; - - // Logical position inside a node: - // - index: index of the edge. - // - n: size or offset value depending on context. - struct Position { - size_t index; - size_t n; - }; - - // Creates a btree from the given input. Adopts a ref of `rep`. - // If the input `rep` is itself a btree, i.e., `IsBtree()`, then this - // function immediately returns `rep->btree()`. If the input is a valid data - // edge (see IsDataEdge()), then a new leaf node is returned containing `rep` - // as the sole data edge. Else, the input is assumed to be a (legacy) concat - // tree, and the input is consumed and transformed into a btree(). - static CordRepBtree* Create(CordRep* rep); - - // Destroys the provided tree. Should only be called by cord internal API's, - // typically after a ref_count.Decrement() on the last reference count. - static void Destroy(CordRepBtree* tree); - - // Use CordRep::Unref() as we overload for y_absl::Span<CordRep* const>. - using CordRep::Unref; - - // Unrefs all edges in `edges` which are assumed to be 'likely one'. - static void Unref(y_absl::Span<CordRep* const> edges); - - // Appends / Prepends an existing CordRep instance to this tree. - // The below methods accept three types of input: - // 1) `rep` is a data node (See `IsDataNode` for valid data edges). - // `rep` is appended or prepended to this tree 'as is'. - // 2) `rep` is a BTREE. - // `rep` is merged into `tree` respecting the Append/Prepend order. - // 3) `rep` is some other (legacy) type. - // `rep` is converted in place and added to `tree` - // Requires `tree` and `rep` to be not null. - static CordRepBtree* Append(CordRepBtree* tree, CordRep* rep); - static CordRepBtree* Prepend(CordRepBtree* tree, CordRep* rep); - - // Append/Prepend the data in `data` to this tree. - // The `extra` parameter defines how much extra capacity should be allocated - // for any additional FLAT being allocated. This is an optimization hint from - // the caller. For example, a caller may need to add 2 string_views of data - // "abc" and "defghi" which are not consecutive. The caller can in this case - // invoke `AddData(tree, "abc", 6)`, and any newly added flat is allocated - // where possible with at least 6 bytes of extra capacity beyond `length`. - // This helps avoiding data getting fragmented over multiple flats. - // There is no limit on the size of `data`. If `data` can not be stored inside - // a single flat, then the function will iteratively add flats until all data - // has been consumed and appended or prepended to the tree. - static CordRepBtree* Append(CordRepBtree* tree, string_view data, - size_t extra = 0); - static CordRepBtree* Prepend(CordRepBtree* tree, string_view data, - size_t extra = 0); - - // Returns a new tree, containing `n` bytes of data from this instance - // starting at offset `offset`. Where possible, the returned tree shares - // (re-uses) data edges and nodes with this instance to minimize the - // combined memory footprint of both trees. - // Requires `offset + n <= length`. Returns `nullptr` if `n` is zero. - CordRep* SubTree(size_t offset, size_t n); - - // Removes `n` trailing bytes from `tree`, and returns the resulting tree - // or data edge. Returns `tree` if n is zero, and nullptr if n == length. - // This function is logically identical to: - // result = tree->SubTree(0, tree->length - n); - // Unref(tree); - // return result; - // However, the actual implementation will as much as possible perform 'in - // place' modifications on the tree on all nodes and edges that are mutable. - // For example, in a fully privately owned tree with the last edge being a - // flat of length 12, RemoveSuffix(1) will simply set the length of that data - // edge to 11, and reduce the length of all nodes on the edge path by 1. - static CordRep* RemoveSuffix(CordRepBtree* tree, size_t n); - - // Returns the character at the given offset. - char GetCharacter(size_t offset) const; - - // Returns true if this node holds a single data edge, and if so, sets - // `fragment` to reference the contained data. `fragment` is an optional - // output parameter and allowed to be null. - bool IsFlat(y_absl::string_view* fragment) const; - - // Returns true if the data of `n` bytes starting at offset `offset` - // is contained in a single data edge, and if so, sets fragment to reference - // the contained data. `fragment` is an optional output parameter and allowed - // to be null. - bool IsFlat(size_t offset, size_t n, y_absl::string_view* fragment) const; - - // Returns a span (mutable range of bytes) of up to `size` bytes into the - // last FLAT data edge inside this tree under the following conditions: - // - none of the nodes down into the FLAT node are shared. - // - the last data edge in this tree is a non-shared FLAT. - // - the referenced FLAT has additional capacity available. - // If all these conditions are met, a non-empty span is returned, and the - // length of the flat node and involved tree nodes have been increased by - // `span.length()`. The caller is responsible for immediately assigning values - // to all uninitialized data reference by the returned span. - // Requires `this->refcount.IsMutable()`: this function forces the - // caller to do this fast path check on the top level node, as this is the - // most commonly shared node of a cord tree. - Span<char> GetAppendBuffer(size_t size); - - // Returns the `height` of the tree. The height of a tree is limited to - // kMaxHeight. `height` is implemented as an `int` as in some places we - // use negative (-1) values for 'data edges'. - int height() const { return static_cast<int>(storage[0]); } - - // Properties: begin, back, end, front/back boundary indexes. - size_t begin() const { return static_cast<size_t>(storage[1]); } - size_t back() const { return static_cast<size_t>(storage[2]) - 1; } - size_t end() const { return static_cast<size_t>(storage[2]); } - size_t index(EdgeType edge) const { - return edge == kFront ? begin() : back(); - } - - // Properties: size and capacity. - // `capacity` contains the current capacity of this instance, where - // `kMaxCapacity` contains the maximum capacity of a btree node. - // For now, `capacity` and `kMaxCapacity` return the same value, but this may - // change in the future if we see benefit in dynamically sizing 'small' nodes - // to 'large' nodes for large data trees. - size_t size() const { return end() - begin(); } - size_t capacity() const { return kMaxCapacity; } - - // Edge access - inline CordRep* Edge(size_t index) const; - inline CordRep* Edge(EdgeType edge_type) const; - inline y_absl::Span<CordRep* const> Edges() const; - inline y_absl::Span<CordRep* const> Edges(size_t begin, size_t end) const; - - // Returns reference to the data edge at `index`. - // Requires this instance to be a leaf node, and `index` to be valid index. - inline y_absl::string_view Data(size_t index) const; - - static const char* EdgeDataPtr(const CordRep* r); - static y_absl::string_view EdgeData(const CordRep* r); - - // Returns true if the provided rep is a FLAT, EXTERNAL or a SUBSTRING node - // holding a FLAT or EXTERNAL child rep. - static bool IsDataEdge(const CordRep* rep); - - // Diagnostics: returns true if `tree` is valid and internally consistent. - // If `shallow` is false, then the provided top level node and all child nodes - // below it are recursively checked. If `shallow` is true, only the provided - // node in `tree` and the cumulative length, type and height of the direct - // child nodes of `tree` are checked. The value of `shallow` is ignored if the - // internal `cord_btree_exhaustive_validation` diagnostics variable is true, - // in which case the performed validations works as if `shallow` were false. - // This function is intended for debugging and testing purposes only. - static bool IsValid(const CordRepBtree* tree, bool shallow = false); - - // Diagnostics: asserts that the provided tree is valid. - // `AssertValid()` performs a shallow validation by default. `shallow` can be - // set to false in which case an exhaustive validation is performed. This - // function is implemented in terms of calling `IsValid()` and asserting the - // return value to be true. See `IsValid()` for more information. - // This function is intended for debugging and testing purposes only. - static CordRepBtree* AssertValid(CordRepBtree* tree, bool shallow = true); - static const CordRepBtree* AssertValid(const CordRepBtree* tree, - bool shallow = true); - - // Diagnostics: dump the contents of this tree to `stream`. - // This function is intended for debugging and testing purposes only. - static void Dump(const CordRep* rep, std::ostream& stream); - static void Dump(const CordRep* rep, y_absl::string_view label, - std::ostream& stream); - static void Dump(const CordRep* rep, y_absl::string_view label, - bool include_contents, std::ostream& stream); - - // Adds the edge `edge` to this node if possible. `owned` indicates if the - // current node is potentially shared or not with other threads. Returns: - // - {kSelf, <this>} - // The edge was directly added to this node. - // - {kCopied, <node>} - // The edge was added to a copy of this node. - // - {kPopped, New(edge, height())} - // A new leg with the edge was created as this node has no extra capacity. - template <EdgeType edge_type> - inline OpResult AddEdge(bool owned, CordRep* edge, size_t delta); - - // Replaces the front or back edge with the provided new edge. Returns: - // - {kSelf, <this>} - // The edge was directly set in this node. The old edge is unreffed. - // - {kCopied, <node>} - // A copy of this node was created with the new edge value. - // In both cases, the function adopts a reference on `edge`. - template <EdgeType edge_type> - OpResult SetEdge(bool owned, CordRep* edge, size_t delta); - - // Creates a new empty node at the specified height. - static CordRepBtree* New(int height = 0); - - // Creates a new node containing `rep`, with the height being computed - // automatically based on the type of `rep`. - static CordRepBtree* New(CordRep* rep); - - // Creates a new node containing both `front` and `back` at height - // `front.height() + 1`. Requires `back.height() == front.height()`. - static CordRepBtree* New(CordRepBtree* front, CordRepBtree* back); - - // Creates a fully balanced tree from the provided tree by rebuilding a new - // tree from all data edges in the input. This function is automatically - // invoked internally when the tree exceeds the maximum height. - static CordRepBtree* Rebuild(CordRepBtree* tree); - - private: - CordRepBtree() = default; - ~CordRepBtree() = default; - - // Initializes the main properties `tag`, `begin`, `end`, `height`. - inline void InitInstance(int height, size_t begin = 0, size_t end = 0); - - // Direct property access begin / end - void set_begin(size_t begin) { storage[1] = static_cast<uint8_t>(begin); } - void set_end(size_t end) { storage[2] = static_cast<uint8_t>(end); } - - // Decreases the value of `begin` by `n`, and returns the new value. Notice - // how this returns the new value unlike atomic::fetch_add which returns the - // old value. This is because this is used to prepend edges at 'begin - 1'. - size_t sub_fetch_begin(size_t n) { - storage[1] -= static_cast<uint8_t>(n); - return storage[1]; - } - - // Increases the value of `end` by `n`, and returns the previous value. This - // function is typically used to append edges at 'end'. - size_t fetch_add_end(size_t n) { - const uint8_t current = storage[2]; - storage[2] = static_cast<uint8_t>(current + n); - return current; - } - - // Returns the index of the last edge starting on, or before `offset`, with - // `n` containing the relative offset of `offset` inside that edge. - // Requires `offset` < length. - Position IndexOf(size_t offset) const; - - // Returns the index of the last edge starting before `offset`, with `n` - // containing the relative offset of `offset` inside that edge. - // This function is useful to find the edges for some span of bytes ending at - // `offset` (i.e., `n` bytes). For example: - // - // Position pos = IndexBefore(n) - // edges = Edges(begin(), pos.index) // All full edges (may be empty) - // last = Sub(Edge(pos.index), 0, pos.n) // Last partial edge (may be empty) - // - // Requires 0 < `offset` <= length. - Position IndexBefore(size_t offset) const; - - // Returns the index of the edge ending at (or on) length `length`, and the - // number of bytes inside that edge up to `length`. For example, if we have a - // Node with 2 edges, one of 10 and one of 20 long, then IndexOfLength(27) - // will return {1, 17}, and IndexOfLength(10) will return {0, 10}. - Position IndexOfLength(size_t n) const; - - // Identical to the above function except starting from the position `front`. - // This function is equivalent to `IndexBefore(front.n + offset)`, with - // the difference that this function is optimized to start at `front.index`. - Position IndexBefore(Position front, size_t offset) const; - - // Returns the index of the edge directly beyond the edge containing offset - // `offset`, with `n` containing the distance of that edge from `offset`. - // This function is useful for iteratively finding suffix nodes and remaining - // partial bytes in left-most suffix nodes as for example in CopySuffix. - // Requires `offset` < length. - Position IndexBeyond(size_t offset) const; - - // Destruction - static void DestroyLeaf(CordRepBtree* tree, size_t begin, size_t end); - static void DestroyNonLeaf(CordRepBtree* tree, size_t begin, size_t end); - static void DestroyTree(CordRepBtree* tree, size_t begin, size_t end); - static void Delete(CordRepBtree* tree) { delete tree; } - - // Creates a new leaf node containing as much data as possible from `data`. - // The data is added either forwards or reversed depending on `edge_type`. - // Callers must check the length of the returned node to determine if all data - // was copied or not. - // See the `Append/Prepend` function for the meaning and purpose of `extra`. - template <EdgeType edge_type> - static CordRepBtree* NewLeaf(y_absl::string_view data, size_t extra); - - // Creates a raw copy of this Btree node, copying all properties, but - // without adding any references to existing edges. - CordRepBtree* CopyRaw() const; - - // Creates a full copy of this Btree node, adding a reference on all edges. - CordRepBtree* Copy() const; - - // Creates a partial copy of this Btree node, copying all edges up to `end`, - // adding a reference on each copied edge, and sets the length of the newly - // created copy to `new_length`. - CordRepBtree* CopyBeginTo(size_t end, size_t new_length) const; - - // Returns a tree containing the edges [tree->begin(), end) and length - // of `new_length`. This method consumes a reference on the provided - // tree, and logically performs the following operation: - // result = tree->CopyBeginTo(end, new_length); - // CordRep::Unref(tree); - // return result; - static CordRepBtree* ConsumeBeginTo(CordRepBtree* tree, size_t end, - size_t new_length); - - // Creates a partial copy of this Btree node, copying all edges starting at - // `begin`, adding a reference on each copied edge, and sets the length of - // the newly created copy to `new_length`. - CordRepBtree* CopyToEndFrom(size_t begin, size_t new_length) const; - - // Extracts and returns the front edge from the provided tree. - // This method consumes a reference on the provided tree, and logically - // performs the following operation: - // edge = CordRep::Ref(tree->Edge(kFront)); - // CordRep::Unref(tree); - // return edge; - static CordRep* ExtractFront(CordRepBtree* tree); - - // Returns a tree containing the result of appending `right` to `left`. - static CordRepBtree* MergeTrees(CordRepBtree* left, CordRepBtree* right); - - // Fallback functions for `Create()`, `Append()` and `Prepend()` which - // deal with legacy / non conforming input, i.e.: CONCAT trees. - static CordRepBtree* CreateSlow(CordRep* rep); - static CordRepBtree* AppendSlow(CordRepBtree*, CordRep* rep); - static CordRepBtree* PrependSlow(CordRepBtree*, CordRep* rep); - - // Recursively rebuilds `tree` into `stack`. If 'consume` is set to true, the - // function will consume a reference on `tree`. `stack` is a null terminated - // array containing the new tree's state, with the current leaf node at - // stack[0], and parent nodes above that, or null for 'top of tree'. - static void Rebuild(CordRepBtree** stack, CordRepBtree* tree, bool consume); - - // Aligns existing edges to start at index 0, to allow for a new edge to be - // added to the back of the current edges. - inline void AlignBegin(); - - // Aligns existing edges to end at `capacity`, to allow for a new edge to be - // added in front of the current edges. - inline void AlignEnd(); - - // Adds the provided edge to this node. - // Requires this node to have capacity for the edge. Realigns / moves - // existing edges as needed to prepend or append the new edge. - template <EdgeType edge_type> - inline void Add(CordRep* rep); - - // Adds the provided edges to this node. - // Requires this node to have capacity for the edges. Realigns / moves - // existing edges as needed to prepend or append the new edges. - template <EdgeType edge_type> - inline void Add(y_absl::Span<CordRep* const>); - - // Adds data from `data` to this node until either all data has been consumed, - // or there is no more capacity for additional flat nodes inside this node. - // Requires the current node to be a leaf node, data to be non empty, and the - // current node to have capacity for at least one more data edge. - // Returns any remaining data from `data` that was not added, which is - // depending on the edge type (front / back) either the remaining prefix of - // suffix of the input. - // See the `Append/Prepend` function for the meaning and purpose of `extra`. - template <EdgeType edge_type> - y_absl::string_view AddData(y_absl::string_view data, size_t extra); - - // Replace the front or back edge with the provided value. - // Adopts a reference on `edge` and unrefs the old edge. - template <EdgeType edge_type> - inline void SetEdge(CordRep* edge); - - // Returns a partial copy of the current tree containing the first `n` bytes - // of data. `CopyResult` contains both the resulting edge and its height. The - // resulting tree may be less high than the current tree, or even be a single - // matching data edge if `allow_folding` is set to true. - // For example, if `n == 1`, then the result will be the single data edge, and - // height will be set to -1 (one below the owning leaf node). If n == 0, this - // function returns null. Requires `n <= length` - CopyResult CopyPrefix(size_t n, bool allow_folding = true); - - // Returns a partial copy of the current tree containing all data starting - // after `offset`. `CopyResult` contains both the resulting edge and its - // height. The resulting tree may be less high than the current tree, or even - // be a single matching data edge. For example, if `n == length - 1`, then the - // result will be a single data edge, and height will be set to -1 (one below - // the owning leaf node). - // Requires `offset < length` - CopyResult CopySuffix(size_t offset); - - // Returns a OpResult value of {this, kSelf} or {Copy(), kCopied} - // depending on the value of `owned`. - inline OpResult ToOpResult(bool owned); - - // Adds `rep` to the specified tree, returning the modified tree. - template <EdgeType edge_type> - static CordRepBtree* AddCordRep(CordRepBtree* tree, CordRep* rep); - - // Adds `data` to the specified tree, returning the modified tree. - // See the `Append/Prepend` function for the meaning and purpose of `extra`. - template <EdgeType edge_type> - static CordRepBtree* AddData(CordRepBtree* tree, y_absl::string_view data, - size_t extra = 0); - - // Merges `src` into `dst` with `src` being added either before (kFront) or - // after (kBack) `dst`. Requires the height of `dst` to be greater than or - // equal to the height of `src`. - template <EdgeType edge_type> - static CordRepBtree* Merge(CordRepBtree* dst, CordRepBtree* src); - - // Fallback version of GetAppendBuffer for large trees: GetAppendBuffer() - // implements an inlined version for trees of limited height (3 levels), - // GetAppendBufferSlow implements the logic for large trees. - Span<char> GetAppendBufferSlow(size_t size); - - // `edges_` contains all edges starting from this instance. - // These are explicitly `child` edges only, a cord btree (or any cord tree in - // that respect) does not store `parent` pointers anywhere: multiple trees / - // parents can reference the same shared child edge. The type of these edges - // depends on the height of the node. `Leaf nodes` (height == 0) contain `data - // edges` (external or flat nodes, or sub-strings thereof). All other nodes - // (height > 0) contain pointers to BTREE nodes with a height of `height - 1`. - CordRep* edges_[kMaxCapacity]; - - friend class CordRepBtreeTestPeer; - friend class CordRepBtreeNavigator; -}; - -inline CordRepBtree* CordRep::btree() { - assert(IsBtree()); - return static_cast<CordRepBtree*>(this); -} - -inline const CordRepBtree* CordRep::btree() const { - assert(IsBtree()); - return static_cast<const CordRepBtree*>(this); -} - -inline void CordRepBtree::InitInstance(int height, size_t begin, size_t end) { - tag = BTREE; - storage[0] = static_cast<uint8_t>(height); - storage[1] = static_cast<uint8_t>(begin); - storage[2] = static_cast<uint8_t>(end); -} - -inline CordRep* CordRepBtree::Edge(size_t index) const { - assert(index >= begin()); - assert(index < end()); - return edges_[index]; -} - -inline CordRep* CordRepBtree::Edge(EdgeType edge_type) const { - return edges_[edge_type == kFront ? begin() : back()]; -} - -inline y_absl::Span<CordRep* const> CordRepBtree::Edges() const { - return {edges_ + begin(), size()}; -} - -inline y_absl::Span<CordRep* const> CordRepBtree::Edges(size_t begin, - size_t end) const { - assert(begin <= end); - assert(begin >= this->begin()); - assert(end <= this->end()); - return {edges_ + begin, static_cast<size_t>(end - begin)}; -} - -inline const char* CordRepBtree::EdgeDataPtr(const CordRep* r) { - assert(IsDataEdge(r)); - size_t offset = 0; - if (r->tag == SUBSTRING) { - offset = r->substring()->start; - r = r->substring()->child; - } - return (r->tag >= FLAT ? r->flat()->Data() : r->external()->base) + offset; -} - -inline y_absl::string_view CordRepBtree::EdgeData(const CordRep* r) { - return y_absl::string_view(EdgeDataPtr(r), r->length); -} - -inline y_absl::string_view CordRepBtree::Data(size_t index) const { - assert(height() == 0); - return EdgeData(Edge(index)); -} - -inline bool CordRepBtree::IsDataEdge(const CordRep* rep) { - // The fast path is that `rep` is an EXTERNAL or FLAT node, making the below - // if a single, well predicted branch. We then repeat the FLAT or EXTERNAL - // check in the slow path the SUBSTRING check to optimize for the hot path. - if (rep->tag == EXTERNAL || rep->tag >= FLAT) return true; - if (rep->tag == SUBSTRING) rep = rep->substring()->child; - return rep->tag == EXTERNAL || rep->tag >= FLAT; -} - -inline CordRepBtree* CordRepBtree::New(int height) { - CordRepBtree* tree = new CordRepBtree; - tree->length = 0; - tree->InitInstance(height); - return tree; -} - -inline CordRepBtree* CordRepBtree::New(CordRep* rep) { - CordRepBtree* tree = new CordRepBtree; - int height = rep->IsBtree() ? rep->btree()->height() + 1 : 0; - tree->length = rep->length; - tree->InitInstance(height, /*begin=*/0, /*end=*/1); - tree->edges_[0] = rep; - return tree; -} - -inline CordRepBtree* CordRepBtree::New(CordRepBtree* front, - CordRepBtree* back) { - assert(front->height() == back->height()); - CordRepBtree* tree = new CordRepBtree; - tree->length = front->length + back->length; - tree->InitInstance(front->height() + 1, /*begin=*/0, /*end=*/2); - tree->edges_[0] = front; - tree->edges_[1] = back; - return tree; -} - -inline void CordRepBtree::DestroyTree(CordRepBtree* tree, size_t begin, - size_t end) { - if (tree->height() == 0) { - DestroyLeaf(tree, begin, end); - } else { - DestroyNonLeaf(tree, begin, end); - } -} - -inline void CordRepBtree::Destroy(CordRepBtree* tree) { - DestroyTree(tree, tree->begin(), tree->end()); -} - -inline void CordRepBtree::Unref(y_absl::Span<CordRep* const> edges) { - for (CordRep* edge : edges) { - if (ABSL_PREDICT_FALSE(!edge->refcount.Decrement())) { - CordRep::Destroy(edge); - } - } -} - -inline CordRepBtree* CordRepBtree::CopyRaw() const { - auto* tree = static_cast<CordRepBtree*>(::operator new(sizeof(CordRepBtree))); - memcpy(static_cast<void*>(tree), this, sizeof(CordRepBtree)); - new (&tree->refcount) RefcountAndFlags; - return tree; -} - -inline CordRepBtree* CordRepBtree::Copy() const { - CordRepBtree* tree = CopyRaw(); - for (CordRep* rep : Edges()) CordRep::Ref(rep); - return tree; -} - -inline CordRepBtree* CordRepBtree::CopyToEndFrom(size_t begin, - size_t new_length) const { - assert(begin >= this->begin()); - assert(begin <= this->end()); - CordRepBtree* tree = CopyRaw(); - tree->length = new_length; - tree->set_begin(begin); - for (CordRep* edge : tree->Edges()) CordRep::Ref(edge); - return tree; -} - -inline CordRepBtree* CordRepBtree::CopyBeginTo(size_t end, - size_t new_length) const { - assert(end <= capacity()); - assert(end >= this->begin()); - CordRepBtree* tree = CopyRaw(); - tree->length = new_length; - tree->set_end(end); - for (CordRep* edge : tree->Edges()) CordRep::Ref(edge); - return tree; -} - -inline void CordRepBtree::AlignBegin() { - // The below code itself does not need to be fast as typically we have - // mono-directional append/prepend calls, and `begin` / `end` are typically - // adjusted no more than once. But we want to avoid potential register clobber - // effects, making the compiler emit register save/store/spills, and minimize - // the size of code. - const size_t delta = begin(); - if (ABSL_PREDICT_FALSE(delta != 0)) { - const size_t new_end = end() - delta; - set_begin(0); - set_end(new_end); - // TODO(mvels): we can write this using 2 loads / 2 stores depending on - // total size for the kMaxCapacity = 6 case. I.e., we can branch (switch) on - // size, and then do overlapping load/store of up to 4 pointers (inlined as - // XMM, YMM or ZMM load/store) and up to 2 pointers (XMM / YMM), which is a) - // compact and b) not clobbering any registers. - ABSL_INTERNAL_ASSUME(new_end <= kMaxCapacity); -#ifdef __clang__ -#pragma unroll 1 -#endif - for (size_t i = 0; i < new_end; ++i) { - edges_[i] = edges_[i + delta]; - } - } -} - -inline void CordRepBtree::AlignEnd() { - // See comments in `AlignBegin` for motivation on the hand-rolled for loops. - const size_t delta = capacity() - end(); - if (delta != 0) { - const size_t new_begin = begin() + delta; - const size_t new_end = end() + delta; - set_begin(new_begin); - set_end(new_end); - ABSL_INTERNAL_ASSUME(new_end <= kMaxCapacity); -#ifdef __clang__ -#pragma unroll 1 -#endif - for (size_t i = new_end - 1; i >= new_begin; --i) { - edges_[i] = edges_[i - delta]; - } - } -} - -template <> -inline void CordRepBtree::Add<CordRepBtree::kBack>(CordRep* rep) { - AlignBegin(); - edges_[fetch_add_end(1)] = rep; -} - -template <> -inline void CordRepBtree::Add<CordRepBtree::kBack>( - y_absl::Span<CordRep* const> edges) { - AlignBegin(); - size_t new_end = end(); - for (CordRep* edge : edges) edges_[new_end++] = edge; - set_end(new_end); -} - -template <> -inline void CordRepBtree::Add<CordRepBtree::kFront>(CordRep* rep) { - AlignEnd(); - edges_[sub_fetch_begin(1)] = rep; -} - -template <> -inline void CordRepBtree::Add<CordRepBtree::kFront>( - y_absl::Span<CordRep* const> edges) { - AlignEnd(); - size_t new_begin = begin() - edges.size(); - set_begin(new_begin); - for (CordRep* edge : edges) edges_[new_begin++] = edge; -} - -template <CordRepBtree::EdgeType edge_type> -inline void CordRepBtree::SetEdge(CordRep* edge) { - const int idx = edge_type == kFront ? begin() : back(); - CordRep::Unref(edges_[idx]); - edges_[idx] = edge; -} - -inline CordRepBtree::OpResult CordRepBtree::ToOpResult(bool owned) { - return owned ? OpResult{this, kSelf} : OpResult{Copy(), kCopied}; -} - -inline CordRepBtree::Position CordRepBtree::IndexOf(size_t offset) const { - assert(offset < length); - size_t index = begin(); - while (offset >= edges_[index]->length) offset -= edges_[index++]->length; - return {index, offset}; -} - -inline CordRepBtree::Position CordRepBtree::IndexBefore(size_t offset) const { - assert(offset > 0); - assert(offset <= length); - size_t index = begin(); - while (offset > edges_[index]->length) offset -= edges_[index++]->length; - return {index, offset}; -} - -inline CordRepBtree::Position CordRepBtree::IndexBefore(Position front, - size_t offset) const { - size_t index = front.index; - offset = offset + front.n; - while (offset > edges_[index]->length) offset -= edges_[index++]->length; - return {index, offset}; -} - -inline CordRepBtree::Position CordRepBtree::IndexOfLength(size_t n) const { - assert(n <= length); - size_t index = back(); - size_t strip = length - n; - while (strip >= edges_[index]->length) strip -= edges_[index--]->length; - return {index, edges_[index]->length - strip}; -} - -inline CordRepBtree::Position CordRepBtree::IndexBeyond( - const size_t offset) const { - // We need to find the edge which `starting offset` is beyond (>=)`offset`. - // For this we can't use the `offset -= length` logic of IndexOf. Instead, we - // track the offset of the `current edge` in `off`, which we increase as we - // iterate over the edges until we find the matching edge. - size_t off = 0; - size_t index = begin(); - while (offset > off) off += edges_[index++]->length; - return {index, off - offset}; -} - -inline CordRepBtree* CordRepBtree::Create(CordRep* rep) { - if (IsDataEdge(rep)) return New(rep); - return CreateSlow(rep); -} - -inline Span<char> CordRepBtree::GetAppendBuffer(size_t size) { - assert(refcount.IsMutable()); - CordRepBtree* tree = this; - const int height = this->height(); - CordRepBtree* n1 = tree; - CordRepBtree* n2 = tree; - CordRepBtree* n3 = tree; - switch (height) { - case 3: - tree = tree->Edge(kBack)->btree(); - if (!tree->refcount.IsMutable()) return {}; - n2 = tree; - ABSL_FALLTHROUGH_INTENDED; - case 2: - tree = tree->Edge(kBack)->btree(); - if (!tree->refcount.IsMutable()) return {}; - n1 = tree; - ABSL_FALLTHROUGH_INTENDED; - case 1: - tree = tree->Edge(kBack)->btree(); - if (!tree->refcount.IsMutable()) return {}; - ABSL_FALLTHROUGH_INTENDED; - case 0: - CordRep* edge = tree->Edge(kBack); - if (!edge->refcount.IsMutable()) return {}; - if (edge->tag < FLAT) return {}; - size_t avail = edge->flat()->Capacity() - edge->length; - if (avail == 0) return {}; - size_t delta = (std::min)(size, avail); - Span<char> span = {edge->flat()->Data() + edge->length, delta}; - edge->length += delta; - switch (height) { - case 3: - n3->length += delta; - ABSL_FALLTHROUGH_INTENDED; - case 2: - n2->length += delta; - ABSL_FALLTHROUGH_INTENDED; - case 1: - n1->length += delta; - ABSL_FALLTHROUGH_INTENDED; - case 0: - tree->length += delta; - return span; - } - break; - } - return GetAppendBufferSlow(size); -} - -extern template CordRepBtree* CordRepBtree::AddCordRep<CordRepBtree::kBack>( - CordRepBtree* tree, CordRep* rep); - -extern template CordRepBtree* CordRepBtree::AddCordRep<CordRepBtree::kFront>( - CordRepBtree* tree, CordRep* rep); - -inline CordRepBtree* CordRepBtree::Append(CordRepBtree* tree, CordRep* rep) { - if (ABSL_PREDICT_TRUE(IsDataEdge(rep))) { - return CordRepBtree::AddCordRep<kBack>(tree, rep); - } - return AppendSlow(tree, rep); -} - -inline CordRepBtree* CordRepBtree::Prepend(CordRepBtree* tree, CordRep* rep) { - if (ABSL_PREDICT_TRUE(IsDataEdge(rep))) { - return CordRepBtree::AddCordRep<kFront>(tree, rep); - } - return PrependSlow(tree, rep); -} - -#ifdef NDEBUG - -inline CordRepBtree* CordRepBtree::AssertValid(CordRepBtree* tree, - bool /* shallow */) { - return tree; -} - -inline const CordRepBtree* CordRepBtree::AssertValid(const CordRepBtree* tree, - bool /* shallow */) { - return tree; -} - -#endif - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace y_absl - -#endif // ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_H_ +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_H_ +#define ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_H_ + +#include <cassert> +#include <cstdint> +#include <iosfwd> + +#include "y_absl/base/config.h" +#include "y_absl/base/internal/raw_logging.h" +#include "y_absl/base/optimization.h" +#include "y_absl/strings/internal/cord_internal.h" +#include "y_absl/strings/internal/cord_rep_flat.h" +#include "y_absl/strings/string_view.h" +#include "y_absl/types/span.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +class CordRepBtreeNavigator; + +// CordRepBtree is as the name implies a btree implementation of a Cordrep tree. +// Data is stored at the leaf level only, non leaf nodes contain down pointers +// only. Allowed types of data edges are FLAT, EXTERNAL and SUBSTRINGs of FLAT +// or EXTERNAL nodes. The implementation allows for data to be added to either +// end of the tree only, it does not provide any 'insert' logic. This has the +// benefit that we can expect good fill ratios: all nodes except the outer +// 'legs' will have 100% fill ratios for trees built using Append/Prepend +// methods. Merged trees will typically have a fill ratio well above 50% as in a +// similar fashion, one side of the merged tree will typically have a 100% fill +// ratio, and the 'open' end will average 50%. All operations are O(log(n)) or +// better, and the tree never needs balancing. +// +// All methods accepting a CordRep* or CordRepBtree* adopt a reference on that +// input unless explicitly stated otherwise. All functions returning a CordRep* +// or CordRepBtree* instance transfer a reference back to the caller. +// Simplified, callers both 'donate' and 'consume' a reference count on each +// call, simplifying the API. An example of building a tree: +// +// CordRepBtree* tree = CordRepBtree::Create(MakeFlat("Hello")); +// tree = CordRepBtree::Append(tree, MakeFlat("world")); +// +// In the above example, all inputs are consumed, making each call affecting +// `tree` reference count neutral. The returned `tree` value can be different +// from the input if the input is shared with other threads, or if the tree +// grows in height, but callers typically never have to concern themselves with +// that and trust that all methods DTRT at all times. +class CordRepBtree : public CordRep { + public: + // EdgeType identifies `front` and `back` enum values. + // Various implementations in CordRepBtree such as `Add` and `Edge` are + // generic and templated on operating on either of the boundary edges. + // For more information on the possible edges contained in a CordRepBtree + // instance see the documentation for `edges_`. + enum class EdgeType { kFront, kBack }; + + // Convenience constants into `EdgeType` + static constexpr EdgeType kFront = EdgeType::kFront; + static constexpr EdgeType kBack = EdgeType::kBack; + + // Maximum number of edges: based on experiments and performance data, we can + // pick suitable values resulting in optimum cacheline aligned values. The + // preferred values are based on 64-bit systems where we aim to align this + // class onto 64 bytes, i.e.: 6 = 64 bytes, 14 = 128 bytes, etc. + // TODO(b/192061034): experiment with alternative sizes. + static constexpr size_t kMaxCapacity = 6; + + // Reasonable maximum height of the btree. We can expect a fill ratio of at + // least 50%: trees are always expanded at the front or back. Concatenating + // trees will then typically fold at the top most node, where the lower nodes + // are at least at capacity on one side of joined inputs. At a lower fill + // rate of 4 edges per node, we have capacity for ~16 million leaf nodes. + // We will fail / abort if an application ever exceeds this height, which + // should be extremely rare (near impossible) and be an indication of an + // application error: we do not assume it reasonable for any application to + // operate correctly with such monster trees. + // Another compelling reason for the number `12` is that any contextual stack + // required for navigation or insertion requires 12 words and 12 bytes, which + // fits inside 2 cache lines with some room to spare, and is reasonable as a + // local stack variable compared to Cord's current near 400 bytes stack use. + // The maximum `height` value of a node is then `kMaxDepth - 1` as node height + // values start with a value of 0 for leaf nodes. + static constexpr int kMaxDepth = 12; + static constexpr int kMaxHeight = kMaxDepth - 1; + + // `Action` defines the action for unwinding changes done at the btree's leaf + // level that need to be propagated up to the parent node(s). Each operation + // on a node has an effect / action defined as follows: + // - kSelf + // The operation (add / update, etc) was performed directly on the node as + // the node is private to the current thread (i.e.: not shared directly or + // indirectly through a refcount > 1). Changes can be propagated directly to + // all parent nodes as all parent nodes are also then private to the current + // thread. + // - kCopied + // The operation (add / update, etc) was performed on a copy of the original + // node, as the node is (potentially) directly or indirectly shared with + // other threads. Changes need to be propagated into the parent nodes where + // the old down pointer must be unreffed and replaced with this new copy. + // Such changes to parent nodes may themselves require a copy if the parent + // node is also shared. A kCopied action can propagate all the way to the + // top node where we then must unref the `tree` input provided by the + // caller, and return the new copy. + // - kPopped + // The operation (typically add) could not be satisfied due to insufficient + // capacity in the targeted node, and a new 'leg' was created that needs to + // be added into the parent node. For example, adding a FLAT inside a leaf + // node that is at capacity will create a new leaf node containing that + // FLAT, that needs to be 'popped' up the btree. Such 'pop' actions can + // cascade up the tree if parent nodes are also at capacity. A 'Popped' + // action propagating all the way to the top of the tree will result in + // the tree becoming one level higher than the current tree through a final + // `CordRepBtree::New(tree, popped)` call, resulting in a new top node + // referencing the old tree and the new (fully popped upwards) 'leg'. + enum Action { kSelf, kCopied, kPopped }; + + // Result of an operation on a node. See the `Action` enum for details. + struct OpResult { + CordRepBtree* tree; + Action action; + }; + + // Return value of the CopyPrefix and CopySuffix methods which can + // return a node or data edge at any height inside the tree. + // A height of 0 defines the lowest (leaf) node, a height of -1 identifies + // `edge` as being a plain data node: EXTERNAL / FLAT or SUBSTRING thereof. + struct CopyResult { + CordRep* edge; + int height; + }; + + // Logical position inside a node: + // - index: index of the edge. + // - n: size or offset value depending on context. + struct Position { + size_t index; + size_t n; + }; + + // Creates a btree from the given input. Adopts a ref of `rep`. + // If the input `rep` is itself a btree, i.e., `IsBtree()`, then this + // function immediately returns `rep->btree()`. If the input is a valid data + // edge (see IsDataEdge()), then a new leaf node is returned containing `rep` + // as the sole data edge. Else, the input is assumed to be a (legacy) concat + // tree, and the input is consumed and transformed into a btree(). + static CordRepBtree* Create(CordRep* rep); + + // Destroys the provided tree. Should only be called by cord internal API's, + // typically after a ref_count.Decrement() on the last reference count. + static void Destroy(CordRepBtree* tree); + + // Use CordRep::Unref() as we overload for y_absl::Span<CordRep* const>. + using CordRep::Unref; + + // Unrefs all edges in `edges` which are assumed to be 'likely one'. + static void Unref(y_absl::Span<CordRep* const> edges); + + // Appends / Prepends an existing CordRep instance to this tree. + // The below methods accept three types of input: + // 1) `rep` is a data node (See `IsDataNode` for valid data edges). + // `rep` is appended or prepended to this tree 'as is'. + // 2) `rep` is a BTREE. + // `rep` is merged into `tree` respecting the Append/Prepend order. + // 3) `rep` is some other (legacy) type. + // `rep` is converted in place and added to `tree` + // Requires `tree` and `rep` to be not null. + static CordRepBtree* Append(CordRepBtree* tree, CordRep* rep); + static CordRepBtree* Prepend(CordRepBtree* tree, CordRep* rep); + + // Append/Prepend the data in `data` to this tree. + // The `extra` parameter defines how much extra capacity should be allocated + // for any additional FLAT being allocated. This is an optimization hint from + // the caller. For example, a caller may need to add 2 string_views of data + // "abc" and "defghi" which are not consecutive. The caller can in this case + // invoke `AddData(tree, "abc", 6)`, and any newly added flat is allocated + // where possible with at least 6 bytes of extra capacity beyond `length`. + // This helps avoiding data getting fragmented over multiple flats. + // There is no limit on the size of `data`. If `data` can not be stored inside + // a single flat, then the function will iteratively add flats until all data + // has been consumed and appended or prepended to the tree. + static CordRepBtree* Append(CordRepBtree* tree, string_view data, + size_t extra = 0); + static CordRepBtree* Prepend(CordRepBtree* tree, string_view data, + size_t extra = 0); + + // Returns a new tree, containing `n` bytes of data from this instance + // starting at offset `offset`. Where possible, the returned tree shares + // (re-uses) data edges and nodes with this instance to minimize the + // combined memory footprint of both trees. + // Requires `offset + n <= length`. Returns `nullptr` if `n` is zero. + CordRep* SubTree(size_t offset, size_t n); + + // Removes `n` trailing bytes from `tree`, and returns the resulting tree + // or data edge. Returns `tree` if n is zero, and nullptr if n == length. + // This function is logically identical to: + // result = tree->SubTree(0, tree->length - n); + // Unref(tree); + // return result; + // However, the actual implementation will as much as possible perform 'in + // place' modifications on the tree on all nodes and edges that are mutable. + // For example, in a fully privately owned tree with the last edge being a + // flat of length 12, RemoveSuffix(1) will simply set the length of that data + // edge to 11, and reduce the length of all nodes on the edge path by 1. + static CordRep* RemoveSuffix(CordRepBtree* tree, size_t n); + + // Returns the character at the given offset. + char GetCharacter(size_t offset) const; + + // Returns true if this node holds a single data edge, and if so, sets + // `fragment` to reference the contained data. `fragment` is an optional + // output parameter and allowed to be null. + bool IsFlat(y_absl::string_view* fragment) const; + + // Returns true if the data of `n` bytes starting at offset `offset` + // is contained in a single data edge, and if so, sets fragment to reference + // the contained data. `fragment` is an optional output parameter and allowed + // to be null. + bool IsFlat(size_t offset, size_t n, y_absl::string_view* fragment) const; + + // Returns a span (mutable range of bytes) of up to `size` bytes into the + // last FLAT data edge inside this tree under the following conditions: + // - none of the nodes down into the FLAT node are shared. + // - the last data edge in this tree is a non-shared FLAT. + // - the referenced FLAT has additional capacity available. + // If all these conditions are met, a non-empty span is returned, and the + // length of the flat node and involved tree nodes have been increased by + // `span.length()`. The caller is responsible for immediately assigning values + // to all uninitialized data reference by the returned span. + // Requires `this->refcount.IsMutable()`: this function forces the + // caller to do this fast path check on the top level node, as this is the + // most commonly shared node of a cord tree. + Span<char> GetAppendBuffer(size_t size); + + // Returns the `height` of the tree. The height of a tree is limited to + // kMaxHeight. `height` is implemented as an `int` as in some places we + // use negative (-1) values for 'data edges'. + int height() const { return static_cast<int>(storage[0]); } + + // Properties: begin, back, end, front/back boundary indexes. + size_t begin() const { return static_cast<size_t>(storage[1]); } + size_t back() const { return static_cast<size_t>(storage[2]) - 1; } + size_t end() const { return static_cast<size_t>(storage[2]); } + size_t index(EdgeType edge) const { + return edge == kFront ? begin() : back(); + } + + // Properties: size and capacity. + // `capacity` contains the current capacity of this instance, where + // `kMaxCapacity` contains the maximum capacity of a btree node. + // For now, `capacity` and `kMaxCapacity` return the same value, but this may + // change in the future if we see benefit in dynamically sizing 'small' nodes + // to 'large' nodes for large data trees. + size_t size() const { return end() - begin(); } + size_t capacity() const { return kMaxCapacity; } + + // Edge access + inline CordRep* Edge(size_t index) const; + inline CordRep* Edge(EdgeType edge_type) const; + inline y_absl::Span<CordRep* const> Edges() const; + inline y_absl::Span<CordRep* const> Edges(size_t begin, size_t end) const; + + // Returns reference to the data edge at `index`. + // Requires this instance to be a leaf node, and `index` to be valid index. + inline y_absl::string_view Data(size_t index) const; + + static const char* EdgeDataPtr(const CordRep* r); + static y_absl::string_view EdgeData(const CordRep* r); + + // Returns true if the provided rep is a FLAT, EXTERNAL or a SUBSTRING node + // holding a FLAT or EXTERNAL child rep. + static bool IsDataEdge(const CordRep* rep); + + // Diagnostics: returns true if `tree` is valid and internally consistent. + // If `shallow` is false, then the provided top level node and all child nodes + // below it are recursively checked. If `shallow` is true, only the provided + // node in `tree` and the cumulative length, type and height of the direct + // child nodes of `tree` are checked. The value of `shallow` is ignored if the + // internal `cord_btree_exhaustive_validation` diagnostics variable is true, + // in which case the performed validations works as if `shallow` were false. + // This function is intended for debugging and testing purposes only. + static bool IsValid(const CordRepBtree* tree, bool shallow = false); + + // Diagnostics: asserts that the provided tree is valid. + // `AssertValid()` performs a shallow validation by default. `shallow` can be + // set to false in which case an exhaustive validation is performed. This + // function is implemented in terms of calling `IsValid()` and asserting the + // return value to be true. See `IsValid()` for more information. + // This function is intended for debugging and testing purposes only. + static CordRepBtree* AssertValid(CordRepBtree* tree, bool shallow = true); + static const CordRepBtree* AssertValid(const CordRepBtree* tree, + bool shallow = true); + + // Diagnostics: dump the contents of this tree to `stream`. + // This function is intended for debugging and testing purposes only. + static void Dump(const CordRep* rep, std::ostream& stream); + static void Dump(const CordRep* rep, y_absl::string_view label, + std::ostream& stream); + static void Dump(const CordRep* rep, y_absl::string_view label, + bool include_contents, std::ostream& stream); + + // Adds the edge `edge` to this node if possible. `owned` indicates if the + // current node is potentially shared or not with other threads. Returns: + // - {kSelf, <this>} + // The edge was directly added to this node. + // - {kCopied, <node>} + // The edge was added to a copy of this node. + // - {kPopped, New(edge, height())} + // A new leg with the edge was created as this node has no extra capacity. + template <EdgeType edge_type> + inline OpResult AddEdge(bool owned, CordRep* edge, size_t delta); + + // Replaces the front or back edge with the provided new edge. Returns: + // - {kSelf, <this>} + // The edge was directly set in this node. The old edge is unreffed. + // - {kCopied, <node>} + // A copy of this node was created with the new edge value. + // In both cases, the function adopts a reference on `edge`. + template <EdgeType edge_type> + OpResult SetEdge(bool owned, CordRep* edge, size_t delta); + + // Creates a new empty node at the specified height. + static CordRepBtree* New(int height = 0); + + // Creates a new node containing `rep`, with the height being computed + // automatically based on the type of `rep`. + static CordRepBtree* New(CordRep* rep); + + // Creates a new node containing both `front` and `back` at height + // `front.height() + 1`. Requires `back.height() == front.height()`. + static CordRepBtree* New(CordRepBtree* front, CordRepBtree* back); + + // Creates a fully balanced tree from the provided tree by rebuilding a new + // tree from all data edges in the input. This function is automatically + // invoked internally when the tree exceeds the maximum height. + static CordRepBtree* Rebuild(CordRepBtree* tree); + + private: + CordRepBtree() = default; + ~CordRepBtree() = default; + + // Initializes the main properties `tag`, `begin`, `end`, `height`. + inline void InitInstance(int height, size_t begin = 0, size_t end = 0); + + // Direct property access begin / end + void set_begin(size_t begin) { storage[1] = static_cast<uint8_t>(begin); } + void set_end(size_t end) { storage[2] = static_cast<uint8_t>(end); } + + // Decreases the value of `begin` by `n`, and returns the new value. Notice + // how this returns the new value unlike atomic::fetch_add which returns the + // old value. This is because this is used to prepend edges at 'begin - 1'. + size_t sub_fetch_begin(size_t n) { + storage[1] -= static_cast<uint8_t>(n); + return storage[1]; + } + + // Increases the value of `end` by `n`, and returns the previous value. This + // function is typically used to append edges at 'end'. + size_t fetch_add_end(size_t n) { + const uint8_t current = storage[2]; + storage[2] = static_cast<uint8_t>(current + n); + return current; + } + + // Returns the index of the last edge starting on, or before `offset`, with + // `n` containing the relative offset of `offset` inside that edge. + // Requires `offset` < length. + Position IndexOf(size_t offset) const; + + // Returns the index of the last edge starting before `offset`, with `n` + // containing the relative offset of `offset` inside that edge. + // This function is useful to find the edges for some span of bytes ending at + // `offset` (i.e., `n` bytes). For example: + // + // Position pos = IndexBefore(n) + // edges = Edges(begin(), pos.index) // All full edges (may be empty) + // last = Sub(Edge(pos.index), 0, pos.n) // Last partial edge (may be empty) + // + // Requires 0 < `offset` <= length. + Position IndexBefore(size_t offset) const; + + // Returns the index of the edge ending at (or on) length `length`, and the + // number of bytes inside that edge up to `length`. For example, if we have a + // Node with 2 edges, one of 10 and one of 20 long, then IndexOfLength(27) + // will return {1, 17}, and IndexOfLength(10) will return {0, 10}. + Position IndexOfLength(size_t n) const; + + // Identical to the above function except starting from the position `front`. + // This function is equivalent to `IndexBefore(front.n + offset)`, with + // the difference that this function is optimized to start at `front.index`. + Position IndexBefore(Position front, size_t offset) const; + + // Returns the index of the edge directly beyond the edge containing offset + // `offset`, with `n` containing the distance of that edge from `offset`. + // This function is useful for iteratively finding suffix nodes and remaining + // partial bytes in left-most suffix nodes as for example in CopySuffix. + // Requires `offset` < length. + Position IndexBeyond(size_t offset) const; + + // Destruction + static void DestroyLeaf(CordRepBtree* tree, size_t begin, size_t end); + static void DestroyNonLeaf(CordRepBtree* tree, size_t begin, size_t end); + static void DestroyTree(CordRepBtree* tree, size_t begin, size_t end); + static void Delete(CordRepBtree* tree) { delete tree; } + + // Creates a new leaf node containing as much data as possible from `data`. + // The data is added either forwards or reversed depending on `edge_type`. + // Callers must check the length of the returned node to determine if all data + // was copied or not. + // See the `Append/Prepend` function for the meaning and purpose of `extra`. + template <EdgeType edge_type> + static CordRepBtree* NewLeaf(y_absl::string_view data, size_t extra); + + // Creates a raw copy of this Btree node, copying all properties, but + // without adding any references to existing edges. + CordRepBtree* CopyRaw() const; + + // Creates a full copy of this Btree node, adding a reference on all edges. + CordRepBtree* Copy() const; + + // Creates a partial copy of this Btree node, copying all edges up to `end`, + // adding a reference on each copied edge, and sets the length of the newly + // created copy to `new_length`. + CordRepBtree* CopyBeginTo(size_t end, size_t new_length) const; + + // Returns a tree containing the edges [tree->begin(), end) and length + // of `new_length`. This method consumes a reference on the provided + // tree, and logically performs the following operation: + // result = tree->CopyBeginTo(end, new_length); + // CordRep::Unref(tree); + // return result; + static CordRepBtree* ConsumeBeginTo(CordRepBtree* tree, size_t end, + size_t new_length); + + // Creates a partial copy of this Btree node, copying all edges starting at + // `begin`, adding a reference on each copied edge, and sets the length of + // the newly created copy to `new_length`. + CordRepBtree* CopyToEndFrom(size_t begin, size_t new_length) const; + + // Extracts and returns the front edge from the provided tree. + // This method consumes a reference on the provided tree, and logically + // performs the following operation: + // edge = CordRep::Ref(tree->Edge(kFront)); + // CordRep::Unref(tree); + // return edge; + static CordRep* ExtractFront(CordRepBtree* tree); + + // Returns a tree containing the result of appending `right` to `left`. + static CordRepBtree* MergeTrees(CordRepBtree* left, CordRepBtree* right); + + // Fallback functions for `Create()`, `Append()` and `Prepend()` which + // deal with legacy / non conforming input, i.e.: CONCAT trees. + static CordRepBtree* CreateSlow(CordRep* rep); + static CordRepBtree* AppendSlow(CordRepBtree*, CordRep* rep); + static CordRepBtree* PrependSlow(CordRepBtree*, CordRep* rep); + + // Recursively rebuilds `tree` into `stack`. If 'consume` is set to true, the + // function will consume a reference on `tree`. `stack` is a null terminated + // array containing the new tree's state, with the current leaf node at + // stack[0], and parent nodes above that, or null for 'top of tree'. + static void Rebuild(CordRepBtree** stack, CordRepBtree* tree, bool consume); + + // Aligns existing edges to start at index 0, to allow for a new edge to be + // added to the back of the current edges. + inline void AlignBegin(); + + // Aligns existing edges to end at `capacity`, to allow for a new edge to be + // added in front of the current edges. + inline void AlignEnd(); + + // Adds the provided edge to this node. + // Requires this node to have capacity for the edge. Realigns / moves + // existing edges as needed to prepend or append the new edge. + template <EdgeType edge_type> + inline void Add(CordRep* rep); + + // Adds the provided edges to this node. + // Requires this node to have capacity for the edges. Realigns / moves + // existing edges as needed to prepend or append the new edges. + template <EdgeType edge_type> + inline void Add(y_absl::Span<CordRep* const>); + + // Adds data from `data` to this node until either all data has been consumed, + // or there is no more capacity for additional flat nodes inside this node. + // Requires the current node to be a leaf node, data to be non empty, and the + // current node to have capacity for at least one more data edge. + // Returns any remaining data from `data` that was not added, which is + // depending on the edge type (front / back) either the remaining prefix of + // suffix of the input. + // See the `Append/Prepend` function for the meaning and purpose of `extra`. + template <EdgeType edge_type> + y_absl::string_view AddData(y_absl::string_view data, size_t extra); + + // Replace the front or back edge with the provided value. + // Adopts a reference on `edge` and unrefs the old edge. + template <EdgeType edge_type> + inline void SetEdge(CordRep* edge); + + // Returns a partial copy of the current tree containing the first `n` bytes + // of data. `CopyResult` contains both the resulting edge and its height. The + // resulting tree may be less high than the current tree, or even be a single + // matching data edge if `allow_folding` is set to true. + // For example, if `n == 1`, then the result will be the single data edge, and + // height will be set to -1 (one below the owning leaf node). If n == 0, this + // function returns null. Requires `n <= length` + CopyResult CopyPrefix(size_t n, bool allow_folding = true); + + // Returns a partial copy of the current tree containing all data starting + // after `offset`. `CopyResult` contains both the resulting edge and its + // height. The resulting tree may be less high than the current tree, or even + // be a single matching data edge. For example, if `n == length - 1`, then the + // result will be a single data edge, and height will be set to -1 (one below + // the owning leaf node). + // Requires `offset < length` + CopyResult CopySuffix(size_t offset); + + // Returns a OpResult value of {this, kSelf} or {Copy(), kCopied} + // depending on the value of `owned`. + inline OpResult ToOpResult(bool owned); + + // Adds `rep` to the specified tree, returning the modified tree. + template <EdgeType edge_type> + static CordRepBtree* AddCordRep(CordRepBtree* tree, CordRep* rep); + + // Adds `data` to the specified tree, returning the modified tree. + // See the `Append/Prepend` function for the meaning and purpose of `extra`. + template <EdgeType edge_type> + static CordRepBtree* AddData(CordRepBtree* tree, y_absl::string_view data, + size_t extra = 0); + + // Merges `src` into `dst` with `src` being added either before (kFront) or + // after (kBack) `dst`. Requires the height of `dst` to be greater than or + // equal to the height of `src`. + template <EdgeType edge_type> + static CordRepBtree* Merge(CordRepBtree* dst, CordRepBtree* src); + + // Fallback version of GetAppendBuffer for large trees: GetAppendBuffer() + // implements an inlined version for trees of limited height (3 levels), + // GetAppendBufferSlow implements the logic for large trees. + Span<char> GetAppendBufferSlow(size_t size); + + // `edges_` contains all edges starting from this instance. + // These are explicitly `child` edges only, a cord btree (or any cord tree in + // that respect) does not store `parent` pointers anywhere: multiple trees / + // parents can reference the same shared child edge. The type of these edges + // depends on the height of the node. `Leaf nodes` (height == 0) contain `data + // edges` (external or flat nodes, or sub-strings thereof). All other nodes + // (height > 0) contain pointers to BTREE nodes with a height of `height - 1`. + CordRep* edges_[kMaxCapacity]; + + friend class CordRepBtreeTestPeer; + friend class CordRepBtreeNavigator; +}; + +inline CordRepBtree* CordRep::btree() { + assert(IsBtree()); + return static_cast<CordRepBtree*>(this); +} + +inline const CordRepBtree* CordRep::btree() const { + assert(IsBtree()); + return static_cast<const CordRepBtree*>(this); +} + +inline void CordRepBtree::InitInstance(int height, size_t begin, size_t end) { + tag = BTREE; + storage[0] = static_cast<uint8_t>(height); + storage[1] = static_cast<uint8_t>(begin); + storage[2] = static_cast<uint8_t>(end); +} + +inline CordRep* CordRepBtree::Edge(size_t index) const { + assert(index >= begin()); + assert(index < end()); + return edges_[index]; +} + +inline CordRep* CordRepBtree::Edge(EdgeType edge_type) const { + return edges_[edge_type == kFront ? begin() : back()]; +} + +inline y_absl::Span<CordRep* const> CordRepBtree::Edges() const { + return {edges_ + begin(), size()}; +} + +inline y_absl::Span<CordRep* const> CordRepBtree::Edges(size_t begin, + size_t end) const { + assert(begin <= end); + assert(begin >= this->begin()); + assert(end <= this->end()); + return {edges_ + begin, static_cast<size_t>(end - begin)}; +} + +inline const char* CordRepBtree::EdgeDataPtr(const CordRep* r) { + assert(IsDataEdge(r)); + size_t offset = 0; + if (r->tag == SUBSTRING) { + offset = r->substring()->start; + r = r->substring()->child; + } + return (r->tag >= FLAT ? r->flat()->Data() : r->external()->base) + offset; +} + +inline y_absl::string_view CordRepBtree::EdgeData(const CordRep* r) { + return y_absl::string_view(EdgeDataPtr(r), r->length); +} + +inline y_absl::string_view CordRepBtree::Data(size_t index) const { + assert(height() == 0); + return EdgeData(Edge(index)); +} + +inline bool CordRepBtree::IsDataEdge(const CordRep* rep) { + // The fast path is that `rep` is an EXTERNAL or FLAT node, making the below + // if a single, well predicted branch. We then repeat the FLAT or EXTERNAL + // check in the slow path the SUBSTRING check to optimize for the hot path. + if (rep->tag == EXTERNAL || rep->tag >= FLAT) return true; + if (rep->tag == SUBSTRING) rep = rep->substring()->child; + return rep->tag == EXTERNAL || rep->tag >= FLAT; +} + +inline CordRepBtree* CordRepBtree::New(int height) { + CordRepBtree* tree = new CordRepBtree; + tree->length = 0; + tree->InitInstance(height); + return tree; +} + +inline CordRepBtree* CordRepBtree::New(CordRep* rep) { + CordRepBtree* tree = new CordRepBtree; + int height = rep->IsBtree() ? rep->btree()->height() + 1 : 0; + tree->length = rep->length; + tree->InitInstance(height, /*begin=*/0, /*end=*/1); + tree->edges_[0] = rep; + return tree; +} + +inline CordRepBtree* CordRepBtree::New(CordRepBtree* front, + CordRepBtree* back) { + assert(front->height() == back->height()); + CordRepBtree* tree = new CordRepBtree; + tree->length = front->length + back->length; + tree->InitInstance(front->height() + 1, /*begin=*/0, /*end=*/2); + tree->edges_[0] = front; + tree->edges_[1] = back; + return tree; +} + +inline void CordRepBtree::DestroyTree(CordRepBtree* tree, size_t begin, + size_t end) { + if (tree->height() == 0) { + DestroyLeaf(tree, begin, end); + } else { + DestroyNonLeaf(tree, begin, end); + } +} + +inline void CordRepBtree::Destroy(CordRepBtree* tree) { + DestroyTree(tree, tree->begin(), tree->end()); +} + +inline void CordRepBtree::Unref(y_absl::Span<CordRep* const> edges) { + for (CordRep* edge : edges) { + if (ABSL_PREDICT_FALSE(!edge->refcount.Decrement())) { + CordRep::Destroy(edge); + } + } +} + +inline CordRepBtree* CordRepBtree::CopyRaw() const { + auto* tree = static_cast<CordRepBtree*>(::operator new(sizeof(CordRepBtree))); + memcpy(static_cast<void*>(tree), this, sizeof(CordRepBtree)); + new (&tree->refcount) RefcountAndFlags; + return tree; +} + +inline CordRepBtree* CordRepBtree::Copy() const { + CordRepBtree* tree = CopyRaw(); + for (CordRep* rep : Edges()) CordRep::Ref(rep); + return tree; +} + +inline CordRepBtree* CordRepBtree::CopyToEndFrom(size_t begin, + size_t new_length) const { + assert(begin >= this->begin()); + assert(begin <= this->end()); + CordRepBtree* tree = CopyRaw(); + tree->length = new_length; + tree->set_begin(begin); + for (CordRep* edge : tree->Edges()) CordRep::Ref(edge); + return tree; +} + +inline CordRepBtree* CordRepBtree::CopyBeginTo(size_t end, + size_t new_length) const { + assert(end <= capacity()); + assert(end >= this->begin()); + CordRepBtree* tree = CopyRaw(); + tree->length = new_length; + tree->set_end(end); + for (CordRep* edge : tree->Edges()) CordRep::Ref(edge); + return tree; +} + +inline void CordRepBtree::AlignBegin() { + // The below code itself does not need to be fast as typically we have + // mono-directional append/prepend calls, and `begin` / `end` are typically + // adjusted no more than once. But we want to avoid potential register clobber + // effects, making the compiler emit register save/store/spills, and minimize + // the size of code. + const size_t delta = begin(); + if (ABSL_PREDICT_FALSE(delta != 0)) { + const size_t new_end = end() - delta; + set_begin(0); + set_end(new_end); + // TODO(mvels): we can write this using 2 loads / 2 stores depending on + // total size for the kMaxCapacity = 6 case. I.e., we can branch (switch) on + // size, and then do overlapping load/store of up to 4 pointers (inlined as + // XMM, YMM or ZMM load/store) and up to 2 pointers (XMM / YMM), which is a) + // compact and b) not clobbering any registers. + ABSL_INTERNAL_ASSUME(new_end <= kMaxCapacity); +#ifdef __clang__ +#pragma unroll 1 +#endif + for (size_t i = 0; i < new_end; ++i) { + edges_[i] = edges_[i + delta]; + } + } +} + +inline void CordRepBtree::AlignEnd() { + // See comments in `AlignBegin` for motivation on the hand-rolled for loops. + const size_t delta = capacity() - end(); + if (delta != 0) { + const size_t new_begin = begin() + delta; + const size_t new_end = end() + delta; + set_begin(new_begin); + set_end(new_end); + ABSL_INTERNAL_ASSUME(new_end <= kMaxCapacity); +#ifdef __clang__ +#pragma unroll 1 +#endif + for (size_t i = new_end - 1; i >= new_begin; --i) { + edges_[i] = edges_[i - delta]; + } + } +} + +template <> +inline void CordRepBtree::Add<CordRepBtree::kBack>(CordRep* rep) { + AlignBegin(); + edges_[fetch_add_end(1)] = rep; +} + +template <> +inline void CordRepBtree::Add<CordRepBtree::kBack>( + y_absl::Span<CordRep* const> edges) { + AlignBegin(); + size_t new_end = end(); + for (CordRep* edge : edges) edges_[new_end++] = edge; + set_end(new_end); +} + +template <> +inline void CordRepBtree::Add<CordRepBtree::kFront>(CordRep* rep) { + AlignEnd(); + edges_[sub_fetch_begin(1)] = rep; +} + +template <> +inline void CordRepBtree::Add<CordRepBtree::kFront>( + y_absl::Span<CordRep* const> edges) { + AlignEnd(); + size_t new_begin = begin() - edges.size(); + set_begin(new_begin); + for (CordRep* edge : edges) edges_[new_begin++] = edge; +} + +template <CordRepBtree::EdgeType edge_type> +inline void CordRepBtree::SetEdge(CordRep* edge) { + const int idx = edge_type == kFront ? begin() : back(); + CordRep::Unref(edges_[idx]); + edges_[idx] = edge; +} + +inline CordRepBtree::OpResult CordRepBtree::ToOpResult(bool owned) { + return owned ? OpResult{this, kSelf} : OpResult{Copy(), kCopied}; +} + +inline CordRepBtree::Position CordRepBtree::IndexOf(size_t offset) const { + assert(offset < length); + size_t index = begin(); + while (offset >= edges_[index]->length) offset -= edges_[index++]->length; + return {index, offset}; +} + +inline CordRepBtree::Position CordRepBtree::IndexBefore(size_t offset) const { + assert(offset > 0); + assert(offset <= length); + size_t index = begin(); + while (offset > edges_[index]->length) offset -= edges_[index++]->length; + return {index, offset}; +} + +inline CordRepBtree::Position CordRepBtree::IndexBefore(Position front, + size_t offset) const { + size_t index = front.index; + offset = offset + front.n; + while (offset > edges_[index]->length) offset -= edges_[index++]->length; + return {index, offset}; +} + +inline CordRepBtree::Position CordRepBtree::IndexOfLength(size_t n) const { + assert(n <= length); + size_t index = back(); + size_t strip = length - n; + while (strip >= edges_[index]->length) strip -= edges_[index--]->length; + return {index, edges_[index]->length - strip}; +} + +inline CordRepBtree::Position CordRepBtree::IndexBeyond( + const size_t offset) const { + // We need to find the edge which `starting offset` is beyond (>=)`offset`. + // For this we can't use the `offset -= length` logic of IndexOf. Instead, we + // track the offset of the `current edge` in `off`, which we increase as we + // iterate over the edges until we find the matching edge. + size_t off = 0; + size_t index = begin(); + while (offset > off) off += edges_[index++]->length; + return {index, off - offset}; +} + +inline CordRepBtree* CordRepBtree::Create(CordRep* rep) { + if (IsDataEdge(rep)) return New(rep); + return CreateSlow(rep); +} + +inline Span<char> CordRepBtree::GetAppendBuffer(size_t size) { + assert(refcount.IsMutable()); + CordRepBtree* tree = this; + const int height = this->height(); + CordRepBtree* n1 = tree; + CordRepBtree* n2 = tree; + CordRepBtree* n3 = tree; + switch (height) { + case 3: + tree = tree->Edge(kBack)->btree(); + if (!tree->refcount.IsMutable()) return {}; + n2 = tree; + ABSL_FALLTHROUGH_INTENDED; + case 2: + tree = tree->Edge(kBack)->btree(); + if (!tree->refcount.IsMutable()) return {}; + n1 = tree; + ABSL_FALLTHROUGH_INTENDED; + case 1: + tree = tree->Edge(kBack)->btree(); + if (!tree->refcount.IsMutable()) return {}; + ABSL_FALLTHROUGH_INTENDED; + case 0: + CordRep* edge = tree->Edge(kBack); + if (!edge->refcount.IsMutable()) return {}; + if (edge->tag < FLAT) return {}; + size_t avail = edge->flat()->Capacity() - edge->length; + if (avail == 0) return {}; + size_t delta = (std::min)(size, avail); + Span<char> span = {edge->flat()->Data() + edge->length, delta}; + edge->length += delta; + switch (height) { + case 3: + n3->length += delta; + ABSL_FALLTHROUGH_INTENDED; + case 2: + n2->length += delta; + ABSL_FALLTHROUGH_INTENDED; + case 1: + n1->length += delta; + ABSL_FALLTHROUGH_INTENDED; + case 0: + tree->length += delta; + return span; + } + break; + } + return GetAppendBufferSlow(size); +} + +extern template CordRepBtree* CordRepBtree::AddCordRep<CordRepBtree::kBack>( + CordRepBtree* tree, CordRep* rep); + +extern template CordRepBtree* CordRepBtree::AddCordRep<CordRepBtree::kFront>( + CordRepBtree* tree, CordRep* rep); + +inline CordRepBtree* CordRepBtree::Append(CordRepBtree* tree, CordRep* rep) { + if (ABSL_PREDICT_TRUE(IsDataEdge(rep))) { + return CordRepBtree::AddCordRep<kBack>(tree, rep); + } + return AppendSlow(tree, rep); +} + +inline CordRepBtree* CordRepBtree::Prepend(CordRepBtree* tree, CordRep* rep) { + if (ABSL_PREDICT_TRUE(IsDataEdge(rep))) { + return CordRepBtree::AddCordRep<kFront>(tree, rep); + } + return PrependSlow(tree, rep); +} + +#ifdef NDEBUG + +inline CordRepBtree* CordRepBtree::AssertValid(CordRepBtree* tree, + bool /* shallow */) { + return tree; +} + +inline const CordRepBtree* CordRepBtree::AssertValid(const CordRepBtree* tree, + bool /* shallow */) { + return tree; +} + +#endif + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace y_absl + +#endif // ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree_navigator.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree_navigator.cc index 6dae7bcd3e..9ed428681a 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree_navigator.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree_navigator.cc @@ -1,185 +1,185 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "y_absl/strings/internal/cord_rep_btree_navigator.h" - -#include <cassert> - -#include "y_absl/strings/internal/cord_internal.h" -#include "y_absl/strings/internal/cord_rep_btree.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -using ReadResult = CordRepBtreeNavigator::ReadResult; - -namespace { - -// Returns a `CordRepSubstring` from `rep` starting at `offset` of size `n`. -// If `rep` is already a `CordRepSubstring` instance, an adjusted instance is -// created based on the old offset and new offset. -// Adopts a reference on `rep`. Rep must be a valid data edge. Returns -// nullptr if `n == 0`, `rep` if `n == rep->length`. -// Requires `offset < rep->length` and `offset + n <= rep->length`. -// TODO(192061034): move to utility library in internal and optimize for small -// substrings of larger reps. -inline CordRep* Substring(CordRep* rep, size_t offset, size_t n) { - assert(n <= rep->length); - assert(offset < rep->length); - assert(offset <= rep->length - n); - assert(CordRepBtree::IsDataEdge(rep)); - - if (n == 0) return nullptr; - if (n == rep->length) return CordRep::Ref(rep); - - if (rep->tag == SUBSTRING) { - offset += rep->substring()->start; - rep = rep->substring()->child; - } - - CordRepSubstring* substring = new CordRepSubstring(); - substring->length = n; - substring->tag = SUBSTRING; - substring->start = offset; - substring->child = CordRep::Ref(rep); - return substring; -} - -inline CordRep* Substring(CordRep* rep, size_t offset) { - return Substring(rep, offset, rep->length - offset); -} - -} // namespace - -CordRepBtreeNavigator::Position CordRepBtreeNavigator::Skip(size_t n) { - int height = 0; - size_t index = index_[0]; - CordRepBtree* node = node_[0]; - CordRep* edge = node->Edge(index); - - // Overall logic: Find an edge of at least the length we need to skip. - // We consume all edges which are smaller (i.e., must be 100% skipped). - // If we exhausted all edges on the current level, we move one level - // up the tree, and repeat until we either find the edge, or until we hit - // the top of the tree meaning the skip exceeds tree->length. - while (n >= edge->length) { - n -= edge->length; - while (++index == node->end()) { - if (++height > height_) return {nullptr, n}; - node = node_[height]; - index = index_[height]; - } - edge = node->Edge(index); - } - - // If we moved up the tree, descend down to the leaf level, consuming all - // edges that must be skipped. - while (height > 0) { - node = edge->btree(); - index_[height] = index; - node_[--height] = node; - index = node->begin(); - edge = node->Edge(index); - while (n >= edge->length) { - n -= edge->length; - ++index; - assert(index != node->end()); - edge = node->Edge(index); - } - } - index_[0] = index; - return {edge, n}; -} - -ReadResult CordRepBtreeNavigator::Read(size_t edge_offset, size_t n) { - int height = 0; - size_t length = edge_offset + n; - size_t index = index_[0]; - CordRepBtree* node = node_[0]; - CordRep* edge = node->Edge(index); - assert(edge_offset < edge->length); - - if (length < edge->length) { - return {Substring(edge, edge_offset, n), length}; - } - - // Similar to 'Skip', we consume all edges that are inside the 'length' of - // data that needs to be read. If we exhaust the current level, we move one - // level up the tree and repeat until we hit the final edge that must be - // (partially) read. We consume all edges into `subtree`. - CordRepBtree* subtree = CordRepBtree::New(Substring(edge, edge_offset)); - size_t subtree_end = 1; - do { - length -= edge->length; - while (++index == node->end()) { - index_[height] = index; - if (++height > height_) { - subtree->set_end(subtree_end); - if (length == 0) return {subtree, 0}; - CordRep::Unref(subtree); - return {nullptr, length}; - } - if (length != 0) { - subtree->set_end(subtree_end); - subtree = CordRepBtree::New(subtree); - subtree_end = 1; - } - node = node_[height]; - index = index_[height]; - } - edge = node->Edge(index); - if (length >= edge->length) { - subtree->length += edge->length; - subtree->edges_[subtree_end++] = CordRep::Ref(edge); - } - } while (length >= edge->length); - CordRepBtree* tree = subtree; - subtree->length += length; - - // If we moved up the tree, descend down to the leaf level, consuming all - // edges that must be read, adding 'down' nodes to `subtree`. - while (height > 0) { - node = edge->btree(); - index_[height] = index; - node_[--height] = node; - index = node->begin(); - edge = node->Edge(index); - - if (length != 0) { - CordRepBtree* right = CordRepBtree::New(height); - right->length = length; - subtree->edges_[subtree_end++] = right; - subtree->set_end(subtree_end); - subtree = right; - subtree_end = 0; - while (length >= edge->length) { - subtree->edges_[subtree_end++] = CordRep::Ref(edge); - length -= edge->length; - edge = node->Edge(++index); - } - } - } - // Add any (partial) edge still remaining at the leaf level. - if (length != 0) { - subtree->edges_[subtree_end++] = Substring(edge, 0, length); - } - subtree->set_end(subtree_end); - index_[0] = index; - return {tree, length}; -} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace y_absl +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "y_absl/strings/internal/cord_rep_btree_navigator.h" + +#include <cassert> + +#include "y_absl/strings/internal/cord_internal.h" +#include "y_absl/strings/internal/cord_rep_btree.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +using ReadResult = CordRepBtreeNavigator::ReadResult; + +namespace { + +// Returns a `CordRepSubstring` from `rep` starting at `offset` of size `n`. +// If `rep` is already a `CordRepSubstring` instance, an adjusted instance is +// created based on the old offset and new offset. +// Adopts a reference on `rep`. Rep must be a valid data edge. Returns +// nullptr if `n == 0`, `rep` if `n == rep->length`. +// Requires `offset < rep->length` and `offset + n <= rep->length`. +// TODO(192061034): move to utility library in internal and optimize for small +// substrings of larger reps. +inline CordRep* Substring(CordRep* rep, size_t offset, size_t n) { + assert(n <= rep->length); + assert(offset < rep->length); + assert(offset <= rep->length - n); + assert(CordRepBtree::IsDataEdge(rep)); + + if (n == 0) return nullptr; + if (n == rep->length) return CordRep::Ref(rep); + + if (rep->tag == SUBSTRING) { + offset += rep->substring()->start; + rep = rep->substring()->child; + } + + CordRepSubstring* substring = new CordRepSubstring(); + substring->length = n; + substring->tag = SUBSTRING; + substring->start = offset; + substring->child = CordRep::Ref(rep); + return substring; +} + +inline CordRep* Substring(CordRep* rep, size_t offset) { + return Substring(rep, offset, rep->length - offset); +} + +} // namespace + +CordRepBtreeNavigator::Position CordRepBtreeNavigator::Skip(size_t n) { + int height = 0; + size_t index = index_[0]; + CordRepBtree* node = node_[0]; + CordRep* edge = node->Edge(index); + + // Overall logic: Find an edge of at least the length we need to skip. + // We consume all edges which are smaller (i.e., must be 100% skipped). + // If we exhausted all edges on the current level, we move one level + // up the tree, and repeat until we either find the edge, or until we hit + // the top of the tree meaning the skip exceeds tree->length. + while (n >= edge->length) { + n -= edge->length; + while (++index == node->end()) { + if (++height > height_) return {nullptr, n}; + node = node_[height]; + index = index_[height]; + } + edge = node->Edge(index); + } + + // If we moved up the tree, descend down to the leaf level, consuming all + // edges that must be skipped. + while (height > 0) { + node = edge->btree(); + index_[height] = index; + node_[--height] = node; + index = node->begin(); + edge = node->Edge(index); + while (n >= edge->length) { + n -= edge->length; + ++index; + assert(index != node->end()); + edge = node->Edge(index); + } + } + index_[0] = index; + return {edge, n}; +} + +ReadResult CordRepBtreeNavigator::Read(size_t edge_offset, size_t n) { + int height = 0; + size_t length = edge_offset + n; + size_t index = index_[0]; + CordRepBtree* node = node_[0]; + CordRep* edge = node->Edge(index); + assert(edge_offset < edge->length); + + if (length < edge->length) { + return {Substring(edge, edge_offset, n), length}; + } + + // Similar to 'Skip', we consume all edges that are inside the 'length' of + // data that needs to be read. If we exhaust the current level, we move one + // level up the tree and repeat until we hit the final edge that must be + // (partially) read. We consume all edges into `subtree`. + CordRepBtree* subtree = CordRepBtree::New(Substring(edge, edge_offset)); + size_t subtree_end = 1; + do { + length -= edge->length; + while (++index == node->end()) { + index_[height] = index; + if (++height > height_) { + subtree->set_end(subtree_end); + if (length == 0) return {subtree, 0}; + CordRep::Unref(subtree); + return {nullptr, length}; + } + if (length != 0) { + subtree->set_end(subtree_end); + subtree = CordRepBtree::New(subtree); + subtree_end = 1; + } + node = node_[height]; + index = index_[height]; + } + edge = node->Edge(index); + if (length >= edge->length) { + subtree->length += edge->length; + subtree->edges_[subtree_end++] = CordRep::Ref(edge); + } + } while (length >= edge->length); + CordRepBtree* tree = subtree; + subtree->length += length; + + // If we moved up the tree, descend down to the leaf level, consuming all + // edges that must be read, adding 'down' nodes to `subtree`. + while (height > 0) { + node = edge->btree(); + index_[height] = index; + node_[--height] = node; + index = node->begin(); + edge = node->Edge(index); + + if (length != 0) { + CordRepBtree* right = CordRepBtree::New(height); + right->length = length; + subtree->edges_[subtree_end++] = right; + subtree->set_end(subtree_end); + subtree = right; + subtree_end = 0; + while (length >= edge->length) { + subtree->edges_[subtree_end++] = CordRep::Ref(edge); + length -= edge->length; + edge = node->Edge(++index); + } + } + } + // Add any (partial) edge still remaining at the leaf level. + if (length != 0) { + subtree->edges_[subtree_end++] = Substring(edge, 0, length); + } + subtree->set_end(subtree_end); + index_[0] = index; + return {tree, length}; +} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree_navigator.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree_navigator.h index 40c58e3b3c..8ea166f16e 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree_navigator.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree_navigator.h @@ -1,265 +1,265 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_NAVIGATOR_H_ -#define ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_NAVIGATOR_H_ - -#include <cassert> -#include <iostream> - -#include "y_absl/strings/internal/cord_internal.h" -#include "y_absl/strings/internal/cord_rep_btree.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -// CordRepBtreeNavigator is a bi-directional navigator allowing callers to -// navigate all the (leaf) data edges in a CordRepBtree instance. -// -// A CordRepBtreeNavigator instance is by default empty. Callers initialize a -// navigator instance by calling one of `InitFirst()`, `InitLast()` or -// `InitOffset()`, which establishes a current position. Callers can then -// navigate using the `Next`, `Previous`, `Skip` and `Seek` methods. -// -// The navigator instance does not take or adopt a reference on the provided -// `tree` on any of the initialization calls. Callers are responsible for -// guaranteeing the lifecycle of the provided tree. A navigator instance can -// be reset to the empty state by calling `Reset`. -// -// A navigator only keeps positional state on the 'current data edge', it does -// explicitly not keep any 'offset' state. The class does accept and return -// offsets in the `Read()`, `Skip()` and 'Seek()` methods as these would -// otherwise put a big burden on callers. Callers are expected to maintain -// (returned) offset info if they require such granular state. -class CordRepBtreeNavigator { - public: - // The logical position as returned by the Seek() and Skip() functions. - // Returns the current leaf edge for the desired seek or skip position and - // the offset of that position inside that edge. - struct Position { - CordRep* edge; - size_t offset; - }; - - // The read result as returned by the Read() function. - // `tree` contains the resulting tree which is identical to the result - // of calling CordRepBtree::SubTree(...) on the tree being navigated. - // `n` contains the number of bytes used from the last navigated to - // edge of the tree. - struct ReadResult { - CordRep* tree; - size_t n; - }; - - // Returns true if this instance is not empty. - explicit operator bool() const; - - // Returns the tree for this instance or nullptr if empty. - CordRepBtree* btree() const; - - // Returns the data edge of the current position. - // Requires this instance to not be empty. - CordRep* Current() const; - - // Resets this navigator to `tree`, returning the first data edge in the tree. - CordRep* InitFirst(CordRepBtree* tree); - - // Resets this navigator to `tree`, returning the last data edge in the tree. - CordRep* InitLast(CordRepBtree* tree); - - // Resets this navigator to `tree` returning the data edge at position - // `offset` and the relative offset of `offset` into that data edge. - // Returns `Position.edge = nullptr` if the provided offset is greater - // than or equal to the length of the tree, in which case the state of - // the navigator instance remains unchanged. - Position InitOffset(CordRepBtree* tree, size_t offset); - - // Navigates to the next data edge. - // Returns the next data edge or nullptr if there is no next data edge, in - // which case the current position remains unchanged. - CordRep* Next(); - - // Navigates to the previous data edge. - // Returns the previous data edge or nullptr if there is no previous data - // edge, in which case the current position remains unchanged. - CordRep* Previous(); - - // Navigates to the data edge at position `offset`. Returns the navigated to - // data edge in `Position.edge` and the relative offset of `offset` into that - // data edge in `Position.offset`. Returns `Position.edge = nullptr` if the - // provide offset is greater than or equal to the tree's length. - Position Seek(size_t offset); - - // Reads `n` bytes of data starting at offset `edge_offset` of the current - // data edge, and returns the result in `ReadResult.tree`. `ReadResult.n` - // contains the 'bytes used` from the last / current data edge in the tree. - // This allows users that mix regular navigation (using string views) and - // 'read into cord' navigation to keep track of the current state, and which - // bytes have been consumed from a navigator. - // This function returns `ReadResult.tree = nullptr` if the requested length - // exceeds the length of the tree starting at the current data edge. - ReadResult Read(size_t edge_offset, size_t n); - - // Skips `n` bytes forward from the current data edge, returning the navigated - // to data edge in `Position.edge` and `Position.offset` containing the offset - // inside that data edge. Note that the state of the navigator is left - // unchanged if `n` is smaller than the length of the current data edge. - Position Skip(size_t n); - - // Resets this instance to the default / empty state. - void Reset(); - - private: - // Slow path for Next() if Next() reached the end of a leaf node. Backtracks - // up the stack until it finds a node that has a 'next' position available, - // and then does a 'front dive' towards the next leaf node. - CordRep* NextUp(); - - // Slow path for Previous() if Previous() reached the beginning of a leaf - // node. Backtracks up the stack until it finds a node that has a 'previous' - // position available, and then does a 'back dive' towards the previous leaf - // node. - CordRep* PreviousUp(); - - // Generic implementation of InitFirst() and InitLast(). - template <CordRepBtree::EdgeType edge_type> - CordRep* Init(CordRepBtree* tree); - - // `height_` contains the height of the current tree, or -1 if empty. - int height_ = -1; - - // `index_` and `node_` contain the navigation state as the 'path' to the - // current data edge which is at `node_[0]->Edge(index_[0])`. The contents - // of these are undefined until the instance is initialized (`height_ >= 0`). - uint8_t index_[CordRepBtree::kMaxHeight]; - CordRepBtree* node_[CordRepBtree::kMaxHeight]; -}; - -// Returns true if this instance is not empty. -inline CordRepBtreeNavigator::operator bool() const { return height_ >= 0; } - -inline CordRepBtree* CordRepBtreeNavigator::btree() const { - return height_ >= 0 ? node_[height_] : nullptr; -} - -inline CordRep* CordRepBtreeNavigator::Current() const { - assert(height_ >= 0); - return node_[0]->Edge(index_[0]); -} - -inline void CordRepBtreeNavigator::Reset() { height_ = -1; } - -inline CordRep* CordRepBtreeNavigator::InitFirst(CordRepBtree* tree) { - return Init<CordRepBtree::kFront>(tree); -} - -inline CordRep* CordRepBtreeNavigator::InitLast(CordRepBtree* tree) { - return Init<CordRepBtree::kBack>(tree); -} - -template <CordRepBtree::EdgeType edge_type> -inline CordRep* CordRepBtreeNavigator::Init(CordRepBtree* tree) { - assert(tree != nullptr); - assert(tree->size() > 0); - int height = height_ = tree->height(); - size_t index = tree->index(edge_type); - node_[height] = tree; - index_[height] = static_cast<uint8_t>(index); - while (--height >= 0) { - tree = tree->Edge(index)->btree(); - node_[height] = tree; - index = tree->index(edge_type); - index_[height] = static_cast<uint8_t>(index); - } - return node_[0]->Edge(index); -} - -inline CordRepBtreeNavigator::Position CordRepBtreeNavigator::Seek( - size_t offset) { - assert(btree() != nullptr); - int height = height_; - CordRepBtree* edge = node_[height]; - if (ABSL_PREDICT_FALSE(offset >= edge->length)) return {nullptr, 0}; - CordRepBtree::Position index = edge->IndexOf(offset); - index_[height] = static_cast<uint8_t>(index.index); - while (--height >= 0) { - edge = edge->Edge(index.index)->btree(); - node_[height] = edge; - index = edge->IndexOf(index.n); - index_[height] = static_cast<uint8_t>(index.index); - } - return {edge->Edge(index.index), index.n}; -} - -inline CordRepBtreeNavigator::Position CordRepBtreeNavigator::InitOffset( - CordRepBtree* tree, size_t offset) { - assert(tree != nullptr); - if (ABSL_PREDICT_FALSE(offset >= tree->length)) return {nullptr, 0}; - height_ = tree->height(); - node_[height_] = tree; - return Seek(offset); -} - -inline CordRep* CordRepBtreeNavigator::Next() { - CordRepBtree* edge = node_[0]; - return index_[0] == edge->back() ? NextUp() : edge->Edge(++index_[0]); -} - -inline CordRep* CordRepBtreeNavigator::Previous() { - CordRepBtree* edge = node_[0]; - return index_[0] == edge->begin() ? PreviousUp() : edge->Edge(--index_[0]); -} - -inline CordRep* CordRepBtreeNavigator::NextUp() { - assert(index_[0] == node_[0]->back()); - CordRepBtree* edge; - size_t index; - int height = 0; - do { - if (++height > height_) return nullptr; - edge = node_[height]; - index = index_[height] + 1; - } while (index == edge->end()); - index_[height] = static_cast<uint8_t>(index); - do { - node_[--height] = edge = edge->Edge(index)->btree(); - index_[height] = static_cast<uint8_t>(index = edge->begin()); - } while (height > 0); - return edge->Edge(index); -} - -inline CordRep* CordRepBtreeNavigator::PreviousUp() { - assert(index_[0] == node_[0]->begin()); - CordRepBtree* edge; - size_t index; - int height = 0; - do { - if (++height > height_) return nullptr; - edge = node_[height]; - index = index_[height]; - } while (index == edge->begin()); - index_[height] = static_cast<uint8_t>(--index); - do { - node_[--height] = edge = edge->Edge(index)->btree(); - index_[height] = static_cast<uint8_t>(index = edge->back()); - } while (height > 0); - return edge->Edge(index); -} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace y_absl - -#endif // ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_NAVIGATOR_H_ +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_NAVIGATOR_H_ +#define ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_NAVIGATOR_H_ + +#include <cassert> +#include <iostream> + +#include "y_absl/strings/internal/cord_internal.h" +#include "y_absl/strings/internal/cord_rep_btree.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +// CordRepBtreeNavigator is a bi-directional navigator allowing callers to +// navigate all the (leaf) data edges in a CordRepBtree instance. +// +// A CordRepBtreeNavigator instance is by default empty. Callers initialize a +// navigator instance by calling one of `InitFirst()`, `InitLast()` or +// `InitOffset()`, which establishes a current position. Callers can then +// navigate using the `Next`, `Previous`, `Skip` and `Seek` methods. +// +// The navigator instance does not take or adopt a reference on the provided +// `tree` on any of the initialization calls. Callers are responsible for +// guaranteeing the lifecycle of the provided tree. A navigator instance can +// be reset to the empty state by calling `Reset`. +// +// A navigator only keeps positional state on the 'current data edge', it does +// explicitly not keep any 'offset' state. The class does accept and return +// offsets in the `Read()`, `Skip()` and 'Seek()` methods as these would +// otherwise put a big burden on callers. Callers are expected to maintain +// (returned) offset info if they require such granular state. +class CordRepBtreeNavigator { + public: + // The logical position as returned by the Seek() and Skip() functions. + // Returns the current leaf edge for the desired seek or skip position and + // the offset of that position inside that edge. + struct Position { + CordRep* edge; + size_t offset; + }; + + // The read result as returned by the Read() function. + // `tree` contains the resulting tree which is identical to the result + // of calling CordRepBtree::SubTree(...) on the tree being navigated. + // `n` contains the number of bytes used from the last navigated to + // edge of the tree. + struct ReadResult { + CordRep* tree; + size_t n; + }; + + // Returns true if this instance is not empty. + explicit operator bool() const; + + // Returns the tree for this instance or nullptr if empty. + CordRepBtree* btree() const; + + // Returns the data edge of the current position. + // Requires this instance to not be empty. + CordRep* Current() const; + + // Resets this navigator to `tree`, returning the first data edge in the tree. + CordRep* InitFirst(CordRepBtree* tree); + + // Resets this navigator to `tree`, returning the last data edge in the tree. + CordRep* InitLast(CordRepBtree* tree); + + // Resets this navigator to `tree` returning the data edge at position + // `offset` and the relative offset of `offset` into that data edge. + // Returns `Position.edge = nullptr` if the provided offset is greater + // than or equal to the length of the tree, in which case the state of + // the navigator instance remains unchanged. + Position InitOffset(CordRepBtree* tree, size_t offset); + + // Navigates to the next data edge. + // Returns the next data edge or nullptr if there is no next data edge, in + // which case the current position remains unchanged. + CordRep* Next(); + + // Navigates to the previous data edge. + // Returns the previous data edge or nullptr if there is no previous data + // edge, in which case the current position remains unchanged. + CordRep* Previous(); + + // Navigates to the data edge at position `offset`. Returns the navigated to + // data edge in `Position.edge` and the relative offset of `offset` into that + // data edge in `Position.offset`. Returns `Position.edge = nullptr` if the + // provide offset is greater than or equal to the tree's length. + Position Seek(size_t offset); + + // Reads `n` bytes of data starting at offset `edge_offset` of the current + // data edge, and returns the result in `ReadResult.tree`. `ReadResult.n` + // contains the 'bytes used` from the last / current data edge in the tree. + // This allows users that mix regular navigation (using string views) and + // 'read into cord' navigation to keep track of the current state, and which + // bytes have been consumed from a navigator. + // This function returns `ReadResult.tree = nullptr` if the requested length + // exceeds the length of the tree starting at the current data edge. + ReadResult Read(size_t edge_offset, size_t n); + + // Skips `n` bytes forward from the current data edge, returning the navigated + // to data edge in `Position.edge` and `Position.offset` containing the offset + // inside that data edge. Note that the state of the navigator is left + // unchanged if `n` is smaller than the length of the current data edge. + Position Skip(size_t n); + + // Resets this instance to the default / empty state. + void Reset(); + + private: + // Slow path for Next() if Next() reached the end of a leaf node. Backtracks + // up the stack until it finds a node that has a 'next' position available, + // and then does a 'front dive' towards the next leaf node. + CordRep* NextUp(); + + // Slow path for Previous() if Previous() reached the beginning of a leaf + // node. Backtracks up the stack until it finds a node that has a 'previous' + // position available, and then does a 'back dive' towards the previous leaf + // node. + CordRep* PreviousUp(); + + // Generic implementation of InitFirst() and InitLast(). + template <CordRepBtree::EdgeType edge_type> + CordRep* Init(CordRepBtree* tree); + + // `height_` contains the height of the current tree, or -1 if empty. + int height_ = -1; + + // `index_` and `node_` contain the navigation state as the 'path' to the + // current data edge which is at `node_[0]->Edge(index_[0])`. The contents + // of these are undefined until the instance is initialized (`height_ >= 0`). + uint8_t index_[CordRepBtree::kMaxHeight]; + CordRepBtree* node_[CordRepBtree::kMaxHeight]; +}; + +// Returns true if this instance is not empty. +inline CordRepBtreeNavigator::operator bool() const { return height_ >= 0; } + +inline CordRepBtree* CordRepBtreeNavigator::btree() const { + return height_ >= 0 ? node_[height_] : nullptr; +} + +inline CordRep* CordRepBtreeNavigator::Current() const { + assert(height_ >= 0); + return node_[0]->Edge(index_[0]); +} + +inline void CordRepBtreeNavigator::Reset() { height_ = -1; } + +inline CordRep* CordRepBtreeNavigator::InitFirst(CordRepBtree* tree) { + return Init<CordRepBtree::kFront>(tree); +} + +inline CordRep* CordRepBtreeNavigator::InitLast(CordRepBtree* tree) { + return Init<CordRepBtree::kBack>(tree); +} + +template <CordRepBtree::EdgeType edge_type> +inline CordRep* CordRepBtreeNavigator::Init(CordRepBtree* tree) { + assert(tree != nullptr); + assert(tree->size() > 0); + int height = height_ = tree->height(); + size_t index = tree->index(edge_type); + node_[height] = tree; + index_[height] = static_cast<uint8_t>(index); + while (--height >= 0) { + tree = tree->Edge(index)->btree(); + node_[height] = tree; + index = tree->index(edge_type); + index_[height] = static_cast<uint8_t>(index); + } + return node_[0]->Edge(index); +} + +inline CordRepBtreeNavigator::Position CordRepBtreeNavigator::Seek( + size_t offset) { + assert(btree() != nullptr); + int height = height_; + CordRepBtree* edge = node_[height]; + if (ABSL_PREDICT_FALSE(offset >= edge->length)) return {nullptr, 0}; + CordRepBtree::Position index = edge->IndexOf(offset); + index_[height] = static_cast<uint8_t>(index.index); + while (--height >= 0) { + edge = edge->Edge(index.index)->btree(); + node_[height] = edge; + index = edge->IndexOf(index.n); + index_[height] = static_cast<uint8_t>(index.index); + } + return {edge->Edge(index.index), index.n}; +} + +inline CordRepBtreeNavigator::Position CordRepBtreeNavigator::InitOffset( + CordRepBtree* tree, size_t offset) { + assert(tree != nullptr); + if (ABSL_PREDICT_FALSE(offset >= tree->length)) return {nullptr, 0}; + height_ = tree->height(); + node_[height_] = tree; + return Seek(offset); +} + +inline CordRep* CordRepBtreeNavigator::Next() { + CordRepBtree* edge = node_[0]; + return index_[0] == edge->back() ? NextUp() : edge->Edge(++index_[0]); +} + +inline CordRep* CordRepBtreeNavigator::Previous() { + CordRepBtree* edge = node_[0]; + return index_[0] == edge->begin() ? PreviousUp() : edge->Edge(--index_[0]); +} + +inline CordRep* CordRepBtreeNavigator::NextUp() { + assert(index_[0] == node_[0]->back()); + CordRepBtree* edge; + size_t index; + int height = 0; + do { + if (++height > height_) return nullptr; + edge = node_[height]; + index = index_[height] + 1; + } while (index == edge->end()); + index_[height] = static_cast<uint8_t>(index); + do { + node_[--height] = edge = edge->Edge(index)->btree(); + index_[height] = static_cast<uint8_t>(index = edge->begin()); + } while (height > 0); + return edge->Edge(index); +} + +inline CordRep* CordRepBtreeNavigator::PreviousUp() { + assert(index_[0] == node_[0]->begin()); + CordRepBtree* edge; + size_t index; + int height = 0; + do { + if (++height > height_) return nullptr; + edge = node_[height]; + index = index_[height]; + } while (index == edge->begin()); + index_[height] = static_cast<uint8_t>(--index); + do { + node_[--height] = edge = edge->Edge(index)->btree(); + index_[height] = static_cast<uint8_t>(index = edge->back()); + } while (height > 0); + return edge->Edge(index); +} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace y_absl + +#endif // ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_NAVIGATOR_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree_reader.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree_reader.cc index 0bc9dba2e6..f1bc2d6bdb 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree_reader.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree_reader.cc @@ -1,68 +1,68 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "y_absl/strings/internal/cord_rep_btree_reader.h" - -#include <cassert> - -#include "y_absl/base/config.h" -#include "y_absl/strings/internal/cord_internal.h" -#include "y_absl/strings/internal/cord_rep_btree.h" -#include "y_absl/strings/internal/cord_rep_btree_navigator.h" -#include "y_absl/strings/internal/cord_rep_flat.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -y_absl::string_view CordRepBtreeReader::Read(size_t n, size_t chunk_size, - CordRep*& tree) { - assert(chunk_size <= navigator_.Current()->length); - - // If chunk_size is non-zero, we need to start inside last returned edge. - // Else we start reading at the next data edge of the tree. - CordRep* edge = chunk_size ? navigator_.Current() : navigator_.Next(); - const size_t offset = chunk_size ? edge->length - chunk_size : 0; - - // Read the sub tree and verify we got what we wanted. - ReadResult result = navigator_.Read(offset, n); - tree = result.tree; - - // If the data returned in `tree` was covered entirely by `chunk_size`, i.e., - // read from the 'previous' edge, we did not consume any additional data, and - // can directly return the substring into the current data edge as the next - // chunk. We can easily establish from the above code that `navigator_.Next()` - // has not been called as that requires `chunk_size` to be zero. - if (n < chunk_size) return CordRepBtree::EdgeData(edge).substr(result.n); - - // The amount of data taken from the last edge is `chunk_size` and `result.n` - // contains the offset into the current edge trailing the read data (which can - // be 0). As the call to `navigator_.Read()` could have consumed all remaining - // data, calling `navigator_.Current()` is not safe before checking if we - // already consumed all remaining data. - const size_t consumed_by_read = n - chunk_size - result.n; - if (consumed_by_read >= remaining_) { - remaining_ = 0; - return {}; - } - - // We did not read all data, return remaining data from current edge. - edge = navigator_.Current(); - remaining_ -= consumed_by_read + edge->length; - return CordRepBtree::EdgeData(edge).substr(result.n); -} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace y_absl +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "y_absl/strings/internal/cord_rep_btree_reader.h" + +#include <cassert> + +#include "y_absl/base/config.h" +#include "y_absl/strings/internal/cord_internal.h" +#include "y_absl/strings/internal/cord_rep_btree.h" +#include "y_absl/strings/internal/cord_rep_btree_navigator.h" +#include "y_absl/strings/internal/cord_rep_flat.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +y_absl::string_view CordRepBtreeReader::Read(size_t n, size_t chunk_size, + CordRep*& tree) { + assert(chunk_size <= navigator_.Current()->length); + + // If chunk_size is non-zero, we need to start inside last returned edge. + // Else we start reading at the next data edge of the tree. + CordRep* edge = chunk_size ? navigator_.Current() : navigator_.Next(); + const size_t offset = chunk_size ? edge->length - chunk_size : 0; + + // Read the sub tree and verify we got what we wanted. + ReadResult result = navigator_.Read(offset, n); + tree = result.tree; + + // If the data returned in `tree` was covered entirely by `chunk_size`, i.e., + // read from the 'previous' edge, we did not consume any additional data, and + // can directly return the substring into the current data edge as the next + // chunk. We can easily establish from the above code that `navigator_.Next()` + // has not been called as that requires `chunk_size` to be zero. + if (n < chunk_size) return CordRepBtree::EdgeData(edge).substr(result.n); + + // The amount of data taken from the last edge is `chunk_size` and `result.n` + // contains the offset into the current edge trailing the read data (which can + // be 0). As the call to `navigator_.Read()` could have consumed all remaining + // data, calling `navigator_.Current()` is not safe before checking if we + // already consumed all remaining data. + const size_t consumed_by_read = n - chunk_size - result.n; + if (consumed_by_read >= remaining_) { + remaining_ = 0; + return {}; + } + + // We did not read all data, return remaining data from current edge. + edge = navigator_.Current(); + remaining_ -= consumed_by_read + edge->length; + return CordRepBtree::EdgeData(edge).substr(result.n); +} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree_reader.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree_reader.h index 00b2261f71..23f729fc3d 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree_reader.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_btree_reader.h @@ -1,211 +1,211 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_READER_H_ -#define ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_READER_H_ - -#include <cassert> - -#include "y_absl/base/config.h" -#include "y_absl/strings/internal/cord_internal.h" -#include "y_absl/strings/internal/cord_rep_btree.h" -#include "y_absl/strings/internal/cord_rep_btree_navigator.h" -#include "y_absl/strings/internal/cord_rep_flat.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -// CordRepBtreeReader implements logic to iterate over cord btrees. -// References to the underlying data are returned as y_absl::string_view values. -// The most typical use case is a forward only iteration over tree data. -// The class also provides `Skip()`, `Seek()` and `Read()` methods similar to -// CordRepBtreeNavigator that allow more advanced navigation. -// -// Example: iterate over all data inside a cord btree: -// -// CordRepBtreeReader reader; -// for (string_view sv = reader.Init(tree); !sv.Empty(); sv = sv.Next()) { -// DoSomethingWithDataIn(sv); -// } -// -// All navigation methods always return the next 'chunk' of data. The class -// assumes that all data is directly 'consumed' by the caller. For example: -// invoking `Skip()` will skip the desired number of bytes, and directly -// read and return the next chunk of data directly after the skipped bytes. -// -// Example: iterate over all data inside a btree skipping the first 100 bytes: -// -// CordRepBtreeReader reader; -// y_absl::string_view sv = reader.Init(tree); -// if (sv.length() > 100) { -// sv.RemovePrefix(100); -// } else { -// sv = reader.Skip(100 - sv.length()); -// } -// while (!sv.empty()) { -// DoSomethingWithDataIn(sv); -// y_absl::string_view sv = reader.Next(); -// } -// -// It is important to notice that `remaining` is based on the end position of -// the last data edge returned to the caller, not the cumulative data returned -// to the caller which can be less in cases of skipping or seeking over data. -// -// For example, consider a cord btree with five data edges: "abc", "def", "ghi", -// "jkl" and "mno": -// -// y_absl::string_view sv; -// CordRepBtreeReader reader; -// -// sv = reader.Init(tree); // sv = "abc", remaining = 12 -// sv = reader.Skip(4); // sv = "hi", remaining = 6 -// sv = reader.Skip(2); // sv = "l", remaining = 3 -// sv = reader.Next(); // sv = "mno", remaining = 0 -// sv = reader.Seek(1); // sv = "bc", remaining = 12 -// -class CordRepBtreeReader { - public: - using ReadResult = CordRepBtreeNavigator::ReadResult; - using Position = CordRepBtreeNavigator::Position; - - // Returns true if this instance is not empty. - explicit operator bool() const { return navigator_.btree() != nullptr; } - - // Returns the tree referenced by this instance or nullptr if empty. - CordRepBtree* btree() const { return navigator_.btree(); } - - // Returns the current data edge inside the referenced btree. - // Requires that the current instance is not empty. - CordRep* node() const { return navigator_.Current(); } - - // Returns the length of the referenced tree. - // Requires that the current instance is not empty. - size_t length() const; - - // Returns the number of remaining bytes available for iteration, which is the - // number of bytes directly following the end of the last chunk returned. - // This value will be zero if we iterated over the last edge in the bound - // tree, in which case any call to Next() or Skip() will return an empty - // string_view reflecting the EOF state. - // Note that a call to `Seek()` resets `remaining` to a value based on the - // end position of the chunk returned by that call. - size_t remaining() const { return remaining_; } - - // Resets this instance to an empty value. - void Reset() { navigator_.Reset(); } - - // Initializes this instance with `tree`. `tree` must not be null. - // Returns a reference to the first data edge of the provided tree. - y_absl::string_view Init(CordRepBtree* tree); - - // Navigates to and returns the next data edge of the referenced tree. - // Returns an empty string_view if an attempt is made to read beyond the end - // of the tree, i.e.: if `remaining()` is zero indicating an EOF condition. - // Requires that the current instance is not empty. - y_absl::string_view Next(); - - // Skips the provided amount of bytes and returns a reference to the data - // directly following the skipped bytes. - y_absl::string_view Skip(size_t skip); - - // Reads `n` bytes into `tree`. - // If `chunk_size` is zero, starts reading at the next data edge. If - // `chunk_size` is non zero, the read starts at the last `chunk_size` bytes of - // the last returned data edge. Effectively, this means that the read starts - // at offset `consumed() - chunk_size`. - // Requires that `chunk_size` is less than or equal to the length of the - // last returned data edge. The purpose of `chunk_size` is to simplify code - // partially consuming a returned chunk and wanting to include the remaining - // bytes in the Read call. For example, the below code will read 1000 bytes of - // data into a cord tree if the first chunk starts with "big:": - // - // CordRepBtreeReader reader; - // y_absl::string_view sv = reader.Init(tree); - // if (y_absl::StartsWith(sv, "big:")) { - // CordRepBtree tree; - // sv = reader.Read(1000, sv.size() - 4 /* "big:" */, &tree); - // } - // - // This method will return an empty string view if all remaining data was - // read. If `n` exceeded the amount of remaining data this function will - // return an empty string view and `tree` will be set to nullptr. - // In both cases, `consumed` will be set to `length`. - y_absl::string_view Read(size_t n, size_t chunk_size, CordRep*& tree); - - // Navigates to the chunk at offset `offset`. - // Returns a reference into the navigated to chunk, adjusted for the relative - // position of `offset` into that chunk. For example, calling `Seek(13)` on a - // cord tree containing 2 chunks of 10 and 20 bytes respectively will return - // a string view into the second chunk starting at offset 3 with a size of 17. - // Returns an empty string view if `offset` is equal to or greater than the - // length of the referenced tree. - y_absl::string_view Seek(size_t offset); - - private: - size_t remaining_ = 0; - CordRepBtreeNavigator navigator_; -}; - -inline size_t CordRepBtreeReader::length() const { - assert(btree() != nullptr); - return btree()->length; -} - -inline y_absl::string_view CordRepBtreeReader::Init(CordRepBtree* tree) { - assert(tree != nullptr); - const CordRep* edge = navigator_.InitFirst(tree); - remaining_ = tree->length - edge->length; - return CordRepBtree::EdgeData(edge); -} - -inline y_absl::string_view CordRepBtreeReader::Next() { - if (remaining_ == 0) return {}; - const CordRep* edge = navigator_.Next(); - assert(edge != nullptr); - remaining_ -= edge->length; - return CordRepBtree::EdgeData(edge); -} - -inline y_absl::string_view CordRepBtreeReader::Skip(size_t skip) { - // As we are always positioned on the last 'consumed' edge, we - // need to skip the current edge as well as `skip`. - const size_t edge_length = navigator_.Current()->length; - CordRepBtreeNavigator::Position pos = navigator_.Skip(skip + edge_length); - if (ABSL_PREDICT_FALSE(pos.edge == nullptr)) { - remaining_ = 0; - return {}; - } - // The combined length of all edges skipped before `pos.edge` is `skip - - // pos.offset`, all of which are 'consumed', as well as the current edge. - remaining_ -= skip - pos.offset + pos.edge->length; - return CordRepBtree::EdgeData(pos.edge).substr(pos.offset); -} - -inline y_absl::string_view CordRepBtreeReader::Seek(size_t offset) { - const CordRepBtreeNavigator::Position pos = navigator_.Seek(offset); - if (ABSL_PREDICT_FALSE(pos.edge == nullptr)) { - remaining_ = 0; - return {}; - } - y_absl::string_view chunk = CordRepBtree::EdgeData(pos.edge).substr(pos.offset); - remaining_ = length() - offset - chunk.length(); - return chunk; -} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace y_absl - -#endif // ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_READER_H_ +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_READER_H_ +#define ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_READER_H_ + +#include <cassert> + +#include "y_absl/base/config.h" +#include "y_absl/strings/internal/cord_internal.h" +#include "y_absl/strings/internal/cord_rep_btree.h" +#include "y_absl/strings/internal/cord_rep_btree_navigator.h" +#include "y_absl/strings/internal/cord_rep_flat.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +// CordRepBtreeReader implements logic to iterate over cord btrees. +// References to the underlying data are returned as y_absl::string_view values. +// The most typical use case is a forward only iteration over tree data. +// The class also provides `Skip()`, `Seek()` and `Read()` methods similar to +// CordRepBtreeNavigator that allow more advanced navigation. +// +// Example: iterate over all data inside a cord btree: +// +// CordRepBtreeReader reader; +// for (string_view sv = reader.Init(tree); !sv.Empty(); sv = sv.Next()) { +// DoSomethingWithDataIn(sv); +// } +// +// All navigation methods always return the next 'chunk' of data. The class +// assumes that all data is directly 'consumed' by the caller. For example: +// invoking `Skip()` will skip the desired number of bytes, and directly +// read and return the next chunk of data directly after the skipped bytes. +// +// Example: iterate over all data inside a btree skipping the first 100 bytes: +// +// CordRepBtreeReader reader; +// y_absl::string_view sv = reader.Init(tree); +// if (sv.length() > 100) { +// sv.RemovePrefix(100); +// } else { +// sv = reader.Skip(100 - sv.length()); +// } +// while (!sv.empty()) { +// DoSomethingWithDataIn(sv); +// y_absl::string_view sv = reader.Next(); +// } +// +// It is important to notice that `remaining` is based on the end position of +// the last data edge returned to the caller, not the cumulative data returned +// to the caller which can be less in cases of skipping or seeking over data. +// +// For example, consider a cord btree with five data edges: "abc", "def", "ghi", +// "jkl" and "mno": +// +// y_absl::string_view sv; +// CordRepBtreeReader reader; +// +// sv = reader.Init(tree); // sv = "abc", remaining = 12 +// sv = reader.Skip(4); // sv = "hi", remaining = 6 +// sv = reader.Skip(2); // sv = "l", remaining = 3 +// sv = reader.Next(); // sv = "mno", remaining = 0 +// sv = reader.Seek(1); // sv = "bc", remaining = 12 +// +class CordRepBtreeReader { + public: + using ReadResult = CordRepBtreeNavigator::ReadResult; + using Position = CordRepBtreeNavigator::Position; + + // Returns true if this instance is not empty. + explicit operator bool() const { return navigator_.btree() != nullptr; } + + // Returns the tree referenced by this instance or nullptr if empty. + CordRepBtree* btree() const { return navigator_.btree(); } + + // Returns the current data edge inside the referenced btree. + // Requires that the current instance is not empty. + CordRep* node() const { return navigator_.Current(); } + + // Returns the length of the referenced tree. + // Requires that the current instance is not empty. + size_t length() const; + + // Returns the number of remaining bytes available for iteration, which is the + // number of bytes directly following the end of the last chunk returned. + // This value will be zero if we iterated over the last edge in the bound + // tree, in which case any call to Next() or Skip() will return an empty + // string_view reflecting the EOF state. + // Note that a call to `Seek()` resets `remaining` to a value based on the + // end position of the chunk returned by that call. + size_t remaining() const { return remaining_; } + + // Resets this instance to an empty value. + void Reset() { navigator_.Reset(); } + + // Initializes this instance with `tree`. `tree` must not be null. + // Returns a reference to the first data edge of the provided tree. + y_absl::string_view Init(CordRepBtree* tree); + + // Navigates to and returns the next data edge of the referenced tree. + // Returns an empty string_view if an attempt is made to read beyond the end + // of the tree, i.e.: if `remaining()` is zero indicating an EOF condition. + // Requires that the current instance is not empty. + y_absl::string_view Next(); + + // Skips the provided amount of bytes and returns a reference to the data + // directly following the skipped bytes. + y_absl::string_view Skip(size_t skip); + + // Reads `n` bytes into `tree`. + // If `chunk_size` is zero, starts reading at the next data edge. If + // `chunk_size` is non zero, the read starts at the last `chunk_size` bytes of + // the last returned data edge. Effectively, this means that the read starts + // at offset `consumed() - chunk_size`. + // Requires that `chunk_size` is less than or equal to the length of the + // last returned data edge. The purpose of `chunk_size` is to simplify code + // partially consuming a returned chunk and wanting to include the remaining + // bytes in the Read call. For example, the below code will read 1000 bytes of + // data into a cord tree if the first chunk starts with "big:": + // + // CordRepBtreeReader reader; + // y_absl::string_view sv = reader.Init(tree); + // if (y_absl::StartsWith(sv, "big:")) { + // CordRepBtree tree; + // sv = reader.Read(1000, sv.size() - 4 /* "big:" */, &tree); + // } + // + // This method will return an empty string view if all remaining data was + // read. If `n` exceeded the amount of remaining data this function will + // return an empty string view and `tree` will be set to nullptr. + // In both cases, `consumed` will be set to `length`. + y_absl::string_view Read(size_t n, size_t chunk_size, CordRep*& tree); + + // Navigates to the chunk at offset `offset`. + // Returns a reference into the navigated to chunk, adjusted for the relative + // position of `offset` into that chunk. For example, calling `Seek(13)` on a + // cord tree containing 2 chunks of 10 and 20 bytes respectively will return + // a string view into the second chunk starting at offset 3 with a size of 17. + // Returns an empty string view if `offset` is equal to or greater than the + // length of the referenced tree. + y_absl::string_view Seek(size_t offset); + + private: + size_t remaining_ = 0; + CordRepBtreeNavigator navigator_; +}; + +inline size_t CordRepBtreeReader::length() const { + assert(btree() != nullptr); + return btree()->length; +} + +inline y_absl::string_view CordRepBtreeReader::Init(CordRepBtree* tree) { + assert(tree != nullptr); + const CordRep* edge = navigator_.InitFirst(tree); + remaining_ = tree->length - edge->length; + return CordRepBtree::EdgeData(edge); +} + +inline y_absl::string_view CordRepBtreeReader::Next() { + if (remaining_ == 0) return {}; + const CordRep* edge = navigator_.Next(); + assert(edge != nullptr); + remaining_ -= edge->length; + return CordRepBtree::EdgeData(edge); +} + +inline y_absl::string_view CordRepBtreeReader::Skip(size_t skip) { + // As we are always positioned on the last 'consumed' edge, we + // need to skip the current edge as well as `skip`. + const size_t edge_length = navigator_.Current()->length; + CordRepBtreeNavigator::Position pos = navigator_.Skip(skip + edge_length); + if (ABSL_PREDICT_FALSE(pos.edge == nullptr)) { + remaining_ = 0; + return {}; + } + // The combined length of all edges skipped before `pos.edge` is `skip - + // pos.offset`, all of which are 'consumed', as well as the current edge. + remaining_ -= skip - pos.offset + pos.edge->length; + return CordRepBtree::EdgeData(pos.edge).substr(pos.offset); +} + +inline y_absl::string_view CordRepBtreeReader::Seek(size_t offset) { + const CordRepBtreeNavigator::Position pos = navigator_.Seek(offset); + if (ABSL_PREDICT_FALSE(pos.edge == nullptr)) { + remaining_ = 0; + return {}; + } + y_absl::string_view chunk = CordRepBtree::EdgeData(pos.edge).substr(pos.offset); + remaining_ = length() - offset - chunk.length(); + return chunk; +} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace y_absl + +#endif // ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_READER_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_consume.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_consume.cc index ffc0179e52..1cc83d7f26 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_consume.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_consume.cc @@ -1,129 +1,129 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "y_absl/strings/internal/cord_rep_consume.h" - -#include <array> -#include <utility> - -#include "y_absl/container/inlined_vector.h" -#include "y_absl/functional/function_ref.h" -#include "y_absl/strings/internal/cord_internal.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -namespace { - -// Unrefs the provided `substring`, and returns `substring->child` -// Adds or assumes a reference on `substring->child` -CordRep* ClipSubstring(CordRepSubstring* substring) { - CordRep* child = substring->child; - if (substring->refcount.IsOne()) { - delete substring; - } else { - CordRep::Ref(child); - CordRep::Unref(substring); - } - return child; -} - -// Unrefs the provided `concat`, and returns `{concat->left, concat->right}` -// Adds or assumes a reference on `concat->left` and `concat->right`. -// Returns an array of 2 elements containing the left and right nodes. -std::array<CordRep*, 2> ClipConcat(CordRepConcat* concat) { - std::array<CordRep*, 2> result{concat->left, concat->right}; - if (concat->refcount.IsOne()) { - delete concat; - } else { - CordRep::Ref(result[0]); - CordRep::Ref(result[1]); - CordRep::Unref(concat); - } - return result; -} - -void Consume(bool forward, CordRep* rep, ConsumeFn consume_fn) { - size_t offset = 0; - size_t length = rep->length; - struct Entry { - CordRep* rep; - size_t offset; - size_t length; - }; - y_absl::InlinedVector<Entry, 40> stack; - - for (;;) { - if (rep->tag == CONCAT) { - std::array<CordRep*, 2> res = ClipConcat(rep->concat()); - CordRep* left = res[0]; - CordRep* right = res[1]; - - if (left->length <= offset) { - // Don't need left node - offset -= left->length; - CordRep::Unref(left); - rep = right; - continue; - } - - size_t length_left = left->length - offset; - if (length_left >= length) { - // Don't need right node - CordRep::Unref(right); - rep = left; - continue; - } - - // Need both nodes - size_t length_right = length - length_left; - if (forward) { - stack.push_back({right, 0, length_right}); - rep = left; - length = length_left; - } else { - stack.push_back({left, offset, length_left}); - rep = right; - offset = 0; - length = length_right; - } - } else if (rep->tag == SUBSTRING) { - offset += rep->substring()->start; - rep = ClipSubstring(rep->substring()); - } else { - consume_fn(rep, offset, length); - if (stack.empty()) return; - - rep = stack.back().rep; - offset = stack.back().offset; - length = stack.back().length; - stack.pop_back(); - } - } -} - -} // namespace - -void Consume(CordRep* rep, ConsumeFn consume_fn) { - return Consume(true, rep, std::move(consume_fn)); -} - -void ReverseConsume(CordRep* rep, ConsumeFn consume_fn) { - return Consume(false, rep, std::move(consume_fn)); -} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace y_absl +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "y_absl/strings/internal/cord_rep_consume.h" + +#include <array> +#include <utility> + +#include "y_absl/container/inlined_vector.h" +#include "y_absl/functional/function_ref.h" +#include "y_absl/strings/internal/cord_internal.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +namespace { + +// Unrefs the provided `substring`, and returns `substring->child` +// Adds or assumes a reference on `substring->child` +CordRep* ClipSubstring(CordRepSubstring* substring) { + CordRep* child = substring->child; + if (substring->refcount.IsOne()) { + delete substring; + } else { + CordRep::Ref(child); + CordRep::Unref(substring); + } + return child; +} + +// Unrefs the provided `concat`, and returns `{concat->left, concat->right}` +// Adds or assumes a reference on `concat->left` and `concat->right`. +// Returns an array of 2 elements containing the left and right nodes. +std::array<CordRep*, 2> ClipConcat(CordRepConcat* concat) { + std::array<CordRep*, 2> result{concat->left, concat->right}; + if (concat->refcount.IsOne()) { + delete concat; + } else { + CordRep::Ref(result[0]); + CordRep::Ref(result[1]); + CordRep::Unref(concat); + } + return result; +} + +void Consume(bool forward, CordRep* rep, ConsumeFn consume_fn) { + size_t offset = 0; + size_t length = rep->length; + struct Entry { + CordRep* rep; + size_t offset; + size_t length; + }; + y_absl::InlinedVector<Entry, 40> stack; + + for (;;) { + if (rep->tag == CONCAT) { + std::array<CordRep*, 2> res = ClipConcat(rep->concat()); + CordRep* left = res[0]; + CordRep* right = res[1]; + + if (left->length <= offset) { + // Don't need left node + offset -= left->length; + CordRep::Unref(left); + rep = right; + continue; + } + + size_t length_left = left->length - offset; + if (length_left >= length) { + // Don't need right node + CordRep::Unref(right); + rep = left; + continue; + } + + // Need both nodes + size_t length_right = length - length_left; + if (forward) { + stack.push_back({right, 0, length_right}); + rep = left; + length = length_left; + } else { + stack.push_back({left, offset, length_left}); + rep = right; + offset = 0; + length = length_right; + } + } else if (rep->tag == SUBSTRING) { + offset += rep->substring()->start; + rep = ClipSubstring(rep->substring()); + } else { + consume_fn(rep, offset, length); + if (stack.empty()) return; + + rep = stack.back().rep; + offset = stack.back().offset; + length = stack.back().length; + stack.pop_back(); + } + } +} + +} // namespace + +void Consume(CordRep* rep, ConsumeFn consume_fn) { + return Consume(true, rep, std::move(consume_fn)); +} + +void ReverseConsume(CordRep* rep, ConsumeFn consume_fn) { + return Consume(false, rep, std::move(consume_fn)); +} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_consume.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_consume.h index 7f6e5584f4..f6329df545 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_consume.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_consume.h @@ -1,50 +1,50 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_CONSUME_H_ -#define ABSL_STRINGS_INTERNAL_CORD_REP_CONSUME_H_ - -#include <functional> - -#include "y_absl/functional/function_ref.h" -#include "y_absl/strings/internal/cord_internal.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -// Functor for the Consume() and ReverseConsume() functions: -// void ConsumeFunc(CordRep* rep, size_t offset, size_t length); -// See the Consume() and ReverseConsume() function comments for documentation. -using ConsumeFn = FunctionRef<void(CordRep*, size_t, size_t)>; - -// Consume() and ReverseConsume() consume CONCAT based trees and invoke the -// provided functor with the contained nodes in the proper forward or reverse -// order, which is used to convert CONCAT trees into other tree or cord data. -// All CONCAT and SUBSTRING nodes are processed internally. The 'offset` -// parameter of the functor is non-zero for any nodes below SUBSTRING nodes. -// It's up to the caller to form these back into SUBSTRING nodes or otherwise -// store offset / prefix information. These functions are intended to be used -// only for migration / transitional code where due to factors such as ODR -// violations, we can not 100% guarantee that all code respects 'new format' -// settings and flags, so we need to be able to parse old data on the fly until -// all old code is deprecated / no longer the default format. -void Consume(CordRep* rep, ConsumeFn consume_fn); -void ReverseConsume(CordRep* rep, ConsumeFn consume_fn); - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace y_absl - -#endif // ABSL_STRINGS_INTERNAL_CORD_REP_CONSUME_H_ +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_CONSUME_H_ +#define ABSL_STRINGS_INTERNAL_CORD_REP_CONSUME_H_ + +#include <functional> + +#include "y_absl/functional/function_ref.h" +#include "y_absl/strings/internal/cord_internal.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +// Functor for the Consume() and ReverseConsume() functions: +// void ConsumeFunc(CordRep* rep, size_t offset, size_t length); +// See the Consume() and ReverseConsume() function comments for documentation. +using ConsumeFn = FunctionRef<void(CordRep*, size_t, size_t)>; + +// Consume() and ReverseConsume() consume CONCAT based trees and invoke the +// provided functor with the contained nodes in the proper forward or reverse +// order, which is used to convert CONCAT trees into other tree or cord data. +// All CONCAT and SUBSTRING nodes are processed internally. The 'offset` +// parameter of the functor is non-zero for any nodes below SUBSTRING nodes. +// It's up to the caller to form these back into SUBSTRING nodes or otherwise +// store offset / prefix information. These functions are intended to be used +// only for migration / transitional code where due to factors such as ODR +// violations, we can not 100% guarantee that all code respects 'new format' +// settings and flags, so we need to be able to parse old data on the fly until +// all old code is deprecated / no longer the default format. +void Consume(CordRep* rep, ConsumeFn consume_fn); +void ReverseConsume(CordRep* rep, ConsumeFn consume_fn); + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace y_absl + +#endif // ABSL_STRINGS_INTERNAL_CORD_REP_CONSUME_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_flat.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_flat.h index 976613031c..74841c5955 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_flat.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_flat.h @@ -44,11 +44,11 @@ static constexpr size_t kMaxFlatLength = kMaxFlatSize - kFlatOverhead; static constexpr size_t kMinFlatLength = kMinFlatSize - kFlatOverhead; constexpr uint8_t AllocatedSizeToTagUnchecked(size_t size) { - return static_cast<uint8_t>((size <= 1024) ? size / 8 + 1 - : 129 + size / 32 - 1024 / 32); + return static_cast<uint8_t>((size <= 1024) ? size / 8 + 1 + : 129 + size / 32 - 1024 / 32); } -static_assert(kMinFlatSize / 8 + 1 >= FLAT, ""); +static_assert(kMinFlatSize / 8 + 1 >= FLAT, ""); static_assert(AllocatedSizeToTagUnchecked(kMaxFlatSize) <= MAX_FLAT_TAG, ""); // Helper functions for rounded div, and rounding to exact sizes. @@ -73,7 +73,7 @@ inline uint8_t AllocatedSizeToTag(size_t size) { // Converts the provided tag to the corresponding allocated size constexpr size_t TagToAllocatedSize(uint8_t tag) { - return (tag <= 129) ? ((tag - 1) * 8) : (1024 + (tag - 129) * 32); + return (tag <= 129) ? ((tag - 1) * 8) : (1024 + (tag - 129) * 32); } // Converts the provided tag to the corresponding available data length @@ -82,7 +82,7 @@ constexpr size_t TagToLength(uint8_t tag) { } // Enforce that kMaxFlatSize maps to a well-known exact tag value. -static_assert(TagToAllocatedSize(225) == kMaxFlatSize, "Bad tag logic"); +static_assert(TagToAllocatedSize(225) == kMaxFlatSize, "Bad tag logic"); struct CordRepFlat : public CordRep { // Creates a new flat node. @@ -118,8 +118,8 @@ struct CordRepFlat : public CordRep { } // Returns a pointer to the data inside this flat rep. - char* Data() { return reinterpret_cast<char*>(storage); } - const char* Data() const { return reinterpret_cast<const char*>(storage); } + char* Data() { return reinterpret_cast<char*>(storage); } + const char* Data() const { return reinterpret_cast<const char*>(storage); } // Returns the maximum capacity (payload size) of this instance. size_t Capacity() const { return TagToLength(tag); } diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_ring.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_ring.cc index 06c7e75bd8..be7703d4ab 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_ring.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_ring.cc @@ -26,7 +26,7 @@ #include "y_absl/base/macros.h" #include "y_absl/container/inlined_vector.h" #include "y_absl/strings/internal/cord_internal.h" -#include "y_absl/strings/internal/cord_rep_consume.h" +#include "y_absl/strings/internal/cord_rep_consume.h" #include "y_absl/strings/internal/cord_rep_flat.h" namespace y_absl { @@ -40,7 +40,7 @@ using index_type = CordRepRing::index_type; enum class Direction { kForward, kReversed }; inline bool IsFlatOrExternal(CordRep* rep) { - return rep->IsFlat() || rep->IsExternal(); + return rep->IsFlat() || rep->IsExternal(); } // Verifies that n + extra <= kMaxCapacity: throws std::length_error otherwise. @@ -178,7 +178,7 @@ bool CordRepRing::IsValid(std::ostream& output) const { if (offset >= child->length || entry_length > child->length - offset) { output << "entry[" << head << "] has offset " << offset << " and entry length " << entry_length - << " which are outside of the child's length of " << child->length; + << " which are outside of the child's length of " << child->length; return false; } @@ -229,7 +229,7 @@ void CordRepRing::SetCapacityForTesting(size_t capacity) { } void CordRepRing::Delete(CordRepRing* rep) { - assert(rep != nullptr && rep->IsRing()); + assert(rep != nullptr && rep->IsRing()); #if defined(__cpp_sized_deallocation) size_t size = AllocSize(rep->capacity_); rep->~CordRepRing(); @@ -277,11 +277,11 @@ CordRepRing* CordRepRing::Mutable(CordRepRing* rep, size_t extra) { // Get current number of entries, and check for max capacity. size_t entries = rep->entries(); - if (!rep->refcount.IsMutable()) { - return Copy(rep, rep->head(), rep->tail(), extra); + if (!rep->refcount.IsMutable()) { + return Copy(rep, rep->head(), rep->tail(), extra); } else if (entries + extra > rep->capacity()) { - const size_t min_grow = rep->capacity() + rep->capacity() / 2; - const size_t min_extra = (std::max)(extra, min_grow - entries); + const size_t min_grow = rep->capacity() + rep->capacity() / 2; + const size_t min_extra = (std::max)(extra, min_grow - entries); CordRepRing* newrep = CordRepRing::New(entries, min_extra); newrep->Fill<false>(rep, rep->head(), rep->tail()); CordRepRing::Delete(rep); @@ -292,10 +292,10 @@ CordRepRing* CordRepRing::Mutable(CordRepRing* rep, size_t extra) { } Span<char> CordRepRing::GetAppendBuffer(size_t size) { - assert(refcount.IsMutable()); + assert(refcount.IsMutable()); index_type back = retreat(tail_); CordRep* child = entry_child(back); - if (child->tag >= FLAT && child->refcount.IsMutable()) { + if (child->tag >= FLAT && child->refcount.IsMutable()) { size_t capacity = child->flat()->Capacity(); pos_type end_pos = entry_end_pos(back); size_t data_offset = entry_data_offset(back); @@ -312,10 +312,10 @@ Span<char> CordRepRing::GetAppendBuffer(size_t size) { } Span<char> CordRepRing::GetPrependBuffer(size_t size) { - assert(refcount.IsMutable()); + assert(refcount.IsMutable()); CordRep* child = entry_child(head_); size_t data_offset = entry_data_offset(head_); - if (data_offset && child->refcount.IsMutable() && child->tag >= FLAT) { + if (data_offset && child->refcount.IsMutable() && child->tag >= FLAT) { size_t n = (std::min)(data_offset, size); this->length += n; begin_pos_ -= n; @@ -327,12 +327,12 @@ Span<char> CordRepRing::GetPrependBuffer(size_t size) { } CordRepRing* CordRepRing::CreateFromLeaf(CordRep* child, size_t offset, - size_t len, size_t extra) { + size_t len, size_t extra) { CordRepRing* rep = CordRepRing::New(1, extra); rep->head_ = 0; rep->tail_ = rep->advance(0); - rep->length = len; - rep->entry_end_pos()[0] = len; + rep->length = len; + rep->entry_end_pos()[0] = len; rep->entry_child()[0] = child; rep->entry_data_offset()[0] = static_cast<offset_type>(offset); return Validate(rep); @@ -340,16 +340,16 @@ CordRepRing* CordRepRing::CreateFromLeaf(CordRep* child, size_t offset, CordRepRing* CordRepRing::CreateSlow(CordRep* child, size_t extra) { CordRepRing* rep = nullptr; - Consume(child, [&](CordRep* child_arg, size_t offset, size_t len) { - if (IsFlatOrExternal(child_arg)) { - rep = rep ? AppendLeaf(rep, child_arg, offset, len) - : CreateFromLeaf(child_arg, offset, len, extra); + Consume(child, [&](CordRep* child_arg, size_t offset, size_t len) { + if (IsFlatOrExternal(child_arg)) { + rep = rep ? AppendLeaf(rep, child_arg, offset, len) + : CreateFromLeaf(child_arg, offset, len, extra); } else if (rep) { - rep = AddRing<AddMode::kAppend>(rep, child_arg->ring(), offset, len); - } else if (offset == 0 && child_arg->length == len) { - rep = Mutable(child_arg->ring(), extra); + rep = AddRing<AddMode::kAppend>(rep, child_arg->ring(), offset, len); + } else if (offset == 0 && child_arg->length == len) { + rep = Mutable(child_arg->ring(), extra); } else { - rep = SubRing(child_arg->ring(), offset, len, extra); + rep = SubRing(child_arg->ring(), offset, len, extra); } }); return Validate(rep, nullptr, __LINE__); @@ -360,7 +360,7 @@ CordRepRing* CordRepRing::Create(CordRep* child, size_t extra) { if (IsFlatOrExternal(child)) { return CreateFromLeaf(child, 0, length, extra); } - if (child->IsRing()) { + if (child->IsRing()) { return Mutable(child->ring(), extra); } return CreateSlow(child, extra); @@ -368,18 +368,18 @@ CordRepRing* CordRepRing::Create(CordRep* child, size_t extra) { template <CordRepRing::AddMode mode> CordRepRing* CordRepRing::AddRing(CordRepRing* rep, CordRepRing* ring, - size_t offset, size_t len) { + size_t offset, size_t len) { assert(offset < ring->length); constexpr bool append = mode == AddMode::kAppend; Position head = ring->Find(offset); - Position tail = ring->FindTail(head.index, offset + len); + Position tail = ring->FindTail(head.index, offset + len); const index_type entries = ring->entries(head.index, tail.index); rep = Mutable(rep, entries); // The delta for making ring[head].end_pos into 'len - offset' const pos_type delta_length = - (append ? rep->begin_pos_ + rep->length : rep->begin_pos_ - len) - + (append ? rep->begin_pos_ + rep->length : rep->begin_pos_ - len) - ring->entry_begin_pos(head.index) - head.offset; // Start filling at `tail`, or `entries` before `head` @@ -420,36 +420,36 @@ CordRepRing* CordRepRing::AddRing(CordRepRing* rep, CordRepRing* ring, } // Commit changes - rep->length += len; + rep->length += len; if (append) { rep->tail_ = filler.pos(); } else { rep->head_ = filler.head(); - rep->begin_pos_ -= len; + rep->begin_pos_ -= len; } return Validate(rep); } CordRepRing* CordRepRing::AppendSlow(CordRepRing* rep, CordRep* child) { - Consume(child, [&rep](CordRep* child_arg, size_t offset, size_t len) { - if (child_arg->IsRing()) { - rep = AddRing<AddMode::kAppend>(rep, child_arg->ring(), offset, len); + Consume(child, [&rep](CordRep* child_arg, size_t offset, size_t len) { + if (child_arg->IsRing()) { + rep = AddRing<AddMode::kAppend>(rep, child_arg->ring(), offset, len); } else { - rep = AppendLeaf(rep, child_arg, offset, len); + rep = AppendLeaf(rep, child_arg, offset, len); } }); return rep; } CordRepRing* CordRepRing::AppendLeaf(CordRepRing* rep, CordRep* child, - size_t offset, size_t len) { + size_t offset, size_t len) { rep = Mutable(rep, 1); index_type back = rep->tail_; const pos_type begin_pos = rep->begin_pos_ + rep->length; rep->tail_ = rep->advance(rep->tail_); - rep->length += len; - rep->entry_end_pos()[back] = begin_pos + len; + rep->length += len; + rep->entry_end_pos()[back] = begin_pos + len; rep->entry_child()[back] = child; rep->entry_data_offset()[back] = static_cast<offset_type>(offset); return Validate(rep, nullptr, __LINE__); @@ -460,31 +460,31 @@ CordRepRing* CordRepRing::Append(CordRepRing* rep, CordRep* child) { if (IsFlatOrExternal(child)) { return AppendLeaf(rep, child, 0, length); } - if (child->IsRing()) { + if (child->IsRing()) { return AddRing<AddMode::kAppend>(rep, child->ring(), 0, length); } return AppendSlow(rep, child); } CordRepRing* CordRepRing::PrependSlow(CordRepRing* rep, CordRep* child) { - ReverseConsume(child, [&](CordRep* child_arg, size_t offset, size_t len) { - if (IsFlatOrExternal(child_arg)) { - rep = PrependLeaf(rep, child_arg, offset, len); + ReverseConsume(child, [&](CordRep* child_arg, size_t offset, size_t len) { + if (IsFlatOrExternal(child_arg)) { + rep = PrependLeaf(rep, child_arg, offset, len); } else { - rep = AddRing<AddMode::kPrepend>(rep, child_arg->ring(), offset, len); + rep = AddRing<AddMode::kPrepend>(rep, child_arg->ring(), offset, len); } }); return Validate(rep); } CordRepRing* CordRepRing::PrependLeaf(CordRepRing* rep, CordRep* child, - size_t offset, size_t len) { + size_t offset, size_t len) { rep = Mutable(rep, 1); index_type head = rep->retreat(rep->head_); pos_type end_pos = rep->begin_pos_; rep->head_ = head; - rep->length += len; - rep->begin_pos_ -= len; + rep->length += len; + rep->begin_pos_ -= len; rep->entry_end_pos()[head] = end_pos; rep->entry_child()[head] = child; rep->entry_data_offset()[head] = static_cast<offset_type>(offset); @@ -496,7 +496,7 @@ CordRepRing* CordRepRing::Prepend(CordRepRing* rep, CordRep* child) { if (IsFlatOrExternal(child)) { return PrependLeaf(rep, child, 0, length); } - if (child->IsRing()) { + if (child->IsRing()) { return AddRing<AddMode::kPrepend>(rep, child->ring(), 0, length); } return PrependSlow(rep, child); @@ -504,7 +504,7 @@ CordRepRing* CordRepRing::Prepend(CordRepRing* rep, CordRep* child) { CordRepRing* CordRepRing::Append(CordRepRing* rep, y_absl::string_view data, size_t extra) { - if (rep->refcount.IsMutable()) { + if (rep->refcount.IsMutable()) { Span<char> avail = rep->GetAppendBuffer(data.length()); if (!avail.empty()) { memcpy(avail.data(), data.data(), avail.length()); @@ -538,7 +538,7 @@ CordRepRing* CordRepRing::Append(CordRepRing* rep, y_absl::string_view data, CordRepRing* CordRepRing::Prepend(CordRepRing* rep, y_absl::string_view data, size_t extra) { - if (rep->refcount.IsMutable()) { + if (rep->refcount.IsMutable()) { Span<char> avail = rep->GetPrependBuffer(data.length()); if (!avail.empty()) { const char* tail = data.data() + data.length() - avail.length(); @@ -664,21 +664,21 @@ char CordRepRing::GetCharacter(size_t offset) const { } CordRepRing* CordRepRing::SubRing(CordRepRing* rep, size_t offset, - size_t len, size_t extra) { + size_t len, size_t extra) { assert(offset <= rep->length); - assert(offset <= rep->length - len); + assert(offset <= rep->length - len); - if (len == 0) { + if (len == 0) { CordRep::Unref(rep); return nullptr; } // Find position of first byte Position head = rep->Find(offset); - Position tail = rep->FindTail(head.index, offset + len); + Position tail = rep->FindTail(head.index, offset + len); const size_t new_entries = rep->entries(head.index, tail.index); - if (rep->refcount.IsMutable() && extra <= (rep->capacity() - new_entries)) { + if (rep->refcount.IsMutable() && extra <= (rep->capacity() - new_entries)) { // We adopt a privately owned rep and no extra entries needed. if (head.index != rep->head_) UnrefEntries(rep, rep->head_, head.index); if (tail.index != rep->tail_) UnrefEntries(rep, tail.index, rep->tail_); @@ -692,7 +692,7 @@ CordRepRing* CordRepRing::SubRing(CordRepRing* rep, size_t offset, } // Adjust begin_pos and length - rep->length = len; + rep->length = len; rep->begin_pos_ += offset; // Adjust head and tail blocks @@ -715,7 +715,7 @@ CordRepRing* CordRepRing::RemovePrefix(CordRepRing* rep, size_t len, } Position head = rep->Find(len); - if (rep->refcount.IsMutable()) { + if (rep->refcount.IsMutable()) { if (head.index != rep->head_) UnrefEntries(rep, rep->head_, head.index); rep->head_ = head.index; } else { @@ -745,7 +745,7 @@ CordRepRing* CordRepRing::RemoveSuffix(CordRepRing* rep, size_t len, } Position tail = rep->FindTail(rep->length - len); - if (rep->refcount.IsMutable()) { + if (rep->refcount.IsMutable()) { // We adopt a privately owned rep, scrub. if (tail.index != rep->tail_) UnrefEntries(rep, tail.index, rep->tail_); rep->tail_ = tail.index; diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_ring.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_ring.h index 5f9784d8da..30018aa3d5 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_ring.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_ring.h @@ -201,23 +201,23 @@ class CordRepRing : public CordRep { // referencing up to `size` capacity directly before the existing data. Span<char> GetPrependBuffer(size_t size); - // Returns a cord ring buffer containing `len` bytes of data starting at + // Returns a cord ring buffer containing `len` bytes of data starting at // `offset`. If the input is not shared, this function will remove all head // and tail child nodes outside of the requested range, and adjust the new // head and tail nodes as required. If the input is shared, this function // returns a new instance sharing some or all of the nodes from the input. - static CordRepRing* SubRing(CordRepRing* r, size_t offset, size_t len, + static CordRepRing* SubRing(CordRepRing* r, size_t offset, size_t len, size_t extra = 0); - // Returns a cord ring buffer with the first `len` bytes removed. + // Returns a cord ring buffer with the first `len` bytes removed. // If the input is not shared, this function will remove all head child nodes // fully inside the first `length` bytes, and adjust the new head as required. // If the input is shared, this function returns a new instance sharing some // or all of the nodes from the input. - static CordRepRing* RemoveSuffix(CordRepRing* r, size_t len, + static CordRepRing* RemoveSuffix(CordRepRing* r, size_t len, size_t extra = 0); - // Returns a cord ring buffer with the last `len` bytes removed. + // Returns a cord ring buffer with the last `len` bytes removed. // If the input is not shared, this function will remove all head child nodes // fully inside the first `length` bytes, and adjust the new head as required. // If the input is shared, this function returns a new instance sharing some @@ -228,18 +228,18 @@ class CordRepRing : public CordRep { // Returns the character at `offset`. Requires that `offset < length`. char GetCharacter(size_t offset) const; - // Returns true if this instance manages a single contiguous buffer, in which - // case the (optional) output parameter `fragment` is set. Otherwise, the - // function returns false, and `fragment` is left unchanged. - bool IsFlat(y_absl::string_view* fragment) const; - - // Returns true if the data starting at `offset` with length `len` is - // managed by this instance inside a single contiguous buffer, in which case - // the (optional) output parameter `fragment` is set to the contiguous memory - // starting at offset `offset` with length `length`. Otherwise, the function - // returns false, and `fragment` is left unchanged. - bool IsFlat(size_t offset, size_t len, y_absl::string_view* fragment) const; - + // Returns true if this instance manages a single contiguous buffer, in which + // case the (optional) output parameter `fragment` is set. Otherwise, the + // function returns false, and `fragment` is left unchanged. + bool IsFlat(y_absl::string_view* fragment) const; + + // Returns true if the data starting at `offset` with length `len` is + // managed by this instance inside a single contiguous buffer, in which case + // the (optional) output parameter `fragment` is set to the contiguous memory + // starting at offset `offset` with length `length`. Otherwise, the function + // returns false, and `fragment` is left unchanged. + bool IsFlat(size_t offset, size_t len, y_absl::string_view* fragment) const; + // Testing only: set capacity to requested capacity. void SetCapacityForTesting(size_t capacity); @@ -383,8 +383,8 @@ class CordRepRing : public CordRep { // Destroys the provided ring buffer, decrementing the reference count of all // contained child CordReps. The provided 1\`rep` should have a ref count of - // one (pre decrement destroy call observing `refcount.IsOne()`) or zero - // (post decrement destroy call observing `!refcount.Decrement()`). + // one (pre decrement destroy call observing `refcount.IsOne()`) or zero + // (post decrement destroy call observing `!refcount.Decrement()`). static void Destroy(CordRepRing* rep); // Returns a mutable reference to the logical end position array. @@ -464,10 +464,10 @@ class CordRepRing : public CordRep { size_t length, size_t extra); // Appends or prepends (depending on AddMode) the ring buffer in `ring' to - // `rep` starting at `offset` with length `len`. + // `rep` starting at `offset` with length `len`. template <AddMode mode> static CordRepRing* AddRing(CordRepRing* rep, CordRepRing* ring, - size_t offset, size_t len); + size_t offset, size_t len); // Increases the data offset for entry `index` by `n`. void AddDataOffset(index_type index, size_t n); @@ -570,34 +570,34 @@ inline CordRepRing::Position CordRepRing::FindTail(index_type head, // Now that CordRepRing is defined, we can define CordRep's helper casts: inline CordRepRing* CordRep::ring() { - assert(IsRing()); + assert(IsRing()); return static_cast<CordRepRing*>(this); } inline const CordRepRing* CordRep::ring() const { - assert(IsRing()); + assert(IsRing()); return static_cast<const CordRepRing*>(this); } -inline bool CordRepRing::IsFlat(y_absl::string_view* fragment) const { - if (entries() == 1) { - if (fragment) *fragment = entry_data(head()); - return true; - } - return false; -} - -inline bool CordRepRing::IsFlat(size_t offset, size_t len, - y_absl::string_view* fragment) const { - const Position pos = Find(offset); - const y_absl::string_view data = entry_data(pos.index); - if (data.length() >= len && data.length() - len >= pos.offset) { - if (fragment) *fragment = data.substr(pos.offset, len); - return true; - } - return false; -} - +inline bool CordRepRing::IsFlat(y_absl::string_view* fragment) const { + if (entries() == 1) { + if (fragment) *fragment = entry_data(head()); + return true; + } + return false; +} + +inline bool CordRepRing::IsFlat(size_t offset, size_t len, + y_absl::string_view* fragment) const { + const Position pos = Find(offset); + const y_absl::string_view data = entry_data(pos.index); + if (data.length() >= len && data.length() - len >= pos.offset) { + if (fragment) *fragment = data.substr(pos.offset, len); + return true; + } + return false; +} + std::ostream& operator<<(std::ostream& s, const CordRepRing& rep); } // namespace cord_internal diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_ring_reader.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_ring_reader.h index 3f64d04fae..0ce03abdac 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_ring_reader.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_ring_reader.h @@ -40,10 +40,10 @@ class CordRepRingReader { // The returned value is undefined if this instance is empty. CordRepRing::index_type index() const { return index_; } - // Returns the current node inside the ring buffer for this instance. - // The returned value is undefined if this instance is empty. - CordRep* node() const { return ring_->entry_child(index_); } - + // Returns the current node inside the ring buffer for this instance. + // The returned value is undefined if this instance is empty. + CordRep* node() const { return ring_->entry_child(index_); } + // Returns the length of the referenced ring buffer. // Requires the current instance to be non empty. size_t length() const { diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_test_util.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_test_util.h index 98dcc0d649..3aa041449b 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_test_util.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cord_rep_test_util.h @@ -1,220 +1,220 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_TEST_UTIL_H_ -#define ABSL_STRINGS_INTERNAL_CORD_REP_TEST_UTIL_H_ - -#include <cassert> -#include <memory> -#include <random> -#include <util/generic/string.h> -#include <vector> - -#include "y_absl/base/config.h" -#include "y_absl/base/internal/raw_logging.h" -#include "y_absl/strings/internal/cord_internal.h" -#include "y_absl/strings/internal/cord_rep_btree.h" -#include "y_absl/strings/internal/cord_rep_flat.h" -#include "y_absl/strings/string_view.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace cordrep_testing { - -inline cord_internal::CordRepSubstring* MakeSubstring( - size_t start, size_t len, cord_internal::CordRep* rep) { - auto* sub = new cord_internal::CordRepSubstring; - sub->tag = cord_internal::SUBSTRING; - sub->start = start; - sub->length = len <= 0 ? rep->length - start + len : len; - sub->child = rep; - return sub; -} - -inline cord_internal::CordRepConcat* MakeConcat(cord_internal::CordRep* left, - cord_internal::CordRep* right, - int depth = 0) { - auto* concat = new cord_internal::CordRepConcat; - concat->tag = cord_internal::CONCAT; - concat->length = left->length + right->length; - concat->left = left; - concat->right = right; - concat->set_depth(depth); - return concat; -} - -inline cord_internal::CordRepFlat* MakeFlat(y_absl::string_view value) { - assert(value.length() <= cord_internal::kMaxFlatLength); - auto* flat = cord_internal::CordRepFlat::New(value.length()); - flat->length = value.length(); - memcpy(flat->Data(), value.data(), value.length()); - return flat; -} - -// Creates an external node for testing -inline cord_internal::CordRepExternal* MakeExternal(y_absl::string_view s) { - struct Rep : public cord_internal::CordRepExternal { - TString s; - explicit Rep(y_absl::string_view sv) : s(sv) { - this->tag = cord_internal::EXTERNAL; - this->base = s.data(); - this->length = s.length(); - this->releaser_invoker = [](cord_internal::CordRepExternal* self) { - delete static_cast<Rep*>(self); - }; - } - }; - return new Rep(s); -} - -inline TString CreateRandomString(size_t n) { - y_absl::string_view data = - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789~!@#$%^&*()_+=-<>?:\"{}[]|"; - std::minstd_rand rnd; - std::uniform_int_distribution<size_t> dist(0, data.size() - 1); - TString s(n, ' '); - for (size_t i = 0; i < n; ++i) { - s[i] = data[dist(rnd)]; - } - return s; -} - -// Creates an array of flats from the provided string, chopping -// the provided string up into flats of size `chunk_size` characters -// resulting in roughly `data.size() / chunk_size` total flats. -inline std::vector<cord_internal::CordRep*> CreateFlatsFromString( - y_absl::string_view data, size_t chunk_size) { - assert(chunk_size > 0); - std::vector<cord_internal::CordRep*> flats; - for (y_absl::string_view s = data; !s.empty(); s.remove_prefix(chunk_size)) { - flats.push_back(MakeFlat(s.substr(0, chunk_size))); - } - return flats; -} - -inline cord_internal::CordRepBtree* CordRepBtreeFromFlats( - y_absl::Span<cord_internal::CordRep* const> flats) { - assert(!flats.empty()); - auto* node = cord_internal::CordRepBtree::Create(flats[0]); - for (size_t i = 1; i < flats.size(); ++i) { - node = cord_internal::CordRepBtree::Append(node, flats[i]); - } - return node; -} - -template <typename Fn> -inline void CordVisitReps(cord_internal::CordRep* rep, Fn&& fn) { - fn(rep); - while (rep->tag == cord_internal::SUBSTRING) { - rep = rep->substring()->child; - fn(rep); - } - if (rep->tag == cord_internal::BTREE) { - for (cord_internal::CordRep* edge : rep->btree()->Edges()) { - CordVisitReps(edge, fn); - } - } else if (rep->tag == cord_internal::CONCAT) { - CordVisitReps(rep->concat()->left, fn); - CordVisitReps(rep->concat()->right, fn); - } -} - -template <typename Predicate> -inline std::vector<cord_internal::CordRep*> CordCollectRepsIf( - Predicate&& predicate, cord_internal::CordRep* rep) { - std::vector<cord_internal::CordRep*> reps; - CordVisitReps(rep, [&reps, &predicate](cord_internal::CordRep* rep) { - if (predicate(rep)) reps.push_back(rep); - }); - return reps; -} - -inline std::vector<cord_internal::CordRep*> CordCollectReps( - cord_internal::CordRep* rep) { - std::vector<cord_internal::CordRep*> reps; - auto fn = [&reps](cord_internal::CordRep* rep) { reps.push_back(rep); }; - CordVisitReps(rep, fn); - return reps; -} - -inline void CordToString(cord_internal::CordRep* rep, TString& s) { - size_t offset = 0; - size_t length = rep->length; - while (rep->tag == cord_internal::SUBSTRING) { - offset += rep->substring()->start; - rep = rep->substring()->child; - } - if (rep->tag == cord_internal::BTREE) { - for (cord_internal::CordRep* edge : rep->btree()->Edges()) { - CordToString(edge, s); - } - } else if (rep->tag >= cord_internal::FLAT) { - s.append(rep->flat()->Data() + offset, length); - } else if (rep->tag == cord_internal::EXTERNAL) { - s.append(rep->external()->base + offset, length); - } else { - ABSL_RAW_LOG(FATAL, "Unsupported tag %d", rep->tag); - } -} - -inline TString CordToString(cord_internal::CordRep* rep) { - TString s; - s.reserve(rep->length); - CordToString(rep, s); - return s; -} - -// RAII Helper class to automatically unref reps on destruction. -class AutoUnref { - public: - ~AutoUnref() { - for (CordRep* rep : unrefs_) CordRep::Unref(rep); - } - - // Adds `rep` to the list of reps to be unreffed at destruction. - template <typename CordRepType> - CordRepType* Add(CordRepType* rep) { - unrefs_.push_back(rep); - return rep; - } - - // Increments the reference count of `rep` by one, and adds it to - // the list of reps to be unreffed at destruction. - template <typename CordRepType> - CordRepType* Ref(CordRepType* rep) { - unrefs_.push_back(CordRep::Ref(rep)); - return rep; - } - - // Increments the reference count of `rep` by one if `condition` is true, - // and adds it to the list of reps to be unreffed at destruction. - template <typename CordRepType> - CordRepType* RefIf(bool condition, CordRepType* rep) { - if (condition) unrefs_.push_back(CordRep::Ref(rep)); - return rep; - } - - private: - using CordRep = y_absl::cord_internal::CordRep; - - std::vector<CordRep*> unrefs_; -}; - -} // namespace cordrep_testing -ABSL_NAMESPACE_END -} // namespace y_absl - -#endif // ABSL_STRINGS_INTERNAL_CORD_REP_TEST_UTIL_H_ +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_TEST_UTIL_H_ +#define ABSL_STRINGS_INTERNAL_CORD_REP_TEST_UTIL_H_ + +#include <cassert> +#include <memory> +#include <random> +#include <util/generic/string.h> +#include <vector> + +#include "y_absl/base/config.h" +#include "y_absl/base/internal/raw_logging.h" +#include "y_absl/strings/internal/cord_internal.h" +#include "y_absl/strings/internal/cord_rep_btree.h" +#include "y_absl/strings/internal/cord_rep_flat.h" +#include "y_absl/strings/string_view.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace cordrep_testing { + +inline cord_internal::CordRepSubstring* MakeSubstring( + size_t start, size_t len, cord_internal::CordRep* rep) { + auto* sub = new cord_internal::CordRepSubstring; + sub->tag = cord_internal::SUBSTRING; + sub->start = start; + sub->length = len <= 0 ? rep->length - start + len : len; + sub->child = rep; + return sub; +} + +inline cord_internal::CordRepConcat* MakeConcat(cord_internal::CordRep* left, + cord_internal::CordRep* right, + int depth = 0) { + auto* concat = new cord_internal::CordRepConcat; + concat->tag = cord_internal::CONCAT; + concat->length = left->length + right->length; + concat->left = left; + concat->right = right; + concat->set_depth(depth); + return concat; +} + +inline cord_internal::CordRepFlat* MakeFlat(y_absl::string_view value) { + assert(value.length() <= cord_internal::kMaxFlatLength); + auto* flat = cord_internal::CordRepFlat::New(value.length()); + flat->length = value.length(); + memcpy(flat->Data(), value.data(), value.length()); + return flat; +} + +// Creates an external node for testing +inline cord_internal::CordRepExternal* MakeExternal(y_absl::string_view s) { + struct Rep : public cord_internal::CordRepExternal { + TString s; + explicit Rep(y_absl::string_view sv) : s(sv) { + this->tag = cord_internal::EXTERNAL; + this->base = s.data(); + this->length = s.length(); + this->releaser_invoker = [](cord_internal::CordRepExternal* self) { + delete static_cast<Rep*>(self); + }; + } + }; + return new Rep(s); +} + +inline TString CreateRandomString(size_t n) { + y_absl::string_view data = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789~!@#$%^&*()_+=-<>?:\"{}[]|"; + std::minstd_rand rnd; + std::uniform_int_distribution<size_t> dist(0, data.size() - 1); + TString s(n, ' '); + for (size_t i = 0; i < n; ++i) { + s[i] = data[dist(rnd)]; + } + return s; +} + +// Creates an array of flats from the provided string, chopping +// the provided string up into flats of size `chunk_size` characters +// resulting in roughly `data.size() / chunk_size` total flats. +inline std::vector<cord_internal::CordRep*> CreateFlatsFromString( + y_absl::string_view data, size_t chunk_size) { + assert(chunk_size > 0); + std::vector<cord_internal::CordRep*> flats; + for (y_absl::string_view s = data; !s.empty(); s.remove_prefix(chunk_size)) { + flats.push_back(MakeFlat(s.substr(0, chunk_size))); + } + return flats; +} + +inline cord_internal::CordRepBtree* CordRepBtreeFromFlats( + y_absl::Span<cord_internal::CordRep* const> flats) { + assert(!flats.empty()); + auto* node = cord_internal::CordRepBtree::Create(flats[0]); + for (size_t i = 1; i < flats.size(); ++i) { + node = cord_internal::CordRepBtree::Append(node, flats[i]); + } + return node; +} + +template <typename Fn> +inline void CordVisitReps(cord_internal::CordRep* rep, Fn&& fn) { + fn(rep); + while (rep->tag == cord_internal::SUBSTRING) { + rep = rep->substring()->child; + fn(rep); + } + if (rep->tag == cord_internal::BTREE) { + for (cord_internal::CordRep* edge : rep->btree()->Edges()) { + CordVisitReps(edge, fn); + } + } else if (rep->tag == cord_internal::CONCAT) { + CordVisitReps(rep->concat()->left, fn); + CordVisitReps(rep->concat()->right, fn); + } +} + +template <typename Predicate> +inline std::vector<cord_internal::CordRep*> CordCollectRepsIf( + Predicate&& predicate, cord_internal::CordRep* rep) { + std::vector<cord_internal::CordRep*> reps; + CordVisitReps(rep, [&reps, &predicate](cord_internal::CordRep* rep) { + if (predicate(rep)) reps.push_back(rep); + }); + return reps; +} + +inline std::vector<cord_internal::CordRep*> CordCollectReps( + cord_internal::CordRep* rep) { + std::vector<cord_internal::CordRep*> reps; + auto fn = [&reps](cord_internal::CordRep* rep) { reps.push_back(rep); }; + CordVisitReps(rep, fn); + return reps; +} + +inline void CordToString(cord_internal::CordRep* rep, TString& s) { + size_t offset = 0; + size_t length = rep->length; + while (rep->tag == cord_internal::SUBSTRING) { + offset += rep->substring()->start; + rep = rep->substring()->child; + } + if (rep->tag == cord_internal::BTREE) { + for (cord_internal::CordRep* edge : rep->btree()->Edges()) { + CordToString(edge, s); + } + } else if (rep->tag >= cord_internal::FLAT) { + s.append(rep->flat()->Data() + offset, length); + } else if (rep->tag == cord_internal::EXTERNAL) { + s.append(rep->external()->base + offset, length); + } else { + ABSL_RAW_LOG(FATAL, "Unsupported tag %d", rep->tag); + } +} + +inline TString CordToString(cord_internal::CordRep* rep) { + TString s; + s.reserve(rep->length); + CordToString(rep, s); + return s; +} + +// RAII Helper class to automatically unref reps on destruction. +class AutoUnref { + public: + ~AutoUnref() { + for (CordRep* rep : unrefs_) CordRep::Unref(rep); + } + + // Adds `rep` to the list of reps to be unreffed at destruction. + template <typename CordRepType> + CordRepType* Add(CordRepType* rep) { + unrefs_.push_back(rep); + return rep; + } + + // Increments the reference count of `rep` by one, and adds it to + // the list of reps to be unreffed at destruction. + template <typename CordRepType> + CordRepType* Ref(CordRepType* rep) { + unrefs_.push_back(CordRep::Ref(rep)); + return rep; + } + + // Increments the reference count of `rep` by one if `condition` is true, + // and adds it to the list of reps to be unreffed at destruction. + template <typename CordRepType> + CordRepType* RefIf(bool condition, CordRepType* rep) { + if (condition) unrefs_.push_back(CordRep::Ref(rep)); + return rep; + } + + private: + using CordRep = y_absl::cord_internal::CordRep; + + std::vector<CordRep*> unrefs_; +}; + +} // namespace cordrep_testing +ABSL_NAMESPACE_END +} // namespace y_absl + +#endif // ABSL_STRINGS_INTERNAL_CORD_REP_TEST_UTIL_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions.cc index e9936f22fe..843641c779 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions.cc @@ -1,96 +1,96 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "y_absl/strings/internal/cordz_functions.h" - -#include <atomic> -#include <cmath> -#include <limits> -#include <random> - -#include "y_absl/base/attributes.h" -#include "y_absl/base/config.h" -#include "y_absl/base/internal/raw_logging.h" -#include "y_absl/profiling/internal/exponential_biased.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { -namespace { - -// The average interval until the next sample. A value of 0 disables profiling -// while a value of 1 will profile all Cords. -std::atomic<int> g_cordz_mean_interval(50000); - -} // namespace - -#ifdef ABSL_INTERNAL_CORDZ_ENABLED - -// Special negative 'not initialized' per thread value for cordz_next_sample. -static constexpr int64_t kInitCordzNextSample = -1; - -ABSL_CONST_INIT thread_local int64_t cordz_next_sample = kInitCordzNextSample; - -// kIntervalIfDisabled is the number of profile-eligible events need to occur -// before the code will confirm that cordz is still disabled. -constexpr int64_t kIntervalIfDisabled = 1 << 16; - -ABSL_ATTRIBUTE_NOINLINE bool cordz_should_profile_slow() { - - thread_local y_absl::profiling_internal::ExponentialBiased - exponential_biased_generator; - int32_t mean_interval = get_cordz_mean_interval(); - - // Check if we disabled profiling. If so, set the next sample to a "large" - // number to minimize the overhead of the should_profile codepath. - if (mean_interval <= 0) { - cordz_next_sample = kIntervalIfDisabled; - return false; - } - - // Check if we're always sampling. - if (mean_interval == 1) { - cordz_next_sample = 1; - return true; - } - - if (cordz_next_sample <= 0) { - // If first check on current thread, check cordz_should_profile() - // again using the created (initial) stride in cordz_next_sample. - const bool initialized = cordz_next_sample != kInitCordzNextSample; - cordz_next_sample = exponential_biased_generator.GetStride(mean_interval); - return initialized || cordz_should_profile(); - } - - --cordz_next_sample; - return false; -} - -void cordz_set_next_sample_for_testing(int64_t next_sample) { - cordz_next_sample = next_sample; -} - -#endif // ABSL_INTERNAL_CORDZ_ENABLED - -int32_t get_cordz_mean_interval() { - return g_cordz_mean_interval.load(std::memory_order_acquire); -} - -void set_cordz_mean_interval(int32_t mean_interval) { - g_cordz_mean_interval.store(mean_interval, std::memory_order_release); -} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace y_absl +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "y_absl/strings/internal/cordz_functions.h" + +#include <atomic> +#include <cmath> +#include <limits> +#include <random> + +#include "y_absl/base/attributes.h" +#include "y_absl/base/config.h" +#include "y_absl/base/internal/raw_logging.h" +#include "y_absl/profiling/internal/exponential_biased.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { +namespace { + +// The average interval until the next sample. A value of 0 disables profiling +// while a value of 1 will profile all Cords. +std::atomic<int> g_cordz_mean_interval(50000); + +} // namespace + +#ifdef ABSL_INTERNAL_CORDZ_ENABLED + +// Special negative 'not initialized' per thread value for cordz_next_sample. +static constexpr int64_t kInitCordzNextSample = -1; + +ABSL_CONST_INIT thread_local int64_t cordz_next_sample = kInitCordzNextSample; + +// kIntervalIfDisabled is the number of profile-eligible events need to occur +// before the code will confirm that cordz is still disabled. +constexpr int64_t kIntervalIfDisabled = 1 << 16; + +ABSL_ATTRIBUTE_NOINLINE bool cordz_should_profile_slow() { + + thread_local y_absl::profiling_internal::ExponentialBiased + exponential_biased_generator; + int32_t mean_interval = get_cordz_mean_interval(); + + // Check if we disabled profiling. If so, set the next sample to a "large" + // number to minimize the overhead of the should_profile codepath. + if (mean_interval <= 0) { + cordz_next_sample = kIntervalIfDisabled; + return false; + } + + // Check if we're always sampling. + if (mean_interval == 1) { + cordz_next_sample = 1; + return true; + } + + if (cordz_next_sample <= 0) { + // If first check on current thread, check cordz_should_profile() + // again using the created (initial) stride in cordz_next_sample. + const bool initialized = cordz_next_sample != kInitCordzNextSample; + cordz_next_sample = exponential_biased_generator.GetStride(mean_interval); + return initialized || cordz_should_profile(); + } + + --cordz_next_sample; + return false; +} + +void cordz_set_next_sample_for_testing(int64_t next_sample) { + cordz_next_sample = next_sample; +} + +#endif // ABSL_INTERNAL_CORDZ_ENABLED + +int32_t get_cordz_mean_interval() { + return g_cordz_mean_interval.load(std::memory_order_acquire); +} + +void set_cordz_mean_interval(int32_t mean_interval) { + g_cordz_mean_interval.store(mean_interval, std::memory_order_release); +} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions.h index 802efaa976..b3d70b8316 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions.h @@ -1,85 +1,85 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_CORDZ_FUNCTIONS_H_ -#define ABSL_STRINGS_CORDZ_FUNCTIONS_H_ - -#include <stdint.h> - -#include "y_absl/base/attributes.h" -#include "y_absl/base/config.h" -#include "y_absl/base/optimization.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -// Returns the current sample rate. This represents the average interval -// between samples. -int32_t get_cordz_mean_interval(); - -// Sets the sample rate with the average interval between samples. -void set_cordz_mean_interval(int32_t mean_interval); - -// Enable cordz unless any of the following applies: -// - no thread local support -// - MSVC build -// - Android build -// - Apple build -// - DLL build -// Hashtablez is turned off completely in opensource builds. -// MSVC's static atomics are dynamically initialized in debug mode, which breaks -// sampling. -#if defined(ABSL_HAVE_THREAD_LOCAL) && !defined(_MSC_VER) && \ - !defined(ABSL_BUILD_DLL) && !defined(ABSL_CONSUME_DLL) && \ - !defined(__ANDROID__) && !defined(__APPLE__) -#define ABSL_INTERNAL_CORDZ_ENABLED 1 -#endif - -#ifdef ABSL_INTERNAL_CORDZ_ENABLED - -// cordz_next_sample is the number of events until the next sample event. If -// the value is 1 or less, the code will check on the next event if cordz is -// enabled, and if so, will sample the Cord. cordz is only enabled when we can -// use thread locals. -ABSL_CONST_INIT extern thread_local int64_t cordz_next_sample; - -// Determines if the next sample should be profiled. If it is, the value pointed -// at by next_sample will be set with the interval until the next sample. -bool cordz_should_profile_slow(); - -// Returns true if the next cord should be sampled. -inline bool cordz_should_profile() { - if (ABSL_PREDICT_TRUE(cordz_next_sample > 1)) { - cordz_next_sample--; - return false; - } - return cordz_should_profile_slow(); -} - -// Sets the interval until the next sample (for testing only) -void cordz_set_next_sample_for_testing(int64_t next_sample); - -#else // ABSL_INTERNAL_CORDZ_ENABLED - -inline bool cordz_should_profile() { return false; } -inline void cordz_set_next_sample_for_testing(int64_t) {} - -#endif // ABSL_INTERNAL_CORDZ_ENABLED - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace y_absl - -#endif // ABSL_STRINGS_CORDZ_FUNCTIONS_H_ +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_CORDZ_FUNCTIONS_H_ +#define ABSL_STRINGS_CORDZ_FUNCTIONS_H_ + +#include <stdint.h> + +#include "y_absl/base/attributes.h" +#include "y_absl/base/config.h" +#include "y_absl/base/optimization.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +// Returns the current sample rate. This represents the average interval +// between samples. +int32_t get_cordz_mean_interval(); + +// Sets the sample rate with the average interval between samples. +void set_cordz_mean_interval(int32_t mean_interval); + +// Enable cordz unless any of the following applies: +// - no thread local support +// - MSVC build +// - Android build +// - Apple build +// - DLL build +// Hashtablez is turned off completely in opensource builds. +// MSVC's static atomics are dynamically initialized in debug mode, which breaks +// sampling. +#if defined(ABSL_HAVE_THREAD_LOCAL) && !defined(_MSC_VER) && \ + !defined(ABSL_BUILD_DLL) && !defined(ABSL_CONSUME_DLL) && \ + !defined(__ANDROID__) && !defined(__APPLE__) +#define ABSL_INTERNAL_CORDZ_ENABLED 1 +#endif + +#ifdef ABSL_INTERNAL_CORDZ_ENABLED + +// cordz_next_sample is the number of events until the next sample event. If +// the value is 1 or less, the code will check on the next event if cordz is +// enabled, and if so, will sample the Cord. cordz is only enabled when we can +// use thread locals. +ABSL_CONST_INIT extern thread_local int64_t cordz_next_sample; + +// Determines if the next sample should be profiled. If it is, the value pointed +// at by next_sample will be set with the interval until the next sample. +bool cordz_should_profile_slow(); + +// Returns true if the next cord should be sampled. +inline bool cordz_should_profile() { + if (ABSL_PREDICT_TRUE(cordz_next_sample > 1)) { + cordz_next_sample--; + return false; + } + return cordz_should_profile_slow(); +} + +// Sets the interval until the next sample (for testing only) +void cordz_set_next_sample_for_testing(int64_t next_sample); + +#else // ABSL_INTERNAL_CORDZ_ENABLED + +inline bool cordz_should_profile() { return false; } +inline void cordz_set_next_sample_for_testing(int64_t) {} + +#endif // ABSL_INTERNAL_CORDZ_ENABLED + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace y_absl + +#endif // ABSL_STRINGS_CORDZ_FUNCTIONS_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions/ya.make index 06e99346da..7afa600674 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions/ya.make @@ -11,22 +11,22 @@ OWNER( LICENSE(Apache-2.0) -PEERDIR( - contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/raw_logging - contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity - contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased -) - +PEERDIR( + contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/raw_logging + contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity + contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased +) + ADDINCL( GLOBAL contrib/restricted/abseil-cpp-tstring ) NO_COMPILER_WARNINGS() -SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal) +SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal) SRCS( - cordz_functions.cc + cordz_functions.cc ) END() diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle.cc index 707c6d2a9b..cf9903d4bb 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle.cc @@ -1,139 +1,139 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#include "y_absl/strings/internal/cordz_handle.h" - -#include <atomic> - -#include "y_absl/base/internal/raw_logging.h" // For ABSL_RAW_CHECK -#include "y_absl/base/internal/spinlock.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -using ::y_absl::base_internal::SpinLockHolder; - -ABSL_CONST_INIT CordzHandle::Queue CordzHandle::global_queue_(y_absl::kConstInit); - -CordzHandle::CordzHandle(bool is_snapshot) : is_snapshot_(is_snapshot) { - if (is_snapshot) { - SpinLockHolder lock(&queue_->mutex); - CordzHandle* dq_tail = queue_->dq_tail.load(std::memory_order_acquire); - if (dq_tail != nullptr) { - dq_prev_ = dq_tail; - dq_tail->dq_next_ = this; - } - queue_->dq_tail.store(this, std::memory_order_release); - } -} - -CordzHandle::~CordzHandle() { - ODRCheck(); - if (is_snapshot_) { - std::vector<CordzHandle*> to_delete; - { - SpinLockHolder lock(&queue_->mutex); - CordzHandle* next = dq_next_; - if (dq_prev_ == nullptr) { - // We were head of the queue, delete every CordzHandle until we reach - // either the end of the list, or a snapshot handle. - while (next && !next->is_snapshot_) { - to_delete.push_back(next); - next = next->dq_next_; - } - } else { - // Another CordzHandle existed before this one, don't delete anything. - dq_prev_->dq_next_ = next; - } - if (next) { - next->dq_prev_ = dq_prev_; - } else { - queue_->dq_tail.store(dq_prev_, std::memory_order_release); - } - } - for (CordzHandle* handle : to_delete) { - delete handle; - } - } -} - -bool CordzHandle::SafeToDelete() const { - return is_snapshot_ || queue_->IsEmpty(); -} - -void CordzHandle::Delete(CordzHandle* handle) { - assert(handle); - if (handle) { - handle->ODRCheck(); - Queue* const queue = handle->queue_; - if (!handle->SafeToDelete()) { - SpinLockHolder lock(&queue->mutex); - CordzHandle* dq_tail = queue->dq_tail.load(std::memory_order_acquire); - if (dq_tail != nullptr) { - handle->dq_prev_ = dq_tail; - dq_tail->dq_next_ = handle; - queue->dq_tail.store(handle, std::memory_order_release); - return; - } - } - delete handle; - } -} - -std::vector<const CordzHandle*> CordzHandle::DiagnosticsGetDeleteQueue() { - std::vector<const CordzHandle*> handles; - SpinLockHolder lock(&global_queue_.mutex); - CordzHandle* dq_tail = global_queue_.dq_tail.load(std::memory_order_acquire); - for (const CordzHandle* p = dq_tail; p; p = p->dq_prev_) { - handles.push_back(p); - } - return handles; -} - -bool CordzHandle::DiagnosticsHandleIsSafeToInspect( - const CordzHandle* handle) const { - ODRCheck(); - if (!is_snapshot_) return false; - if (handle == nullptr) return true; - if (handle->is_snapshot_) return false; - bool snapshot_found = false; - SpinLockHolder lock(&queue_->mutex); - for (const CordzHandle* p = queue_->dq_tail; p; p = p->dq_prev_) { - if (p == handle) return !snapshot_found; - if (p == this) snapshot_found = true; - } - ABSL_ASSERT(snapshot_found); // Assert that 'this' is in delete queue. - return true; -} - -std::vector<const CordzHandle*> -CordzHandle::DiagnosticsGetSafeToInspectDeletedHandles() { - ODRCheck(); - std::vector<const CordzHandle*> handles; - if (!is_snapshot()) { - return handles; - } - - SpinLockHolder lock(&queue_->mutex); - for (const CordzHandle* p = dq_next_; p != nullptr; p = p->dq_next_) { - if (!p->is_snapshot()) { - handles.push_back(p); - } - } - return handles; -} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace y_absl +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "y_absl/strings/internal/cordz_handle.h" + +#include <atomic> + +#include "y_absl/base/internal/raw_logging.h" // For ABSL_RAW_CHECK +#include "y_absl/base/internal/spinlock.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +using ::y_absl::base_internal::SpinLockHolder; + +ABSL_CONST_INIT CordzHandle::Queue CordzHandle::global_queue_(y_absl::kConstInit); + +CordzHandle::CordzHandle(bool is_snapshot) : is_snapshot_(is_snapshot) { + if (is_snapshot) { + SpinLockHolder lock(&queue_->mutex); + CordzHandle* dq_tail = queue_->dq_tail.load(std::memory_order_acquire); + if (dq_tail != nullptr) { + dq_prev_ = dq_tail; + dq_tail->dq_next_ = this; + } + queue_->dq_tail.store(this, std::memory_order_release); + } +} + +CordzHandle::~CordzHandle() { + ODRCheck(); + if (is_snapshot_) { + std::vector<CordzHandle*> to_delete; + { + SpinLockHolder lock(&queue_->mutex); + CordzHandle* next = dq_next_; + if (dq_prev_ == nullptr) { + // We were head of the queue, delete every CordzHandle until we reach + // either the end of the list, or a snapshot handle. + while (next && !next->is_snapshot_) { + to_delete.push_back(next); + next = next->dq_next_; + } + } else { + // Another CordzHandle existed before this one, don't delete anything. + dq_prev_->dq_next_ = next; + } + if (next) { + next->dq_prev_ = dq_prev_; + } else { + queue_->dq_tail.store(dq_prev_, std::memory_order_release); + } + } + for (CordzHandle* handle : to_delete) { + delete handle; + } + } +} + +bool CordzHandle::SafeToDelete() const { + return is_snapshot_ || queue_->IsEmpty(); +} + +void CordzHandle::Delete(CordzHandle* handle) { + assert(handle); + if (handle) { + handle->ODRCheck(); + Queue* const queue = handle->queue_; + if (!handle->SafeToDelete()) { + SpinLockHolder lock(&queue->mutex); + CordzHandle* dq_tail = queue->dq_tail.load(std::memory_order_acquire); + if (dq_tail != nullptr) { + handle->dq_prev_ = dq_tail; + dq_tail->dq_next_ = handle; + queue->dq_tail.store(handle, std::memory_order_release); + return; + } + } + delete handle; + } +} + +std::vector<const CordzHandle*> CordzHandle::DiagnosticsGetDeleteQueue() { + std::vector<const CordzHandle*> handles; + SpinLockHolder lock(&global_queue_.mutex); + CordzHandle* dq_tail = global_queue_.dq_tail.load(std::memory_order_acquire); + for (const CordzHandle* p = dq_tail; p; p = p->dq_prev_) { + handles.push_back(p); + } + return handles; +} + +bool CordzHandle::DiagnosticsHandleIsSafeToInspect( + const CordzHandle* handle) const { + ODRCheck(); + if (!is_snapshot_) return false; + if (handle == nullptr) return true; + if (handle->is_snapshot_) return false; + bool snapshot_found = false; + SpinLockHolder lock(&queue_->mutex); + for (const CordzHandle* p = queue_->dq_tail; p; p = p->dq_prev_) { + if (p == handle) return !snapshot_found; + if (p == this) snapshot_found = true; + } + ABSL_ASSERT(snapshot_found); // Assert that 'this' is in delete queue. + return true; +} + +std::vector<const CordzHandle*> +CordzHandle::DiagnosticsGetSafeToInspectDeletedHandles() { + ODRCheck(); + std::vector<const CordzHandle*> handles; + if (!is_snapshot()) { + return handles; + } + + SpinLockHolder lock(&queue_->mutex); + for (const CordzHandle* p = dq_next_; p != nullptr; p = p->dq_next_) { + if (!p->is_snapshot()) { + handles.push_back(p); + } + } + return handles; +} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle.h index f181bc7d6b..4c79308947 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle.h @@ -1,131 +1,131 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_CORDZ_HANDLE_H_ -#define ABSL_STRINGS_CORDZ_HANDLE_H_ - -#include <atomic> -#include <vector> - -#include "y_absl/base/config.h" -#include "y_absl/base/internal/raw_logging.h" -#include "y_absl/base/internal/spinlock.h" -#include "y_absl/synchronization/mutex.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -// This base class allows multiple types of object (CordzInfo and -// CordzSampleToken) to exist simultaneously on the delete queue (pointed to by -// global_dq_tail and traversed using dq_prev_ and dq_next_). The -// delete queue guarantees that once a profiler creates a CordzSampleToken and -// has gained visibility into a CordzInfo object, that CordzInfo object will not -// be deleted prematurely. This allows the profiler to inspect all CordzInfo -// objects that are alive without needing to hold a global lock. -class CordzHandle { - public: - CordzHandle() : CordzHandle(false) {} - - bool is_snapshot() const { return is_snapshot_; } - - // Returns true if this instance is safe to be deleted because it is either a - // snapshot, which is always safe to delete, or not included in the global - // delete queue and thus not included in any snapshot. - // Callers are responsible for making sure this instance can not be newly - // discovered by other threads. For example, CordzInfo instances first de-list - // themselves from the global CordzInfo list before determining if they are - // safe to be deleted directly. - // If SafeToDelete returns false, callers MUST use the Delete() method to - // safely queue CordzHandle instances for deletion. - bool SafeToDelete() const; - - // Deletes the provided instance, or puts it on the delete queue to be deleted - // once there are no more sample tokens (snapshot) instances potentially - // referencing the instance. `handle` should not be null. - static void Delete(CordzHandle* handle); - - // Returns the current entries in the delete queue in LIFO order. - static std::vector<const CordzHandle*> DiagnosticsGetDeleteQueue(); - - // Returns true if the provided handle is nullptr or guarded by this handle. - // Since the CordzSnapshot token is itself a CordzHandle, this method will - // allow tests to check if that token is keeping an arbitrary CordzHandle - // alive. - bool DiagnosticsHandleIsSafeToInspect(const CordzHandle* handle) const; - - // Returns the current entries in the delete queue, in LIFO order, that are - // protected by this. CordzHandle objects are only placed on the delete queue - // after CordzHandle::Delete is called with them as an argument. Only - // CordzHandle objects that are not also CordzSnapshot objects will be - // included in the return vector. For each of the handles in the return - // vector, the earliest that their memory can be freed is when this - // CordzSnapshot object is deleted. - std::vector<const CordzHandle*> DiagnosticsGetSafeToInspectDeletedHandles(); - - protected: - explicit CordzHandle(bool is_snapshot); - virtual ~CordzHandle(); - - private: - // Global queue data. CordzHandle stores a pointer to the global queue - // instance to harden against ODR violations. - struct Queue { - constexpr explicit Queue(y_absl::ConstInitType) - : mutex(y_absl::kConstInit, - y_absl::base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL) {} - - y_absl::base_internal::SpinLock mutex; - std::atomic<CordzHandle*> dq_tail ABSL_GUARDED_BY(mutex){nullptr}; - - // Returns true if this delete queue is empty. This method does not acquire - // the lock, but does a 'load acquire' observation on the delete queue tail. - // It is used inside Delete() to check for the presence of a delete queue - // without holding the lock. The assumption is that the caller is in the - // state of 'being deleted', and can not be newly discovered by a concurrent - // 'being constructed' snapshot instance. Practically, this means that any - // such discovery (`find`, 'first' or 'next', etc) must have proper 'happens - // before / after' semantics and atomic fences. - bool IsEmpty() const ABSL_NO_THREAD_SAFETY_ANALYSIS { - return dq_tail.load(std::memory_order_acquire) == nullptr; - } - }; - - void ODRCheck() const { -#ifndef NDEBUG - ABSL_RAW_CHECK(queue_ == &global_queue_, "ODR violation in Cord"); -#endif - } - - ABSL_CONST_INIT static Queue global_queue_; - Queue* const queue_ = &global_queue_; - const bool is_snapshot_; - - // dq_prev_ and dq_next_ require the global queue mutex to be held. - // Unfortunately we can't use thread annotations such that the thread safety - // analysis understands that queue_ and global_queue_ are one and the same. - CordzHandle* dq_prev_ = nullptr; - CordzHandle* dq_next_ = nullptr; -}; - -class CordzSnapshot : public CordzHandle { - public: - CordzSnapshot() : CordzHandle(true) {} -}; - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace y_absl - -#endif // ABSL_STRINGS_CORDZ_HANDLE_H_ +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_CORDZ_HANDLE_H_ +#define ABSL_STRINGS_CORDZ_HANDLE_H_ + +#include <atomic> +#include <vector> + +#include "y_absl/base/config.h" +#include "y_absl/base/internal/raw_logging.h" +#include "y_absl/base/internal/spinlock.h" +#include "y_absl/synchronization/mutex.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +// This base class allows multiple types of object (CordzInfo and +// CordzSampleToken) to exist simultaneously on the delete queue (pointed to by +// global_dq_tail and traversed using dq_prev_ and dq_next_). The +// delete queue guarantees that once a profiler creates a CordzSampleToken and +// has gained visibility into a CordzInfo object, that CordzInfo object will not +// be deleted prematurely. This allows the profiler to inspect all CordzInfo +// objects that are alive without needing to hold a global lock. +class CordzHandle { + public: + CordzHandle() : CordzHandle(false) {} + + bool is_snapshot() const { return is_snapshot_; } + + // Returns true if this instance is safe to be deleted because it is either a + // snapshot, which is always safe to delete, or not included in the global + // delete queue and thus not included in any snapshot. + // Callers are responsible for making sure this instance can not be newly + // discovered by other threads. For example, CordzInfo instances first de-list + // themselves from the global CordzInfo list before determining if they are + // safe to be deleted directly. + // If SafeToDelete returns false, callers MUST use the Delete() method to + // safely queue CordzHandle instances for deletion. + bool SafeToDelete() const; + + // Deletes the provided instance, or puts it on the delete queue to be deleted + // once there are no more sample tokens (snapshot) instances potentially + // referencing the instance. `handle` should not be null. + static void Delete(CordzHandle* handle); + + // Returns the current entries in the delete queue in LIFO order. + static std::vector<const CordzHandle*> DiagnosticsGetDeleteQueue(); + + // Returns true if the provided handle is nullptr or guarded by this handle. + // Since the CordzSnapshot token is itself a CordzHandle, this method will + // allow tests to check if that token is keeping an arbitrary CordzHandle + // alive. + bool DiagnosticsHandleIsSafeToInspect(const CordzHandle* handle) const; + + // Returns the current entries in the delete queue, in LIFO order, that are + // protected by this. CordzHandle objects are only placed on the delete queue + // after CordzHandle::Delete is called with them as an argument. Only + // CordzHandle objects that are not also CordzSnapshot objects will be + // included in the return vector. For each of the handles in the return + // vector, the earliest that their memory can be freed is when this + // CordzSnapshot object is deleted. + std::vector<const CordzHandle*> DiagnosticsGetSafeToInspectDeletedHandles(); + + protected: + explicit CordzHandle(bool is_snapshot); + virtual ~CordzHandle(); + + private: + // Global queue data. CordzHandle stores a pointer to the global queue + // instance to harden against ODR violations. + struct Queue { + constexpr explicit Queue(y_absl::ConstInitType) + : mutex(y_absl::kConstInit, + y_absl::base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL) {} + + y_absl::base_internal::SpinLock mutex; + std::atomic<CordzHandle*> dq_tail ABSL_GUARDED_BY(mutex){nullptr}; + + // Returns true if this delete queue is empty. This method does not acquire + // the lock, but does a 'load acquire' observation on the delete queue tail. + // It is used inside Delete() to check for the presence of a delete queue + // without holding the lock. The assumption is that the caller is in the + // state of 'being deleted', and can not be newly discovered by a concurrent + // 'being constructed' snapshot instance. Practically, this means that any + // such discovery (`find`, 'first' or 'next', etc) must have proper 'happens + // before / after' semantics and atomic fences. + bool IsEmpty() const ABSL_NO_THREAD_SAFETY_ANALYSIS { + return dq_tail.load(std::memory_order_acquire) == nullptr; + } + }; + + void ODRCheck() const { +#ifndef NDEBUG + ABSL_RAW_CHECK(queue_ == &global_queue_, "ODR violation in Cord"); +#endif + } + + ABSL_CONST_INIT static Queue global_queue_; + Queue* const queue_ = &global_queue_; + const bool is_snapshot_; + + // dq_prev_ and dq_next_ require the global queue mutex to be held. + // Unfortunately we can't use thread annotations such that the thread safety + // analysis understands that queue_ and global_queue_ are one and the same. + CordzHandle* dq_prev_ = nullptr; + CordzHandle* dq_next_ = nullptr; +}; + +class CordzSnapshot : public CordzHandle { + public: + CordzSnapshot() : CordzHandle(true) {} +}; + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace y_absl + +#endif // ABSL_STRINGS_CORDZ_HANDLE_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle/ya.make index e181217139..5c4f81d727 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle/ya.make @@ -13,23 +13,23 @@ LICENSE(Apache-2.0) PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/base - contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/low_level_alloc contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/raw_logging contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/throw_delegate contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity - contrib/restricted/abseil-cpp-tstring/y_absl/debugging - contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace - contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize - contrib/restricted/abseil-cpp-tstring/y_absl/demangle + contrib/restricted/abseil-cpp-tstring/y_absl/debugging + contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace + contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize + contrib/restricted/abseil-cpp-tstring/y_absl/demangle contrib/restricted/abseil-cpp-tstring/y_absl/numeric contrib/restricted/abseil-cpp-tstring/y_absl/strings - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp-tstring/y_absl/synchronization - contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal - contrib/restricted/abseil-cpp-tstring/y_absl/time - contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time - contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp-tstring/y_absl/synchronization + contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal + contrib/restricted/abseil-cpp-tstring/y_absl/time + contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time + contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone ) ADDINCL( @@ -38,10 +38,10 @@ ADDINCL( NO_COMPILER_WARNINGS() -SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal) +SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal) SRCS( - cordz_handle.cc + cordz_handle.cc ) END() diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info.cc index e3849a0b49..c45fff490a 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info.cc @@ -1,445 +1,445 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "y_absl/strings/internal/cordz_info.h" - -#include "y_absl/base/config.h" -#include "y_absl/base/internal/spinlock.h" -#include "y_absl/container/inlined_vector.h" -#include "y_absl/debugging/stacktrace.h" -#include "y_absl/strings/internal/cord_internal.h" -#include "y_absl/strings/internal/cord_rep_btree.h" -#include "y_absl/strings/internal/cord_rep_ring.h" -#include "y_absl/strings/internal/cordz_handle.h" -#include "y_absl/strings/internal/cordz_statistics.h" -#include "y_absl/strings/internal/cordz_update_tracker.h" -#include "y_absl/synchronization/mutex.h" -#include "y_absl/types/span.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -using ::y_absl::base_internal::SpinLockHolder; - -constexpr int CordzInfo::kMaxStackDepth; - -ABSL_CONST_INIT CordzInfo::List CordzInfo::global_list_{y_absl::kConstInit}; - -namespace { - -// CordRepAnalyzer performs the analysis of a cord. -// -// It computes absolute node counts and total memory usage, and an 'estimated -// fair share memory usage` statistic. -// Conceptually, it divides the 'memory usage' at each location in the 'cord -// graph' by the cumulative reference count of that location. The cumulative -// reference count is the factored total of all edges leading into that node. -// -// The top level node is treated specially: we assume the current thread -// (typically called from the CordzHandler) to hold a reference purely to -// perform a safe analysis, and not being part of the application. So we -// substract 1 from the reference count of the top node to compute the -// 'application fair share' excluding the reference of the current thread. -// -// An example of fair sharing, and why we multiply reference counts: -// Assume we have 2 CordReps, both being a Substring referencing a Flat: -// CordSubstring A (refcount = 5) --> child Flat C (refcount = 2) -// CordSubstring B (refcount = 9) --> child Flat C (refcount = 2) -// -// Flat C has 2 incoming edges from the 2 substrings (refcount = 2) and is not -// referenced directly anywhere else. Translated into a 'fair share', we then -// attribute 50% of the memory (memory / refcount = 2) to each incoming edge. -// Rep A has a refcount of 5, so we attribute each incoming edge 1 / 5th of the -// memory cost below it, i.e.: the fair share of Rep A of the memory used by C -// is then 'memory C / (refcount C * refcount A) + (memory A / refcount A)'. -// It is also easy to see how all incoming edges add up to 100%. -class CordRepAnalyzer { - public: - // Creates an analyzer instance binding to `statistics`. - explicit CordRepAnalyzer(CordzStatistics& statistics) - : statistics_(statistics) {} - - // Analyzes the memory statistics and node counts for the provided `rep`, and - // adds the results to `statistics`. Note that node counts and memory sizes - // are not initialized, computed values are added to any existing values. - void AnalyzeCordRep(const CordRep* rep) { - // Process all linear nodes. - // As per the class comments, use refcout - 1 on the top level node, as the - // top level node is assumed to be referenced only for analysis purposes. - size_t refcount = rep->refcount.Get(); - RepRef repref{rep, (refcount > 1) ? refcount - 1 : 1}; - - // Process all top level linear nodes (substrings and flats). - repref = CountLinearReps(repref, memory_usage_); - - if (repref.rep != nullptr) { - if (repref.rep->tag == RING) { - AnalyzeRing(repref); - } else if (repref.rep->tag == BTREE) { - AnalyzeBtree(repref); - } else if (repref.rep->tag == CONCAT) { - AnalyzeConcat(repref); - } else { - // We should have either a concat, btree, or ring node if not null. - assert(false); - } - } - - // Adds values to output - statistics_.estimated_memory_usage += memory_usage_.total; - statistics_.estimated_fair_share_memory_usage += - static_cast<size_t>(memory_usage_.fair_share); - } - - private: - // RepRef identifies a CordRep* inside the Cord tree with its cumulative - // refcount including itself. For example, a tree consisting of a substring - // with a refcount of 3 and a child flat with a refcount of 4 will have RepRef - // refcounts of 3 and 12 respectively. - struct RepRef { - const CordRep* rep; - size_t refcount; - - // Returns a 'child' RepRef which contains the cumulative reference count of - // this instance multiplied by the child's reference count. - RepRef Child(const CordRep* child) const { - return RepRef{child, refcount * child->refcount.Get()}; - } - }; - - // Memory usage values - struct MemoryUsage { - size_t total = 0; - double fair_share = 0.0; - - // Adds 'size` memory usage to this class, with a cumulative (recursive) - // reference count of `refcount` - void Add(size_t size, size_t refcount) { - total += size; - fair_share += static_cast<double>(size) / refcount; - } - }; - - // Returns `rr` if `rr.rep` is not null and a CONCAT type. - // Asserts that `rr.rep` is a concat node or null. - static RepRef AssertConcat(RepRef repref) { - const CordRep* rep = repref.rep; - assert(rep == nullptr || rep->tag == CONCAT); - return (rep != nullptr && rep->tag == CONCAT) ? repref : RepRef{nullptr, 0}; - } - - // Counts a flat of the provide allocated size - void CountFlat(size_t size) { - statistics_.node_count++; - statistics_.node_counts.flat++; - if (size <= 64) { - statistics_.node_counts.flat_64++; - } else if (size <= 128) { - statistics_.node_counts.flat_128++; - } else if (size <= 256) { - statistics_.node_counts.flat_256++; - } else if (size <= 512) { - statistics_.node_counts.flat_512++; - } else if (size <= 1024) { - statistics_.node_counts.flat_1k++; - } - } - - // Processes 'linear' reps (substring, flat, external) not requiring iteration - // or recursion. Returns RefRep{null} if all reps were processed, else returns - // the top-most non-linear concat or ring cordrep. - // Node counts are updated into `statistics_`, memory usage is update into - // `memory_usage`, which typically references `memory_usage_` except for ring - // buffers where we count children unrounded. - RepRef CountLinearReps(RepRef rep, MemoryUsage& memory_usage) { - // Consume all substrings - while (rep.rep->tag == SUBSTRING) { - statistics_.node_count++; - statistics_.node_counts.substring++; - memory_usage.Add(sizeof(CordRepSubstring), rep.refcount); - rep = rep.Child(rep.rep->substring()->child); - } - - // Consume possible FLAT - if (rep.rep->tag >= FLAT) { - size_t size = rep.rep->flat()->AllocatedSize(); - CountFlat(size); - memory_usage.Add(size, rep.refcount); - return RepRef{nullptr, 0}; - } - - // Consume possible external - if (rep.rep->tag == EXTERNAL) { - statistics_.node_count++; - statistics_.node_counts.external++; - size_t size = rep.rep->length + sizeof(CordRepExternalImpl<intptr_t>); - memory_usage.Add(size, rep.refcount); - return RepRef{nullptr, 0}; - } - - return rep; - } - - // Analyzes the provided concat node in a flattened recursive way. - void AnalyzeConcat(RepRef rep) { - y_absl::InlinedVector<RepRef, 47> pending; - - while (rep.rep != nullptr) { - const CordRepConcat* concat = rep.rep->concat(); - RepRef left = rep.Child(concat->left); - RepRef right = rep.Child(concat->right); - - statistics_.node_count++; - statistics_.node_counts.concat++; - memory_usage_.Add(sizeof(CordRepConcat), rep.refcount); - - right = AssertConcat(CountLinearReps(right, memory_usage_)); - rep = AssertConcat(CountLinearReps(left, memory_usage_)); - if (rep.rep != nullptr) { - if (right.rep != nullptr) { - pending.push_back(right); - } - } else if (right.rep != nullptr) { - rep = right; - } else if (!pending.empty()) { - rep = pending.back(); - pending.pop_back(); - } - } - } - - // Analyzes the provided ring. - void AnalyzeRing(RepRef rep) { - statistics_.node_count++; - statistics_.node_counts.ring++; - const CordRepRing* ring = rep.rep->ring(); - memory_usage_.Add(CordRepRing::AllocSize(ring->capacity()), rep.refcount); - ring->ForEach([&](CordRepRing::index_type pos) { - CountLinearReps(rep.Child(ring->entry_child(pos)), memory_usage_); - }); - } - - // Analyzes the provided btree. - void AnalyzeBtree(RepRef rep) { - statistics_.node_count++; - statistics_.node_counts.btree++; - memory_usage_.Add(sizeof(CordRepBtree), rep.refcount); - const CordRepBtree* tree = rep.rep->btree(); - if (tree->height() > 0) { - for (CordRep* edge : tree->Edges()) { - AnalyzeBtree(rep.Child(edge)); - } - } else { - for (CordRep* edge : tree->Edges()) { - CountLinearReps(rep.Child(edge), memory_usage_); - } - } - } - - CordzStatistics& statistics_; - MemoryUsage memory_usage_; -}; - -} // namespace - -CordzInfo* CordzInfo::Head(const CordzSnapshot& snapshot) { - ABSL_ASSERT(snapshot.is_snapshot()); - - // We can do an 'unsafe' load of 'head', as we are guaranteed that the - // instance it points to is kept alive by the provided CordzSnapshot, so we - // can simply return the current value using an acquire load. - // We do enforce in DEBUG builds that the 'head' value is present in the - // delete queue: ODR violations may lead to 'snapshot' and 'global_list_' - // being in different libraries / modules. - CordzInfo* head = global_list_.head.load(std::memory_order_acquire); - ABSL_ASSERT(snapshot.DiagnosticsHandleIsSafeToInspect(head)); - return head; -} - -CordzInfo* CordzInfo::Next(const CordzSnapshot& snapshot) const { - ABSL_ASSERT(snapshot.is_snapshot()); - - // Similar to the 'Head()' function, we do not need a mutex here. - CordzInfo* next = ci_next_.load(std::memory_order_acquire); - ABSL_ASSERT(snapshot.DiagnosticsHandleIsSafeToInspect(this)); - ABSL_ASSERT(snapshot.DiagnosticsHandleIsSafeToInspect(next)); - return next; -} - -void CordzInfo::TrackCord(InlineData& cord, MethodIdentifier method) { - assert(cord.is_tree()); - assert(!cord.is_profiled()); - CordzInfo* cordz_info = new CordzInfo(cord.as_tree(), nullptr, method); - cord.set_cordz_info(cordz_info); - cordz_info->Track(); -} - -void CordzInfo::TrackCord(InlineData& cord, const InlineData& src, - MethodIdentifier method) { - assert(cord.is_tree()); - assert(src.is_tree()); - - // Unsample current as we the current cord is being replaced with 'src', - // so any method history is no longer relevant. - CordzInfo* cordz_info = cord.cordz_info(); - if (cordz_info != nullptr) cordz_info->Untrack(); - - // Start new cord sample - cordz_info = new CordzInfo(cord.as_tree(), src.cordz_info(), method); - cord.set_cordz_info(cordz_info); - cordz_info->Track(); -} - -void CordzInfo::MaybeTrackCordImpl(InlineData& cord, const InlineData& src, - MethodIdentifier method) { - if (src.is_profiled()) { - TrackCord(cord, src, method); - } else if (cord.is_profiled()) { - cord.cordz_info()->Untrack(); - cord.clear_cordz_info(); - } -} - -CordzInfo::MethodIdentifier CordzInfo::GetParentMethod(const CordzInfo* src) { - if (src == nullptr) return MethodIdentifier::kUnknown; - return src->parent_method_ != MethodIdentifier::kUnknown ? src->parent_method_ - : src->method_; -} - -int CordzInfo::FillParentStack(const CordzInfo* src, void** stack) { - assert(stack); - if (src == nullptr) return 0; - if (src->parent_stack_depth_) { - memcpy(stack, src->parent_stack_, src->parent_stack_depth_ * sizeof(void*)); - return src->parent_stack_depth_; - } - memcpy(stack, src->stack_, src->stack_depth_ * sizeof(void*)); - return src->stack_depth_; -} - -CordzInfo::CordzInfo(CordRep* rep, const CordzInfo* src, - MethodIdentifier method) - : rep_(rep), - stack_depth_(y_absl::GetStackTrace(stack_, /*max_depth=*/kMaxStackDepth, - /*skip_count=*/1)), - parent_stack_depth_(FillParentStack(src, parent_stack_)), - method_(method), - parent_method_(GetParentMethod(src)), - create_time_(y_absl::Now()) { - update_tracker_.LossyAdd(method); - if (src) { - // Copy parent counters. - update_tracker_.LossyAdd(src->update_tracker_); - } -} - -CordzInfo::~CordzInfo() { - // `rep_` is potentially kept alive if CordzInfo is included - // in a collection snapshot (which should be rare). - if (ABSL_PREDICT_FALSE(rep_)) { - CordRep::Unref(rep_); - } -} - -void CordzInfo::Track() { - SpinLockHolder l(&list_->mutex); - - CordzInfo* const head = list_->head.load(std::memory_order_acquire); - if (head != nullptr) { - head->ci_prev_.store(this, std::memory_order_release); - } - ci_next_.store(head, std::memory_order_release); - list_->head.store(this, std::memory_order_release); -} - -void CordzInfo::Untrack() { - ODRCheck(); - { - SpinLockHolder l(&list_->mutex); - - CordzInfo* const head = list_->head.load(std::memory_order_acquire); - CordzInfo* const next = ci_next_.load(std::memory_order_acquire); - CordzInfo* const prev = ci_prev_.load(std::memory_order_acquire); - - if (next) { - ABSL_ASSERT(next->ci_prev_.load(std::memory_order_acquire) == this); - next->ci_prev_.store(prev, std::memory_order_release); - } - if (prev) { - ABSL_ASSERT(head != this); - ABSL_ASSERT(prev->ci_next_.load(std::memory_order_acquire) == this); - prev->ci_next_.store(next, std::memory_order_release); - } else { - ABSL_ASSERT(head == this); - list_->head.store(next, std::memory_order_release); - } - } - - // We can no longer be discovered: perform a fast path check if we are not - // listed on any delete queue, so we can directly delete this instance. - if (SafeToDelete()) { - UnsafeSetCordRep(nullptr); - delete this; - return; - } - - // We are likely part of a snapshot, extend the life of the CordRep - { - y_absl::MutexLock lock(&mutex_); - if (rep_) CordRep::Ref(rep_); - } - CordzHandle::Delete(this); -} - -void CordzInfo::Lock(MethodIdentifier method) - ABSL_EXCLUSIVE_LOCK_FUNCTION(mutex_) { - mutex_.Lock(); - update_tracker_.LossyAdd(method); - assert(rep_); -} - -void CordzInfo::Unlock() ABSL_UNLOCK_FUNCTION(mutex_) { - bool tracked = rep_ != nullptr; - mutex_.Unlock(); - if (!tracked) { - Untrack(); - } -} - -y_absl::Span<void* const> CordzInfo::GetStack() const { - return y_absl::MakeConstSpan(stack_, stack_depth_); -} - -y_absl::Span<void* const> CordzInfo::GetParentStack() const { - return y_absl::MakeConstSpan(parent_stack_, parent_stack_depth_); -} - -CordzStatistics CordzInfo::GetCordzStatistics() const { - CordzStatistics stats; - stats.method = method_; - stats.parent_method = parent_method_; - stats.update_tracker = update_tracker_; - if (CordRep* rep = RefCordRep()) { - stats.size = rep->length; - CordRepAnalyzer analyzer(stats); - analyzer.AnalyzeCordRep(rep); - CordRep::Unref(rep); - } - return stats; -} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace y_absl +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "y_absl/strings/internal/cordz_info.h" + +#include "y_absl/base/config.h" +#include "y_absl/base/internal/spinlock.h" +#include "y_absl/container/inlined_vector.h" +#include "y_absl/debugging/stacktrace.h" +#include "y_absl/strings/internal/cord_internal.h" +#include "y_absl/strings/internal/cord_rep_btree.h" +#include "y_absl/strings/internal/cord_rep_ring.h" +#include "y_absl/strings/internal/cordz_handle.h" +#include "y_absl/strings/internal/cordz_statistics.h" +#include "y_absl/strings/internal/cordz_update_tracker.h" +#include "y_absl/synchronization/mutex.h" +#include "y_absl/types/span.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +using ::y_absl::base_internal::SpinLockHolder; + +constexpr int CordzInfo::kMaxStackDepth; + +ABSL_CONST_INIT CordzInfo::List CordzInfo::global_list_{y_absl::kConstInit}; + +namespace { + +// CordRepAnalyzer performs the analysis of a cord. +// +// It computes absolute node counts and total memory usage, and an 'estimated +// fair share memory usage` statistic. +// Conceptually, it divides the 'memory usage' at each location in the 'cord +// graph' by the cumulative reference count of that location. The cumulative +// reference count is the factored total of all edges leading into that node. +// +// The top level node is treated specially: we assume the current thread +// (typically called from the CordzHandler) to hold a reference purely to +// perform a safe analysis, and not being part of the application. So we +// substract 1 from the reference count of the top node to compute the +// 'application fair share' excluding the reference of the current thread. +// +// An example of fair sharing, and why we multiply reference counts: +// Assume we have 2 CordReps, both being a Substring referencing a Flat: +// CordSubstring A (refcount = 5) --> child Flat C (refcount = 2) +// CordSubstring B (refcount = 9) --> child Flat C (refcount = 2) +// +// Flat C has 2 incoming edges from the 2 substrings (refcount = 2) and is not +// referenced directly anywhere else. Translated into a 'fair share', we then +// attribute 50% of the memory (memory / refcount = 2) to each incoming edge. +// Rep A has a refcount of 5, so we attribute each incoming edge 1 / 5th of the +// memory cost below it, i.e.: the fair share of Rep A of the memory used by C +// is then 'memory C / (refcount C * refcount A) + (memory A / refcount A)'. +// It is also easy to see how all incoming edges add up to 100%. +class CordRepAnalyzer { + public: + // Creates an analyzer instance binding to `statistics`. + explicit CordRepAnalyzer(CordzStatistics& statistics) + : statistics_(statistics) {} + + // Analyzes the memory statistics and node counts for the provided `rep`, and + // adds the results to `statistics`. Note that node counts and memory sizes + // are not initialized, computed values are added to any existing values. + void AnalyzeCordRep(const CordRep* rep) { + // Process all linear nodes. + // As per the class comments, use refcout - 1 on the top level node, as the + // top level node is assumed to be referenced only for analysis purposes. + size_t refcount = rep->refcount.Get(); + RepRef repref{rep, (refcount > 1) ? refcount - 1 : 1}; + + // Process all top level linear nodes (substrings and flats). + repref = CountLinearReps(repref, memory_usage_); + + if (repref.rep != nullptr) { + if (repref.rep->tag == RING) { + AnalyzeRing(repref); + } else if (repref.rep->tag == BTREE) { + AnalyzeBtree(repref); + } else if (repref.rep->tag == CONCAT) { + AnalyzeConcat(repref); + } else { + // We should have either a concat, btree, or ring node if not null. + assert(false); + } + } + + // Adds values to output + statistics_.estimated_memory_usage += memory_usage_.total; + statistics_.estimated_fair_share_memory_usage += + static_cast<size_t>(memory_usage_.fair_share); + } + + private: + // RepRef identifies a CordRep* inside the Cord tree with its cumulative + // refcount including itself. For example, a tree consisting of a substring + // with a refcount of 3 and a child flat with a refcount of 4 will have RepRef + // refcounts of 3 and 12 respectively. + struct RepRef { + const CordRep* rep; + size_t refcount; + + // Returns a 'child' RepRef which contains the cumulative reference count of + // this instance multiplied by the child's reference count. + RepRef Child(const CordRep* child) const { + return RepRef{child, refcount * child->refcount.Get()}; + } + }; + + // Memory usage values + struct MemoryUsage { + size_t total = 0; + double fair_share = 0.0; + + // Adds 'size` memory usage to this class, with a cumulative (recursive) + // reference count of `refcount` + void Add(size_t size, size_t refcount) { + total += size; + fair_share += static_cast<double>(size) / refcount; + } + }; + + // Returns `rr` if `rr.rep` is not null and a CONCAT type. + // Asserts that `rr.rep` is a concat node or null. + static RepRef AssertConcat(RepRef repref) { + const CordRep* rep = repref.rep; + assert(rep == nullptr || rep->tag == CONCAT); + return (rep != nullptr && rep->tag == CONCAT) ? repref : RepRef{nullptr, 0}; + } + + // Counts a flat of the provide allocated size + void CountFlat(size_t size) { + statistics_.node_count++; + statistics_.node_counts.flat++; + if (size <= 64) { + statistics_.node_counts.flat_64++; + } else if (size <= 128) { + statistics_.node_counts.flat_128++; + } else if (size <= 256) { + statistics_.node_counts.flat_256++; + } else if (size <= 512) { + statistics_.node_counts.flat_512++; + } else if (size <= 1024) { + statistics_.node_counts.flat_1k++; + } + } + + // Processes 'linear' reps (substring, flat, external) not requiring iteration + // or recursion. Returns RefRep{null} if all reps were processed, else returns + // the top-most non-linear concat or ring cordrep. + // Node counts are updated into `statistics_`, memory usage is update into + // `memory_usage`, which typically references `memory_usage_` except for ring + // buffers where we count children unrounded. + RepRef CountLinearReps(RepRef rep, MemoryUsage& memory_usage) { + // Consume all substrings + while (rep.rep->tag == SUBSTRING) { + statistics_.node_count++; + statistics_.node_counts.substring++; + memory_usage.Add(sizeof(CordRepSubstring), rep.refcount); + rep = rep.Child(rep.rep->substring()->child); + } + + // Consume possible FLAT + if (rep.rep->tag >= FLAT) { + size_t size = rep.rep->flat()->AllocatedSize(); + CountFlat(size); + memory_usage.Add(size, rep.refcount); + return RepRef{nullptr, 0}; + } + + // Consume possible external + if (rep.rep->tag == EXTERNAL) { + statistics_.node_count++; + statistics_.node_counts.external++; + size_t size = rep.rep->length + sizeof(CordRepExternalImpl<intptr_t>); + memory_usage.Add(size, rep.refcount); + return RepRef{nullptr, 0}; + } + + return rep; + } + + // Analyzes the provided concat node in a flattened recursive way. + void AnalyzeConcat(RepRef rep) { + y_absl::InlinedVector<RepRef, 47> pending; + + while (rep.rep != nullptr) { + const CordRepConcat* concat = rep.rep->concat(); + RepRef left = rep.Child(concat->left); + RepRef right = rep.Child(concat->right); + + statistics_.node_count++; + statistics_.node_counts.concat++; + memory_usage_.Add(sizeof(CordRepConcat), rep.refcount); + + right = AssertConcat(CountLinearReps(right, memory_usage_)); + rep = AssertConcat(CountLinearReps(left, memory_usage_)); + if (rep.rep != nullptr) { + if (right.rep != nullptr) { + pending.push_back(right); + } + } else if (right.rep != nullptr) { + rep = right; + } else if (!pending.empty()) { + rep = pending.back(); + pending.pop_back(); + } + } + } + + // Analyzes the provided ring. + void AnalyzeRing(RepRef rep) { + statistics_.node_count++; + statistics_.node_counts.ring++; + const CordRepRing* ring = rep.rep->ring(); + memory_usage_.Add(CordRepRing::AllocSize(ring->capacity()), rep.refcount); + ring->ForEach([&](CordRepRing::index_type pos) { + CountLinearReps(rep.Child(ring->entry_child(pos)), memory_usage_); + }); + } + + // Analyzes the provided btree. + void AnalyzeBtree(RepRef rep) { + statistics_.node_count++; + statistics_.node_counts.btree++; + memory_usage_.Add(sizeof(CordRepBtree), rep.refcount); + const CordRepBtree* tree = rep.rep->btree(); + if (tree->height() > 0) { + for (CordRep* edge : tree->Edges()) { + AnalyzeBtree(rep.Child(edge)); + } + } else { + for (CordRep* edge : tree->Edges()) { + CountLinearReps(rep.Child(edge), memory_usage_); + } + } + } + + CordzStatistics& statistics_; + MemoryUsage memory_usage_; +}; + +} // namespace + +CordzInfo* CordzInfo::Head(const CordzSnapshot& snapshot) { + ABSL_ASSERT(snapshot.is_snapshot()); + + // We can do an 'unsafe' load of 'head', as we are guaranteed that the + // instance it points to is kept alive by the provided CordzSnapshot, so we + // can simply return the current value using an acquire load. + // We do enforce in DEBUG builds that the 'head' value is present in the + // delete queue: ODR violations may lead to 'snapshot' and 'global_list_' + // being in different libraries / modules. + CordzInfo* head = global_list_.head.load(std::memory_order_acquire); + ABSL_ASSERT(snapshot.DiagnosticsHandleIsSafeToInspect(head)); + return head; +} + +CordzInfo* CordzInfo::Next(const CordzSnapshot& snapshot) const { + ABSL_ASSERT(snapshot.is_snapshot()); + + // Similar to the 'Head()' function, we do not need a mutex here. + CordzInfo* next = ci_next_.load(std::memory_order_acquire); + ABSL_ASSERT(snapshot.DiagnosticsHandleIsSafeToInspect(this)); + ABSL_ASSERT(snapshot.DiagnosticsHandleIsSafeToInspect(next)); + return next; +} + +void CordzInfo::TrackCord(InlineData& cord, MethodIdentifier method) { + assert(cord.is_tree()); + assert(!cord.is_profiled()); + CordzInfo* cordz_info = new CordzInfo(cord.as_tree(), nullptr, method); + cord.set_cordz_info(cordz_info); + cordz_info->Track(); +} + +void CordzInfo::TrackCord(InlineData& cord, const InlineData& src, + MethodIdentifier method) { + assert(cord.is_tree()); + assert(src.is_tree()); + + // Unsample current as we the current cord is being replaced with 'src', + // so any method history is no longer relevant. + CordzInfo* cordz_info = cord.cordz_info(); + if (cordz_info != nullptr) cordz_info->Untrack(); + + // Start new cord sample + cordz_info = new CordzInfo(cord.as_tree(), src.cordz_info(), method); + cord.set_cordz_info(cordz_info); + cordz_info->Track(); +} + +void CordzInfo::MaybeTrackCordImpl(InlineData& cord, const InlineData& src, + MethodIdentifier method) { + if (src.is_profiled()) { + TrackCord(cord, src, method); + } else if (cord.is_profiled()) { + cord.cordz_info()->Untrack(); + cord.clear_cordz_info(); + } +} + +CordzInfo::MethodIdentifier CordzInfo::GetParentMethod(const CordzInfo* src) { + if (src == nullptr) return MethodIdentifier::kUnknown; + return src->parent_method_ != MethodIdentifier::kUnknown ? src->parent_method_ + : src->method_; +} + +int CordzInfo::FillParentStack(const CordzInfo* src, void** stack) { + assert(stack); + if (src == nullptr) return 0; + if (src->parent_stack_depth_) { + memcpy(stack, src->parent_stack_, src->parent_stack_depth_ * sizeof(void*)); + return src->parent_stack_depth_; + } + memcpy(stack, src->stack_, src->stack_depth_ * sizeof(void*)); + return src->stack_depth_; +} + +CordzInfo::CordzInfo(CordRep* rep, const CordzInfo* src, + MethodIdentifier method) + : rep_(rep), + stack_depth_(y_absl::GetStackTrace(stack_, /*max_depth=*/kMaxStackDepth, + /*skip_count=*/1)), + parent_stack_depth_(FillParentStack(src, parent_stack_)), + method_(method), + parent_method_(GetParentMethod(src)), + create_time_(y_absl::Now()) { + update_tracker_.LossyAdd(method); + if (src) { + // Copy parent counters. + update_tracker_.LossyAdd(src->update_tracker_); + } +} + +CordzInfo::~CordzInfo() { + // `rep_` is potentially kept alive if CordzInfo is included + // in a collection snapshot (which should be rare). + if (ABSL_PREDICT_FALSE(rep_)) { + CordRep::Unref(rep_); + } +} + +void CordzInfo::Track() { + SpinLockHolder l(&list_->mutex); + + CordzInfo* const head = list_->head.load(std::memory_order_acquire); + if (head != nullptr) { + head->ci_prev_.store(this, std::memory_order_release); + } + ci_next_.store(head, std::memory_order_release); + list_->head.store(this, std::memory_order_release); +} + +void CordzInfo::Untrack() { + ODRCheck(); + { + SpinLockHolder l(&list_->mutex); + + CordzInfo* const head = list_->head.load(std::memory_order_acquire); + CordzInfo* const next = ci_next_.load(std::memory_order_acquire); + CordzInfo* const prev = ci_prev_.load(std::memory_order_acquire); + + if (next) { + ABSL_ASSERT(next->ci_prev_.load(std::memory_order_acquire) == this); + next->ci_prev_.store(prev, std::memory_order_release); + } + if (prev) { + ABSL_ASSERT(head != this); + ABSL_ASSERT(prev->ci_next_.load(std::memory_order_acquire) == this); + prev->ci_next_.store(next, std::memory_order_release); + } else { + ABSL_ASSERT(head == this); + list_->head.store(next, std::memory_order_release); + } + } + + // We can no longer be discovered: perform a fast path check if we are not + // listed on any delete queue, so we can directly delete this instance. + if (SafeToDelete()) { + UnsafeSetCordRep(nullptr); + delete this; + return; + } + + // We are likely part of a snapshot, extend the life of the CordRep + { + y_absl::MutexLock lock(&mutex_); + if (rep_) CordRep::Ref(rep_); + } + CordzHandle::Delete(this); +} + +void CordzInfo::Lock(MethodIdentifier method) + ABSL_EXCLUSIVE_LOCK_FUNCTION(mutex_) { + mutex_.Lock(); + update_tracker_.LossyAdd(method); + assert(rep_); +} + +void CordzInfo::Unlock() ABSL_UNLOCK_FUNCTION(mutex_) { + bool tracked = rep_ != nullptr; + mutex_.Unlock(); + if (!tracked) { + Untrack(); + } +} + +y_absl::Span<void* const> CordzInfo::GetStack() const { + return y_absl::MakeConstSpan(stack_, stack_depth_); +} + +y_absl::Span<void* const> CordzInfo::GetParentStack() const { + return y_absl::MakeConstSpan(parent_stack_, parent_stack_depth_); +} + +CordzStatistics CordzInfo::GetCordzStatistics() const { + CordzStatistics stats; + stats.method = method_; + stats.parent_method = parent_method_; + stats.update_tracker = update_tracker_; + if (CordRep* rep = RefCordRep()) { + stats.size = rep->length; + CordRepAnalyzer analyzer(stats); + analyzer.AnalyzeCordRep(rep); + CordRep::Unref(rep); + } + return stats; +} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info.h index e24214d259..4057e9a8a8 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info.h @@ -1,298 +1,298 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_CORDZ_INFO_H_ -#define ABSL_STRINGS_CORDZ_INFO_H_ - -#include <atomic> -#include <cstdint> -#include <functional> - -#include "y_absl/base/config.h" -#include "y_absl/base/internal/raw_logging.h" -#include "y_absl/base/internal/spinlock.h" -#include "y_absl/base/thread_annotations.h" -#include "y_absl/strings/internal/cord_internal.h" -#include "y_absl/strings/internal/cordz_functions.h" -#include "y_absl/strings/internal/cordz_handle.h" -#include "y_absl/strings/internal/cordz_statistics.h" -#include "y_absl/strings/internal/cordz_update_tracker.h" -#include "y_absl/synchronization/mutex.h" -#include "y_absl/types/span.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -// CordzInfo tracks a profiled Cord. Each of these objects can be in two places. -// If a Cord is alive, the CordzInfo will be in the global_cordz_infos map, and -// can also be retrieved via the linked list starting with -// global_cordz_infos_head and continued via the cordz_info_next() method. When -// a Cord has reached the end of its lifespan, the CordzInfo object will be -// migrated out of the global_cordz_infos list and the global_cordz_infos_map, -// and will either be deleted or appended to the global_delete_queue. If it is -// placed on the global_delete_queue, the CordzInfo object will be cleaned in -// the destructor of a CordzSampleToken object. -class ABSL_LOCKABLE CordzInfo : public CordzHandle { - public: - using MethodIdentifier = CordzUpdateTracker::MethodIdentifier; - - // TrackCord creates a CordzInfo instance which tracks important metrics of - // a sampled cord, and stores the created CordzInfo instance into `cord'. All - // CordzInfo instances are placed in a global list which is used to discover - // and snapshot all actively tracked cords. Callers are responsible for - // calling UntrackCord() before the tracked Cord instance is deleted, or to - // stop tracking the sampled Cord. Callers are also responsible for guarding - // changes to the 'tree' value of a Cord (InlineData.tree) through the Lock() - // and Unlock() calls. Any change resulting in a new tree value for the cord - // requires a call to SetCordRep() before the old tree has been unreffed - // and/or deleted. `method` identifies the Cord public API method initiating - // the cord to be sampled. - // Requires `cord` to hold a tree, and `cord.cordz_info()` to be null. - static void TrackCord(InlineData& cord, MethodIdentifier method); - - // Identical to TrackCord(), except that this function fills the - // `parent_stack` and `parent_method` properties of the returned CordzInfo - // instance from the provided `src` instance if `src` is sampled. - // This function should be used for sampling 'copy constructed' and 'copy - // assigned' cords. This function allows 'cord` to be already sampled, in - // which case the CordzInfo will be newly created from `src`. - static void TrackCord(InlineData& cord, const InlineData& src, - MethodIdentifier method); - - // Maybe sample the cord identified by 'cord' for method 'method'. - // Uses `cordz_should_profile` to randomly pick cords to be sampled, and if - // so, invokes `TrackCord` to start sampling `cord`. - static void MaybeTrackCord(InlineData& cord, MethodIdentifier method); - - // Maybe sample the cord identified by 'cord' for method 'method'. - // `src` identifies a 'parent' cord which is assigned to `cord`, typically the - // input cord for a copy constructor, or an assign method such as `operator=` - // `cord` will be sampled if (and only if) `src` is sampled. - // If `cord` is currently being sampled and `src` is not being sampled, then - // this function will stop sampling the cord and reset the cord's cordz_info. - // - // Previously this function defined that `cord` will be sampled if either - // `src` is sampled, or if `cord` is randomly picked for sampling. However, - // this can cause issues, as there may be paths where some cord is assigned an - // indirect copy of it's own value. As such a 'string of copies' would then - // remain sampled (`src.is_profiled`), then assigning such a cord back to - // 'itself' creates a cycle where the cord will converge to 'always sampled`. - // - // For example: - // - // Cord x; - // for (...) { - // // Copy ctor --> y.is_profiled := x.is_profiled | random(...) - // Cord y = x; - // ... - // // Assign x = y --> x.is_profiled = y.is_profiled | random(...) - // // ==> x.is_profiled |= random(...) - // // ==> x converges to 'always profiled' - // x = y; - // } - static void MaybeTrackCord(InlineData& cord, const InlineData& src, - MethodIdentifier method); - - // Stops tracking changes for a sampled cord, and deletes the provided info. - // This function must be called before the sampled cord instance is deleted, - // and before the root cordrep of the sampled cord is unreffed. - // This function may extend the lifetime of the cordrep in cases where the - // CordInfo instance is being held by a concurrent collection thread. - void Untrack(); - - // Invokes UntrackCord() on `info` if `info` is not null. - static void MaybeUntrackCord(CordzInfo* info); - - CordzInfo() = delete; - CordzInfo(const CordzInfo&) = delete; - CordzInfo& operator=(const CordzInfo&) = delete; - - // Retrieves the oldest existing CordzInfo. - static CordzInfo* Head(const CordzSnapshot& snapshot) - ABSL_NO_THREAD_SAFETY_ANALYSIS; - - // Retrieves the next oldest existing CordzInfo older than 'this' instance. - CordzInfo* Next(const CordzSnapshot& snapshot) const - ABSL_NO_THREAD_SAFETY_ANALYSIS; - - // Locks this instance for the update identified by `method`. - // Increases the count for `method` in `update_tracker`. - void Lock(MethodIdentifier method) ABSL_EXCLUSIVE_LOCK_FUNCTION(mutex_); - - // Unlocks this instance. If the contained `rep` has been set to null - // indicating the Cord has been cleared or is otherwise no longer sampled, - // then this method will delete this CordzInfo instance. - void Unlock() ABSL_UNLOCK_FUNCTION(mutex_); - - // Asserts that this CordzInfo instance is locked. - void AssertHeld() ABSL_ASSERT_EXCLUSIVE_LOCK(mutex_); - - // Updates the `rep` property of this instance. This methods is invoked by - // Cord logic each time the root node of a sampled Cord changes, and before - // the old root reference count is deleted. This guarantees that collection - // code can always safely take a reference on the tracked cord. - // Requires a lock to be held through the `Lock()` method. - // TODO(b/117940323): annotate with ABSL_EXCLUSIVE_LOCKS_REQUIRED once all - // Cord code is in a state where this can be proven true by the compiler. - void SetCordRep(CordRep* rep); - - // Returns the current `rep` property of this instance with a reference - // added, or null if this instance represents a cord that has since been - // deleted or untracked. - CordRep* RefCordRep() const ABSL_LOCKS_EXCLUDED(mutex_); - - // Returns the current value of `rep_` for testing purposes only. - CordRep* GetCordRepForTesting() const ABSL_NO_THREAD_SAFETY_ANALYSIS { - return rep_; - } - - // Sets the current value of `rep_` for testing purposes only. - void SetCordRepForTesting(CordRep* rep) ABSL_NO_THREAD_SAFETY_ANALYSIS { - rep_ = rep; - } - - // Returns the stack trace for where the cord was first sampled. Cords are - // potentially sampled when they promote from an inlined cord to a tree or - // ring representation, which is not necessarily the location where the cord - // was first created. Some cords are created as inlined cords, and only as - // data is added do they become a non-inlined cord. However, typically the - // location represents reasonably well where the cord is 'created'. - y_absl::Span<void* const> GetStack() const; - - // Returns the stack trace for a sampled cord's 'parent stack trace'. This - // value may be set if the cord is sampled (promoted) after being created - // from, or being assigned the value of an existing (sampled) cord. - y_absl::Span<void* const> GetParentStack() const; - - // Retrieves the CordzStatistics associated with this Cord. The statistics - // are only updated when a Cord goes through a mutation, such as an Append - // or RemovePrefix. - CordzStatistics GetCordzStatistics() const; - - private: - using SpinLock = y_absl::base_internal::SpinLock; - using SpinLockHolder = ::y_absl::base_internal::SpinLockHolder; - - // Global cordz info list. CordzInfo stores a pointer to the global list - // instance to harden against ODR violations. - struct List { - constexpr explicit List(y_absl::ConstInitType) - : mutex(y_absl::kConstInit, - y_absl::base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL) {} - - SpinLock mutex; - std::atomic<CordzInfo*> head ABSL_GUARDED_BY(mutex){nullptr}; - }; - - static constexpr int kMaxStackDepth = 64; - - explicit CordzInfo(CordRep* rep, const CordzInfo* src, - MethodIdentifier method); - ~CordzInfo() override; - - // Sets `rep_` without holding a lock. - void UnsafeSetCordRep(CordRep* rep) ABSL_NO_THREAD_SAFETY_ANALYSIS; - - void Track(); - - // Returns the parent method from `src`, which is either `parent_method_` or - // `method_` depending on `parent_method_` being kUnknown. - // Returns kUnknown if `src` is null. - static MethodIdentifier GetParentMethod(const CordzInfo* src); - - // Fills the provided stack from `src`, copying either `parent_stack_` or - // `stack_` depending on `parent_stack_` being empty, returning the size of - // the parent stack. - // Returns 0 if `src` is null. - static int FillParentStack(const CordzInfo* src, void** stack); - - void ODRCheck() const { -#ifndef NDEBUG - ABSL_RAW_CHECK(list_ == &global_list_, "ODR violation in Cord"); -#endif - } - - // Non-inlined implementation of `MaybeTrackCord`, which is executed if - // either `src` is sampled or `cord` is sampled, and either untracks or - // tracks `cord` as documented per `MaybeTrackCord`. - static void MaybeTrackCordImpl(InlineData& cord, const InlineData& src, - MethodIdentifier method); - - ABSL_CONST_INIT static List global_list_; - List* const list_ = &global_list_; - - // ci_prev_ and ci_next_ require the global list mutex to be held. - // Unfortunately we can't use thread annotations such that the thread safety - // analysis understands that list_ and global_list_ are one and the same. - std::atomic<CordzInfo*> ci_prev_{nullptr}; - std::atomic<CordzInfo*> ci_next_{nullptr}; - - mutable y_absl::Mutex mutex_; - CordRep* rep_ ABSL_GUARDED_BY(mutex_); - - void* stack_[kMaxStackDepth]; - void* parent_stack_[kMaxStackDepth]; - const int stack_depth_; - const int parent_stack_depth_; - const MethodIdentifier method_; - const MethodIdentifier parent_method_; - CordzUpdateTracker update_tracker_; - const y_absl::Time create_time_; -}; - -inline ABSL_ATTRIBUTE_ALWAYS_INLINE void CordzInfo::MaybeTrackCord( - InlineData& cord, MethodIdentifier method) { - if (ABSL_PREDICT_FALSE(cordz_should_profile())) { - TrackCord(cord, method); - } -} - -inline ABSL_ATTRIBUTE_ALWAYS_INLINE void CordzInfo::MaybeTrackCord( - InlineData& cord, const InlineData& src, MethodIdentifier method) { - if (ABSL_PREDICT_FALSE(InlineData::is_either_profiled(cord, src))) { - MaybeTrackCordImpl(cord, src, method); - } -} - -inline ABSL_ATTRIBUTE_ALWAYS_INLINE void CordzInfo::MaybeUntrackCord( - CordzInfo* info) { - if (ABSL_PREDICT_FALSE(info)) { - info->Untrack(); - } -} - -inline void CordzInfo::AssertHeld() ABSL_ASSERT_EXCLUSIVE_LOCK(mutex_) { -#ifndef NDEBUG - mutex_.AssertHeld(); -#endif -} - -inline void CordzInfo::SetCordRep(CordRep* rep) { - AssertHeld(); - rep_ = rep; -} - -inline void CordzInfo::UnsafeSetCordRep(CordRep* rep) { rep_ = rep; } - -inline CordRep* CordzInfo::RefCordRep() const ABSL_LOCKS_EXCLUDED(mutex_) { - MutexLock lock(&mutex_); - return rep_ ? CordRep::Ref(rep_) : nullptr; -} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace y_absl - -#endif // ABSL_STRINGS_CORDZ_INFO_H_ +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_CORDZ_INFO_H_ +#define ABSL_STRINGS_CORDZ_INFO_H_ + +#include <atomic> +#include <cstdint> +#include <functional> + +#include "y_absl/base/config.h" +#include "y_absl/base/internal/raw_logging.h" +#include "y_absl/base/internal/spinlock.h" +#include "y_absl/base/thread_annotations.h" +#include "y_absl/strings/internal/cord_internal.h" +#include "y_absl/strings/internal/cordz_functions.h" +#include "y_absl/strings/internal/cordz_handle.h" +#include "y_absl/strings/internal/cordz_statistics.h" +#include "y_absl/strings/internal/cordz_update_tracker.h" +#include "y_absl/synchronization/mutex.h" +#include "y_absl/types/span.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +// CordzInfo tracks a profiled Cord. Each of these objects can be in two places. +// If a Cord is alive, the CordzInfo will be in the global_cordz_infos map, and +// can also be retrieved via the linked list starting with +// global_cordz_infos_head and continued via the cordz_info_next() method. When +// a Cord has reached the end of its lifespan, the CordzInfo object will be +// migrated out of the global_cordz_infos list and the global_cordz_infos_map, +// and will either be deleted or appended to the global_delete_queue. If it is +// placed on the global_delete_queue, the CordzInfo object will be cleaned in +// the destructor of a CordzSampleToken object. +class ABSL_LOCKABLE CordzInfo : public CordzHandle { + public: + using MethodIdentifier = CordzUpdateTracker::MethodIdentifier; + + // TrackCord creates a CordzInfo instance which tracks important metrics of + // a sampled cord, and stores the created CordzInfo instance into `cord'. All + // CordzInfo instances are placed in a global list which is used to discover + // and snapshot all actively tracked cords. Callers are responsible for + // calling UntrackCord() before the tracked Cord instance is deleted, or to + // stop tracking the sampled Cord. Callers are also responsible for guarding + // changes to the 'tree' value of a Cord (InlineData.tree) through the Lock() + // and Unlock() calls. Any change resulting in a new tree value for the cord + // requires a call to SetCordRep() before the old tree has been unreffed + // and/or deleted. `method` identifies the Cord public API method initiating + // the cord to be sampled. + // Requires `cord` to hold a tree, and `cord.cordz_info()` to be null. + static void TrackCord(InlineData& cord, MethodIdentifier method); + + // Identical to TrackCord(), except that this function fills the + // `parent_stack` and `parent_method` properties of the returned CordzInfo + // instance from the provided `src` instance if `src` is sampled. + // This function should be used for sampling 'copy constructed' and 'copy + // assigned' cords. This function allows 'cord` to be already sampled, in + // which case the CordzInfo will be newly created from `src`. + static void TrackCord(InlineData& cord, const InlineData& src, + MethodIdentifier method); + + // Maybe sample the cord identified by 'cord' for method 'method'. + // Uses `cordz_should_profile` to randomly pick cords to be sampled, and if + // so, invokes `TrackCord` to start sampling `cord`. + static void MaybeTrackCord(InlineData& cord, MethodIdentifier method); + + // Maybe sample the cord identified by 'cord' for method 'method'. + // `src` identifies a 'parent' cord which is assigned to `cord`, typically the + // input cord for a copy constructor, or an assign method such as `operator=` + // `cord` will be sampled if (and only if) `src` is sampled. + // If `cord` is currently being sampled and `src` is not being sampled, then + // this function will stop sampling the cord and reset the cord's cordz_info. + // + // Previously this function defined that `cord` will be sampled if either + // `src` is sampled, or if `cord` is randomly picked for sampling. However, + // this can cause issues, as there may be paths where some cord is assigned an + // indirect copy of it's own value. As such a 'string of copies' would then + // remain sampled (`src.is_profiled`), then assigning such a cord back to + // 'itself' creates a cycle where the cord will converge to 'always sampled`. + // + // For example: + // + // Cord x; + // for (...) { + // // Copy ctor --> y.is_profiled := x.is_profiled | random(...) + // Cord y = x; + // ... + // // Assign x = y --> x.is_profiled = y.is_profiled | random(...) + // // ==> x.is_profiled |= random(...) + // // ==> x converges to 'always profiled' + // x = y; + // } + static void MaybeTrackCord(InlineData& cord, const InlineData& src, + MethodIdentifier method); + + // Stops tracking changes for a sampled cord, and deletes the provided info. + // This function must be called before the sampled cord instance is deleted, + // and before the root cordrep of the sampled cord is unreffed. + // This function may extend the lifetime of the cordrep in cases where the + // CordInfo instance is being held by a concurrent collection thread. + void Untrack(); + + // Invokes UntrackCord() on `info` if `info` is not null. + static void MaybeUntrackCord(CordzInfo* info); + + CordzInfo() = delete; + CordzInfo(const CordzInfo&) = delete; + CordzInfo& operator=(const CordzInfo&) = delete; + + // Retrieves the oldest existing CordzInfo. + static CordzInfo* Head(const CordzSnapshot& snapshot) + ABSL_NO_THREAD_SAFETY_ANALYSIS; + + // Retrieves the next oldest existing CordzInfo older than 'this' instance. + CordzInfo* Next(const CordzSnapshot& snapshot) const + ABSL_NO_THREAD_SAFETY_ANALYSIS; + + // Locks this instance for the update identified by `method`. + // Increases the count for `method` in `update_tracker`. + void Lock(MethodIdentifier method) ABSL_EXCLUSIVE_LOCK_FUNCTION(mutex_); + + // Unlocks this instance. If the contained `rep` has been set to null + // indicating the Cord has been cleared or is otherwise no longer sampled, + // then this method will delete this CordzInfo instance. + void Unlock() ABSL_UNLOCK_FUNCTION(mutex_); + + // Asserts that this CordzInfo instance is locked. + void AssertHeld() ABSL_ASSERT_EXCLUSIVE_LOCK(mutex_); + + // Updates the `rep` property of this instance. This methods is invoked by + // Cord logic each time the root node of a sampled Cord changes, and before + // the old root reference count is deleted. This guarantees that collection + // code can always safely take a reference on the tracked cord. + // Requires a lock to be held through the `Lock()` method. + // TODO(b/117940323): annotate with ABSL_EXCLUSIVE_LOCKS_REQUIRED once all + // Cord code is in a state where this can be proven true by the compiler. + void SetCordRep(CordRep* rep); + + // Returns the current `rep` property of this instance with a reference + // added, or null if this instance represents a cord that has since been + // deleted or untracked. + CordRep* RefCordRep() const ABSL_LOCKS_EXCLUDED(mutex_); + + // Returns the current value of `rep_` for testing purposes only. + CordRep* GetCordRepForTesting() const ABSL_NO_THREAD_SAFETY_ANALYSIS { + return rep_; + } + + // Sets the current value of `rep_` for testing purposes only. + void SetCordRepForTesting(CordRep* rep) ABSL_NO_THREAD_SAFETY_ANALYSIS { + rep_ = rep; + } + + // Returns the stack trace for where the cord was first sampled. Cords are + // potentially sampled when they promote from an inlined cord to a tree or + // ring representation, which is not necessarily the location where the cord + // was first created. Some cords are created as inlined cords, and only as + // data is added do they become a non-inlined cord. However, typically the + // location represents reasonably well where the cord is 'created'. + y_absl::Span<void* const> GetStack() const; + + // Returns the stack trace for a sampled cord's 'parent stack trace'. This + // value may be set if the cord is sampled (promoted) after being created + // from, or being assigned the value of an existing (sampled) cord. + y_absl::Span<void* const> GetParentStack() const; + + // Retrieves the CordzStatistics associated with this Cord. The statistics + // are only updated when a Cord goes through a mutation, such as an Append + // or RemovePrefix. + CordzStatistics GetCordzStatistics() const; + + private: + using SpinLock = y_absl::base_internal::SpinLock; + using SpinLockHolder = ::y_absl::base_internal::SpinLockHolder; + + // Global cordz info list. CordzInfo stores a pointer to the global list + // instance to harden against ODR violations. + struct List { + constexpr explicit List(y_absl::ConstInitType) + : mutex(y_absl::kConstInit, + y_absl::base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL) {} + + SpinLock mutex; + std::atomic<CordzInfo*> head ABSL_GUARDED_BY(mutex){nullptr}; + }; + + static constexpr int kMaxStackDepth = 64; + + explicit CordzInfo(CordRep* rep, const CordzInfo* src, + MethodIdentifier method); + ~CordzInfo() override; + + // Sets `rep_` without holding a lock. + void UnsafeSetCordRep(CordRep* rep) ABSL_NO_THREAD_SAFETY_ANALYSIS; + + void Track(); + + // Returns the parent method from `src`, which is either `parent_method_` or + // `method_` depending on `parent_method_` being kUnknown. + // Returns kUnknown if `src` is null. + static MethodIdentifier GetParentMethod(const CordzInfo* src); + + // Fills the provided stack from `src`, copying either `parent_stack_` or + // `stack_` depending on `parent_stack_` being empty, returning the size of + // the parent stack. + // Returns 0 if `src` is null. + static int FillParentStack(const CordzInfo* src, void** stack); + + void ODRCheck() const { +#ifndef NDEBUG + ABSL_RAW_CHECK(list_ == &global_list_, "ODR violation in Cord"); +#endif + } + + // Non-inlined implementation of `MaybeTrackCord`, which is executed if + // either `src` is sampled or `cord` is sampled, and either untracks or + // tracks `cord` as documented per `MaybeTrackCord`. + static void MaybeTrackCordImpl(InlineData& cord, const InlineData& src, + MethodIdentifier method); + + ABSL_CONST_INIT static List global_list_; + List* const list_ = &global_list_; + + // ci_prev_ and ci_next_ require the global list mutex to be held. + // Unfortunately we can't use thread annotations such that the thread safety + // analysis understands that list_ and global_list_ are one and the same. + std::atomic<CordzInfo*> ci_prev_{nullptr}; + std::atomic<CordzInfo*> ci_next_{nullptr}; + + mutable y_absl::Mutex mutex_; + CordRep* rep_ ABSL_GUARDED_BY(mutex_); + + void* stack_[kMaxStackDepth]; + void* parent_stack_[kMaxStackDepth]; + const int stack_depth_; + const int parent_stack_depth_; + const MethodIdentifier method_; + const MethodIdentifier parent_method_; + CordzUpdateTracker update_tracker_; + const y_absl::Time create_time_; +}; + +inline ABSL_ATTRIBUTE_ALWAYS_INLINE void CordzInfo::MaybeTrackCord( + InlineData& cord, MethodIdentifier method) { + if (ABSL_PREDICT_FALSE(cordz_should_profile())) { + TrackCord(cord, method); + } +} + +inline ABSL_ATTRIBUTE_ALWAYS_INLINE void CordzInfo::MaybeTrackCord( + InlineData& cord, const InlineData& src, MethodIdentifier method) { + if (ABSL_PREDICT_FALSE(InlineData::is_either_profiled(cord, src))) { + MaybeTrackCordImpl(cord, src, method); + } +} + +inline ABSL_ATTRIBUTE_ALWAYS_INLINE void CordzInfo::MaybeUntrackCord( + CordzInfo* info) { + if (ABSL_PREDICT_FALSE(info)) { + info->Untrack(); + } +} + +inline void CordzInfo::AssertHeld() ABSL_ASSERT_EXCLUSIVE_LOCK(mutex_) { +#ifndef NDEBUG + mutex_.AssertHeld(); +#endif +} + +inline void CordzInfo::SetCordRep(CordRep* rep) { + AssertHeld(); + rep_ = rep; +} + +inline void CordzInfo::UnsafeSetCordRep(CordRep* rep) { rep_ = rep; } + +inline CordRep* CordzInfo::RefCordRep() const ABSL_LOCKS_EXCLUDED(mutex_) { + MutexLock lock(&mutex_); + return rep_ ? CordRep::Ref(rep_) : nullptr; +} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace y_absl + +#endif // ABSL_STRINGS_CORDZ_INFO_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info/ya.make index 930eaa8b05..4c33f695e7 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info/ya.make @@ -13,27 +13,27 @@ LICENSE(Apache-2.0) PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/base - contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/low_level_alloc contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/raw_logging contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/throw_delegate contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity - contrib/restricted/abseil-cpp-tstring/y_absl/debugging - contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace - contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize - contrib/restricted/abseil-cpp-tstring/y_absl/demangle + contrib/restricted/abseil-cpp-tstring/y_absl/debugging + contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace + contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize + contrib/restricted/abseil-cpp-tstring/y_absl/demangle contrib/restricted/abseil-cpp-tstring/y_absl/numeric - contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased contrib/restricted/abseil-cpp-tstring/y_absl/strings - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_cord_internal - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle - contrib/restricted/abseil-cpp-tstring/y_absl/synchronization - contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal - contrib/restricted/abseil-cpp-tstring/y_absl/time - contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time - contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_cord_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle + contrib/restricted/abseil-cpp-tstring/y_absl/synchronization + contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal + contrib/restricted/abseil-cpp-tstring/y_absl/time + contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time + contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone ) ADDINCL( @@ -42,10 +42,10 @@ ADDINCL( NO_COMPILER_WARNINGS() -SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal) +SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal) SRCS( - cordz_info.cc + cordz_info.cc ) END() diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_sample_token.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_sample_token.cc index f29678adb8..0f79f2dbd0 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_sample_token.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_sample_token.cc @@ -1,64 +1,64 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "y_absl/strings/internal/cordz_sample_token.h" - -#include "y_absl/base/config.h" -#include "y_absl/strings/internal/cordz_handle.h" -#include "y_absl/strings/internal/cordz_info.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -CordzSampleToken::Iterator& CordzSampleToken::Iterator::operator++() { - if (current_) { - current_ = current_->Next(*token_); - } - return *this; -} - -CordzSampleToken::Iterator CordzSampleToken::Iterator::operator++(int) { - Iterator it(*this); - operator++(); - return it; -} - -bool operator==(const CordzSampleToken::Iterator& lhs, - const CordzSampleToken::Iterator& rhs) { - return lhs.current_ == rhs.current_ && - (lhs.current_ == nullptr || lhs.token_ == rhs.token_); -} - -bool operator!=(const CordzSampleToken::Iterator& lhs, - const CordzSampleToken::Iterator& rhs) { - return !(lhs == rhs); -} - -CordzSampleToken::Iterator::reference CordzSampleToken::Iterator::operator*() - const { - return *current_; -} - -CordzSampleToken::Iterator::pointer CordzSampleToken::Iterator::operator->() - const { - return current_; -} - -CordzSampleToken::Iterator::Iterator(const CordzSampleToken* token) - : token_(token), current_(CordzInfo::Head(*token)) {} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace y_absl +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "y_absl/strings/internal/cordz_sample_token.h" + +#include "y_absl/base/config.h" +#include "y_absl/strings/internal/cordz_handle.h" +#include "y_absl/strings/internal/cordz_info.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +CordzSampleToken::Iterator& CordzSampleToken::Iterator::operator++() { + if (current_) { + current_ = current_->Next(*token_); + } + return *this; +} + +CordzSampleToken::Iterator CordzSampleToken::Iterator::operator++(int) { + Iterator it(*this); + operator++(); + return it; +} + +bool operator==(const CordzSampleToken::Iterator& lhs, + const CordzSampleToken::Iterator& rhs) { + return lhs.current_ == rhs.current_ && + (lhs.current_ == nullptr || lhs.token_ == rhs.token_); +} + +bool operator!=(const CordzSampleToken::Iterator& lhs, + const CordzSampleToken::Iterator& rhs) { + return !(lhs == rhs); +} + +CordzSampleToken::Iterator::reference CordzSampleToken::Iterator::operator*() + const { + return *current_; +} + +CordzSampleToken::Iterator::pointer CordzSampleToken::Iterator::operator->() + const { + return current_; +} + +CordzSampleToken::Iterator::Iterator(const CordzSampleToken* token) + : token_(token), current_(CordzInfo::Head(*token)) {} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_sample_token.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_sample_token.h index 85bed6dae8..ae4aea50b6 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_sample_token.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_sample_token.h @@ -1,97 +1,97 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "y_absl/base/config.h" -#include "y_absl/strings/internal/cordz_handle.h" -#include "y_absl/strings/internal/cordz_info.h" - -#ifndef ABSL_STRINGS_CORDZ_SAMPLE_TOKEN_H_ -#define ABSL_STRINGS_CORDZ_SAMPLE_TOKEN_H_ - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -// The existence of a CordzSampleToken guarantees that a reader can traverse the -// global_cordz_infos_head linked-list without needing to hold a mutex. When a -// CordzSampleToken exists, all CordzInfo objects that would be destroyed are -// instead appended to a deletion queue. When the CordzSampleToken is destroyed, -// it will also clean up any of these CordzInfo objects. -// -// E.g., ST are CordzSampleToken objects and CH are CordzHandle objects. -// ST1 <- CH1 <- CH2 <- ST2 <- CH3 <- global_delete_queue_tail -// -// This list tracks that CH1 and CH2 were created after ST1, so the thread -// holding ST1 might have a referece to CH1, CH2, ST2, and CH3. However, ST2 was -// created later, so the thread holding the ST2 token cannot have a reference to -// ST1, CH1, or CH2. If ST1 is cleaned up first, that thread will delete ST1, -// CH1, and CH2. If instead ST2 is cleaned up first, that thread will only -// delete ST2. -// -// If ST1 is cleaned up first, the new list will be: -// ST2 <- CH3 <- global_delete_queue_tail -// -// If ST2 is cleaned up first, the new list will be: -// ST1 <- CH1 <- CH2 <- CH3 <- global_delete_queue_tail -// -// All new CordzHandle objects are appended to the list, so if a new thread -// comes along before either ST1 or ST2 are cleaned up, the new list will be: -// ST1 <- CH1 <- CH2 <- ST2 <- CH3 <- ST3 <- global_delete_queue_tail -// -// A thread must hold the global_delete_queue_mu mutex whenever it's altering -// this list. -// -// It is safe for thread that holds a CordzSampleToken to read -// global_cordz_infos at any time since the objects it is able to retrieve will -// not be deleted while the CordzSampleToken exists. -class CordzSampleToken : public CordzSnapshot { - public: - class Iterator { - public: - using iterator_category = std::input_iterator_tag; - using value_type = const CordzInfo&; - using difference_type = ptrdiff_t; - using pointer = const CordzInfo*; - using reference = value_type; - - Iterator() = default; - - Iterator& operator++(); - Iterator operator++(int); - friend bool operator==(const Iterator& lhs, const Iterator& rhs); - friend bool operator!=(const Iterator& lhs, const Iterator& rhs); - reference operator*() const; - pointer operator->() const; - - private: - friend class CordzSampleToken; - explicit Iterator(const CordzSampleToken* token); - - const CordzSampleToken* token_ = nullptr; - pointer current_ = nullptr; - }; - - CordzSampleToken() = default; - CordzSampleToken(const CordzSampleToken&) = delete; - CordzSampleToken& operator=(const CordzSampleToken&) = delete; - - Iterator begin() { return Iterator(this); } - Iterator end() { return Iterator(); } -}; - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace y_absl - -#endif // ABSL_STRINGS_CORDZ_SAMPLE_TOKEN_H_ +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "y_absl/base/config.h" +#include "y_absl/strings/internal/cordz_handle.h" +#include "y_absl/strings/internal/cordz_info.h" + +#ifndef ABSL_STRINGS_CORDZ_SAMPLE_TOKEN_H_ +#define ABSL_STRINGS_CORDZ_SAMPLE_TOKEN_H_ + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +// The existence of a CordzSampleToken guarantees that a reader can traverse the +// global_cordz_infos_head linked-list without needing to hold a mutex. When a +// CordzSampleToken exists, all CordzInfo objects that would be destroyed are +// instead appended to a deletion queue. When the CordzSampleToken is destroyed, +// it will also clean up any of these CordzInfo objects. +// +// E.g., ST are CordzSampleToken objects and CH are CordzHandle objects. +// ST1 <- CH1 <- CH2 <- ST2 <- CH3 <- global_delete_queue_tail +// +// This list tracks that CH1 and CH2 were created after ST1, so the thread +// holding ST1 might have a referece to CH1, CH2, ST2, and CH3. However, ST2 was +// created later, so the thread holding the ST2 token cannot have a reference to +// ST1, CH1, or CH2. If ST1 is cleaned up first, that thread will delete ST1, +// CH1, and CH2. If instead ST2 is cleaned up first, that thread will only +// delete ST2. +// +// If ST1 is cleaned up first, the new list will be: +// ST2 <- CH3 <- global_delete_queue_tail +// +// If ST2 is cleaned up first, the new list will be: +// ST1 <- CH1 <- CH2 <- CH3 <- global_delete_queue_tail +// +// All new CordzHandle objects are appended to the list, so if a new thread +// comes along before either ST1 or ST2 are cleaned up, the new list will be: +// ST1 <- CH1 <- CH2 <- ST2 <- CH3 <- ST3 <- global_delete_queue_tail +// +// A thread must hold the global_delete_queue_mu mutex whenever it's altering +// this list. +// +// It is safe for thread that holds a CordzSampleToken to read +// global_cordz_infos at any time since the objects it is able to retrieve will +// not be deleted while the CordzSampleToken exists. +class CordzSampleToken : public CordzSnapshot { + public: + class Iterator { + public: + using iterator_category = std::input_iterator_tag; + using value_type = const CordzInfo&; + using difference_type = ptrdiff_t; + using pointer = const CordzInfo*; + using reference = value_type; + + Iterator() = default; + + Iterator& operator++(); + Iterator operator++(int); + friend bool operator==(const Iterator& lhs, const Iterator& rhs); + friend bool operator!=(const Iterator& lhs, const Iterator& rhs); + reference operator*() const; + pointer operator->() const; + + private: + friend class CordzSampleToken; + explicit Iterator(const CordzSampleToken* token); + + const CordzSampleToken* token_ = nullptr; + pointer current_ = nullptr; + }; + + CordzSampleToken() = default; + CordzSampleToken(const CordzSampleToken&) = delete; + CordzSampleToken& operator=(const CordzSampleToken&) = delete; + + Iterator begin() { return Iterator(this); } + Iterator end() { return Iterator(); } +}; + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace y_absl + +#endif // ABSL_STRINGS_CORDZ_SAMPLE_TOKEN_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_sample_token/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_sample_token/ya.make index 4d46274f4e..6a14824712 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_sample_token/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_sample_token/ya.make @@ -1,52 +1,52 @@ -# Generated by devtools/yamaker. - -LIBRARY() - -WITHOUT_LICENSE_TEXTS() - -OWNER( - somov - g:cpp-contrib -) - -LICENSE(Apache-2.0) - -PEERDIR( - contrib/restricted/abseil-cpp-tstring/y_absl/base - contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/low_level_alloc - contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/raw_logging - contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock_wait - contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/throw_delegate - contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity - contrib/restricted/abseil-cpp-tstring/y_absl/debugging - contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace - contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize - contrib/restricted/abseil-cpp-tstring/y_absl/demangle - contrib/restricted/abseil-cpp-tstring/y_absl/numeric - contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased - contrib/restricted/abseil-cpp-tstring/y_absl/strings - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_cord_internal - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info - contrib/restricted/abseil-cpp-tstring/y_absl/synchronization - contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal - contrib/restricted/abseil-cpp-tstring/y_absl/time - contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time - contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone -) - -ADDINCL( - GLOBAL contrib/restricted/abseil-cpp-tstring -) - -NO_COMPILER_WARNINGS() - -SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal) - -SRCS( - cordz_sample_token.cc -) - -END() +# Generated by devtools/yamaker. + +LIBRARY() + +WITHOUT_LICENSE_TEXTS() + +OWNER( + somov + g:cpp-contrib +) + +LICENSE(Apache-2.0) + +PEERDIR( + contrib/restricted/abseil-cpp-tstring/y_absl/base + contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/raw_logging + contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/spinlock_wait + contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/throw_delegate + contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity + contrib/restricted/abseil-cpp-tstring/y_absl/debugging + contrib/restricted/abseil-cpp-tstring/y_absl/debugging/stacktrace + contrib/restricted/abseil-cpp-tstring/y_absl/debugging/symbolize + contrib/restricted/abseil-cpp-tstring/y_absl/demangle + contrib/restricted/abseil-cpp-tstring/y_absl/numeric + contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp-tstring/y_absl/strings + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_cord_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info + contrib/restricted/abseil-cpp-tstring/y_absl/synchronization + contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal + contrib/restricted/abseil-cpp-tstring/y_absl/time + contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time + contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone +) + +ADDINCL( + GLOBAL contrib/restricted/abseil-cpp-tstring +) + +NO_COMPILER_WARNINGS() + +SRCDIR(contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal) + +SRCS( + cordz_sample_token.cc +) + +END() diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_statistics.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_statistics.h index 34e7c34bd8..fbee9dd1c2 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_statistics.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_statistics.h @@ -1,87 +1,87 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_INTERNAL_CORDZ_STATISTICS_H_ -#define ABSL_STRINGS_INTERNAL_CORDZ_STATISTICS_H_ - -#include <cstdint> - -#include "y_absl/base/config.h" -#include "y_absl/strings/internal/cordz_update_tracker.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -// CordzStatistics captures some meta information about a Cord's shape. -struct CordzStatistics { - using MethodIdentifier = CordzUpdateTracker::MethodIdentifier; - - // Node counts information - struct NodeCounts { - size_t flat = 0; // #flats - size_t flat_64 = 0; // #flats up to 64 bytes - size_t flat_128 = 0; // #flats up to 128 bytes - size_t flat_256 = 0; // #flats up to 256 bytes - size_t flat_512 = 0; // #flats up to 512 bytes - size_t flat_1k = 0; // #flats up to 1K bytes - size_t external = 0; // #external reps - size_t substring = 0; // #substring reps - size_t concat = 0; // #concat reps - size_t ring = 0; // #ring buffer reps - size_t btree = 0; // #btree reps - }; - - // The size of the cord in bytes. This matches the result of Cord::size(). - int64_t size = 0; - - // The estimated memory used by the sampled cord. This value matches the - // value as reported by Cord::EstimatedMemoryUsage(). - // A value of 0 implies the property has not been recorded. - int64_t estimated_memory_usage = 0; - - // The effective memory used by the sampled cord, inversely weighted by the - // effective indegree of each allocated node. This is a representation of the - // fair share of memory usage that should be attributed to the sampled cord. - // This value is more useful for cases where one or more nodes are referenced - // by multiple Cord instances, and for cases where a Cord includes the same - // node multiple times (either directly or indirectly). - // A value of 0 implies the property has not been recorded. - int64_t estimated_fair_share_memory_usage = 0; - - // The total number of nodes referenced by this cord. - // For ring buffer Cords, this includes the 'ring buffer' node. - // For btree Cords, this includes all 'CordRepBtree' tree nodes as well as all - // the substring, flat and external nodes referenced by the tree. - // A value of 0 implies the property has not been recorded. - int64_t node_count = 0; - - // Detailed node counts per type - NodeCounts node_counts; - - // The cord method responsible for sampling the cord. - MethodIdentifier method = MethodIdentifier::kUnknown; - - // The cord method responsible for sampling the parent cord if applicable. - MethodIdentifier parent_method = MethodIdentifier::kUnknown; - - // Update tracker tracking invocation count per cord method. - CordzUpdateTracker update_tracker; -}; - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace y_absl - -#endif // ABSL_STRINGS_INTERNAL_CORDZ_STATISTICS_H_ +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_INTERNAL_CORDZ_STATISTICS_H_ +#define ABSL_STRINGS_INTERNAL_CORDZ_STATISTICS_H_ + +#include <cstdint> + +#include "y_absl/base/config.h" +#include "y_absl/strings/internal/cordz_update_tracker.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +// CordzStatistics captures some meta information about a Cord's shape. +struct CordzStatistics { + using MethodIdentifier = CordzUpdateTracker::MethodIdentifier; + + // Node counts information + struct NodeCounts { + size_t flat = 0; // #flats + size_t flat_64 = 0; // #flats up to 64 bytes + size_t flat_128 = 0; // #flats up to 128 bytes + size_t flat_256 = 0; // #flats up to 256 bytes + size_t flat_512 = 0; // #flats up to 512 bytes + size_t flat_1k = 0; // #flats up to 1K bytes + size_t external = 0; // #external reps + size_t substring = 0; // #substring reps + size_t concat = 0; // #concat reps + size_t ring = 0; // #ring buffer reps + size_t btree = 0; // #btree reps + }; + + // The size of the cord in bytes. This matches the result of Cord::size(). + int64_t size = 0; + + // The estimated memory used by the sampled cord. This value matches the + // value as reported by Cord::EstimatedMemoryUsage(). + // A value of 0 implies the property has not been recorded. + int64_t estimated_memory_usage = 0; + + // The effective memory used by the sampled cord, inversely weighted by the + // effective indegree of each allocated node. This is a representation of the + // fair share of memory usage that should be attributed to the sampled cord. + // This value is more useful for cases where one or more nodes are referenced + // by multiple Cord instances, and for cases where a Cord includes the same + // node multiple times (either directly or indirectly). + // A value of 0 implies the property has not been recorded. + int64_t estimated_fair_share_memory_usage = 0; + + // The total number of nodes referenced by this cord. + // For ring buffer Cords, this includes the 'ring buffer' node. + // For btree Cords, this includes all 'CordRepBtree' tree nodes as well as all + // the substring, flat and external nodes referenced by the tree. + // A value of 0 implies the property has not been recorded. + int64_t node_count = 0; + + // Detailed node counts per type + NodeCounts node_counts; + + // The cord method responsible for sampling the cord. + MethodIdentifier method = MethodIdentifier::kUnknown; + + // The cord method responsible for sampling the parent cord if applicable. + MethodIdentifier parent_method = MethodIdentifier::kUnknown; + + // Update tracker tracking invocation count per cord method. + CordzUpdateTracker update_tracker; +}; + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace y_absl + +#endif // ABSL_STRINGS_INTERNAL_CORDZ_STATISTICS_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_update_scope.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_update_scope.h index 66e0e8f51b..a8495c0503 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_update_scope.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_update_scope.h @@ -1,71 +1,71 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_SCOPE_H_ -#define ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_SCOPE_H_ - -#include "y_absl/base/config.h" -#include "y_absl/base/optimization.h" -#include "y_absl/base/thread_annotations.h" -#include "y_absl/strings/internal/cord_internal.h" -#include "y_absl/strings/internal/cordz_info.h" -#include "y_absl/strings/internal/cordz_update_tracker.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -// CordzUpdateScope scopes an update to the provided CordzInfo. -// The class invokes `info->Lock(method)` and `info->Unlock()` to guard -// cordrep updates. This class does nothing if `info` is null. -// See also the 'Lock`, `Unlock` and `SetCordRep` methods in `CordzInfo`. -class ABSL_SCOPED_LOCKABLE CordzUpdateScope { - public: - CordzUpdateScope(CordzInfo* info, CordzUpdateTracker::MethodIdentifier method) - ABSL_EXCLUSIVE_LOCK_FUNCTION(info) - : info_(info) { - if (ABSL_PREDICT_FALSE(info_)) { - info->Lock(method); - } - } - - // CordzUpdateScope can not be copied or assigned to. - CordzUpdateScope(CordzUpdateScope&& rhs) = delete; - CordzUpdateScope(const CordzUpdateScope&) = delete; - CordzUpdateScope& operator=(CordzUpdateScope&& rhs) = delete; - CordzUpdateScope& operator=(const CordzUpdateScope&) = delete; - - ~CordzUpdateScope() ABSL_UNLOCK_FUNCTION() { - if (ABSL_PREDICT_FALSE(info_)) { - info_->Unlock(); - } - } - - void SetCordRep(CordRep* rep) const { - if (ABSL_PREDICT_FALSE(info_)) { - info_->SetCordRep(rep); - } - } - - CordzInfo* info() const { return info_; } - - private: - CordzInfo* info_; -}; - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace y_absl - -#endif // ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_SCOPE_H_ +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_SCOPE_H_ +#define ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_SCOPE_H_ + +#include "y_absl/base/config.h" +#include "y_absl/base/optimization.h" +#include "y_absl/base/thread_annotations.h" +#include "y_absl/strings/internal/cord_internal.h" +#include "y_absl/strings/internal/cordz_info.h" +#include "y_absl/strings/internal/cordz_update_tracker.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +// CordzUpdateScope scopes an update to the provided CordzInfo. +// The class invokes `info->Lock(method)` and `info->Unlock()` to guard +// cordrep updates. This class does nothing if `info` is null. +// See also the 'Lock`, `Unlock` and `SetCordRep` methods in `CordzInfo`. +class ABSL_SCOPED_LOCKABLE CordzUpdateScope { + public: + CordzUpdateScope(CordzInfo* info, CordzUpdateTracker::MethodIdentifier method) + ABSL_EXCLUSIVE_LOCK_FUNCTION(info) + : info_(info) { + if (ABSL_PREDICT_FALSE(info_)) { + info->Lock(method); + } + } + + // CordzUpdateScope can not be copied or assigned to. + CordzUpdateScope(CordzUpdateScope&& rhs) = delete; + CordzUpdateScope(const CordzUpdateScope&) = delete; + CordzUpdateScope& operator=(CordzUpdateScope&& rhs) = delete; + CordzUpdateScope& operator=(const CordzUpdateScope&) = delete; + + ~CordzUpdateScope() ABSL_UNLOCK_FUNCTION() { + if (ABSL_PREDICT_FALSE(info_)) { + info_->Unlock(); + } + } + + void SetCordRep(CordRep* rep) const { + if (ABSL_PREDICT_FALSE(info_)) { + info_->SetCordRep(rep); + } + } + + CordzInfo* info() const { return info_; } + + private: + CordzInfo* info_; +}; + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace y_absl + +#endif // ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_SCOPE_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_update_tracker.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_update_tracker.h index 48a449b4bf..670ecffcec 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_update_tracker.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_update_tracker.h @@ -1,121 +1,121 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_TRACKER_H_ -#define ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_TRACKER_H_ - -#include <atomic> -#include <cstdint> - -#include "y_absl/base/config.h" - -namespace y_absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -// CordzUpdateTracker tracks counters for Cord update methods. -// -// The purpose of CordzUpdateTracker is to track the number of calls to methods -// updating Cord data for sampled cords. The class internally uses 'lossy' -// atomic operations: Cord is thread-compatible, so there is no need to -// synchronize updates. However, Cordz collection threads may call 'Value()' at -// any point, so the class needs to provide thread safe access. -// -// This class is thread-safe. But as per above comments, all non-const methods -// should be used single-threaded only: updates are thread-safe but lossy. -class CordzUpdateTracker { - public: - // Tracked update methods. - enum MethodIdentifier { - kUnknown, - kAppendBuffer, - kAppendCord, - kAppendExternalMemory, - kAppendString, - kAssignCord, - kAssignString, - kClear, - kConstructorCord, - kConstructorString, - kCordReader, - kFlatten, - kGetAppendRegion, - kMakeCordFromExternal, - kMoveAppendCord, - kMoveAssignCord, - kMovePrependCord, - kPrependBuffer, - kPrependCord, - kPrependString, - kRemovePrefix, - kRemoveSuffix, - kSubCord, - - // kNumMethods defines the number of entries: must be the last entry. - kNumMethods, - }; - - // Constructs a new instance. All counters are zero-initialized. - constexpr CordzUpdateTracker() noexcept : values_{} {} - - // Copy constructs a new instance. - CordzUpdateTracker(const CordzUpdateTracker& rhs) noexcept { *this = rhs; } - - // Assigns the provided value to this instance. - CordzUpdateTracker& operator=(const CordzUpdateTracker& rhs) noexcept { - for (int i = 0; i < kNumMethods; ++i) { - values_[i].store(rhs.values_[i].load(std::memory_order_relaxed), - std::memory_order_relaxed); - } - return *this; - } - - // Returns the value for the specified method. - int64_t Value(MethodIdentifier method) const { - return values_[method].load(std::memory_order_relaxed); - } - - // Increases the value for the specified method by `n` - void LossyAdd(MethodIdentifier method, int64_t n = 1) { - auto& value = values_[method]; - value.store(value.load(std::memory_order_relaxed) + n, - std::memory_order_relaxed); - } - - // Adds all the values from `src` to this instance - void LossyAdd(const CordzUpdateTracker& src) { - for (int i = 0; i < kNumMethods; ++i) { - MethodIdentifier method = static_cast<MethodIdentifier>(i); - if (int64_t value = src.Value(method)) { - LossyAdd(method, value); - } - } - } - - private: - // Until C++20 std::atomic is not constexpr default-constructible, so we need - // a wrapper for this class to be constexpr constructible. - class Counter : public std::atomic<int64_t> { - public: - constexpr Counter() noexcept : std::atomic<int64_t>(0) {} - }; - - Counter values_[kNumMethods]; -}; - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace y_absl - -#endif // ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_TRACKER_H_ +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_TRACKER_H_ +#define ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_TRACKER_H_ + +#include <atomic> +#include <cstdint> + +#include "y_absl/base/config.h" + +namespace y_absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +// CordzUpdateTracker tracks counters for Cord update methods. +// +// The purpose of CordzUpdateTracker is to track the number of calls to methods +// updating Cord data for sampled cords. The class internally uses 'lossy' +// atomic operations: Cord is thread-compatible, so there is no need to +// synchronize updates. However, Cordz collection threads may call 'Value()' at +// any point, so the class needs to provide thread safe access. +// +// This class is thread-safe. But as per above comments, all non-const methods +// should be used single-threaded only: updates are thread-safe but lossy. +class CordzUpdateTracker { + public: + // Tracked update methods. + enum MethodIdentifier { + kUnknown, + kAppendBuffer, + kAppendCord, + kAppendExternalMemory, + kAppendString, + kAssignCord, + kAssignString, + kClear, + kConstructorCord, + kConstructorString, + kCordReader, + kFlatten, + kGetAppendRegion, + kMakeCordFromExternal, + kMoveAppendCord, + kMoveAssignCord, + kMovePrependCord, + kPrependBuffer, + kPrependCord, + kPrependString, + kRemovePrefix, + kRemoveSuffix, + kSubCord, + + // kNumMethods defines the number of entries: must be the last entry. + kNumMethods, + }; + + // Constructs a new instance. All counters are zero-initialized. + constexpr CordzUpdateTracker() noexcept : values_{} {} + + // Copy constructs a new instance. + CordzUpdateTracker(const CordzUpdateTracker& rhs) noexcept { *this = rhs; } + + // Assigns the provided value to this instance. + CordzUpdateTracker& operator=(const CordzUpdateTracker& rhs) noexcept { + for (int i = 0; i < kNumMethods; ++i) { + values_[i].store(rhs.values_[i].load(std::memory_order_relaxed), + std::memory_order_relaxed); + } + return *this; + } + + // Returns the value for the specified method. + int64_t Value(MethodIdentifier method) const { + return values_[method].load(std::memory_order_relaxed); + } + + // Increases the value for the specified method by `n` + void LossyAdd(MethodIdentifier method, int64_t n = 1) { + auto& value = values_[method]; + value.store(value.load(std::memory_order_relaxed) + n, + std::memory_order_relaxed); + } + + // Adds all the values from `src` to this instance + void LossyAdd(const CordzUpdateTracker& src) { + for (int i = 0; i < kNumMethods; ++i) { + MethodIdentifier method = static_cast<MethodIdentifier>(i); + if (int64_t value = src.Value(method)) { + LossyAdd(method, value); + } + } + } + + private: + // Until C++20 std::atomic is not constexpr default-constructible, so we need + // a wrapper for this class to be constexpr constructible. + class Counter : public std::atomic<int64_t> { + public: + constexpr Counter() noexcept : std::atomic<int64_t>(0) {} + }; + + Counter values_[kNumMethods]; +}; + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace y_absl + +#endif // ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_TRACKER_H_ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/resize_uninitialized.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/resize_uninitialized.h index 14860bb237..70ad53c714 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/resize_uninitialized.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/resize_uninitialized.h @@ -17,7 +17,7 @@ #ifndef ABSL_STRINGS_INTERNAL_RESIZE_UNINITIALIZED_H_ #define ABSL_STRINGS_INTERNAL_RESIZE_UNINITIALIZED_H_ -#include <algorithm> +#include <algorithm> #include <util/generic/string.h> #include <type_traits> #include <utility> @@ -29,9 +29,9 @@ namespace y_absl { ABSL_NAMESPACE_BEGIN namespace strings_internal { -// In this type trait, we look for a __resize_default_init member function, and -// we use it if available, otherwise, we use resize. We provide HasMember to -// indicate whether __resize_default_init is present. +// In this type trait, we look for a __resize_default_init member function, and +// we use it if available, otherwise, we use resize. We provide HasMember to +// indicate whether __resize_default_init is present. template <typename string_type, typename = void> struct ResizeUninitializedTraits { using HasMember = std::false_type; @@ -68,50 +68,50 @@ inline void STLStringResizeUninitialized(string_type* s, size_t new_size) { ResizeUninitializedTraits<string_type>::Resize(s, new_size); } -// Used to ensure exponential growth so that the amortized complexity of -// increasing the string size by a small amount is O(1), in contrast to -// O(str->size()) in the case of precise growth. -template <typename string_type> -void STLStringReserveAmortized(string_type* s, size_t new_size) { - const size_t cap = s->capacity(); - if (new_size > cap) { - // Make sure to always grow by at least a factor of 2x. - s->reserve((std::max)(new_size, 2 * cap)); - } -} - -// In this type trait, we look for an __append_default_init member function, and -// we use it if available, otherwise, we use append. -template <typename string_type, typename = void> -struct AppendUninitializedTraits { - static void Append(string_type* s, size_t n) { - s->append(n, typename string_type::value_type()); - } -}; - -template <typename string_type> -struct AppendUninitializedTraits< - string_type, y_absl::void_t<decltype(std::declval<string_type&>() - .__append_default_init(237))> > { - static void Append(string_type* s, size_t n) { - s->__append_default_init(n); - } -}; - -// Like STLStringResizeUninitialized(str, new_size), except guaranteed to use -// exponential growth so that the amortized complexity of increasing the string -// size by a small amount is O(1), in contrast to O(str->size()) in the case of -// precise growth. -template <typename string_type> -void STLStringResizeUninitializedAmortized(string_type* s, size_t new_size) { - const size_t size = s->size(); - if (new_size > size) { - AppendUninitializedTraits<string_type>::Append(s, new_size - size); - } else { - s->erase(new_size); - } -} - +// Used to ensure exponential growth so that the amortized complexity of +// increasing the string size by a small amount is O(1), in contrast to +// O(str->size()) in the case of precise growth. +template <typename string_type> +void STLStringReserveAmortized(string_type* s, size_t new_size) { + const size_t cap = s->capacity(); + if (new_size > cap) { + // Make sure to always grow by at least a factor of 2x. + s->reserve((std::max)(new_size, 2 * cap)); + } +} + +// In this type trait, we look for an __append_default_init member function, and +// we use it if available, otherwise, we use append. +template <typename string_type, typename = void> +struct AppendUninitializedTraits { + static void Append(string_type* s, size_t n) { + s->append(n, typename string_type::value_type()); + } +}; + +template <typename string_type> +struct AppendUninitializedTraits< + string_type, y_absl::void_t<decltype(std::declval<string_type&>() + .__append_default_init(237))> > { + static void Append(string_type* s, size_t n) { + s->__append_default_init(n); + } +}; + +// Like STLStringResizeUninitialized(str, new_size), except guaranteed to use +// exponential growth so that the amortized complexity of increasing the string +// size by a small amount is O(1), in contrast to O(str->size()) in the case of +// precise growth. +template <typename string_type> +void STLStringResizeUninitializedAmortized(string_type* s, size_t new_size) { + const size_t size = s->size(); + if (new_size > size) { + AppendUninitializedTraits<string_type>::Append(s, new_size - size); + } else { + s->erase(new_size); + } +} + } // namespace strings_internal ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/arg.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/arg.h index 59b7bcc727..fef5fa1c1f 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/arg.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/arg.h @@ -123,14 +123,14 @@ StringConvertResult FormatConvertImpl(const TString& v, StringConvertResult FormatConvertImpl(string_view v, FormatConversionSpecImpl conv, FormatSinkImpl* sink); -#if defined(ABSL_HAVE_STD_STRING_VIEW) && !defined(ABSL_USES_STD_STRING_VIEW) -inline StringConvertResult FormatConvertImpl(std::string_view v, - FormatConversionSpecImpl conv, - FormatSinkImpl* sink) { - return FormatConvertImpl(y_absl::string_view(v.data(), v.size()), conv, sink); -} -#endif // ABSL_HAVE_STD_STRING_VIEW && !ABSL_USES_STD_STRING_VIEW - +#if defined(ABSL_HAVE_STD_STRING_VIEW) && !defined(ABSL_USES_STD_STRING_VIEW) +inline StringConvertResult FormatConvertImpl(std::string_view v, + FormatConversionSpecImpl conv, + FormatSinkImpl* sink) { + return FormatConvertImpl(y_absl::string_view(v.data(), v.size()), conv, sink); +} +#endif // ABSL_HAVE_STD_STRING_VIEW && !ABSL_USES_STD_STRING_VIEW + ArgConvertResult<FormatConversionCharSetUnion( FormatConversionCharSetInternal::s, FormatConversionCharSetInternal::p)> FormatConvertImpl(const char* v, const FormatConversionSpecImpl conv, diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/bind.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/bind.cc index 211ce25dea..534a739440 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/bind.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/bind.cc @@ -58,7 +58,7 @@ inline bool ArgContext::Bind(const UnboundConversion* unbound, if (static_cast<size_t>(arg_position - 1) >= pack_.size()) return false; arg = &pack_[arg_position - 1]; // 1-based - if (unbound->flags != Flags::kBasic) { + if (unbound->flags != Flags::kBasic) { int width = unbound->width.value(); bool force_left = false; if (unbound->width.is_from_arg()) { @@ -84,8 +84,8 @@ inline bool ArgContext::Bind(const UnboundConversion* unbound, FormatConversionSpecImplFriend::SetPrecision(precision, bound); if (force_left) { - FormatConversionSpecImplFriend::SetFlags(unbound->flags | Flags::kLeft, - bound); + FormatConversionSpecImplFriend::SetFlags(unbound->flags | Flags::kLeft, + bound); } else { FormatConversionSpecImplFriend::SetFlags(unbound->flags, bound); } diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/bind.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/bind.h index 3966610710..547cabcb90 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/bind.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/bind.h @@ -100,7 +100,7 @@ class FormatSpecTemplate // We use the 'unavailable' attribute to give a better compiler error than // just 'method is deleted'. // To avoid checking the format twice, we just check that the format is - // constexpr. If it is valid, then the overload below will kick in. + // constexpr. If it is valid, then the overload below will kick in. // We add the template here to make this overload have lower priority. template <typename = void> FormatSpecTemplate(const char* s) // NOLINT diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/extension.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/extension.cc index f2a4169ae7..dd72c071f6 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/extension.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/extension.cc @@ -23,13 +23,13 @@ namespace y_absl { ABSL_NAMESPACE_BEGIN namespace str_format_internal { -TString FlagsToString(Flags v) { +TString FlagsToString(Flags v) { TString s; - s.append(FlagsContains(v, Flags::kLeft) ? "-" : ""); - s.append(FlagsContains(v, Flags::kShowPos) ? "+" : ""); - s.append(FlagsContains(v, Flags::kSignCol) ? " " : ""); - s.append(FlagsContains(v, Flags::kAlt) ? "#" : ""); - s.append(FlagsContains(v, Flags::kZero) ? "0" : ""); + s.append(FlagsContains(v, Flags::kLeft) ? "-" : ""); + s.append(FlagsContains(v, Flags::kShowPos) ? "+" : ""); + s.append(FlagsContains(v, Flags::kSignCol) ? " " : ""); + s.append(FlagsContains(v, Flags::kAlt) ? "#" : ""); + s.append(FlagsContains(v, Flags::kZero) ? "0" : ""); return s; } diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/extension.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/extension.h index e5de5cb6a1..70a35342c4 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/extension.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/extension.h @@ -128,33 +128,33 @@ class FormatSinkImpl { char buf_[1024]; }; -enum class Flags : uint8_t { - kBasic = 0, - kLeft = 1 << 0, - kShowPos = 1 << 1, - kSignCol = 1 << 2, - kAlt = 1 << 3, - kZero = 1 << 4, - // This is not a real flag. It just exists to turn off kBasic when no other - // flags are set. This is for when width/precision are specified. - kNonBasic = 1 << 5, +enum class Flags : uint8_t { + kBasic = 0, + kLeft = 1 << 0, + kShowPos = 1 << 1, + kSignCol = 1 << 2, + kAlt = 1 << 3, + kZero = 1 << 4, + // This is not a real flag. It just exists to turn off kBasic when no other + // flags are set. This is for when width/precision are specified. + kNonBasic = 1 << 5, }; -constexpr Flags operator|(Flags a, Flags b) { - return static_cast<Flags>(static_cast<uint8_t>(a) | static_cast<uint8_t>(b)); -} - -constexpr bool FlagsContains(Flags haystack, Flags needle) { - return (static_cast<uint8_t>(haystack) & static_cast<uint8_t>(needle)) == - static_cast<uint8_t>(needle); -} - -TString FlagsToString(Flags v); - -inline std::ostream& operator<<(std::ostream& os, Flags v) { - return os << FlagsToString(v); -} - +constexpr Flags operator|(Flags a, Flags b) { + return static_cast<Flags>(static_cast<uint8_t>(a) | static_cast<uint8_t>(b)); +} + +constexpr bool FlagsContains(Flags haystack, Flags needle) { + return (static_cast<uint8_t>(haystack) & static_cast<uint8_t>(needle)) == + static_cast<uint8_t>(needle); +} + +TString FlagsToString(Flags v); + +inline std::ostream& operator<<(std::ostream& os, Flags v) { + return os << FlagsToString(v); +} + // clang-format off #define ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(X_VAL, X_SEP) \ /* text */ \ @@ -271,16 +271,16 @@ struct FormatConversionSpecImplFriend; class FormatConversionSpecImpl { public: // Width and precison are not specified, no flags are set. - bool is_basic() const { return flags_ == Flags::kBasic; } - bool has_left_flag() const { return FlagsContains(flags_, Flags::kLeft); } - bool has_show_pos_flag() const { - return FlagsContains(flags_, Flags::kShowPos); - } - bool has_sign_col_flag() const { - return FlagsContains(flags_, Flags::kSignCol); - } - bool has_alt_flag() const { return FlagsContains(flags_, Flags::kAlt); } - bool has_zero_flag() const { return FlagsContains(flags_, Flags::kZero); } + bool is_basic() const { return flags_ == Flags::kBasic; } + bool has_left_flag() const { return FlagsContains(flags_, Flags::kLeft); } + bool has_show_pos_flag() const { + return FlagsContains(flags_, Flags::kShowPos); + } + bool has_sign_col_flag() const { + return FlagsContains(flags_, Flags::kSignCol); + } + bool has_alt_flag() const { return FlagsContains(flags_, Flags::kAlt); } + bool has_zero_flag() const { return FlagsContains(flags_, Flags::kZero); } FormatConversionChar conversion_char() const { // Keep this field first in the struct . It generates better code when @@ -324,7 +324,7 @@ struct FormatConversionSpecImplFriend final { conv->precision_ = p; } static TString FlagsToString(const FormatConversionSpecImpl& spec) { - return str_format_internal::FlagsToString(spec.flags_); + return str_format_internal::FlagsToString(spec.flags_); } }; diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/parser.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/parser.cc index af07e32fe5..594b943151 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/parser.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/parser.cc @@ -34,67 +34,67 @@ namespace str_format_internal { using CC = FormatConversionCharInternal; using LM = LengthMod; -// Abbreviations to fit in the table below. -constexpr auto f_sign = Flags::kSignCol; -constexpr auto f_alt = Flags::kAlt; -constexpr auto f_pos = Flags::kShowPos; -constexpr auto f_left = Flags::kLeft; -constexpr auto f_zero = Flags::kZero; - +// Abbreviations to fit in the table below. +constexpr auto f_sign = Flags::kSignCol; +constexpr auto f_alt = Flags::kAlt; +constexpr auto f_pos = Flags::kShowPos; +constexpr auto f_left = Flags::kLeft; +constexpr auto f_zero = Flags::kZero; + ABSL_CONST_INIT const ConvTag kTags[256] = { - {}, {}, {}, {}, {}, {}, {}, {}, // 00-07 - {}, {}, {}, {}, {}, {}, {}, {}, // 08-0f - {}, {}, {}, {}, {}, {}, {}, {}, // 10-17 - {}, {}, {}, {}, {}, {}, {}, {}, // 18-1f - f_sign, {}, {}, f_alt, {}, {}, {}, {}, // !"#$%&' - {}, {}, {}, f_pos, {}, f_left, {}, {}, // ()*+,-./ - f_zero, {}, {}, {}, {}, {}, {}, {}, // 01234567 - {}, {}, {}, {}, {}, {}, {}, {}, // 89:;<=>? - {}, CC::A, {}, {}, {}, CC::E, CC::F, CC::G, // @ABCDEFG - {}, {}, {}, {}, LM::L, {}, {}, {}, // HIJKLMNO - {}, {}, {}, {}, {}, {}, {}, {}, // PQRSTUVW - CC::X, {}, {}, {}, {}, {}, {}, {}, // XYZ[\]^_ - {}, CC::a, {}, CC::c, CC::d, CC::e, CC::f, CC::g, // `abcdefg - LM::h, CC::i, LM::j, {}, LM::l, {}, CC::n, CC::o, // hijklmno - CC::p, LM::q, {}, CC::s, LM::t, CC::u, {}, {}, // pqrstuvw - CC::x, {}, LM::z, {}, {}, {}, {}, {}, // xyz{|}! - {}, {}, {}, {}, {}, {}, {}, {}, // 80-87 - {}, {}, {}, {}, {}, {}, {}, {}, // 88-8f - {}, {}, {}, {}, {}, {}, {}, {}, // 90-97 - {}, {}, {}, {}, {}, {}, {}, {}, // 98-9f - {}, {}, {}, {}, {}, {}, {}, {}, // a0-a7 - {}, {}, {}, {}, {}, {}, {}, {}, // a8-af - {}, {}, {}, {}, {}, {}, {}, {}, // b0-b7 - {}, {}, {}, {}, {}, {}, {}, {}, // b8-bf - {}, {}, {}, {}, {}, {}, {}, {}, // c0-c7 - {}, {}, {}, {}, {}, {}, {}, {}, // c8-cf - {}, {}, {}, {}, {}, {}, {}, {}, // d0-d7 - {}, {}, {}, {}, {}, {}, {}, {}, // d8-df - {}, {}, {}, {}, {}, {}, {}, {}, // e0-e7 - {}, {}, {}, {}, {}, {}, {}, {}, // e8-ef - {}, {}, {}, {}, {}, {}, {}, {}, // f0-f7 - {}, {}, {}, {}, {}, {}, {}, {}, // f8-ff + {}, {}, {}, {}, {}, {}, {}, {}, // 00-07 + {}, {}, {}, {}, {}, {}, {}, {}, // 08-0f + {}, {}, {}, {}, {}, {}, {}, {}, // 10-17 + {}, {}, {}, {}, {}, {}, {}, {}, // 18-1f + f_sign, {}, {}, f_alt, {}, {}, {}, {}, // !"#$%&' + {}, {}, {}, f_pos, {}, f_left, {}, {}, // ()*+,-./ + f_zero, {}, {}, {}, {}, {}, {}, {}, // 01234567 + {}, {}, {}, {}, {}, {}, {}, {}, // 89:;<=>? + {}, CC::A, {}, {}, {}, CC::E, CC::F, CC::G, // @ABCDEFG + {}, {}, {}, {}, LM::L, {}, {}, {}, // HIJKLMNO + {}, {}, {}, {}, {}, {}, {}, {}, // PQRSTUVW + CC::X, {}, {}, {}, {}, {}, {}, {}, // XYZ[\]^_ + {}, CC::a, {}, CC::c, CC::d, CC::e, CC::f, CC::g, // `abcdefg + LM::h, CC::i, LM::j, {}, LM::l, {}, CC::n, CC::o, // hijklmno + CC::p, LM::q, {}, CC::s, LM::t, CC::u, {}, {}, // pqrstuvw + CC::x, {}, LM::z, {}, {}, {}, {}, {}, // xyz{|}! + {}, {}, {}, {}, {}, {}, {}, {}, // 80-87 + {}, {}, {}, {}, {}, {}, {}, {}, // 88-8f + {}, {}, {}, {}, {}, {}, {}, {}, // 90-97 + {}, {}, {}, {}, {}, {}, {}, {}, // 98-9f + {}, {}, {}, {}, {}, {}, {}, {}, // a0-a7 + {}, {}, {}, {}, {}, {}, {}, {}, // a8-af + {}, {}, {}, {}, {}, {}, {}, {}, // b0-b7 + {}, {}, {}, {}, {}, {}, {}, {}, // b8-bf + {}, {}, {}, {}, {}, {}, {}, {}, // c0-c7 + {}, {}, {}, {}, {}, {}, {}, {}, // c8-cf + {}, {}, {}, {}, {}, {}, {}, {}, // d0-d7 + {}, {}, {}, {}, {}, {}, {}, {}, // d8-df + {}, {}, {}, {}, {}, {}, {}, {}, // e0-e7 + {}, {}, {}, {}, {}, {}, {}, {}, // e8-ef + {}, {}, {}, {}, {}, {}, {}, {}, // f0-f7 + {}, {}, {}, {}, {}, {}, {}, {}, // f8-ff }; namespace { bool CheckFastPathSetting(const UnboundConversion& conv) { - bool width_precision_needed = - conv.width.value() >= 0 || conv.precision.value() >= 0; - if (width_precision_needed && conv.flags == Flags::kBasic) { + bool width_precision_needed = + conv.width.value() >= 0 || conv.precision.value() >= 0; + if (width_precision_needed && conv.flags == Flags::kBasic) { fprintf(stderr, "basic=%d left=%d show_pos=%d sign_col=%d alt=%d zero=%d " "width=%d precision=%d\n", - conv.flags == Flags::kBasic ? 1 : 0, - FlagsContains(conv.flags, Flags::kLeft) ? 1 : 0, - FlagsContains(conv.flags, Flags::kShowPos) ? 1 : 0, - FlagsContains(conv.flags, Flags::kSignCol) ? 1 : 0, - FlagsContains(conv.flags, Flags::kAlt) ? 1 : 0, - FlagsContains(conv.flags, Flags::kZero) ? 1 : 0, conv.width.value(), - conv.precision.value()); - return false; + conv.flags == Flags::kBasic ? 1 : 0, + FlagsContains(conv.flags, Flags::kLeft) ? 1 : 0, + FlagsContains(conv.flags, Flags::kShowPos) ? 1 : 0, + FlagsContains(conv.flags, Flags::kSignCol) ? 1 : 0, + FlagsContains(conv.flags, Flags::kAlt) ? 1 : 0, + FlagsContains(conv.flags, Flags::kZero) ? 1 : 0, conv.width.value(), + conv.precision.value()); + return false; } - return true; + return true; } template <bool is_positional> @@ -138,19 +138,19 @@ const char *ConsumeConversion(const char *pos, const char *const end, ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR(); // We should start with the basic flag on. - assert(conv->flags == Flags::kBasic); + assert(conv->flags == Flags::kBasic); // Any non alpha character makes this conversion not basic. // This includes flags (-+ #0), width (1-9, *) or precision (.). // All conversion characters and length modifiers are alpha characters. if (c < 'A') { - while (c <= '0') { - auto tag = GetTagForChar(c); - if (tag.is_flags()) { - conv->flags = conv->flags | tag.as_flags(); - ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR(); - } else { - break; + while (c <= '0') { + auto tag = GetTagForChar(c); + if (tag.is_flags()) { + conv->flags = conv->flags | tag.as_flags(); + ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR(); + } else { + break; } } @@ -163,10 +163,10 @@ const char *ConsumeConversion(const char *pos, const char *const end, *next_arg = -1; return ConsumeConversion<true>(original_pos, end, conv, next_arg); } - conv->flags = conv->flags | Flags::kNonBasic; + conv->flags = conv->flags | Flags::kNonBasic; conv->width.set_value(maybe_width); } else if (c == '*') { - conv->flags = conv->flags | Flags::kNonBasic; + conv->flags = conv->flags | Flags::kNonBasic; ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR(); if (is_positional) { if (ABSL_PREDICT_FALSE(c < '1' || c > '9')) return nullptr; @@ -180,7 +180,7 @@ const char *ConsumeConversion(const char *pos, const char *const end, } if (c == '.') { - conv->flags = conv->flags | Flags::kNonBasic; + conv->flags = conv->flags | Flags::kNonBasic; ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR(); if (std::isdigit(c)) { conv->precision.set_value(parse_digits()); diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/parser.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/parser.h index ba614bb8b4..c8d38e5278 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/parser.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/parser.h @@ -41,7 +41,7 @@ TString LengthModToString(LengthMod v); // The analyzed properties of a single specified conversion. struct UnboundConversion { - UnboundConversion() {} + UnboundConversion() {} class InputValue { public: @@ -76,7 +76,7 @@ struct UnboundConversion { InputValue width; InputValue precision; - Flags flags = Flags::kBasic; + Flags flags = Flags::kBasic; LengthMod length_mod = LengthMod::none; FormatConversionChar conv = FormatConversionCharInternal::kNone; }; @@ -90,43 +90,43 @@ const char* ConsumeUnboundConversion(const char* p, const char* end, UnboundConversion* conv, int* next_arg); // Helper tag class for the table below. -// It allows fast `char -> ConversionChar/LengthMod/Flags` checking and +// It allows fast `char -> ConversionChar/LengthMod/Flags` checking and // conversions. class ConvTag { public: constexpr ConvTag(FormatConversionChar conversion_char) // NOLINT - : tag_(static_cast<uint8_t>(conversion_char)) {} + : tag_(static_cast<uint8_t>(conversion_char)) {} constexpr ConvTag(LengthMod length_mod) // NOLINT - : tag_(0x80 | static_cast<uint8_t>(length_mod)) {} - constexpr ConvTag(Flags flags) // NOLINT - : tag_(0xc0 | static_cast<uint8_t>(flags)) {} - constexpr ConvTag() : tag_(0xFF) {} - - bool is_conv() const { return (tag_ & 0x80) == 0; } - bool is_length() const { return (tag_ & 0xC0) == 0x80; } - bool is_flags() const { return (tag_ & 0xE0) == 0xC0; } - + : tag_(0x80 | static_cast<uint8_t>(length_mod)) {} + constexpr ConvTag(Flags flags) // NOLINT + : tag_(0xc0 | static_cast<uint8_t>(flags)) {} + constexpr ConvTag() : tag_(0xFF) {} + + bool is_conv() const { return (tag_ & 0x80) == 0; } + bool is_length() const { return (tag_ & 0xC0) == 0x80; } + bool is_flags() const { return (tag_ & 0xE0) == 0xC0; } + FormatConversionChar as_conv() const { assert(is_conv()); - assert(!is_length()); - assert(!is_flags()); + assert(!is_length()); + assert(!is_flags()); return static_cast<FormatConversionChar>(tag_); } LengthMod as_length() const { - assert(!is_conv()); + assert(!is_conv()); assert(is_length()); - assert(!is_flags()); - return static_cast<LengthMod>(tag_ & 0x3F); - } - Flags as_flags() const { - assert(!is_conv()); - assert(!is_length()); - assert(is_flags()); - return static_cast<Flags>(tag_ & 0x1F); + assert(!is_flags()); + return static_cast<LengthMod>(tag_ & 0x3F); } + Flags as_flags() const { + assert(!is_conv()); + assert(!is_length()); + assert(is_flags()); + return static_cast<Flags>(tag_ & 0x1F); + } private: - uint8_t tag_; + uint8_t tag_; }; extern const ConvTag kTags[256]; diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/ya.make index ff8069cd0f..ecc59f2d1c 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format/ya.make @@ -19,7 +19,7 @@ PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity contrib/restricted/abseil-cpp-tstring/y_absl/numeric contrib/restricted/abseil-cpp-tstring/y_absl/strings - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal ) ADDINCL( diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_split_internal.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_split_internal.h index 237864c0ed..31699a12bb 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_split_internal.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_split_internal.h @@ -32,7 +32,7 @@ #include <array> #include <initializer_list> #include <iterator> -#include <tuple> +#include <tuple> #include <type_traits> #include <utility> #include <vector> @@ -64,7 +64,7 @@ class ConvertibleToStringView { ConvertibleToStringView(const TString& s) // NOLINT(runtime/explicit) : value_(s) {} - // Disable conversion from rvalue strings. + // Disable conversion from rvalue strings. ConvertibleToStringView(TString&& s) = delete; ConvertibleToStringView(const TString&& s) = delete; @@ -182,13 +182,13 @@ template <typename T> struct HasConstIterator<T, y_absl::void_t<typename T::const_iterator>> : std::true_type {}; -// HasEmplace<T>::value is true iff there exists a method T::emplace(). -template <typename T, typename = void> -struct HasEmplace : std::false_type {}; -template <typename T> -struct HasEmplace<T, y_absl::void_t<decltype(std::declval<T>().emplace())>> - : std::true_type {}; - +// HasEmplace<T>::value is true iff there exists a method T::emplace(). +template <typename T, typename = void> +struct HasEmplace : std::false_type {}; +template <typename T> +struct HasEmplace<T, y_absl::void_t<decltype(std::declval<T>().emplace())>> + : std::true_type {}; + // IsInitializerList<T>::value is true iff T is an std::initializer_list. More // details below in Splitter<> where this is used. std::false_type IsInitializerListDispatch(...); // default: No @@ -379,43 +379,43 @@ class Splitter { // value. template <typename Container, typename First, typename Second> struct ConvertToContainer<Container, std::pair<const First, Second>, true> { - using iterator = typename Container::iterator; - + using iterator = typename Container::iterator; + Container operator()(const Splitter& splitter) const { Container m; - iterator it; + iterator it; bool insert = true; - for (const y_absl::string_view sv : splitter) { + for (const y_absl::string_view sv : splitter) { if (insert) { - it = InsertOrEmplace(&m, sv); + it = InsertOrEmplace(&m, sv); } else { - it->second = Second(sv); + it->second = Second(sv); } insert = !insert; } return m; } - // Inserts the key and an empty value into the map, returning an iterator to - // the inserted item. We use emplace() if available, otherwise insert(). - template <typename M> - static y_absl::enable_if_t<HasEmplace<M>::value, iterator> InsertOrEmplace( - M* m, y_absl::string_view key) { - // Use piecewise_construct to support old versions of gcc in which pair - // constructor can't otherwise construct string from string_view. - return ToIter(m->emplace(std::piecewise_construct, std::make_tuple(key), - std::tuple<>())); - } - template <typename M> - static y_absl::enable_if_t<!HasEmplace<M>::value, iterator> InsertOrEmplace( - M* m, y_absl::string_view key) { - return ToIter(m->insert(std::make_pair(First(key), Second("")))); - } - - static iterator ToIter(std::pair<iterator, bool> pair) { - return pair.first; - } - static iterator ToIter(iterator iter) { return iter; } + // Inserts the key and an empty value into the map, returning an iterator to + // the inserted item. We use emplace() if available, otherwise insert(). + template <typename M> + static y_absl::enable_if_t<HasEmplace<M>::value, iterator> InsertOrEmplace( + M* m, y_absl::string_view key) { + // Use piecewise_construct to support old versions of gcc in which pair + // constructor can't otherwise construct string from string_view. + return ToIter(m->emplace(std::piecewise_construct, std::make_tuple(key), + std::tuple<>())); + } + template <typename M> + static y_absl::enable_if_t<!HasEmplace<M>::value, iterator> InsertOrEmplace( + M* m, y_absl::string_view key) { + return ToIter(m->insert(std::make_pair(First(key), Second("")))); + } + + static iterator ToIter(std::pair<iterator, bool> pair) { + return pair.first; + } + static iterator ToIter(iterator iter) { return iter; } }; StringType text_; diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/numbers.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/numbers.cc index 528d044fa6..355c4b9641 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/numbers.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/numbers.cc @@ -505,7 +505,7 @@ size_t numbers_internal::SixDigitsToBuffer(double d, char* const buffer) { *out++ = '-'; d = -d; } - if (d > std::numeric_limits<double>::max()) { + if (d > std::numeric_limits<double>::max()) { strcpy(out, "inf"); // NOLINT(runtime/printf) return out + 3 - buffer; } diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/numbers.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/numbers.h index ce181d8eb1..488e9d3842 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/numbers.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/numbers.h @@ -104,25 +104,25 @@ ABSL_MUST_USE_RESULT bool SimpleAtod(y_absl::string_view str, double* out); // unspecified state. ABSL_MUST_USE_RESULT bool SimpleAtob(y_absl::string_view str, bool* out); -// SimpleHexAtoi() -// -// Converts a hexadecimal string (optionally followed or preceded by ASCII -// whitespace) to an integer, returning `true` if successful. Only valid base-16 -// hexadecimal integers whose value falls within the range of the integer type -// (optionally preceded by a `+` or `-`) can be converted. A valid hexadecimal -// value may include both upper and lowercase character symbols, and may -// optionally include a leading "0x" (or "0X") number prefix, which is ignored -// by this function. If any errors are encountered, this function returns -// `false`, leaving `out` in an unspecified state. -template <typename int_type> -ABSL_MUST_USE_RESULT bool SimpleHexAtoi(y_absl::string_view str, int_type* out); - -// Overloads of SimpleHexAtoi() for 128 bit integers. -ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(y_absl::string_view str, - y_absl::int128* out); -ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(y_absl::string_view str, - y_absl::uint128* out); - +// SimpleHexAtoi() +// +// Converts a hexadecimal string (optionally followed or preceded by ASCII +// whitespace) to an integer, returning `true` if successful. Only valid base-16 +// hexadecimal integers whose value falls within the range of the integer type +// (optionally preceded by a `+` or `-`) can be converted. A valid hexadecimal +// value may include both upper and lowercase character symbols, and may +// optionally include a leading "0x" (or "0X") number prefix, which is ignored +// by this function. If any errors are encountered, this function returns +// `false`, leaving `out` in an unspecified state. +template <typename int_type> +ABSL_MUST_USE_RESULT bool SimpleHexAtoi(y_absl::string_view str, int_type* out); + +// Overloads of SimpleHexAtoi() for 128 bit integers. +ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(y_absl::string_view str, + y_absl::int128* out); +ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(y_absl::string_view str, + y_absl::uint128* out); + ABSL_NAMESPACE_END } // namespace y_absl @@ -287,21 +287,21 @@ ABSL_MUST_USE_RESULT inline bool SimpleAtoi(y_absl::string_view str, return numbers_internal::safe_strtou128_base(str, out, 10); } -template <typename int_type> -ABSL_MUST_USE_RESULT bool SimpleHexAtoi(y_absl::string_view str, int_type* out) { - return numbers_internal::safe_strtoi_base(str, out, 16); -} - -ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(y_absl::string_view str, - y_absl::int128* out) { - return numbers_internal::safe_strto128_base(str, out, 16); -} - -ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(y_absl::string_view str, - y_absl::uint128* out) { - return numbers_internal::safe_strtou128_base(str, out, 16); -} - +template <typename int_type> +ABSL_MUST_USE_RESULT bool SimpleHexAtoi(y_absl::string_view str, int_type* out) { + return numbers_internal::safe_strtoi_base(str, out, 16); +} + +ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(y_absl::string_view str, + y_absl::int128* out) { + return numbers_internal::safe_strto128_base(str, out, 16); +} + +ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(y_absl::string_view str, + y_absl::uint128* out) { + return numbers_internal::safe_strtou128_base(str, out, 16); +} + ABSL_NAMESPACE_END } // namespace y_absl diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_cat.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_cat.cc index 9e11702eae..38d4ac299e 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_cat.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_cat.cc @@ -174,7 +174,7 @@ void AppendPieces(TString* dest, ASSERT_NO_OVERLAP(*dest, piece); total_size += piece.size(); } - strings_internal::STLStringResizeUninitializedAmortized(dest, total_size); + strings_internal::STLStringResizeUninitializedAmortized(dest, total_size); char* const begin = &(*dest)[0]; char* out = begin + old_size; @@ -199,7 +199,7 @@ void StrAppend(TString* dest, const AlphaNum& a, const AlphaNum& b) { ASSERT_NO_OVERLAP(*dest, a); ASSERT_NO_OVERLAP(*dest, b); TString::size_type old_size = dest->size(); - strings_internal::STLStringResizeUninitializedAmortized( + strings_internal::STLStringResizeUninitializedAmortized( dest, old_size + a.size() + b.size()); char* const begin = &(*dest)[0]; char* out = begin + old_size; @@ -214,7 +214,7 @@ void StrAppend(TString* dest, const AlphaNum& a, const AlphaNum& b, ASSERT_NO_OVERLAP(*dest, b); ASSERT_NO_OVERLAP(*dest, c); TString::size_type old_size = dest->size(); - strings_internal::STLStringResizeUninitializedAmortized( + strings_internal::STLStringResizeUninitializedAmortized( dest, old_size + a.size() + b.size() + c.size()); char* const begin = &(*dest)[0]; char* out = begin + old_size; @@ -231,7 +231,7 @@ void StrAppend(TString* dest, const AlphaNum& a, const AlphaNum& b, ASSERT_NO_OVERLAP(*dest, c); ASSERT_NO_OVERLAP(*dest, d); TString::size_type old_size = dest->size(); - strings_internal::STLStringResizeUninitializedAmortized( + strings_internal::STLStringResizeUninitializedAmortized( dest, old_size + a.size() + b.size() + c.size() + d.size()); char* const begin = &(*dest)[0]; char* out = begin + old_size; diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_format.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_format.h index 4079f38fb4..0fa806d016 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_format.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/str_format.h @@ -536,7 +536,7 @@ using FormatArg = str_format_internal::FormatArgImpl; // The arguments are provided in an `y_absl::Span<const y_absl::FormatArg>`. // Each `y_absl::FormatArg` object binds to a single argument and keeps a // reference to it. The values used to create the `FormatArg` objects must -// outlive this function call. +// outlive this function call. // // Example: // diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/string_view.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/string_view.cc index 9893c7ab99..53f0b10e20 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/string_view.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/string_view.cc @@ -78,8 +78,8 @@ std::ostream& operator<<(std::ostream& o, string_view piece) { return o; } -string_view::size_type string_view::find(string_view s, - size_type pos) const noexcept { +string_view::size_type string_view::find(string_view s, + size_type pos) const noexcept { if (empty() || pos > length_) { if (empty() && pos == 0 && s.empty()) return 0; return npos; @@ -98,8 +98,8 @@ string_view::size_type string_view::find(char c, size_type pos) const noexcept { return result != nullptr ? result - ptr_ : npos; } -string_view::size_type string_view::rfind(string_view s, - size_type pos) const noexcept { +string_view::size_type string_view::rfind(string_view s, + size_type pos) const noexcept { if (length_ < s.length_) return npos; if (s.empty()) return std::min(length_, pos); const char* last = ptr_ + std::min(length_ - s.length_, pos) + s.length_; @@ -108,8 +108,8 @@ string_view::size_type string_view::rfind(string_view s, } // Search range is [0..pos] inclusive. If pos == npos, search everything. -string_view::size_type string_view::rfind(char c, - size_type pos) const noexcept { +string_view::size_type string_view::rfind(char c, + size_type pos) const noexcept { // Note: memrchr() is not available on Windows. if (empty()) return npos; for (size_type i = std::min(pos, length_ - 1);; --i) { @@ -121,8 +121,8 @@ string_view::size_type string_view::rfind(char c, return npos; } -string_view::size_type string_view::find_first_of( - string_view s, size_type pos) const noexcept { +string_view::size_type string_view::find_first_of( + string_view s, size_type pos) const noexcept { if (empty() || s.empty()) { return npos; } @@ -137,8 +137,8 @@ string_view::size_type string_view::find_first_of( return npos; } -string_view::size_type string_view::find_first_not_of( - string_view s, size_type pos) const noexcept { +string_view::size_type string_view::find_first_not_of( + string_view s, size_type pos) const noexcept { if (empty()) return npos; // Avoid the cost of LookupTable() for a single-character search. if (s.length_ == 1) return find_first_not_of(s.ptr_[0], pos); @@ -151,8 +151,8 @@ string_view::size_type string_view::find_first_not_of( return npos; } -string_view::size_type string_view::find_first_not_of( - char c, size_type pos) const noexcept { +string_view::size_type string_view::find_first_not_of( + char c, size_type pos) const noexcept { if (empty()) return npos; for (; pos < length_; ++pos) { if (ptr_[pos] != c) { @@ -177,8 +177,8 @@ string_view::size_type string_view::find_last_of(string_view s, return npos; } -string_view::size_type string_view::find_last_not_of( - string_view s, size_type pos) const noexcept { +string_view::size_type string_view::find_last_not_of( + string_view s, size_type pos) const noexcept { if (empty()) return npos; size_type i = std::min(pos, length_ - 1); if (s.empty()) return i; @@ -194,8 +194,8 @@ string_view::size_type string_view::find_last_not_of( return npos; } -string_view::size_type string_view::find_last_not_of( - char c, size_type pos) const noexcept { +string_view::size_type string_view::find_last_not_of( + char c, size_type pos) const noexcept { if (empty()) return npos; size_type i = std::min(pos, length_ - 1); for (;; --i) { diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/string_view.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/string_view.h index c3906fe1c5..a6ac6a31f6 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/string_view.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/string_view.h @@ -36,7 +36,7 @@ #include <limits> #include <util/generic/string.h> -#include "y_absl/base/attributes.h" +#include "y_absl/base/attributes.h" #include "y_absl/base/config.h" #include "y_absl/base/internal/throw_delegate.h" #include "y_absl/base/macros.h" @@ -64,12 +64,12 @@ ABSL_NAMESPACE_END #define ABSL_INTERNAL_STRING_VIEW_MEMCMP memcmp #endif // ABSL_HAVE_BUILTIN(__builtin_memcmp) -#if defined(__cplusplus) && __cplusplus >= 201402L -#define ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR constexpr -#else -#define ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR -#endif - +#if defined(__cplusplus) && __cplusplus >= 201402L +#define ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR constexpr +#else +#define ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR +#endif + namespace y_absl { ABSL_NAMESPACE_BEGIN @@ -189,20 +189,20 @@ class string_view { template <typename Allocator> string_view( // NOLINT(runtime/explicit) - const std::basic_string<char, std::char_traits<char>, Allocator>& str - ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept + const std::basic_string<char, std::char_traits<char>, Allocator>& str + ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept // This is implemented in terms of `string_view(p, n)` so `str.size()` // doesn't need to be reevaluated after `ptr_` is set. - // The length check is also skipped since it is unnecessary and causes - // code bloat. - : string_view(str.data(), str.size(), SkipCheckLengthTag{}) {} + // The length check is also skipped since it is unnecessary and causes + // code bloat. + : string_view(str.data(), str.size(), SkipCheckLengthTag{}) {} // Implicit constructor of a `string_view` from NUL-terminated `str`. When // accepting possibly null strings, use `y_absl::NullSafeStringView(str)` // instead (see below). - // The length check is skipped since it is unnecessary and causes code bloat. + // The length check is skipped since it is unnecessary and causes code bloat. constexpr string_view(const char* str) // NOLINT(runtime/explicit) - : ptr_(str), length_(str ? StrlenInternal(str) : 0) {} + : ptr_(str), length_(str ? StrlenInternal(str) : 0) {} // Implicit constructor of a `string_view` from a `const char*` and length. constexpr string_view(const char* data, size_type len) @@ -275,7 +275,7 @@ class string_view { // string_view::size() // // Returns the number of characters in the `string_view`. - constexpr size_type size() const noexcept { return length_; } + constexpr size_type size() const noexcept { return length_; } // string_view::length() // @@ -342,7 +342,7 @@ class string_view { // // Removes the first `n` characters from the `string_view`. Note that the // underlying string is not changed, only the view. - ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void remove_prefix(size_type n) { + ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void remove_prefix(size_type n) { ABSL_HARDENING_ASSERT(n <= length_); ptr_ += n; length_ -= n; @@ -352,7 +352,7 @@ class string_view { // // Removes the last `n` characters from the `string_view`. Note that the // underlying string is not changed, only the view. - ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void remove_suffix(size_type n) { + ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void remove_suffix(size_type n) { ABSL_HARDENING_ASSERT(n <= length_); length_ -= n; } @@ -360,7 +360,7 @@ class string_view { // string_view::swap() // // Swaps this `string_view` with another `string_view`. - ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void swap(string_view& s) noexcept { + ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void swap(string_view& s) noexcept { auto t = *this; *this = s; s = t; @@ -397,7 +397,7 @@ class string_view { // `n`) as another string_view. This function throws `std::out_of_bounds` if // `pos > size`. // Use y_absl::ClippedSubstr if you need a truncating substr operation. - constexpr string_view substr(size_type pos = 0, size_type n = npos) const { + constexpr string_view substr(size_type pos = 0, size_type n = npos) const { return ABSL_PREDICT_FALSE(pos > length_) ? (base_internal::ThrowStdOutOfRange( "y_absl::string_view::substr"), @@ -407,10 +407,10 @@ class string_view { // string_view::compare() // - // Performs a lexicographical comparison between this `string_view` and - // another `string_view` `x`, returning a negative value if `*this` is less - // than `x`, 0 if `*this` is equal to `x`, and a positive value if `*this` - // is greater than `x`. + // Performs a lexicographical comparison between this `string_view` and + // another `string_view` `x`, returning a negative value if `*this` is less + // than `x`, 0 if `*this` is equal to `x`, and a positive value if `*this` + // is greater than `x`. constexpr int compare(string_view x) const noexcept { return CompareImpl(length_, x.length_, Min(length_, x.length_) == 0 @@ -421,31 +421,31 @@ class string_view { // Overload of `string_view::compare()` for comparing a substring of the // 'string_view` and another `y_absl::string_view`. - constexpr int compare(size_type pos1, size_type count1, string_view v) const { + constexpr int compare(size_type pos1, size_type count1, string_view v) const { return substr(pos1, count1).compare(v); } // Overload of `string_view::compare()` for comparing a substring of the // `string_view` and a substring of another `y_absl::string_view`. - constexpr int compare(size_type pos1, size_type count1, string_view v, - size_type pos2, size_type count2) const { + constexpr int compare(size_type pos1, size_type count1, string_view v, + size_type pos2, size_type count2) const { return substr(pos1, count1).compare(v.substr(pos2, count2)); } // Overload of `string_view::compare()` for comparing a `string_view` and a - // a different C-style string `s`. - constexpr int compare(const char* s) const { return compare(string_view(s)); } + // a different C-style string `s`. + constexpr int compare(const char* s) const { return compare(string_view(s)); } // Overload of `string_view::compare()` for comparing a substring of the // `string_view` and a different string C-style string `s`. - constexpr int compare(size_type pos1, size_type count1, const char* s) const { + constexpr int compare(size_type pos1, size_type count1, const char* s) const { return substr(pos1, count1).compare(string_view(s)); } // Overload of `string_view::compare()` for comparing a substring of the // `string_view` and a substring of a different C-style string `s`. - constexpr int compare(size_type pos1, size_type count1, const char* s, - size_type count2) const { + constexpr int compare(size_type pos1, size_type count1, const char* s, + size_type count2) const { return substr(pos1, count1).compare(string_view(s, count2)); } @@ -462,92 +462,92 @@ class string_view { // within the `string_view`. size_type find(char c, size_type pos = 0) const noexcept; - // Overload of `string_view::find()` for finding a substring of a different - // C-style string `s` within the `string_view`. - size_type find(const char* s, size_type pos, size_type count) const { - return find(string_view(s, count), pos); - } - - // Overload of `string_view::find()` for finding a different C-style string - // `s` within the `string_view`. - size_type find(const char* s, size_type pos = 0) const { - return find(string_view(s), pos); - } - + // Overload of `string_view::find()` for finding a substring of a different + // C-style string `s` within the `string_view`. + size_type find(const char* s, size_type pos, size_type count) const { + return find(string_view(s, count), pos); + } + + // Overload of `string_view::find()` for finding a different C-style string + // `s` within the `string_view`. + size_type find(const char* s, size_type pos = 0) const { + return find(string_view(s), pos); + } + // string_view::rfind() // // Finds the last occurrence of a substring `s` within the `string_view`, // returning the position of the first character's match, or `npos` if no // match was found. - size_type rfind(string_view s, size_type pos = npos) const noexcept; + size_type rfind(string_view s, size_type pos = npos) const noexcept; // Overload of `string_view::rfind()` for finding the last given character `c` // within the `string_view`. size_type rfind(char c, size_type pos = npos) const noexcept; - // Overload of `string_view::rfind()` for finding a substring of a different - // C-style string `s` within the `string_view`. - size_type rfind(const char* s, size_type pos, size_type count) const { - return rfind(string_view(s, count), pos); - } - - // Overload of `string_view::rfind()` for finding a different C-style string - // `s` within the `string_view`. - size_type rfind(const char* s, size_type pos = npos) const { - return rfind(string_view(s), pos); - } - + // Overload of `string_view::rfind()` for finding a substring of a different + // C-style string `s` within the `string_view`. + size_type rfind(const char* s, size_type pos, size_type count) const { + return rfind(string_view(s, count), pos); + } + + // Overload of `string_view::rfind()` for finding a different C-style string + // `s` within the `string_view`. + size_type rfind(const char* s, size_type pos = npos) const { + return rfind(string_view(s), pos); + } + // string_view::find_first_of() // // Finds the first occurrence of any of the characters in `s` within the // `string_view`, returning the start position of the match, or `npos` if no // match was found. - size_type find_first_of(string_view s, size_type pos = 0) const noexcept; + size_type find_first_of(string_view s, size_type pos = 0) const noexcept; // Overload of `string_view::find_first_of()` for finding a character `c` // within the `string_view`. - size_type find_first_of(char c, size_type pos = 0) const noexcept { + size_type find_first_of(char c, size_type pos = 0) const noexcept { return find(c, pos); } - // Overload of `string_view::find_first_of()` for finding a substring of a - // different C-style string `s` within the `string_view`. - size_type find_first_of(const char* s, size_type pos, - size_type count) const { - return find_first_of(string_view(s, count), pos); - } - - // Overload of `string_view::find_first_of()` for finding a different C-style - // string `s` within the `string_view`. - size_type find_first_of(const char* s, size_type pos = 0) const { - return find_first_of(string_view(s), pos); - } - + // Overload of `string_view::find_first_of()` for finding a substring of a + // different C-style string `s` within the `string_view`. + size_type find_first_of(const char* s, size_type pos, + size_type count) const { + return find_first_of(string_view(s, count), pos); + } + + // Overload of `string_view::find_first_of()` for finding a different C-style + // string `s` within the `string_view`. + size_type find_first_of(const char* s, size_type pos = 0) const { + return find_first_of(string_view(s), pos); + } + // string_view::find_last_of() // // Finds the last occurrence of any of the characters in `s` within the // `string_view`, returning the start position of the match, or `npos` if no // match was found. - size_type find_last_of(string_view s, size_type pos = npos) const noexcept; + size_type find_last_of(string_view s, size_type pos = npos) const noexcept; // Overload of `string_view::find_last_of()` for finding a character `c` // within the `string_view`. - size_type find_last_of(char c, size_type pos = npos) const noexcept { + size_type find_last_of(char c, size_type pos = npos) const noexcept { return rfind(c, pos); } - // Overload of `string_view::find_last_of()` for finding a substring of a - // different C-style string `s` within the `string_view`. - size_type find_last_of(const char* s, size_type pos, size_type count) const { - return find_last_of(string_view(s, count), pos); - } - - // Overload of `string_view::find_last_of()` for finding a different C-style - // string `s` within the `string_view`. - size_type find_last_of(const char* s, size_type pos = npos) const { - return find_last_of(string_view(s), pos); - } - + // Overload of `string_view::find_last_of()` for finding a substring of a + // different C-style string `s` within the `string_view`. + size_type find_last_of(const char* s, size_type pos, size_type count) const { + return find_last_of(string_view(s, count), pos); + } + + // Overload of `string_view::find_last_of()` for finding a different C-style + // string `s` within the `string_view`. + size_type find_last_of(const char* s, size_type pos = npos) const { + return find_last_of(string_view(s), pos); + } + // string_view::find_first_not_of() // // Finds the first occurrence of any of the characters not in `s` within the @@ -559,51 +559,51 @@ class string_view { // that is not `c` within the `string_view`. size_type find_first_not_of(char c, size_type pos = 0) const noexcept; - // Overload of `string_view::find_first_not_of()` for finding a substring of a - // different C-style string `s` within the `string_view`. - size_type find_first_not_of(const char* s, size_type pos, - size_type count) const { - return find_first_not_of(string_view(s, count), pos); - } - - // Overload of `string_view::find_first_not_of()` for finding a different - // C-style string `s` within the `string_view`. - size_type find_first_not_of(const char* s, size_type pos = 0) const { - return find_first_not_of(string_view(s), pos); - } - + // Overload of `string_view::find_first_not_of()` for finding a substring of a + // different C-style string `s` within the `string_view`. + size_type find_first_not_of(const char* s, size_type pos, + size_type count) const { + return find_first_not_of(string_view(s, count), pos); + } + + // Overload of `string_view::find_first_not_of()` for finding a different + // C-style string `s` within the `string_view`. + size_type find_first_not_of(const char* s, size_type pos = 0) const { + return find_first_not_of(string_view(s), pos); + } + // string_view::find_last_not_of() // // Finds the last occurrence of any of the characters not in `s` within the // `string_view`, returning the start position of the last non-match, or // `npos` if no non-match was found. size_type find_last_not_of(string_view s, - size_type pos = npos) const noexcept; + size_type pos = npos) const noexcept; // Overload of `string_view::find_last_not_of()` for finding a character // that is not `c` within the `string_view`. - size_type find_last_not_of(char c, size_type pos = npos) const noexcept; - - // Overload of `string_view::find_last_not_of()` for finding a substring of a - // different C-style string `s` within the `string_view`. - size_type find_last_not_of(const char* s, size_type pos, - size_type count) const { - return find_last_not_of(string_view(s, count), pos); - } - - // Overload of `string_view::find_last_not_of()` for finding a different - // C-style string `s` within the `string_view`. - size_type find_last_not_of(const char* s, size_type pos = npos) const { - return find_last_not_of(string_view(s), pos); - } - + size_type find_last_not_of(char c, size_type pos = npos) const noexcept; + + // Overload of `string_view::find_last_not_of()` for finding a substring of a + // different C-style string `s` within the `string_view`. + size_type find_last_not_of(const char* s, size_type pos, + size_type count) const { + return find_last_not_of(string_view(s, count), pos); + } + + // Overload of `string_view::find_last_not_of()` for finding a different + // C-style string `s` within the `string_view`. + size_type find_last_not_of(const char* s, size_type pos = npos) const { + return find_last_not_of(string_view(s), pos); + } + private: - // The constructor from TString delegates to this constructor. - // See the comment on that constructor for the rationale. - struct SkipCheckLengthTag {}; - string_view(const char* data, size_type len, SkipCheckLengthTag) noexcept - : ptr_(data), length_(len) {} - + // The constructor from TString delegates to this constructor. + // See the comment on that constructor for the rationale. + struct SkipCheckLengthTag {}; + string_view(const char* data, size_type len, SkipCheckLengthTag) noexcept + : ptr_(data), length_(len) {} + static constexpr size_type kMaxSize = (std::numeric_limits<difference_type>::max)(); @@ -679,7 +679,7 @@ std::ostream& operator<<(std::ostream& o, string_view piece); ABSL_NAMESPACE_END } // namespace y_absl -#undef ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR +#undef ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR #undef ABSL_INTERNAL_STRING_VIEW_MEMCMP #endif // ABSL_USES_STD_STRING_VIEW diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/substitute.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/substitute.cc index 177fba8cbe..858ad5f783 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/substitute.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/substitute.cc @@ -75,8 +75,8 @@ void SubstituteAndAppendArray(TString* output, y_absl::string_view format, // Build the string. size_t original_size = output->size(); - strings_internal::STLStringResizeUninitializedAmortized(output, - original_size + size); + strings_internal::STLStringResizeUninitializedAmortized(output, + original_size + size); char* target = &(*output)[original_size]; for (size_t i = 0; i < format.size(); i++) { if (format[i] == '$') { diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/substitute.h b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/substitute.h index c31191fbda..09545cec1e 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/substitute.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/substitute.h @@ -363,49 +363,49 @@ inline void SubstituteAndAppend( // This body of functions catches cases where the number of placeholders // doesn't match the number of data arguments. void SubstituteAndAppend(TString* output, const char* format) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 0, - "There were no substitution arguments " - "but this format string either has a $[0-9] in it or contains " - "an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 0, + "There were no substitution arguments " + "but this format string either has a $[0-9] in it or contains " + "an unescaped $ character (use $$ instead)"); void SubstituteAndAppend(TString* output, const char* format, const substitute_internal::Arg& a0) ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 1, "There was 1 substitution argument given, but " - "this format string is missing its $0, contains " - "one of $1-$9, or contains an unescaped $ character (use " - "$$ instead)"); + "this format string is missing its $0, contains " + "one of $1-$9, or contains an unescaped $ character (use " + "$$ instead)"); void SubstituteAndAppend(TString* output, const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 3, - "There were 2 substitution arguments given, but this format string is " - "missing its $0/$1, contains one of $2-$9, or contains an " - "unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 3, + "There were 2 substitution arguments given, but this format string is " + "missing its $0/$1, contains one of $2-$9, or contains an " + "unescaped $ character (use $$ instead)"); void SubstituteAndAppend(TString* output, const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1, const substitute_internal::Arg& a2) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 7, - "There were 3 substitution arguments given, but " - "this format string is missing its $0/$1/$2, contains one of " - "$3-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 7, + "There were 3 substitution arguments given, but " + "this format string is missing its $0/$1/$2, contains one of " + "$3-$9, or contains an unescaped $ character (use $$ instead)"); void SubstituteAndAppend(TString* output, const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1, const substitute_internal::Arg& a2, const substitute_internal::Arg& a3) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 15, - "There were 4 substitution arguments given, but " - "this format string is missing its $0-$3, contains one of " - "$4-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 15, + "There were 4 substitution arguments given, but " + "this format string is missing its $0-$3, contains one of " + "$4-$9, or contains an unescaped $ character (use $$ instead)"); void SubstituteAndAppend(TString* output, const char* format, const substitute_internal::Arg& a0, @@ -413,11 +413,11 @@ void SubstituteAndAppend(TString* output, const char* format, const substitute_internal::Arg& a2, const substitute_internal::Arg& a3, const substitute_internal::Arg& a4) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 31, - "There were 5 substitution arguments given, but " - "this format string is missing its $0-$4, contains one of " - "$5-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 31, + "There were 5 substitution arguments given, but " + "this format string is missing its $0-$4, contains one of " + "$5-$9, or contains an unescaped $ character (use $$ instead)"); void SubstituteAndAppend(TString* output, const char* format, const substitute_internal::Arg& a0, @@ -426,22 +426,22 @@ void SubstituteAndAppend(TString* output, const char* format, const substitute_internal::Arg& a3, const substitute_internal::Arg& a4, const substitute_internal::Arg& a5) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 63, - "There were 6 substitution arguments given, but " - "this format string is missing its $0-$5, contains one of " - "$6-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 63, + "There were 6 substitution arguments given, but " + "this format string is missing its $0-$5, contains one of " + "$6-$9, or contains an unescaped $ character (use $$ instead)"); void SubstituteAndAppend( TString* output, const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1, const substitute_internal::Arg& a2, const substitute_internal::Arg& a3, const substitute_internal::Arg& a4, const substitute_internal::Arg& a5, const substitute_internal::Arg& a6) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 127, - "There were 7 substitution arguments given, but " - "this format string is missing its $0-$6, contains one of " - "$7-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 127, + "There were 7 substitution arguments given, but " + "this format string is missing its $0-$6, contains one of " + "$7-$9, or contains an unescaped $ character (use $$ instead)"); void SubstituteAndAppend( TString* output, const char* format, const substitute_internal::Arg& a0, @@ -449,11 +449,11 @@ void SubstituteAndAppend( const substitute_internal::Arg& a3, const substitute_internal::Arg& a4, const substitute_internal::Arg& a5, const substitute_internal::Arg& a6, const substitute_internal::Arg& a7) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 255, - "There were 8 substitution arguments given, but " - "this format string is missing its $0-$7, contains one of " - "$8-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 255, + "There were 8 substitution arguments given, but " + "this format string is missing its $0-$7, contains one of " + "$8-$9, or contains an unescaped $ character (use $$ instead)"); void SubstituteAndAppend( TString* output, const char* format, const substitute_internal::Arg& a0, @@ -464,8 +464,8 @@ void SubstituteAndAppend( ABSL_BAD_CALL_IF( substitute_internal::PlaceholderBitmask(format) != 511, "There were 9 substitution arguments given, but " - "this format string is missing its $0-$8, contains a $9, or " - "contains an unescaped $ character (use $$ instead)"); + "this format string is missing its $0-$8, contains a $9, or " + "contains an unescaped $ character (use $$ instead)"); void SubstituteAndAppend( TString* output, const char* format, const substitute_internal::Arg& a0, @@ -474,11 +474,11 @@ void SubstituteAndAppend( const substitute_internal::Arg& a5, const substitute_internal::Arg& a6, const substitute_internal::Arg& a7, const substitute_internal::Arg& a8, const substitute_internal::Arg& a9) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 1023, - "There were 10 substitution arguments given, but this " - "format string either doesn't contain all of $0 through $9 or " - "contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 1023, + "There were 10 substitution arguments given, but this " + "format string either doesn't contain all of $0 through $9 or " + "contains an unescaped $ character (use $$ instead)"); #endif // ABSL_BAD_CALL_IF // Substitute() @@ -604,53 +604,53 @@ ABSL_MUST_USE_RESULT inline TString Substitute( TString Substitute(const char* format) ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 0, "There were no substitution arguments " - "but this format string either has a $[0-9] in it or " - "contains an unescaped $ character (use $$ instead)"); + "but this format string either has a $[0-9] in it or " + "contains an unescaped $ character (use $$ instead)"); TString Substitute(const char* format, const substitute_internal::Arg& a0) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 1, - "There was 1 substitution argument given, but " - "this format string is missing its $0, contains one of $1-$9, " - "or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 1, + "There was 1 substitution argument given, but " + "this format string is missing its $0, contains one of $1-$9, " + "or contains an unescaped $ character (use $$ instead)"); TString Substitute(const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 3, - "There were 2 substitution arguments given, but " - "this format string is missing its $0/$1, contains one of " - "$2-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 3, + "There were 2 substitution arguments given, but " + "this format string is missing its $0/$1, contains one of " + "$2-$9, or contains an unescaped $ character (use $$ instead)"); TString Substitute(const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1, const substitute_internal::Arg& a2) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 7, - "There were 3 substitution arguments given, but " - "this format string is missing its $0/$1/$2, contains one of " - "$3-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 7, + "There were 3 substitution arguments given, but " + "this format string is missing its $0/$1/$2, contains one of " + "$3-$9, or contains an unescaped $ character (use $$ instead)"); TString Substitute(const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1, const substitute_internal::Arg& a2, const substitute_internal::Arg& a3) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 15, - "There were 4 substitution arguments given, but " - "this format string is missing its $0-$3, contains one of " - "$4-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 15, + "There were 4 substitution arguments given, but " + "this format string is missing its $0-$3, contains one of " + "$4-$9, or contains an unescaped $ character (use $$ instead)"); TString Substitute(const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1, const substitute_internal::Arg& a2, const substitute_internal::Arg& a3, const substitute_internal::Arg& a4) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 31, - "There were 5 substitution arguments given, but " - "this format string is missing its $0-$4, contains one of " - "$5-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 31, + "There were 5 substitution arguments given, but " + "this format string is missing its $0-$4, contains one of " + "$5-$9, or contains an unescaped $ character (use $$ instead)"); TString Substitute(const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1, @@ -658,11 +658,11 @@ TString Substitute(const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a3, const substitute_internal::Arg& a4, const substitute_internal::Arg& a5) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 63, - "There were 6 substitution arguments given, but " - "this format string is missing its $0-$5, contains one of " - "$6-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 63, + "There were 6 substitution arguments given, but " + "this format string is missing its $0-$5, contains one of " + "$6-$9, or contains an unescaped $ character (use $$ instead)"); TString Substitute(const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1, @@ -671,11 +671,11 @@ TString Substitute(const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a4, const substitute_internal::Arg& a5, const substitute_internal::Arg& a6) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 127, - "There were 7 substitution arguments given, but " - "this format string is missing its $0-$6, contains one of " - "$7-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 127, + "There were 7 substitution arguments given, but " + "this format string is missing its $0-$6, contains one of " + "$7-$9, or contains an unescaped $ character (use $$ instead)"); TString Substitute(const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1, @@ -685,11 +685,11 @@ TString Substitute(const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a5, const substitute_internal::Arg& a6, const substitute_internal::Arg& a7) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 255, - "There were 8 substitution arguments given, but " - "this format string is missing its $0-$7, contains one of " - "$8-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 255, + "There were 8 substitution arguments given, but " + "this format string is missing its $0-$7, contains one of " + "$8-$9, or contains an unescaped $ character (use $$ instead)"); TString Substitute( const char* format, const substitute_internal::Arg& a0, @@ -700,8 +700,8 @@ TString Substitute( ABSL_BAD_CALL_IF( substitute_internal::PlaceholderBitmask(format) != 511, "There were 9 substitution arguments given, but " - "this format string is missing its $0-$8, contains a $9, or " - "contains an unescaped $ character (use $$ instead)"); + "this format string is missing its $0-$8, contains a $9, or " + "contains an unescaped $ character (use $$ instead)"); TString Substitute( const char* format, const substitute_internal::Arg& a0, @@ -710,11 +710,11 @@ TString Substitute( const substitute_internal::Arg& a5, const substitute_internal::Arg& a6, const substitute_internal::Arg& a7, const substitute_internal::Arg& a8, const substitute_internal::Arg& a9) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 1023, - "There were 10 substitution arguments given, but this " - "format string either doesn't contain all of $0 through $9 or " - "contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 1023, + "There were 10 substitution arguments given, but this " + "format string either doesn't contain all of $0 through $9 or " + "contains an unescaped $ character (use $$ instead)"); #endif // ABSL_BAD_CALL_IF ABSL_NAMESPACE_END diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/ya.make index 77c5a47dc9..6acedd1947 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/strings/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/strings/ya.make @@ -18,7 +18,7 @@ PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/base/internal/throw_delegate contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity contrib/restricted/abseil-cpp-tstring/y_absl/numeric - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal ) ADDINCL( diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/blocking_counter.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/blocking_counter.cc index 056185e51e..bd35531f92 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/blocking_counter.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/blocking_counter.cc @@ -14,37 +14,37 @@ #include "y_absl/synchronization/blocking_counter.h" -#include <atomic> - +#include <atomic> + #include "y_absl/base/internal/raw_logging.h" namespace y_absl { ABSL_NAMESPACE_BEGIN -namespace { - -// Return whether int *arg is true. -bool IsDone(void *arg) { return *reinterpret_cast<bool *>(arg); } - -} // namespace - -BlockingCounter::BlockingCounter(int initial_count) - : count_(initial_count), - num_waiting_(0), - done_{initial_count == 0 ? true : false} { - ABSL_RAW_CHECK(initial_count >= 0, "BlockingCounter initial_count negative"); +namespace { + +// Return whether int *arg is true. +bool IsDone(void *arg) { return *reinterpret_cast<bool *>(arg); } + +} // namespace + +BlockingCounter::BlockingCounter(int initial_count) + : count_(initial_count), + num_waiting_(0), + done_{initial_count == 0 ? true : false} { + ABSL_RAW_CHECK(initial_count >= 0, "BlockingCounter initial_count negative"); } bool BlockingCounter::DecrementCount() { - int count = count_.fetch_sub(1, std::memory_order_acq_rel) - 1; - ABSL_RAW_CHECK(count >= 0, - "BlockingCounter::DecrementCount() called too many times"); - if (count == 0) { - MutexLock l(&lock_); - done_ = true; - return true; + int count = count_.fetch_sub(1, std::memory_order_acq_rel) - 1; + ABSL_RAW_CHECK(count >= 0, + "BlockingCounter::DecrementCount() called too many times"); + if (count == 0) { + MutexLock l(&lock_); + done_ = true; + return true; } - return false; + return false; } void BlockingCounter::Wait() { @@ -55,10 +55,10 @@ void BlockingCounter::Wait() { ABSL_RAW_CHECK(num_waiting_ == 0, "multiple threads called Wait()"); num_waiting_++; - this->lock_.Await(Condition(IsDone, &this->done_)); + this->lock_.Await(Condition(IsDone, &this->done_)); - // At this point, we know that all threads executing DecrementCount - // will not touch this object again. + // At this point, we know that all threads executing DecrementCount + // will not touch this object again. // Therefore, the thread calling this method is free to delete the object // after we return from this method. } diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/blocking_counter.h b/contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/blocking_counter.h index a1644903e3..1419de18cc 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/blocking_counter.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/blocking_counter.h @@ -20,8 +20,8 @@ #ifndef ABSL_SYNCHRONIZATION_BLOCKING_COUNTER_H_ #define ABSL_SYNCHRONIZATION_BLOCKING_COUNTER_H_ -#include <atomic> - +#include <atomic> + #include "y_absl/base/thread_annotations.h" #include "y_absl/synchronization/mutex.h" @@ -62,7 +62,7 @@ ABSL_NAMESPACE_BEGIN // class BlockingCounter { public: - explicit BlockingCounter(int initial_count); + explicit BlockingCounter(int initial_count); BlockingCounter(const BlockingCounter&) = delete; BlockingCounter& operator=(const BlockingCounter&) = delete; @@ -90,9 +90,9 @@ class BlockingCounter { private: Mutex lock_; - std::atomic<int> count_; + std::atomic<int> count_; int num_waiting_ ABSL_GUARDED_BY(lock_); - bool done_ ABSL_GUARDED_BY(lock_); + bool done_ ABSL_GUARDED_BY(lock_); }; ABSL_NAMESPACE_END diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal/waiter.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal/waiter.cc index 573ce9c6c5..e8012ade61 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal/waiter.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal/waiter.cc @@ -79,7 +79,7 @@ bool Waiter::Wait(KernelTimeout t) { // Note that, since the thread ticker is just reset, we don't need to check // whether the thread is idle on the very first pass of the loop. bool first_pass = true; - + while (true) { int32_t x = futex_.load(std::memory_order_relaxed); while (x != 0) { diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/mutex.h b/contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/mutex.h index 0762a852df..b7e4e689b7 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/mutex.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/mutex.h @@ -778,9 +778,9 @@ class Condition { // // Usage to wake T is: // mu.Lock(); -// // process data, possibly establishing C -// if (C) { cv->Signal(); } -// mu.Unlock(); +// // process data, possibly establishing C +// if (C) { cv->Signal(); } +// mu.Unlock(); // // If C may be useful to more than one waiter, use `SignalAll()` instead of // `Signal()`. diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/ya.make index 860fd01b0f..c1dfcab7e9 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/ya.make @@ -24,7 +24,7 @@ PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/demangle contrib/restricted/abseil-cpp-tstring/y_absl/numeric contrib/restricted/abseil-cpp-tstring/y_absl/strings - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal contrib/restricted/abseil-cpp-tstring/y_absl/time contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time.cc index f24bac91e8..65aae95d41 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time.cc @@ -38,7 +38,7 @@ TString FormatYearAnd(string_view fmt, CivilSecond cs) { const CivilSecond ncs(NormalizeYear(cs.year()), cs.month(), cs.day(), cs.hour(), cs.minute(), cs.second()); const TimeZone utc = UTCTimeZone(); - return StrCat(cs.year(), FormatTime(fmt, FromCivil(ncs, utc), utc)); + return StrCat(cs.year(), FormatTime(fmt, FromCivil(ncs, utc), utc)); } template <typename CivilT> diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/time_zone.h b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/time_zone.h index 524654df4b..9639fb1d43 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/time_zone.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/include/cctz/time_zone.h @@ -22,7 +22,7 @@ #include <chrono> #include <cstdint> -#include <limits> +#include <limits> #include <util/generic/string.h> #include <utility> @@ -42,9 +42,9 @@ using sys_seconds = seconds; // Deprecated. Use cctz::seconds instead. namespace detail { template <typename D> -std::pair<time_point<seconds>, D> split_seconds(const time_point<D>& tp); -std::pair<time_point<seconds>, seconds> split_seconds( - const time_point<seconds>& tp); +std::pair<time_point<seconds>, D> split_seconds(const time_point<D>& tp); +std::pair<time_point<seconds>, seconds> split_seconds( + const time_point<seconds>& tp); } // namespace detail // cctz::time_zone is an opaque, small, value-type class representing a @@ -269,20 +269,20 @@ TString format(const TString&, const time_point<seconds>&, const femtoseconds&, const time_zone&); bool parse(const TString&, const TString&, const time_zone&, time_point<seconds>*, femtoseconds*, TString* err = nullptr); -template <typename Rep, std::intmax_t Denom> -bool join_seconds( - const time_point<seconds>& sec, const femtoseconds& fs, - time_point<std::chrono::duration<Rep, std::ratio<1, Denom>>>* tpp); -template <typename Rep, std::intmax_t Num> -bool join_seconds( - const time_point<seconds>& sec, const femtoseconds& fs, - time_point<std::chrono::duration<Rep, std::ratio<Num, 1>>>* tpp); -template <typename Rep> -bool join_seconds( - const time_point<seconds>& sec, const femtoseconds& fs, - time_point<std::chrono::duration<Rep, std::ratio<1, 1>>>* tpp); -bool join_seconds(const time_point<seconds>& sec, const femtoseconds&, - time_point<seconds>* tpp); +template <typename Rep, std::intmax_t Denom> +bool join_seconds( + const time_point<seconds>& sec, const femtoseconds& fs, + time_point<std::chrono::duration<Rep, std::ratio<1, Denom>>>* tpp); +template <typename Rep, std::intmax_t Num> +bool join_seconds( + const time_point<seconds>& sec, const femtoseconds& fs, + time_point<std::chrono::duration<Rep, std::ratio<Num, 1>>>* tpp); +template <typename Rep> +bool join_seconds( + const time_point<seconds>& sec, const femtoseconds& fs, + time_point<std::chrono::duration<Rep, std::ratio<1, 1>>>* tpp); +bool join_seconds(const time_point<seconds>& sec, const femtoseconds&, + time_point<seconds>* tpp); } // namespace detail // Formats the given time_point in the given cctz::time_zone according to @@ -373,84 +373,84 @@ inline bool parse(const TString& fmt, const TString& input, const time_zone& tz, time_point<D>* tpp) { time_point<seconds> sec; detail::femtoseconds fs; - return detail::parse(fmt, input, tz, &sec, &fs) && - detail::join_seconds(sec, fs, tpp); -} - -namespace detail { - -// Split a time_point<D> into a time_point<seconds> and a D subseconds. -// Undefined behavior if time_point<seconds> is not of sufficient range. -// Note that this means it is UB to call cctz::time_zone::lookup(tp) or -// cctz::format(fmt, tp, tz) with a time_point that is outside the range -// of a 64-bit std::time_t. -template <typename D> -std::pair<time_point<seconds>, D> split_seconds(const time_point<D>& tp) { - auto sec = std::chrono::time_point_cast<seconds>(tp); - auto sub = tp - sec; - if (sub.count() < 0) { - sec -= seconds(1); - sub += seconds(1); + return detail::parse(fmt, input, tz, &sec, &fs) && + detail::join_seconds(sec, fs, tpp); +} + +namespace detail { + +// Split a time_point<D> into a time_point<seconds> and a D subseconds. +// Undefined behavior if time_point<seconds> is not of sufficient range. +// Note that this means it is UB to call cctz::time_zone::lookup(tp) or +// cctz::format(fmt, tp, tz) with a time_point that is outside the range +// of a 64-bit std::time_t. +template <typename D> +std::pair<time_point<seconds>, D> split_seconds(const time_point<D>& tp) { + auto sec = std::chrono::time_point_cast<seconds>(tp); + auto sub = tp - sec; + if (sub.count() < 0) { + sec -= seconds(1); + sub += seconds(1); } - return {sec, std::chrono::duration_cast<D>(sub)}; -} - -inline std::pair<time_point<seconds>, seconds> split_seconds( - const time_point<seconds>& tp) { - return {tp, seconds::zero()}; -} - -// Join a time_point<seconds> and femto subseconds into a time_point<D>. -// Floors to the resolution of time_point<D>. Returns false if time_point<D> -// is not of sufficient range. -template <typename Rep, std::intmax_t Denom> -bool join_seconds( - const time_point<seconds>& sec, const femtoseconds& fs, - time_point<std::chrono::duration<Rep, std::ratio<1, Denom>>>* tpp) { - using D = std::chrono::duration<Rep, std::ratio<1, Denom>>; - // TODO(#199): Return false if result unrepresentable as a time_point<D>. - *tpp = std::chrono::time_point_cast<D>(sec); - *tpp += std::chrono::duration_cast<D>(fs); - return true; + return {sec, std::chrono::duration_cast<D>(sub)}; } -template <typename Rep, std::intmax_t Num> -bool join_seconds( - const time_point<seconds>& sec, const femtoseconds&, - time_point<std::chrono::duration<Rep, std::ratio<Num, 1>>>* tpp) { - using D = std::chrono::duration<Rep, std::ratio<Num, 1>>; - auto count = sec.time_since_epoch().count(); - if (count >= 0 || count % Num == 0) { - count /= Num; - } else { - count /= Num; - count -= 1; - } - if (count > (std::numeric_limits<Rep>::max)()) return false; - if (count < (std::numeric_limits<Rep>::min)()) return false; - *tpp = time_point<D>() + D{static_cast<Rep>(count)}; - return true; -} - -template <typename Rep> -bool join_seconds( - const time_point<seconds>& sec, const femtoseconds&, - time_point<std::chrono::duration<Rep, std::ratio<1, 1>>>* tpp) { - using D = std::chrono::duration<Rep, std::ratio<1, 1>>; - auto count = sec.time_since_epoch().count(); - if (count > (std::numeric_limits<Rep>::max)()) return false; - if (count < (std::numeric_limits<Rep>::min)()) return false; - *tpp = time_point<D>() + D{static_cast<Rep>(count)}; - return true; -} - -inline bool join_seconds(const time_point<seconds>& sec, const femtoseconds&, - time_point<seconds>* tpp) { - *tpp = sec; - return true; -} - -} // namespace detail +inline std::pair<time_point<seconds>, seconds> split_seconds( + const time_point<seconds>& tp) { + return {tp, seconds::zero()}; +} + +// Join a time_point<seconds> and femto subseconds into a time_point<D>. +// Floors to the resolution of time_point<D>. Returns false if time_point<D> +// is not of sufficient range. +template <typename Rep, std::intmax_t Denom> +bool join_seconds( + const time_point<seconds>& sec, const femtoseconds& fs, + time_point<std::chrono::duration<Rep, std::ratio<1, Denom>>>* tpp) { + using D = std::chrono::duration<Rep, std::ratio<1, Denom>>; + // TODO(#199): Return false if result unrepresentable as a time_point<D>. + *tpp = std::chrono::time_point_cast<D>(sec); + *tpp += std::chrono::duration_cast<D>(fs); + return true; +} + +template <typename Rep, std::intmax_t Num> +bool join_seconds( + const time_point<seconds>& sec, const femtoseconds&, + time_point<std::chrono::duration<Rep, std::ratio<Num, 1>>>* tpp) { + using D = std::chrono::duration<Rep, std::ratio<Num, 1>>; + auto count = sec.time_since_epoch().count(); + if (count >= 0 || count % Num == 0) { + count /= Num; + } else { + count /= Num; + count -= 1; + } + if (count > (std::numeric_limits<Rep>::max)()) return false; + if (count < (std::numeric_limits<Rep>::min)()) return false; + *tpp = time_point<D>() + D{static_cast<Rep>(count)}; + return true; +} + +template <typename Rep> +bool join_seconds( + const time_point<seconds>& sec, const femtoseconds&, + time_point<std::chrono::duration<Rep, std::ratio<1, 1>>>* tpp) { + using D = std::chrono::duration<Rep, std::ratio<1, 1>>; + auto count = sec.time_since_epoch().count(); + if (count > (std::numeric_limits<Rep>::max)()) return false; + if (count < (std::numeric_limits<Rep>::min)()) return false; + *tpp = time_point<D>() + D{static_cast<Rep>(count)}; + return true; +} + +inline bool join_seconds(const time_point<seconds>& sec, const femtoseconds&, + time_point<seconds>* tpp) { + *tpp = sec; + return true; +} + +} // namespace detail } // namespace cctz } // namespace time_internal ABSL_NAMESPACE_END diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_fixed.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_fixed.cc index 3a22cbea1d..d43acb9997 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_fixed.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_fixed.cc @@ -53,7 +53,7 @@ int Parse02d(const char* p) { } // namespace bool FixedOffsetFromName(const TString& name, seconds* offset) { - if (name == "UTC" || name == "UTC0") { + if (name == "UTC" || name == "UTC0") { *offset = seconds::zero(); return true; } diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_if.h b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_if.h index 10312badc2..d7c3d22d7d 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_if.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_if.h @@ -56,8 +56,8 @@ class TimeZoneIf { // Convert between time_point<seconds> and a count of seconds since the // Unix epoch. We assume that the std::chrono::system_clock and the -// Unix clock are second aligned, and that the results are representable. -// (That is, that they share an epoch, which is required since C++20.) +// Unix clock are second aligned, and that the results are representable. +// (That is, that they share an epoch, which is required since C++20.) inline std::int_fast64_t ToUnixSeconds(const time_point<seconds>& tp) { return (tp - std::chrono::time_point_cast<seconds>( std::chrono::system_clock::from_time_t(0))) diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_info.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_info.cc index 72f7bdc3ca..a812b1f352 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_info.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_info.cc @@ -39,12 +39,12 @@ #include <cstdio> #include <cstdlib> #include <cstring> -#include <fstream> +#include <fstream> #include <functional> #include <memory> #include <sstream> #include <util/generic/string.h> -#include <utility> +#include <utility> #include "y_absl/base/config.h" #include "y_absl/time/internal/cctz/include/cctz/civil_time.h" @@ -578,17 +578,17 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) { namespace { -using FilePtr = std::unique_ptr<FILE, int (*)(FILE*)>; - +using FilePtr = std::unique_ptr<FILE, int (*)(FILE*)>; + // fopen(3) adaptor. -inline FilePtr FOpen(const char* path, const char* mode) { +inline FilePtr FOpen(const char* path, const char* mode) { #if defined(_MSC_VER) FILE* fp; if (fopen_s(&fp, path, mode) != 0) fp = nullptr; - return FilePtr(fp, fclose); + return FilePtr(fp, fclose); #else - // TODO: Enable the close-on-exec flag. - return FilePtr(fopen(path, mode), fclose); + // TODO: Enable the close-on-exec flag. + return FilePtr(fopen(path, mode), fclose); #endif } @@ -616,11 +616,11 @@ class FileZoneInfoSource : public ZoneInfoSource { protected: explicit FileZoneInfoSource( - FilePtr fp, std::size_t len = std::numeric_limits<std::size_t>::max()) - : fp_(std::move(fp)), len_(len) {} + FilePtr fp, std::size_t len = std::numeric_limits<std::size_t>::max()) + : fp_(std::move(fp)), len_(len) {} private: - FilePtr fp_; + FilePtr fp_; std::size_t len_; }; @@ -649,9 +649,9 @@ std::unique_ptr<ZoneInfoSource> FileZoneInfoSource::Open( path.append(name, pos, TString::npos); // Open the zoneinfo file. - auto fp = FOpen(path.c_str(), "rb"); + auto fp = FOpen(path.c_str(), "rb"); if (fp == nullptr) return nullptr; - return std::unique_ptr<ZoneInfoSource>(new FileZoneInfoSource(std::move(fp))); + return std::unique_ptr<ZoneInfoSource>(new FileZoneInfoSource(std::move(fp))); } class AndroidZoneInfoSource : public FileZoneInfoSource { @@ -660,9 +660,9 @@ class AndroidZoneInfoSource : public FileZoneInfoSource { TString Version() const override { return version_; } private: - explicit AndroidZoneInfoSource(FilePtr fp, std::size_t len, - TString version) - : FileZoneInfoSource(std::move(fp), len), version_(std::move(version)) {} + explicit AndroidZoneInfoSource(FilePtr fp, std::size_t len, + TString version) + : FileZoneInfoSource(std::move(fp), len), version_(std::move(version)) {} TString version_; }; @@ -674,8 +674,8 @@ std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open( // See Android's libc/tzcode/bionic.cpp for additional information. for (const char* tzdata : {"/data/misc/zoneinfo/current/tzdata", "/system/usr/share/zoneinfo/tzdata"}) { - auto fp = FOpen(tzdata, "rb"); - if (fp == nullptr) continue; + auto fp = FOpen(tzdata, "rb"); + if (fp == nullptr) continue; char hbuf[24]; // covers header.zonetab_offset too if (fread(hbuf, 1, sizeof(hbuf), fp.get()) != sizeof(hbuf)) continue; @@ -701,7 +701,7 @@ std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open( if (strcmp(name.c_str() + pos, ebuf) == 0) { if (fseek(fp.get(), static_cast<long>(start), SEEK_SET) != 0) break; return std::unique_ptr<ZoneInfoSource>(new AndroidZoneInfoSource( - std::move(fp), static_cast<std::size_t>(length), vers)); + std::move(fp), static_cast<std::size_t>(length), vers)); } } } @@ -709,69 +709,69 @@ std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open( return nullptr; } -// A zoneinfo source for use inside Fuchsia components. This attempts to -// read zoneinfo files from one of several known paths in a component's -// incoming namespace. [Config data][1] is preferred, but package-specific -// resources are also supported. -// -// Fuchsia's implementation supports `FileZoneInfoSource::Version()`. -// -// [1]: -// https://fuchsia.dev/fuchsia-src/development/components/data#using_config_data_in_your_component -class FuchsiaZoneInfoSource : public FileZoneInfoSource { - public: - static std::unique_ptr<ZoneInfoSource> Open(const TString& name); - TString Version() const override { return version_; } - - private: - explicit FuchsiaZoneInfoSource(FilePtr fp, TString version) - : FileZoneInfoSource(std::move(fp)), version_(std::move(version)) {} - TString version_; -}; - -std::unique_ptr<ZoneInfoSource> FuchsiaZoneInfoSource::Open( - const TString& name) { - // Use of the "file:" prefix is intended for testing purposes only. - const std::size_t pos = (name.compare(0, 5, "file:") == 0) ? 5 : 0; - - // Prefixes where a Fuchsia component might find zoneinfo files, - // in descending order of preference. - const auto kTzdataPrefixes = { - "/config/data/tzdata/", - "/pkg/data/tzdata/", - "/data/tzdata/", - }; - const auto kEmptyPrefix = {""}; - const bool name_absolute = (pos != name.size() && name[pos] == '/'); - const auto prefixes = name_absolute ? kEmptyPrefix : kTzdataPrefixes; - - // Fuchsia builds place zoneinfo files at "<prefix><format><name>". - for (const TString prefix : prefixes) { - TString path = prefix; - if (!prefix.empty()) path += "zoneinfo/tzif2/"; // format - path.append(name, pos, TString::npos); - - auto fp = FOpen(path.c_str(), "rb"); - if (fp == nullptr) continue; - - std::string version; - if (!prefix.empty()) { - // Fuchsia builds place the version in "<prefix>revision.txt". - std::ifstream version_stream(prefix + "revision.txt"); - if (version_stream.is_open()) { - // revision.txt should contain no newlines, but to be - // defensive we read just the first line. - std::getline(version_stream, version); - } - } - - return std::unique_ptr<ZoneInfoSource>( - new FuchsiaZoneInfoSource(std::move(fp), std::move(version))); - } - - return nullptr; -} - +// A zoneinfo source for use inside Fuchsia components. This attempts to +// read zoneinfo files from one of several known paths in a component's +// incoming namespace. [Config data][1] is preferred, but package-specific +// resources are also supported. +// +// Fuchsia's implementation supports `FileZoneInfoSource::Version()`. +// +// [1]: +// https://fuchsia.dev/fuchsia-src/development/components/data#using_config_data_in_your_component +class FuchsiaZoneInfoSource : public FileZoneInfoSource { + public: + static std::unique_ptr<ZoneInfoSource> Open(const TString& name); + TString Version() const override { return version_; } + + private: + explicit FuchsiaZoneInfoSource(FilePtr fp, TString version) + : FileZoneInfoSource(std::move(fp)), version_(std::move(version)) {} + TString version_; +}; + +std::unique_ptr<ZoneInfoSource> FuchsiaZoneInfoSource::Open( + const TString& name) { + // Use of the "file:" prefix is intended for testing purposes only. + const std::size_t pos = (name.compare(0, 5, "file:") == 0) ? 5 : 0; + + // Prefixes where a Fuchsia component might find zoneinfo files, + // in descending order of preference. + const auto kTzdataPrefixes = { + "/config/data/tzdata/", + "/pkg/data/tzdata/", + "/data/tzdata/", + }; + const auto kEmptyPrefix = {""}; + const bool name_absolute = (pos != name.size() && name[pos] == '/'); + const auto prefixes = name_absolute ? kEmptyPrefix : kTzdataPrefixes; + + // Fuchsia builds place zoneinfo files at "<prefix><format><name>". + for (const TString prefix : prefixes) { + TString path = prefix; + if (!prefix.empty()) path += "zoneinfo/tzif2/"; // format + path.append(name, pos, TString::npos); + + auto fp = FOpen(path.c_str(), "rb"); + if (fp == nullptr) continue; + + std::string version; + if (!prefix.empty()) { + // Fuchsia builds place the version in "<prefix>revision.txt". + std::ifstream version_stream(prefix + "revision.txt"); + if (version_stream.is_open()) { + // revision.txt should contain no newlines, but to be + // defensive we read just the first line. + std::getline(version_stream, version); + } + } + + return std::unique_ptr<ZoneInfoSource>( + new FuchsiaZoneInfoSource(std::move(fp), std::move(version))); + } + + return nullptr; +} + } // namespace bool TimeZoneInfo::Load(const TString& name) { @@ -789,7 +789,7 @@ bool TimeZoneInfo::Load(const TString& name) { name, [](const TString& n) -> std::unique_ptr<ZoneInfoSource> { if (auto z = FileZoneInfoSource::Open(n)) return z; if (auto z = AndroidZoneInfoSource::Open(n)) return z; - if (auto z = FuchsiaZoneInfoSource::Open(n)) return z; + if (auto z = FuchsiaZoneInfoSource::Open(n)) return z; return nullptr; }); return zip != nullptr && Load(zip.get()); diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_lookup.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_lookup.cc index 92c9208d6d..187da2ca37 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_lookup.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/time_zone_lookup.cc @@ -28,13 +28,13 @@ #include <vector> #endif -#if defined(__Fuchsia__) -#error #include <fuchsia/intl/cpp/fidl.h> -#error #include <lib/async-loop/cpp/loop.h> -#error #include <lib/sys/cpp/component_context.h> -#error #include <zircon/types.h> -#endif - +#if defined(__Fuchsia__) +#error #include <fuchsia/intl/cpp/fidl.h> +#error #include <lib/async-loop/cpp/loop.h> +#error #include <lib/sys/cpp/component_context.h> +#error #include <zircon/types.h> +#endif + #include <cstdlib> #include <cstring> #include <util/generic/string.h> @@ -147,49 +147,49 @@ time_zone local_time_zone() { } CFRelease(tz_default); #endif -#if defined(__Fuchsia__) - TString primary_tz; - [&]() { - // Note: We can't use the synchronous FIDL API here because it doesn't - // allow timeouts; if the FIDL call failed, local_time_zone() would never - // return. - - const zx::duration kTimeout = zx::msec(500); - - // Don't attach to the thread because otherwise the thread's dispatcher - // would be set to null when the loop is destroyed, causing any other FIDL - // code running on the same thread to crash. - async::Loop loop(&kAsyncLoopConfigNeverAttachToThread); - std::unique_ptr<sys::ComponentContext> context = - sys::ComponentContext::Create(); - - fuchsia::intl::PropertyProviderHandle handle; - zx_status_t status = context->svc()->Connect(handle.NewRequest()); - if (status != ZX_OK) { - return; - } - - fuchsia::intl::PropertyProviderPtr intl_provider; - status = intl_provider.Bind(std::move(handle), loop.dispatcher()); - if (status != ZX_OK) { - return; - } - - intl_provider->GetProfile( - [&loop, &primary_tz](fuchsia::intl::Profile profile) { - if (!profile.time_zones().empty()) { - primary_tz = profile.time_zones()[0].id; - } - loop.Quit(); - }); - loop.Run(zx::deadline_after(kTimeout)); - }(); - - if (!primary_tz.empty()) { - zone = primary_tz.c_str(); - } -#endif - +#if defined(__Fuchsia__) + TString primary_tz; + [&]() { + // Note: We can't use the synchronous FIDL API here because it doesn't + // allow timeouts; if the FIDL call failed, local_time_zone() would never + // return. + + const zx::duration kTimeout = zx::msec(500); + + // Don't attach to the thread because otherwise the thread's dispatcher + // would be set to null when the loop is destroyed, causing any other FIDL + // code running on the same thread to crash. + async::Loop loop(&kAsyncLoopConfigNeverAttachToThread); + std::unique_ptr<sys::ComponentContext> context = + sys::ComponentContext::Create(); + + fuchsia::intl::PropertyProviderHandle handle; + zx_status_t status = context->svc()->Connect(handle.NewRequest()); + if (status != ZX_OK) { + return; + } + + fuchsia::intl::PropertyProviderPtr intl_provider; + status = intl_provider.Bind(std::move(handle), loop.dispatcher()); + if (status != ZX_OK) { + return; + } + + intl_provider->GetProfile( + [&loop, &primary_tz](fuchsia::intl::Profile profile) { + if (!profile.time_zones().empty()) { + primary_tz = profile.time_zones()[0].id; + } + loop.Quit(); + }); + loop.Run(zx::deadline_after(kTimeout)); + }(); + + if (!primary_tz.empty()) { + zone = primary_tz.c_str(); + } +#endif + // Allow ${TZ} to override to default zone. char* tz_env = nullptr; #if defined(_MSC_VER) diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/tzfile.h b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/tzfile.h index 31e8598257..88f5b477dc 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/tzfile.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/tzfile.h @@ -43,7 +43,7 @@ struct tzhead { char tzh_magic[4]; /* TZ_MAGIC */ - char tzh_version[1]; /* '\0' or '2'-'4' as of 2021 */ + char tzh_version[1]; /* '\0' or '2'-'4' as of 2021 */ char tzh_reserved[15]; /* reserved; must be zero */ char tzh_ttisutcnt[4]; /* coded number of trans. time flags */ char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/zone_info_source.cc b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/zone_info_source.cc index be58c20fb3..6e340332d3 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/zone_info_source.cc +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/internal/cctz/src/zone_info_source.cc @@ -65,7 +65,7 @@ ZoneInfoSourceFactory zone_info_source_factory __attribute__((weak)) = extern ZoneInfoSourceFactory zone_info_source_factory; extern ZoneInfoSourceFactory default_factory; ZoneInfoSourceFactory default_factory = DefaultFactory; -#if defined(_M_IX86) || defined(_M_ARM) +#if defined(_M_IX86) || defined(_M_ARM) #pragma comment( \ linker, \ "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@" ABSL_INTERNAL_MANGLED_NS \ @@ -83,7 +83,7 @@ ZoneInfoSourceFactory default_factory = DefaultFactory; "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ "@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ "@@ZA") -#elif defined(_M_IA_64) || defined(_M_AMD64) || defined(_M_ARM64) +#elif defined(_M_IA_64) || defined(_M_AMD64) || defined(_M_ARM64) #pragma comment( \ linker, \ "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@" ABSL_INTERNAL_MANGLED_NS \ diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/time.h b/contrib/restricted/abseil-cpp-tstring/y_absl/time/time.h index 16150ad3b6..94ac3c13e5 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/time.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/time.h @@ -182,30 +182,30 @@ class Duration { // Overloads that forward to either the int64_t or double overloads above. // Integer operands must be representable as int64_t. - template <typename T, time_internal::EnableIfIntegral<T> = 0> + template <typename T, time_internal::EnableIfIntegral<T> = 0> Duration& operator*=(T r) { int64_t x = r; return *this *= x; } - - template <typename T, time_internal::EnableIfIntegral<T> = 0> + + template <typename T, time_internal::EnableIfIntegral<T> = 0> Duration& operator/=(T r) { int64_t x = r; return *this /= x; } - template <typename T, time_internal::EnableIfFloat<T> = 0> - Duration& operator*=(T r) { - double x = r; - return *this *= x; - } - - template <typename T, time_internal::EnableIfFloat<T> = 0> - Duration& operator/=(T r) { - double x = r; - return *this /= x; - } - + template <typename T, time_internal::EnableIfFloat<T> = 0> + Duration& operator*=(T r) { + double x = r; + return *this *= x; + } + + template <typename T, time_internal::EnableIfFloat<T> = 0> + Duration& operator/=(T r) { + double x = r; + return *this /= x; + } + template <typename H> friend H AbslHashValue(H h, Duration d) { return H::combine(std::move(h), d.rep_hi_, d.rep_lo_); @@ -403,30 +403,30 @@ constexpr Duration InfiniteDuration(); // // y_absl::Duration a = y_absl::Seconds(60); // y_absl::Duration b = y_absl::Minutes(1); // b == a -template <typename T, time_internal::EnableIfIntegral<T> = 0> -constexpr Duration Nanoseconds(T n) { - return time_internal::FromInt64(n, std::nano{}); -} -template <typename T, time_internal::EnableIfIntegral<T> = 0> -constexpr Duration Microseconds(T n) { - return time_internal::FromInt64(n, std::micro{}); -} -template <typename T, time_internal::EnableIfIntegral<T> = 0> -constexpr Duration Milliseconds(T n) { - return time_internal::FromInt64(n, std::milli{}); -} -template <typename T, time_internal::EnableIfIntegral<T> = 0> -constexpr Duration Seconds(T n) { - return time_internal::FromInt64(n, std::ratio<1>{}); -} -template <typename T, time_internal::EnableIfIntegral<T> = 0> -constexpr Duration Minutes(T n) { - return time_internal::FromInt64(n, std::ratio<60>{}); -} -template <typename T, time_internal::EnableIfIntegral<T> = 0> -constexpr Duration Hours(T n) { - return time_internal::FromInt64(n, std::ratio<3600>{}); -} +template <typename T, time_internal::EnableIfIntegral<T> = 0> +constexpr Duration Nanoseconds(T n) { + return time_internal::FromInt64(n, std::nano{}); +} +template <typename T, time_internal::EnableIfIntegral<T> = 0> +constexpr Duration Microseconds(T n) { + return time_internal::FromInt64(n, std::micro{}); +} +template <typename T, time_internal::EnableIfIntegral<T> = 0> +constexpr Duration Milliseconds(T n) { + return time_internal::FromInt64(n, std::milli{}); +} +template <typename T, time_internal::EnableIfIntegral<T> = 0> +constexpr Duration Seconds(T n) { + return time_internal::FromInt64(n, std::ratio<1>{}); +} +template <typename T, time_internal::EnableIfIntegral<T> = 0> +constexpr Duration Minutes(T n) { + return time_internal::FromInt64(n, std::ratio<60>{}); +} +template <typename T, time_internal::EnableIfIntegral<T> = 0> +constexpr Duration Hours(T n) { + return time_internal::FromInt64(n, std::ratio<3600>{}); +} // Factory overloads for constructing `Duration` values from a floating-point // number of the unit indicated by the factory function's name. These functions @@ -480,9 +480,9 @@ Duration Hours(T n) { // ToInt64Hours() // // Helper functions that convert a Duration to an integral count of the -// indicated unit. These return the same results as the `IDivDuration()` -// function, though they usually do so more efficiently; see the -// documentation of `IDivDuration()` for details about overflow, etc. +// indicated unit. These return the same results as the `IDivDuration()` +// function, though they usually do so more efficiently; see the +// documentation of `IDivDuration()` for details about overflow, etc. // // Example: // @@ -577,20 +577,20 @@ inline std::ostream& operator<<(std::ostream& os, Duration d) { // `ZeroDuration()`. Parses "inf" and "-inf" as +/- `InfiniteDuration()`. bool ParseDuration(y_absl::string_view dur_string, Duration* d); -// AbslParseFlag() -// -// Parses a command-line flag string representation `text` into a a Duration -// value. Duration flags must be specified in a format that is valid input for -// `y_absl::ParseDuration()`. +// AbslParseFlag() +// +// Parses a command-line flag string representation `text` into a a Duration +// value. Duration flags must be specified in a format that is valid input for +// `y_absl::ParseDuration()`. bool AbslParseFlag(y_absl::string_view text, Duration* dst, TString* error); - - -// AbslUnparseFlag() -// -// Unparses a Duration value into a command-line string representation using -// the format specified by `y_absl::ParseDuration()`. + + +// AbslUnparseFlag() +// +// Unparses a Duration value into a command-line string representation using +// the format specified by `y_absl::ParseDuration()`. TString AbslUnparseFlag(Duration d); - + ABSL_DEPRECATED("Use AbslParseFlag() instead.") bool ParseFlag(const TString& text, Duration* dst, TString* error); ABSL_DEPRECATED("Use AbslUnparseFlag() instead.") @@ -853,13 +853,13 @@ Time FromChrono(const std::chrono::system_clock::time_point& tp); // // tp == std::chrono::system_clock::from_time_t(123); std::chrono::system_clock::time_point ToChronoTime(Time); -// AbslParseFlag() -// -// Parses the command-line flag string representation `text` into a Time value. -// Time flags must be specified in a format that matches y_absl::RFC3339_full. -// -// For example: +// AbslParseFlag() // +// Parses the command-line flag string representation `text` into a Time value. +// Time flags must be specified in a format that matches y_absl::RFC3339_full. +// +// For example: +// // --start_time=2016-01-02T03:04:05.678+08:00 // // Note: A UTC offset (or 'Z' indicating a zero-offset from UTC) is required. @@ -868,13 +868,13 @@ std::chrono::system_clock::time_point ToChronoTime(Time); // seconds/milliseconds/etc from the Unix epoch, use an y_absl::Duration flag // and add that duration to y_absl::UnixEpoch() to get an y_absl::Time. bool AbslParseFlag(y_absl::string_view text, Time* t, TString* error); - -// AbslUnparseFlag() -// -// Unparses a Time value into a command-line string representation using -// the format specified by `y_absl::ParseTime()`. + +// AbslUnparseFlag() +// +// Unparses a Time value into a command-line string representation using +// the format specified by `y_absl::ParseTime()`. TString AbslUnparseFlag(Time t); - + ABSL_DEPRECATED("Use AbslParseFlag() instead.") bool ParseFlag(const TString& text, Time* t, TString* error); ABSL_DEPRECATED("Use AbslUnparseFlag() instead.") @@ -1402,7 +1402,7 @@ constexpr Duration MakeDuration(int64_t hi, int64_t lo) { inline Duration MakePosDoubleDuration(double n) { const int64_t int_secs = static_cast<int64_t>(n); const uint32_t ticks = static_cast<uint32_t>( - std::round((n - static_cast<double>(int_secs)) * kTicksPerSecond)); + std::round((n - static_cast<double>(int_secs)) * kTicksPerSecond)); return ticks < kTicksPerSecond ? MakeDuration(int_secs, ticks) : MakeDuration(int_secs + 1, ticks - kTicksPerSecond); diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/time/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/time/ya.make index 37cc779265..60ba111835 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/time/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/time/ya.make @@ -22,7 +22,7 @@ PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/base/log_severity contrib/restricted/abseil-cpp-tstring/y_absl/numeric contrib/restricted/abseil-cpp-tstring/y_absl/strings - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal contrib/restricted/abseil-cpp-tstring/y_absl/time/civil_time contrib/restricted/abseil-cpp-tstring/y_absl/time/time_zone ) diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_optional_access.h b/contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_optional_access.h index 7420ade10f..097f3b80b7 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_optional_access.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_optional_access.h @@ -67,7 +67,7 @@ class bad_optional_access : public std::exception { namespace optional_internal { // throw delegator -[[noreturn]] ABSL_DLL void throw_bad_optional_access(); +[[noreturn]] ABSL_DLL void throw_bad_optional_access(); } // namespace optional_internal ABSL_NAMESPACE_END diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_variant_access.h b/contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_variant_access.h index 6e41782e78..c7789c6226 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_variant_access.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_variant_access.h @@ -70,8 +70,8 @@ class bad_variant_access : public std::exception { namespace variant_internal { -[[noreturn]] ABSL_DLL void ThrowBadVariantAccess(); -[[noreturn]] ABSL_DLL void Rethrow(); +[[noreturn]] ABSL_DLL void ThrowBadVariantAccess(); +[[noreturn]] ABSL_DLL void Rethrow(); } // namespace variant_internal ABSL_NAMESPACE_END diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/types/internal/.yandex_meta/licenses.list.txt b/contrib/restricted/abseil-cpp-tstring/y_absl/types/internal/.yandex_meta/licenses.list.txt index f39e683596..27eb40bafa 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/types/internal/.yandex_meta/licenses.list.txt +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/types/internal/.yandex_meta/licenses.list.txt @@ -1,24 +1,24 @@ -====================Apache-2.0==================== -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -====================COPYRIGHT==================== -// Copyright 2017 The Abseil Authors. - - -====================COPYRIGHT==================== -// Copyright 2018 The Abseil Authors. - - -====================COPYRIGHT==================== -// Copyright 2019 The Abseil Authors. +====================Apache-2.0==================== +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +====================COPYRIGHT==================== +// Copyright 2017 The Abseil Authors. + + +====================COPYRIGHT==================== +// Copyright 2018 The Abseil Authors. + + +====================COPYRIGHT==================== +// Copyright 2019 The Abseil Authors. diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/types/internal/ya.make b/contrib/restricted/abseil-cpp-tstring/y_absl/types/internal/ya.make index b5ead45856..9a44988749 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/types/internal/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/types/internal/ya.make @@ -1,14 +1,14 @@ -# Generated by devtools/yamaker. - -LIBRARY() - -OWNER( - somov - g:cpp-contrib -) - -LICENSE(Apache-2.0) - -LICENSE_TEXTS(.yandex_meta/licenses.list.txt) - -END() +# Generated by devtools/yamaker. + +LIBRARY() + +OWNER( + somov + g:cpp-contrib +) + +LICENSE(Apache-2.0) + +LICENSE_TEXTS(.yandex_meta/licenses.list.txt) + +END() diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/types/span.h b/contrib/restricted/abseil-cpp-tstring/y_absl/types/span.h index 1490b2f1b2..e594da8b4e 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/types/span.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/types/span.h @@ -169,7 +169,7 @@ class Span { typename std::enable_if<!std::is_const<T>::value, U>::type; public: - using element_type = T; + using element_type = T; using value_type = y_absl::remove_cv_t<T>; using pointer = T*; using const_pointer = const T*; @@ -243,8 +243,8 @@ class Span { // template <typename LazyT = T, typename = EnableIfConstView<LazyT>> - Span(std::initializer_list<value_type> v - ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept // NOLINT(runtime/explicit) + Span(std::initializer_list<value_type> v + ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept // NOLINT(runtime/explicit) : Span(v.begin(), v.size()) {} // Accessors diff --git a/contrib/restricted/abseil-cpp-tstring/ya.make b/contrib/restricted/abseil-cpp-tstring/ya.make index 67363a6930..d3ad02ad57 100644 --- a/contrib/restricted/abseil-cpp-tstring/ya.make +++ b/contrib/restricted/abseil-cpp-tstring/ya.make @@ -1,4 +1,4 @@ -# Generated by devtools/yamaker from nixpkgs 21.11. +# Generated by devtools/yamaker from nixpkgs 21.11. LIBRARY() @@ -7,7 +7,7 @@ OWNER( g:cpp-contrib ) -VERSION(20211102.0) +VERSION(20211102.0) LICENSE(Apache-2.0) @@ -50,11 +50,11 @@ PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/functional contrib/restricted/abseil-cpp-tstring/y_absl/hash contrib/restricted/abseil-cpp-tstring/y_absl/hash/internal - contrib/restricted/abseil-cpp-tstring/y_absl/memory - contrib/restricted/abseil-cpp-tstring/y_absl/meta + contrib/restricted/abseil-cpp-tstring/y_absl/memory + contrib/restricted/abseil-cpp-tstring/y_absl/meta contrib/restricted/abseil-cpp-tstring/y_absl/numeric - contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased - contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/periodic_sampler + contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp-tstring/y_absl/profiling/internal/periodic_sampler contrib/restricted/abseil-cpp-tstring/y_absl/random/absl_random_distributions contrib/restricted/abseil-cpp-tstring/y_absl/random/internal/absl_random_internal_distribution_test_util contrib/restricted/abseil-cpp-tstring/y_absl/random/internal/pool_urbg @@ -69,13 +69,13 @@ PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/status contrib/restricted/abseil-cpp-tstring/y_absl/status/statusor contrib/restricted/abseil-cpp-tstring/y_absl/strings - contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_cord_internal - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info - contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_sample_token + contrib/restricted/abseil-cpp-tstring/y_absl/strings/cord + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_cord_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_functions + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_handle + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_info + contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/cordz_sample_token contrib/restricted/abseil-cpp-tstring/y_absl/strings/internal/str_format contrib/restricted/abseil-cpp-tstring/y_absl/synchronization contrib/restricted/abseil-cpp-tstring/y_absl/synchronization/internal @@ -86,7 +86,7 @@ PEERDIR( contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_any_cast contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_optional_access contrib/restricted/abseil-cpp-tstring/y_absl/types/bad_variant_access - contrib/restricted/abseil-cpp-tstring/y_absl/types/internal + contrib/restricted/abseil-cpp-tstring/y_absl/types/internal contrib/restricted/abseil-cpp-tstring/y_absl/utility ) @@ -131,11 +131,11 @@ RECURSE( y_absl/functional y_absl/hash y_absl/hash/internal - y_absl/memory - y_absl/meta + y_absl/memory + y_absl/meta y_absl/numeric - y_absl/profiling/internal/exponential_biased - y_absl/profiling/internal/periodic_sampler + y_absl/profiling/internal/exponential_biased + y_absl/profiling/internal/periodic_sampler y_absl/random/absl_random_distributions y_absl/random/internal/absl_random_internal_distribution_test_util y_absl/random/internal/pool_urbg @@ -150,13 +150,13 @@ RECURSE( y_absl/status y_absl/status/statusor y_absl/strings - y_absl/strings/cord - y_absl/strings/internal/absl_cord_internal - y_absl/strings/internal/absl_strings_internal - y_absl/strings/internal/cordz_functions - y_absl/strings/internal/cordz_handle - y_absl/strings/internal/cordz_info - y_absl/strings/internal/cordz_sample_token + y_absl/strings/cord + y_absl/strings/internal/absl_cord_internal + y_absl/strings/internal/absl_strings_internal + y_absl/strings/internal/cordz_functions + y_absl/strings/internal/cordz_handle + y_absl/strings/internal/cordz_info + y_absl/strings/internal/cordz_sample_token y_absl/strings/internal/str_format y_absl/synchronization y_absl/synchronization/internal @@ -167,6 +167,6 @@ RECURSE( y_absl/types/bad_any_cast y_absl/types/bad_optional_access y_absl/types/bad_variant_access - y_absl/types/internal + y_absl/types/internal y_absl/utility ) diff --git a/contrib/restricted/abseil-cpp/.yandex_meta/devtools.copyrights.report b/contrib/restricted/abseil-cpp/.yandex_meta/devtools.copyrights.report index 52e2892efe..3f14e539e1 100644 --- a/contrib/restricted/abseil-cpp/.yandex_meta/devtools.copyrights.report +++ b/contrib/restricted/abseil-cpp/.yandex_meta/devtools.copyrights.report @@ -30,7 +30,7 @@ # ======================= KEEP COPYRIGHT_SERVICE_LABEL 02e3ff10f74acdb217118846c5465fc1 -BELONGS absl/algorithm/ya.make absl/base/ya.make absl/container/ya.make absl/debugging/internal/ya.make absl/debugging/ya.make absl/memory/ya.make absl/meta/ya.make absl/numeric/ya.make absl/strings/internal/str_format/ya.make absl/strings/ya.make absl/synchronization/internal/ya.make absl/synchronization/ya.make absl/time/ya.make absl/types/internal/ya.make absl/types/ya.make absl/utility/ya.make ya.make +BELONGS absl/algorithm/ya.make absl/base/ya.make absl/container/ya.make absl/debugging/internal/ya.make absl/debugging/ya.make absl/memory/ya.make absl/meta/ya.make absl/numeric/ya.make absl/strings/internal/str_format/ya.make absl/strings/ya.make absl/synchronization/internal/ya.make absl/synchronization/ya.make absl/time/ya.make absl/types/internal/ya.make absl/types/ya.make absl/utility/ya.make ya.make License text: // Copyright 2017 The Abseil Authors. Scancode info: @@ -99,7 +99,7 @@ BELONGS absl/algorithm/ya.make absl/base/ya.make absl/container/ya.make absl/deb absl/debugging/internal/elf_mem_image.h [2:2] absl/debugging/internal/stacktrace_arm-inl.inc [1:1] absl/debugging/internal/stacktrace_config.h [2:2] - absl/debugging/internal/stacktrace_emscripten-inl.inc [1:1] + absl/debugging/internal/stacktrace_emscripten-inl.inc [1:1] absl/debugging/internal/stacktrace_generic-inl.inc [1:1] absl/debugging/internal/stacktrace_powerpc-inl.inc [1:1] absl/debugging/internal/stacktrace_win32-inl.inc [1:1] @@ -264,7 +264,7 @@ BELONGS absl/time/ya.make absl/time/internal/cctz/src/zone_info_source.cc [1:1] KEEP COPYRIGHT_SERVICE_LABEL 2277624a2da390a98ec17138cb6dc2a5 -BELONGS absl/base/ya.make absl/container/ya.make absl/flags/ya.make absl/functional/ya.make absl/status/ya.make absl/strings/ya.make absl/types/internal/ya.make ya.make +BELONGS absl/base/ya.make absl/container/ya.make absl/flags/ya.make absl/functional/ya.make absl/status/ya.make absl/strings/ya.make absl/types/internal/ya.make ya.make License text: // Copyright 2019 The Abseil Authors. Scancode info: @@ -304,10 +304,10 @@ BELONGS absl/base/ya.make absl/container/ya.make absl/flags/ya.make absl/functio absl/flags/usage_config.h [2:2] absl/functional/function_ref.h [1:1] absl/functional/internal/function_ref.h [1:1] - absl/profiling/internal/exponential_biased.cc [1:1] - absl/profiling/internal/exponential_biased.h [1:1] - absl/profiling/internal/periodic_sampler.cc [1:1] - absl/profiling/internal/periodic_sampler.h [1:1] + absl/profiling/internal/exponential_biased.cc [1:1] + absl/profiling/internal/exponential_biased.h [1:1] + absl/profiling/internal/periodic_sampler.cc [1:1] + absl/profiling/internal/periodic_sampler.h [1:1] absl/random/internal/mock_helpers.h [2:2] absl/random/internal/mock_overload_set.h [2:2] absl/random/internal/uniform_helper.h [1:1] @@ -316,15 +316,15 @@ BELONGS absl/base/ya.make absl/container/ya.make absl/flags/ya.make absl/functio absl/status/status.h [1:1] absl/status/status_payload_printer.cc [1:1] absl/status/status_payload_printer.h [1:1] - absl/strings/internal/cordz_functions.cc [1:1] - absl/strings/internal/cordz_functions.h [1:1] - absl/strings/internal/cordz_handle.cc [1:1] - absl/strings/internal/cordz_handle.h [1:1] - absl/strings/internal/cordz_info.cc [1:1] - absl/strings/internal/cordz_info.h [1:1] - absl/strings/internal/cordz_sample_token.cc [1:1] - absl/strings/internal/cordz_sample_token.h [1:1] - absl/strings/internal/cordz_statistics.h [1:1] + absl/strings/internal/cordz_functions.cc [1:1] + absl/strings/internal/cordz_functions.h [1:1] + absl/strings/internal/cordz_handle.cc [1:1] + absl/strings/internal/cordz_handle.h [1:1] + absl/strings/internal/cordz_info.cc [1:1] + absl/strings/internal/cordz_info.h [1:1] + absl/strings/internal/cordz_sample_token.cc [1:1] + absl/strings/internal/cordz_sample_token.h [1:1] + absl/strings/internal/cordz_statistics.h [1:1] absl/types/internal/conformance_archetype.h [1:1] absl/types/internal/conformance_profile.h [1:1] absl/types/internal/conformance_testing.h [1:1] @@ -334,7 +334,7 @@ BELONGS absl/base/ya.make absl/container/ya.make absl/flags/ya.make absl/functio absl/types/internal/transform_args.h [1:1] KEEP COPYRIGHT_SERVICE_LABEL 3fb410b721d46624abdaeb2473ffa5d6 -BELONGS absl/base/ya.make absl/container/ya.make absl/debugging/internal/ya.make absl/debugging/ya.make absl/functional/ya.make absl/hash/internal/ya.make absl/hash/ya.make absl/strings/ya.make absl/time/ya.make absl/types/internal/ya.make absl/types/ya.make ya.make +BELONGS absl/base/ya.make absl/container/ya.make absl/debugging/internal/ya.make absl/debugging/ya.make absl/functional/ya.make absl/hash/internal/ya.make absl/hash/ya.make absl/strings/ya.make absl/time/ya.make absl/types/internal/ya.make absl/types/ya.make ya.make License text: // Copyright 2018 The Abseil Authors. Scancode info: @@ -404,7 +404,7 @@ BELONGS absl/base/ya.make absl/container/ya.make absl/debugging/internal/ya.make absl/hash/internal/hash.cc [1:1] absl/hash/internal/hash.h [1:1] absl/hash/internal/spy_hash_state.h [1:1] - absl/profiling/internal/sample_recorder.h [1:1] + absl/profiling/internal/sample_recorder.h [1:1] absl/random/bit_gen_ref.h [2:2] absl/random/internal/distribution_caller.h [2:2] absl/random/internal/pcg_engine.h [1:1] @@ -441,23 +441,23 @@ BELONGS absl/debugging/internal/ya.make absl/flags/ya.make absl/numeric/ya.make Files with this license: absl/cleanup/cleanup.h [1:1] absl/cleanup/internal/cleanup.h [1:1] - absl/debugging/internal/stacktrace_riscv-inl.inc [1:1] - absl/flags/internal/flag_msvc.inc [2:2] + absl/debugging/internal/stacktrace_riscv-inl.inc [1:1] + absl/flags/internal/flag_msvc.inc [2:2] absl/numeric/internal/representation.h [1:1] - absl/strings/cordz_test_helpers.h [1:1] + absl/strings/cordz_test_helpers.h [1:1] absl/strings/internal/cord_internal.h [1:1] - absl/strings/internal/cord_rep_btree.cc [1:1] - absl/strings/internal/cord_rep_btree.h [1:1] - absl/strings/internal/cord_rep_btree_navigator.cc [1:1] - absl/strings/internal/cord_rep_btree_navigator.h [1:1] - absl/strings/internal/cord_rep_btree_reader.cc [1:1] - absl/strings/internal/cord_rep_btree_reader.h [1:1] - absl/strings/internal/cord_rep_consume.cc [1:1] - absl/strings/internal/cord_rep_consume.h [1:1] + absl/strings/internal/cord_rep_btree.cc [1:1] + absl/strings/internal/cord_rep_btree.h [1:1] + absl/strings/internal/cord_rep_btree_navigator.cc [1:1] + absl/strings/internal/cord_rep_btree_navigator.h [1:1] + absl/strings/internal/cord_rep_btree_reader.cc [1:1] + absl/strings/internal/cord_rep_btree_reader.h [1:1] + absl/strings/internal/cord_rep_consume.cc [1:1] + absl/strings/internal/cord_rep_consume.h [1:1] absl/strings/internal/cord_rep_ring_reader.h [1:1] - absl/strings/internal/cord_rep_test_util.h [1:1] - absl/strings/internal/cordz_update_scope.h [1:1] - absl/strings/internal/cordz_update_tracker.h [1:1] + absl/strings/internal/cord_rep_test_util.h [1:1] + absl/strings/internal/cordz_update_scope.h [1:1] + absl/strings/internal/cordz_update_tracker.h [1:1] KEEP COPYRIGHT_SERVICE_LABEL 6499e2ad737f62db5558c81fbd2749a7 BELONGS ya.make @@ -471,7 +471,7 @@ BELONGS ya.make absl/random/internal/nanobenchmark.h [1:1] KEEP COPYRIGHT_SERVICE_LABEL d34864d3c7c7a5ffae3d414344aa54a8 -BELONGS absl/base/ya.make absl/debugging/ya.make absl/flags/ya.make absl/hash/internal/ya.make absl/numeric/ya.make absl/status/ya.make absl/strings/internal/str_format/ya.make absl/strings/ya.make absl/synchronization/internal/ya.make +BELONGS absl/base/ya.make absl/debugging/ya.make absl/flags/ya.make absl/hash/internal/ya.make absl/numeric/ya.make absl/status/ya.make absl/strings/internal/str_format/ya.make absl/strings/ya.make absl/synchronization/internal/ya.make License text: // Copyright 2020 The Abseil Authors. Scancode info: @@ -483,7 +483,7 @@ BELONGS absl/base/ya.make absl/debugging/ya.make absl/flags/ya.make absl/hash/in absl/base/internal/strerror.cc [1:1] absl/base/internal/strerror.h [1:1] absl/debugging/symbolize_darwin.inc [1:1] - absl/debugging/symbolize_emscripten.inc [1:1] + absl/debugging/symbolize_emscripten.inc [1:1] absl/flags/commandlineflag.cc [2:2] absl/flags/commandlineflag.h [2:2] absl/flags/internal/commandlineflag.cc [2:2] @@ -492,8 +492,8 @@ BELONGS absl/base/ya.make absl/debugging/ya.make absl/flags/ya.make absl/hash/in absl/flags/internal/sequence_lock.h [2:2] absl/flags/reflection.cc [2:2] absl/flags/reflection.h [2:2] - absl/hash/internal/low_level_hash.cc [1:1] - absl/hash/internal/low_level_hash.h [1:1] + absl/hash/internal/low_level_hash.cc [1:1] + absl/hash/internal/low_level_hash.h [1:1] absl/numeric/bits.h [1:1] absl/numeric/internal/bits.h [1:1] absl/status/internal/statusor_internal.h [1:1] diff --git a/contrib/restricted/abseil-cpp/.yandex_meta/devtools.licenses.report b/contrib/restricted/abseil-cpp/.yandex_meta/devtools.licenses.report index e81554edb2..ce2d410f66 100644 --- a/contrib/restricted/abseil-cpp/.yandex_meta/devtools.licenses.report +++ b/contrib/restricted/abseil-cpp/.yandex_meta/devtools.licenses.report @@ -30,7 +30,7 @@ # ======================= KEEP Apache-2.0 0e8699c5f5ea602534a6558430df2b8d -BELONGS absl/debugging/internal/ya.make absl/hash/internal/ya.make absl/numeric/ya.make absl/strings/ya.make ya.make +BELONGS absl/debugging/internal/ya.make absl/hash/internal/ya.make absl/numeric/ya.make absl/strings/ya.make ya.make Note: matched license text is too long. Read it in the source files. Scancode info: Original SPDX id: Apache-2.0 @@ -38,31 +38,31 @@ BELONGS absl/debugging/internal/ya.make absl/hash/internal/ya.make absl/numeric/ Match type : NOTICE Links : http://www.apache.org/licenses/, http://www.apache.org/licenses/LICENSE-2.0, https://spdx.org/licenses/Apache-2.0 Files with this license: - absl/debugging/internal/stacktrace_riscv-inl.inc [3:13] - absl/hash/internal/low_level_hash.cc [3:13] - absl/hash/internal/low_level_hash.h [3:13] + absl/debugging/internal/stacktrace_riscv-inl.inc [3:13] + absl/hash/internal/low_level_hash.cc [3:13] + absl/hash/internal/low_level_hash.h [3:13] absl/numeric/bits.h [3:13] absl/numeric/internal/bits.h [3:13] absl/numeric/internal/representation.h [3:13] - absl/profiling/internal/exponential_biased.cc [3:13] - absl/profiling/internal/exponential_biased.h [3:13] + absl/profiling/internal/exponential_biased.cc [3:13] + absl/profiling/internal/exponential_biased.h [3:13] absl/random/internal/nanobenchmark.h [3:13] - absl/strings/cordz_test_helpers.h [3:13] - absl/strings/internal/cord_rep_btree.cc [3:13] - absl/strings/internal/cord_rep_btree.h [3:13] - absl/strings/internal/cord_rep_btree_navigator.cc [3:13] - absl/strings/internal/cord_rep_btree_navigator.h [3:13] - absl/strings/internal/cord_rep_btree_reader.cc [3:13] - absl/strings/internal/cord_rep_btree_reader.h [3:13] - absl/strings/internal/cord_rep_consume.cc [3:13] - absl/strings/internal/cord_rep_consume.h [3:13] + absl/strings/cordz_test_helpers.h [3:13] + absl/strings/internal/cord_rep_btree.cc [3:13] + absl/strings/internal/cord_rep_btree.h [3:13] + absl/strings/internal/cord_rep_btree_navigator.cc [3:13] + absl/strings/internal/cord_rep_btree_navigator.h [3:13] + absl/strings/internal/cord_rep_btree_reader.cc [3:13] + absl/strings/internal/cord_rep_btree_reader.h [3:13] + absl/strings/internal/cord_rep_consume.cc [3:13] + absl/strings/internal/cord_rep_consume.h [3:13] absl/strings/internal/cord_rep_flat.h [3:13] absl/strings/internal/cord_rep_ring.cc [3:13] absl/strings/internal/cord_rep_ring.h [3:13] absl/strings/internal/cord_rep_ring_reader.h [3:13] - absl/strings/internal/cord_rep_test_util.h [3:13] - absl/strings/internal/cordz_update_scope.h [3:13] - absl/strings/internal/cordz_update_tracker.h [3:13] + absl/strings/internal/cord_rep_test_util.h [3:13] + absl/strings/internal/cordz_update_scope.h [3:13] + absl/strings/internal/cordz_update_tracker.h [3:13] KEEP Apache-2.0 0f66a26c8211d9f8c21369fcb6702370 BELONGS absl/time/ya.make @@ -106,7 +106,7 @@ BELONGS ya.make Match type : NOTICE Links : http://www.apache.org/licenses/, http://www.apache.org/licenses/LICENSE-2.0, https://spdx.org/licenses/Apache-2.0 Files with this license: - README.md [128:131] + README.md [128:131] KEEP Public-Domain 3a682fe6def1cddc889298ee2a043f6f BELONGS absl/time/ya.make @@ -121,7 +121,7 @@ BELONGS absl/time/ya.make absl/time/internal/cctz/src/tzfile.h [8:8] KEEP Apache-2.0 3ea5060c4f08f5769674fbf0c0fb3992 -BELONGS absl/algorithm/ya.make absl/base/ya.make absl/container/ya.make absl/debugging/internal/ya.make absl/debugging/ya.make absl/flags/ya.make absl/functional/ya.make absl/hash/internal/ya.make absl/hash/ya.make absl/memory/ya.make absl/meta/ya.make absl/numeric/ya.make absl/status/ya.make absl/strings/internal/str_format/ya.make absl/strings/ya.make absl/synchronization/internal/ya.make absl/synchronization/ya.make absl/time/ya.make absl/types/internal/ya.make absl/types/ya.make absl/utility/ya.make ya.make +BELONGS absl/algorithm/ya.make absl/base/ya.make absl/container/ya.make absl/debugging/internal/ya.make absl/debugging/ya.make absl/flags/ya.make absl/functional/ya.make absl/hash/internal/ya.make absl/hash/ya.make absl/memory/ya.make absl/meta/ya.make absl/numeric/ya.make absl/status/ya.make absl/strings/internal/str_format/ya.make absl/strings/ya.make absl/synchronization/internal/ya.make absl/synchronization/ya.make absl/time/ya.make absl/types/internal/ya.make absl/types/ya.make absl/utility/ya.make ya.make Note: matched license text is too long. Read it in the source files. Scancode info: Original SPDX id: Apache-2.0 @@ -246,7 +246,7 @@ BELONGS absl/algorithm/ya.make absl/base/ya.make absl/container/ya.make absl/deb absl/debugging/internal/examine_stack.h [4:14] absl/debugging/internal/stack_consumption.h [4:14] absl/debugging/internal/stacktrace_arm-inl.inc [3:13] - absl/debugging/internal/stacktrace_emscripten-inl.inc [3:13] + absl/debugging/internal/stacktrace_emscripten-inl.inc [3:13] absl/debugging/internal/stacktrace_generic-inl.inc [3:13] absl/debugging/internal/stacktrace_powerpc-inl.inc [3:13] absl/debugging/internal/stacktrace_win32-inl.inc [3:13] @@ -263,7 +263,7 @@ BELONGS absl/algorithm/ya.make absl/base/ya.make absl/container/ya.make absl/deb absl/debugging/symbolize.h [3:13] absl/debugging/symbolize_darwin.inc [3:13] absl/debugging/symbolize_elf.inc [3:13] - absl/debugging/symbolize_emscripten.inc [3:13] + absl/debugging/symbolize_emscripten.inc [3:13] absl/debugging/symbolize_unimplemented.inc [3:13] absl/debugging/symbolize_win32.inc [3:13] absl/flags/commandlineflag.cc [4:14] @@ -276,7 +276,7 @@ BELONGS absl/algorithm/ya.make absl/base/ya.make absl/container/ya.make absl/deb absl/flags/internal/commandlineflag.h [4:14] absl/flags/internal/flag.cc [4:14] absl/flags/internal/flag.h [4:14] - absl/flags/internal/flag_msvc.inc [4:14] + absl/flags/internal/flag_msvc.inc [4:14] absl/flags/internal/parse.h [4:14] absl/flags/internal/path_util.h [4:14] absl/flags/internal/private_handle_accessor.cc [4:14] @@ -314,9 +314,9 @@ BELONGS absl/algorithm/ya.make absl/base/ya.make absl/container/ya.make absl/deb absl/numeric/int128.h [4:14] absl/numeric/int128_have_intrinsic.inc [4:14] absl/numeric/int128_no_intrinsic.inc [4:14] - absl/profiling/internal/periodic_sampler.cc [3:13] - absl/profiling/internal/periodic_sampler.h [3:13] - absl/profiling/internal/sample_recorder.h [3:13] + absl/profiling/internal/periodic_sampler.cc [3:13] + absl/profiling/internal/periodic_sampler.h [3:13] + absl/profiling/internal/sample_recorder.h [3:13] absl/random/bernoulli_distribution.h [3:13] absl/random/beta_distribution.h [3:13] absl/random/bit_gen_ref.h [4:14] @@ -396,15 +396,15 @@ BELONGS absl/algorithm/ya.make absl/base/ya.make absl/container/ya.make absl/deb absl/strings/internal/charconv_parse.h [3:13] absl/strings/internal/cord_internal.cc [3:13] absl/strings/internal/cord_internal.h [3:13] - absl/strings/internal/cordz_functions.cc [3:13] - absl/strings/internal/cordz_functions.h [3:13] - absl/strings/internal/cordz_handle.cc [3:13] - absl/strings/internal/cordz_handle.h [3:13] - absl/strings/internal/cordz_info.cc [3:13] - absl/strings/internal/cordz_info.h [3:13] - absl/strings/internal/cordz_sample_token.cc [3:13] - absl/strings/internal/cordz_sample_token.h [3:13] - absl/strings/internal/cordz_statistics.h [3:13] + absl/strings/internal/cordz_functions.cc [3:13] + absl/strings/internal/cordz_functions.h [3:13] + absl/strings/internal/cordz_handle.cc [3:13] + absl/strings/internal/cordz_handle.h [3:13] + absl/strings/internal/cordz_info.cc [3:13] + absl/strings/internal/cordz_info.h [3:13] + absl/strings/internal/cordz_sample_token.cc [3:13] + absl/strings/internal/cordz_sample_token.h [3:13] + absl/strings/internal/cordz_statistics.h [3:13] absl/strings/internal/escaping.cc [3:13] absl/strings/internal/escaping.h [3:13] absl/strings/internal/escaping_test_common.h [3:13] @@ -503,7 +503,7 @@ BELONGS absl/algorithm/ya.make absl/base/ya.make absl/container/ya.make absl/deb absl/utility/utility.h [3:13] SKIP LicenseRef-scancode-warranty-disclaimer 5ba761db85e57267704f71a6bcf20c2a -BELONGS absl/container/ya.make ya.make +BELONGS absl/container/ya.make ya.make License text: // This utility is internal-only. Use at your own risk. Scancode info: @@ -513,7 +513,7 @@ BELONGS absl/container/ya.make ya.make Links : https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/warranty-disclaimer.LICENSE Files with this license: absl/container/internal/hashtablez_sampler.h [37:37] - absl/profiling/internal/sample_recorder.h [22:22] + absl/profiling/internal/sample_recorder.h [22:22] SKIP LicenseRef-scancode-generic-cla 5d780ffa423067f23c6a123ae33e7c18 BELONGS ya.make @@ -537,7 +537,7 @@ BELONGS ya.make Match type : REFERENCE Links : https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/unknown-license-reference.LICENSE Files with this license: - README.md [131:131] + README.md [131:131] SKIP LicenseRef-scancode-generic-exception 99cf00730bf3973359b67cfa5b7ac051 BELONGS absl/synchronization/ya.make @@ -587,23 +587,23 @@ BELONGS ya.make Links : https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/generic-cla.LICENSE Files with this license: CONTRIBUTING.md [11:12] - -SKIP BSD-2-Clause AND GPL-2.0-only e12cf8844c9d92dd647ddf4320b73d06 -BELONGS absl/strings/ya.make -# not a license - License text: - // input unless explicitly stated otherwise. All functions returning a CordRep* - Scancode info: - Original SPDX id: BSD-2-Clause - Score : 8.16 - Match type : NOTICE - Links : http://opensource.org/licenses/bsd-license.php, http://www.opensource.org/licenses/BSD-2-Clause, https://spdx.org/licenses/BSD-2-Clause - Files with this license: - absl/strings/internal/cord_rep_btree.h [49:49] - Scancode info: - Original SPDX id: GPL-2.0-only - Score : 8.16 - Match type : NOTICE - Links : http://www.gnu.org/licenses/gpl-2.0.html, http://www.gnu.org/licenses/gpl-2.0.txt, https://spdx.org/licenses/GPL-2.0-only - Files with this license: - absl/strings/internal/cord_rep_btree.h [49:49] + +SKIP BSD-2-Clause AND GPL-2.0-only e12cf8844c9d92dd647ddf4320b73d06 +BELONGS absl/strings/ya.make +# not a license + License text: + // input unless explicitly stated otherwise. All functions returning a CordRep* + Scancode info: + Original SPDX id: BSD-2-Clause + Score : 8.16 + Match type : NOTICE + Links : http://opensource.org/licenses/bsd-license.php, http://www.opensource.org/licenses/BSD-2-Clause, https://spdx.org/licenses/BSD-2-Clause + Files with this license: + absl/strings/internal/cord_rep_btree.h [49:49] + Scancode info: + Original SPDX id: GPL-2.0-only + Score : 8.16 + Match type : NOTICE + Links : http://www.gnu.org/licenses/gpl-2.0.html, http://www.gnu.org/licenses/gpl-2.0.txt, https://spdx.org/licenses/GPL-2.0-only + Files with this license: + absl/strings/internal/cord_rep_btree.h [49:49] diff --git a/contrib/restricted/abseil-cpp/FAQ.md b/contrib/restricted/abseil-cpp/FAQ.md index fbd92ce975..efc8d6f4c4 100644 --- a/contrib/restricted/abseil-cpp/FAQ.md +++ b/contrib/restricted/abseil-cpp/FAQ.md @@ -27,10 +27,10 @@ compiler, there several ways to do this: file](https://docs.bazel.build/versions/master/guide.html#bazelrc) If you are using CMake as the build system, you'll need to add a line like -`set(CMAKE_CXX_STANDARD 17)` to your top level `CMakeLists.txt` file. If you -are developing a library designed to be used by other clients, you should -instead leave `CMAKE_CXX_STANDARD` unset and configure the minimum C++ standard -required by each of your library targets via `target_compile_features`. See the +`set(CMAKE_CXX_STANDARD 17)` to your top level `CMakeLists.txt` file. If you +are developing a library designed to be used by other clients, you should +instead leave `CMAKE_CXX_STANDARD` unset and configure the minimum C++ standard +required by each of your library targets via `target_compile_features`. See the [CMake build instructions](https://github.com/abseil/abseil-cpp/blob/master/CMake/README.md) for more information. diff --git a/contrib/restricted/abseil-cpp/README.md b/contrib/restricted/abseil-cpp/README.md index db3a7b447a..8e257b5c02 100644 --- a/contrib/restricted/abseil-cpp/README.md +++ b/contrib/restricted/abseil-cpp/README.md @@ -92,9 +92,9 @@ Abseil contains the following C++ library components: available within C++14 and C++17 versions of the C++ `<type_traits>` library. * [`numeric`](absl/numeric/) <br /> The `numeric` library contains C++11-compatible 128-bit integers. -* [`profiling`](absl/profiling/) - <br /> The `profiling` library contains utility code for profiling C++ - entities. It is currently a private dependency of other Abseil libraries. +* [`profiling`](absl/profiling/) + <br /> The `profiling` library contains utility code for profiling C++ + entities. It is currently a private dependency of other Abseil libraries. * [`status`](absl/status/) <br /> The `status` contains abstractions for error handling, specifically `absl::Status` and `absl::StatusOr<T>`. diff --git a/contrib/restricted/abseil-cpp/absl/algorithm/container.h b/contrib/restricted/abseil-cpp/absl/algorithm/container.h index c38a4a63db..edbaeb91c6 100644 --- a/contrib/restricted/abseil-cpp/absl/algorithm/container.h +++ b/contrib/restricted/abseil-cpp/absl/algorithm/container.h @@ -905,11 +905,11 @@ void c_sort(C& c) { // Overload of c_sort() for performing a `comp` comparison other than the // default `operator<`. -template <typename C, typename LessThan> -void c_sort(C& c, LessThan&& comp) { +template <typename C, typename LessThan> +void c_sort(C& c, LessThan&& comp) { std::sort(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_stable_sort() @@ -925,11 +925,11 @@ void c_stable_sort(C& c) { // Overload of c_stable_sort() for performing a `comp` comparison other than the // default `operator<`. -template <typename C, typename LessThan> -void c_stable_sort(C& c, LessThan&& comp) { +template <typename C, typename LessThan> +void c_stable_sort(C& c, LessThan&& comp) { std::stable_sort(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_is_sorted() @@ -944,11 +944,11 @@ bool c_is_sorted(const C& c) { // c_is_sorted() overload for performing a `comp` comparison other than the // default `operator<`. -template <typename C, typename LessThan> -bool c_is_sorted(const C& c, LessThan&& comp) { +template <typename C, typename LessThan> +bool c_is_sorted(const C& c, LessThan&& comp) { return std::is_sorted(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_partial_sort() @@ -966,14 +966,14 @@ void c_partial_sort( // Overload of c_partial_sort() for performing a `comp` comparison other than // the default `operator<`. -template <typename RandomAccessContainer, typename LessThan> +template <typename RandomAccessContainer, typename LessThan> void c_partial_sort( RandomAccessContainer& sequence, container_algorithm_internal::ContainerIter<RandomAccessContainer> middle, - LessThan&& comp) { + LessThan&& comp) { std::partial_sort(container_algorithm_internal::c_begin(sequence), middle, container_algorithm_internal::c_end(sequence), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_partial_sort_copy() @@ -994,15 +994,15 @@ c_partial_sort_copy(const C& sequence, RandomAccessContainer& result) { // Overload of c_partial_sort_copy() for performing a `comp` comparison other // than the default `operator<`. -template <typename C, typename RandomAccessContainer, typename LessThan> +template <typename C, typename RandomAccessContainer, typename LessThan> container_algorithm_internal::ContainerIter<RandomAccessContainer> c_partial_sort_copy(const C& sequence, RandomAccessContainer& result, - LessThan&& comp) { + LessThan&& comp) { return std::partial_sort_copy(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), container_algorithm_internal::c_begin(result), container_algorithm_internal::c_end(result), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_is_sorted_until() @@ -1018,12 +1018,12 @@ container_algorithm_internal::ContainerIter<C> c_is_sorted_until(C& c) { // Overload of c_is_sorted_until() for performing a `comp` comparison other than // the default `operator<`. -template <typename C, typename LessThan> +template <typename C, typename LessThan> container_algorithm_internal::ContainerIter<C> c_is_sorted_until( - C& c, LessThan&& comp) { + C& c, LessThan&& comp) { return std::is_sorted_until(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_nth_element() @@ -1043,14 +1043,14 @@ void c_nth_element( // Overload of c_nth_element() for performing a `comp` comparison other than // the default `operator<`. -template <typename RandomAccessContainer, typename LessThan> +template <typename RandomAccessContainer, typename LessThan> void c_nth_element( RandomAccessContainer& sequence, container_algorithm_internal::ContainerIter<RandomAccessContainer> nth, - LessThan&& comp) { + LessThan&& comp) { std::nth_element(container_algorithm_internal::c_begin(sequence), nth, container_algorithm_internal::c_end(sequence), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } //------------------------------------------------------------------------------ @@ -1072,12 +1072,12 @@ container_algorithm_internal::ContainerIter<Sequence> c_lower_bound( // Overload of c_lower_bound() for performing a `comp` comparison other than // the default `operator<`. -template <typename Sequence, typename T, typename LessThan> +template <typename Sequence, typename T, typename LessThan> container_algorithm_internal::ContainerIter<Sequence> c_lower_bound( - Sequence& sequence, T&& value, LessThan&& comp) { + Sequence& sequence, T&& value, LessThan&& comp) { return std::lower_bound(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<T>(value), std::forward<LessThan>(comp)); + std::forward<T>(value), std::forward<LessThan>(comp)); } // c_upper_bound() @@ -1095,12 +1095,12 @@ container_algorithm_internal::ContainerIter<Sequence> c_upper_bound( // Overload of c_upper_bound() for performing a `comp` comparison other than // the default `operator<`. -template <typename Sequence, typename T, typename LessThan> +template <typename Sequence, typename T, typename LessThan> container_algorithm_internal::ContainerIter<Sequence> c_upper_bound( - Sequence& sequence, T&& value, LessThan&& comp) { + Sequence& sequence, T&& value, LessThan&& comp) { return std::upper_bound(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<T>(value), std::forward<LessThan>(comp)); + std::forward<T>(value), std::forward<LessThan>(comp)); } // c_equal_range() @@ -1118,12 +1118,12 @@ c_equal_range(Sequence& sequence, T&& value) { // Overload of c_equal_range() for performing a `comp` comparison other than // the default `operator<`. -template <typename Sequence, typename T, typename LessThan> +template <typename Sequence, typename T, typename LessThan> container_algorithm_internal::ContainerIterPairType<Sequence, Sequence> -c_equal_range(Sequence& sequence, T&& value, LessThan&& comp) { +c_equal_range(Sequence& sequence, T&& value, LessThan&& comp) { return std::equal_range(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<T>(value), std::forward<LessThan>(comp)); + std::forward<T>(value), std::forward<LessThan>(comp)); } // c_binary_search() @@ -1140,12 +1140,12 @@ bool c_binary_search(Sequence&& sequence, T&& value) { // Overload of c_binary_search() for performing a `comp` comparison other than // the default `operator<`. -template <typename Sequence, typename T, typename LessThan> -bool c_binary_search(Sequence&& sequence, T&& value, LessThan&& comp) { +template <typename Sequence, typename T, typename LessThan> +bool c_binary_search(Sequence&& sequence, T&& value, LessThan&& comp) { return std::binary_search(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<T>(value), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } //------------------------------------------------------------------------------ @@ -1166,14 +1166,14 @@ OutputIterator c_merge(const C1& c1, const C2& c2, OutputIterator result) { // Overload of c_merge() for performing a `comp` comparison other than // the default `operator<`. -template <typename C1, typename C2, typename OutputIterator, typename LessThan> +template <typename C1, typename C2, typename OutputIterator, typename LessThan> OutputIterator c_merge(const C1& c1, const C2& c2, OutputIterator result, - LessThan&& comp) { + LessThan&& comp) { return std::merge(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2), result, - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_inplace_merge() @@ -1189,13 +1189,13 @@ void c_inplace_merge(C& c, // Overload of c_inplace_merge() for performing a merge using a `comp` other // than `operator<`. -template <typename C, typename LessThan> +template <typename C, typename LessThan> void c_inplace_merge(C& c, container_algorithm_internal::ContainerIter<C> middle, - LessThan&& comp) { + LessThan&& comp) { std::inplace_merge(container_algorithm_internal::c_begin(c), middle, container_algorithm_internal::c_end(c), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_includes() @@ -1213,13 +1213,13 @@ bool c_includes(const C1& c1, const C2& c2) { // Overload of c_includes() for performing a merge using a `comp` other than // `operator<`. -template <typename C1, typename C2, typename LessThan> -bool c_includes(const C1& c1, const C2& c2, LessThan&& comp) { +template <typename C1, typename C2, typename LessThan> +bool c_includes(const C1& c1, const C2& c2, LessThan&& comp) { return std::includes(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_set_union() @@ -1243,7 +1243,7 @@ OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output) { // Overload of c_set_union() for performing a merge using a `comp` other than // `operator<`. -template <typename C1, typename C2, typename OutputIterator, typename LessThan, +template <typename C1, typename C2, typename OutputIterator, typename LessThan, typename = typename std::enable_if< !container_algorithm_internal::IsUnorderedContainer<C1>::value, void>::type, @@ -1251,18 +1251,18 @@ template <typename C1, typename C2, typename OutputIterator, typename LessThan, !container_algorithm_internal::IsUnorderedContainer<C2>::value, void>::type> OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output, - LessThan&& comp) { + LessThan&& comp) { return std::set_union(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2), output, - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_set_intersection() // // Container-based version of the <algorithm> `std::set_intersection()` function -// to return an iterator containing the intersection of two sorted containers. +// to return an iterator containing the intersection of two sorted containers. template <typename C1, typename C2, typename OutputIterator, typename = typename std::enable_if< !container_algorithm_internal::IsUnorderedContainer<C1>::value, @@ -1272,11 +1272,11 @@ template <typename C1, typename C2, typename OutputIterator, void>::type> OutputIterator c_set_intersection(const C1& c1, const C2& c2, OutputIterator output) { - // In debug builds, ensure that both containers are sorted with respect to the - // default comparator. std::set_intersection requires the containers be sorted - // using operator<. - assert(absl::c_is_sorted(c1)); - assert(absl::c_is_sorted(c2)); + // In debug builds, ensure that both containers are sorted with respect to the + // default comparator. std::set_intersection requires the containers be sorted + // using operator<. + assert(absl::c_is_sorted(c1)); + assert(absl::c_is_sorted(c2)); return std::set_intersection(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), @@ -1285,7 +1285,7 @@ OutputIterator c_set_intersection(const C1& c1, const C2& c2, // Overload of c_set_intersection() for performing a merge using a `comp` other // than `operator<`. -template <typename C1, typename C2, typename OutputIterator, typename LessThan, +template <typename C1, typename C2, typename OutputIterator, typename LessThan, typename = typename std::enable_if< !container_algorithm_internal::IsUnorderedContainer<C1>::value, void>::type, @@ -1293,17 +1293,17 @@ template <typename C1, typename C2, typename OutputIterator, typename LessThan, !container_algorithm_internal::IsUnorderedContainer<C2>::value, void>::type> OutputIterator c_set_intersection(const C1& c1, const C2& c2, - OutputIterator output, LessThan&& comp) { - // In debug builds, ensure that both containers are sorted with respect to the - // default comparator. std::set_intersection requires the containers be sorted - // using the same comparator. - assert(absl::c_is_sorted(c1, comp)); - assert(absl::c_is_sorted(c2, comp)); + OutputIterator output, LessThan&& comp) { + // In debug builds, ensure that both containers are sorted with respect to the + // default comparator. std::set_intersection requires the containers be sorted + // using the same comparator. + assert(absl::c_is_sorted(c1, comp)); + assert(absl::c_is_sorted(c2, comp)); return std::set_intersection(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2), output, - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_set_difference() @@ -1328,7 +1328,7 @@ OutputIterator c_set_difference(const C1& c1, const C2& c2, // Overload of c_set_difference() for performing a merge using a `comp` other // than `operator<`. -template <typename C1, typename C2, typename OutputIterator, typename LessThan, +template <typename C1, typename C2, typename OutputIterator, typename LessThan, typename = typename std::enable_if< !container_algorithm_internal::IsUnorderedContainer<C1>::value, void>::type, @@ -1336,12 +1336,12 @@ template <typename C1, typename C2, typename OutputIterator, typename LessThan, !container_algorithm_internal::IsUnorderedContainer<C2>::value, void>::type> OutputIterator c_set_difference(const C1& c1, const C2& c2, - OutputIterator output, LessThan&& comp) { + OutputIterator output, LessThan&& comp) { return std::set_difference(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2), output, - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_set_symmetric_difference() @@ -1367,7 +1367,7 @@ OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2, // Overload of c_set_symmetric_difference() for performing a merge using a // `comp` other than `operator<`. -template <typename C1, typename C2, typename OutputIterator, typename LessThan, +template <typename C1, typename C2, typename OutputIterator, typename LessThan, typename = typename std::enable_if< !container_algorithm_internal::IsUnorderedContainer<C1>::value, void>::type, @@ -1376,13 +1376,13 @@ template <typename C1, typename C2, typename OutputIterator, typename LessThan, void>::type> OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2, OutputIterator output, - LessThan&& comp) { + LessThan&& comp) { return std::set_symmetric_difference( container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2), output, - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } //------------------------------------------------------------------------------ @@ -1401,11 +1401,11 @@ void c_push_heap(RandomAccessContainer& sequence) { // Overload of c_push_heap() for performing a push operation on a heap using a // `comp` other than `operator<`. -template <typename RandomAccessContainer, typename LessThan> -void c_push_heap(RandomAccessContainer& sequence, LessThan&& comp) { +template <typename RandomAccessContainer, typename LessThan> +void c_push_heap(RandomAccessContainer& sequence, LessThan&& comp) { std::push_heap(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_pop_heap() @@ -1420,11 +1420,11 @@ void c_pop_heap(RandomAccessContainer& sequence) { // Overload of c_pop_heap() for performing a pop operation on a heap using a // `comp` other than `operator<`. -template <typename RandomAccessContainer, typename LessThan> -void c_pop_heap(RandomAccessContainer& sequence, LessThan&& comp) { +template <typename RandomAccessContainer, typename LessThan> +void c_pop_heap(RandomAccessContainer& sequence, LessThan&& comp) { std::pop_heap(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_make_heap() @@ -1439,11 +1439,11 @@ void c_make_heap(RandomAccessContainer& sequence) { // Overload of c_make_heap() for performing heap comparisons using a // `comp` other than `operator<` -template <typename RandomAccessContainer, typename LessThan> -void c_make_heap(RandomAccessContainer& sequence, LessThan&& comp) { +template <typename RandomAccessContainer, typename LessThan> +void c_make_heap(RandomAccessContainer& sequence, LessThan&& comp) { std::make_heap(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_sort_heap() @@ -1458,11 +1458,11 @@ void c_sort_heap(RandomAccessContainer& sequence) { // Overload of c_sort_heap() for performing heap comparisons using a // `comp` other than `operator<` -template <typename RandomAccessContainer, typename LessThan> -void c_sort_heap(RandomAccessContainer& sequence, LessThan&& comp) { +template <typename RandomAccessContainer, typename LessThan> +void c_sort_heap(RandomAccessContainer& sequence, LessThan&& comp) { std::sort_heap(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_is_heap() @@ -1477,11 +1477,11 @@ bool c_is_heap(const RandomAccessContainer& sequence) { // Overload of c_is_heap() for performing heap comparisons using a // `comp` other than `operator<` -template <typename RandomAccessContainer, typename LessThan> -bool c_is_heap(const RandomAccessContainer& sequence, LessThan&& comp) { +template <typename RandomAccessContainer, typename LessThan> +bool c_is_heap(const RandomAccessContainer& sequence, LessThan&& comp) { return std::is_heap(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_is_heap_until() @@ -1497,12 +1497,12 @@ c_is_heap_until(RandomAccessContainer& sequence) { // Overload of c_is_heap_until() for performing heap comparisons using a // `comp` other than `operator<` -template <typename RandomAccessContainer, typename LessThan> +template <typename RandomAccessContainer, typename LessThan> container_algorithm_internal::ContainerIter<RandomAccessContainer> -c_is_heap_until(RandomAccessContainer& sequence, LessThan&& comp) { +c_is_heap_until(RandomAccessContainer& sequence, LessThan&& comp) { return std::is_heap_until(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } //------------------------------------------------------------------------------ @@ -1523,12 +1523,12 @@ container_algorithm_internal::ContainerIter<Sequence> c_min_element( // Overload of c_min_element() for performing a `comp` comparison other than // `operator<`. -template <typename Sequence, typename LessThan> +template <typename Sequence, typename LessThan> container_algorithm_internal::ContainerIter<Sequence> c_min_element( - Sequence& sequence, LessThan&& comp) { + Sequence& sequence, LessThan&& comp) { return std::min_element(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_max_element() @@ -1545,12 +1545,12 @@ container_algorithm_internal::ContainerIter<Sequence> c_max_element( // Overload of c_max_element() for performing a `comp` comparison other than // `operator<`. -template <typename Sequence, typename LessThan> +template <typename Sequence, typename LessThan> container_algorithm_internal::ContainerIter<Sequence> c_max_element( - Sequence& sequence, LessThan&& comp) { + Sequence& sequence, LessThan&& comp) { return std::max_element(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_minmax_element() @@ -1568,12 +1568,12 @@ c_minmax_element(C& c) { // Overload of c_minmax_element() for performing `comp` comparisons other than // `operator<`. -template <typename C, typename LessThan> +template <typename C, typename LessThan> container_algorithm_internal::ContainerIterPairType<C, C> -c_minmax_element(C& c, LessThan&& comp) { +c_minmax_element(C& c, LessThan&& comp) { return std::minmax_element(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } //------------------------------------------------------------------------------ @@ -1598,15 +1598,15 @@ bool c_lexicographical_compare(Sequence1&& sequence1, Sequence2&& sequence2) { // Overload of c_lexicographical_compare() for performing a lexicographical // comparison using a `comp` operator instead of `operator<`. -template <typename Sequence1, typename Sequence2, typename LessThan> +template <typename Sequence1, typename Sequence2, typename LessThan> bool c_lexicographical_compare(Sequence1&& sequence1, Sequence2&& sequence2, - LessThan&& comp) { + LessThan&& comp) { return std::lexicographical_compare( container_algorithm_internal::c_begin(sequence1), container_algorithm_internal::c_end(sequence1), container_algorithm_internal::c_begin(sequence2), container_algorithm_internal::c_end(sequence2), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_next_permutation() @@ -1622,11 +1622,11 @@ bool c_next_permutation(C& c) { // Overload of c_next_permutation() for performing a lexicographical // comparison using a `comp` operator instead of `operator<`. -template <typename C, typename LessThan> -bool c_next_permutation(C& c, LessThan&& comp) { +template <typename C, typename LessThan> +bool c_next_permutation(C& c, LessThan&& comp) { return std::next_permutation(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } // c_prev_permutation() @@ -1642,11 +1642,11 @@ bool c_prev_permutation(C& c) { // Overload of c_prev_permutation() for performing a lexicographical // comparison using a `comp` operator instead of `operator<`. -template <typename C, typename LessThan> -bool c_prev_permutation(C& c, LessThan&& comp) { +template <typename C, typename LessThan> +bool c_prev_permutation(C& c, LessThan&& comp) { return std::prev_permutation(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), - std::forward<LessThan>(comp)); + std::forward<LessThan>(comp)); } //------------------------------------------------------------------------------ diff --git a/contrib/restricted/abseil-cpp/absl/base/.yandex_meta/licenses.list.txt b/contrib/restricted/abseil-cpp/absl/base/.yandex_meta/licenses.list.txt index 9035904094..143dc6c6be 100644 --- a/contrib/restricted/abseil-cpp/absl/base/.yandex_meta/licenses.list.txt +++ b/contrib/restricted/abseil-cpp/absl/base/.yandex_meta/licenses.list.txt @@ -21,8 +21,8 @@ ====================COPYRIGHT==================== -// Copyright 2019 The Abseil Authors. +// Copyright 2019 The Abseil Authors. ====================COPYRIGHT==================== -// Copyright 2020 The Abseil Authors. +// Copyright 2020 The Abseil Authors. diff --git a/contrib/restricted/abseil-cpp/absl/base/attributes.h b/contrib/restricted/abseil-cpp/absl/base/attributes.h index e3907827d6..eb3ef1a36a 100644 --- a/contrib/restricted/abseil-cpp/absl/base/attributes.h +++ b/contrib/restricted/abseil-cpp/absl/base/attributes.h @@ -131,14 +131,14 @@ // ABSL_ATTRIBUTE_WEAK // // Tags a function as weak for the purposes of compilation and linking. -// Weak attributes did not work properly in LLVM's Windows backend before -// 9.0.0, so disable them there. See https://bugs.llvm.org/show_bug.cgi?id=37598 +// Weak attributes did not work properly in LLVM's Windows backend before +// 9.0.0, so disable them there. See https://bugs.llvm.org/show_bug.cgi?id=37598 // for further information. // The MinGW compiler doesn't complain about the weak attribute until the link // step, presumably because Windows doesn't use ELF binaries. #if (ABSL_HAVE_ATTRIBUTE(weak) || \ (defined(__GNUC__) && !defined(__clang__))) && \ - (!defined(_WIN32) || __clang_major__ < 9) && !defined(__MINGW32__) + (!defined(_WIN32) || __clang_major__ < 9) && !defined(__MINGW32__) #undef ABSL_ATTRIBUTE_WEAK #define ABSL_ATTRIBUTE_WEAK __attribute__((weak)) #define ABSL_HAVE_ATTRIBUTE_WEAK 1 @@ -281,7 +281,7 @@ // ABSL_ATTRIBUTE_RETURNS_NONNULL // // Tells the compiler that a particular function never returns a null pointer. -#if ABSL_HAVE_ATTRIBUTE(returns_nonnull) +#if ABSL_HAVE_ATTRIBUTE(returns_nonnull) #define ABSL_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull)) #else #define ABSL_ATTRIBUTE_RETURNS_NONNULL @@ -318,16 +318,16 @@ // `__start_ ## name` and `__stop_ ## name` symbols to bracket the section. // This functionality is supported by GNU linker. #ifndef ABSL_ATTRIBUTE_SECTION_VARIABLE -#ifdef _AIX -// __attribute__((section(#name))) on AIX is achived by using the `.csect` psudo -// op which includes an additional integer as part of its syntax indcating -// alignment. If data fall under different alignments then you might get a -// compilation error indicating a `Section type conflict`. -#define ABSL_ATTRIBUTE_SECTION_VARIABLE(name) -#else +#ifdef _AIX +// __attribute__((section(#name))) on AIX is achived by using the `.csect` psudo +// op which includes an additional integer as part of its syntax indcating +// alignment. If data fall under different alignments then you might get a +// compilation error indicating a `Section type conflict`. +#define ABSL_ATTRIBUTE_SECTION_VARIABLE(name) +#else #define ABSL_ATTRIBUTE_SECTION_VARIABLE(name) __attribute__((section(#name))) #endif -#endif +#endif // ABSL_DECLARE_ATTRIBUTE_SECTION_VARS // @@ -529,13 +529,13 @@ // ABSL_ATTRIBUTE_UNUSED // // Prevents the compiler from complaining about variables that appear unused. -// -// For code or headers that are assured to only build with C++17 and up, prefer -// just using the standard '[[maybe_unused]]' directly over this macro. -// -// Due to differences in positioning requirements between the old, compiler -// specific __attribute__ syntax and the now standard [[maybe_unused]], this -// macro does not attempt to take advantage of '[[maybe_unused]]'. +// +// For code or headers that are assured to only build with C++17 and up, prefer +// just using the standard '[[maybe_unused]]' directly over this macro. +// +// Due to differences in positioning requirements between the old, compiler +// specific __attribute__ syntax and the now standard [[maybe_unused]], this +// macro does not attempt to take advantage of '[[maybe_unused]]'. #if ABSL_HAVE_ATTRIBUTE(unused) || (defined(__GNUC__) && !defined(__clang__)) #undef ABSL_ATTRIBUTE_UNUSED #define ABSL_ATTRIBUTE_UNUSED __attribute__((__unused__)) @@ -556,20 +556,20 @@ // ABSL_ATTRIBUTE_PACKED // // Instructs the compiler not to use natural alignment for a tagged data -// structure, but instead to reduce its alignment to 1. -// -// Therefore, DO NOT APPLY THIS ATTRIBUTE TO STRUCTS CONTAINING ATOMICS. Doing -// so can cause atomic variables to be mis-aligned and silently violate -// atomicity on x86. -// -// This attribute can either be applied to members of a structure or to a -// structure in its entirety. Applying this attribute (judiciously) to a -// structure in its entirety to optimize the memory footprint of very -// commonly-used structs is fine. Do not apply this attribute to a structure in -// its entirety if the purpose is to control the offsets of the members in the -// structure. Instead, apply this attribute only to structure members that need -// it. -// +// structure, but instead to reduce its alignment to 1. +// +// Therefore, DO NOT APPLY THIS ATTRIBUTE TO STRUCTS CONTAINING ATOMICS. Doing +// so can cause atomic variables to be mis-aligned and silently violate +// atomicity on x86. +// +// This attribute can either be applied to members of a structure or to a +// structure in its entirety. Applying this attribute (judiciously) to a +// structure in its entirety to optimize the memory footprint of very +// commonly-used structs is fine. Do not apply this attribute to a structure in +// its entirety if the purpose is to control the offsets of the members in the +// structure. Instead, apply this attribute only to structure members that need +// it. +// // When applying ABSL_ATTRIBUTE_PACKED only to specific structure members the // natural alignment of structure members not annotated is preserved. Aligned // member accesses are faster than non-aligned member accesses even if the @@ -613,24 +613,24 @@ // case 42: // ... // -// Notes: When supported, GCC and Clang can issue a warning on switch labels -// with unannotated fallthrough using the warning `-Wimplicit-fallthrough`. See -// clang documentation on language extensions for details: +// Notes: When supported, GCC and Clang can issue a warning on switch labels +// with unannotated fallthrough using the warning `-Wimplicit-fallthrough`. See +// clang documentation on language extensions for details: // https://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough // -// When used with unsupported compilers, the ABSL_FALLTHROUGH_INTENDED macro has -// no effect on diagnostics. In any case this macro has no effect on runtime +// When used with unsupported compilers, the ABSL_FALLTHROUGH_INTENDED macro has +// no effect on diagnostics. In any case this macro has no effect on runtime // behavior and performance of code. #ifdef ABSL_FALLTHROUGH_INTENDED #error "ABSL_FALLTHROUGH_INTENDED should not be defined." -#elif ABSL_HAVE_CPP_ATTRIBUTE(fallthrough) -#define ABSL_FALLTHROUGH_INTENDED [[fallthrough]] -#elif ABSL_HAVE_CPP_ATTRIBUTE(clang::fallthrough) +#elif ABSL_HAVE_CPP_ATTRIBUTE(fallthrough) +#define ABSL_FALLTHROUGH_INTENDED [[fallthrough]] +#elif ABSL_HAVE_CPP_ATTRIBUTE(clang::fallthrough) #define ABSL_FALLTHROUGH_INTENDED [[clang::fallthrough]] -#elif ABSL_HAVE_CPP_ATTRIBUTE(gnu::fallthrough) +#elif ABSL_HAVE_CPP_ATTRIBUTE(gnu::fallthrough) #define ABSL_FALLTHROUGH_INTENDED [[gnu::fallthrough]] -#else +#else #define ABSL_FALLTHROUGH_INTENDED \ do { \ } while (0) @@ -710,26 +710,26 @@ #define ABSL_ATTRIBUTE_PURE_FUNCTION #endif -// ABSL_ATTRIBUTE_LIFETIME_BOUND indicates that a resource owned by a function -// parameter or implicit object parameter is retained by the return value of the -// annotated function (or, for a parameter of a constructor, in the value of the -// constructed object). This attribute causes warnings to be produced if a -// temporary object does not live long enough. -// -// When applied to a reference parameter, the referenced object is assumed to be -// retained by the return value of the function. When applied to a non-reference -// parameter (for example, a pointer or a class type), all temporaries -// referenced by the parameter are assumed to be retained by the return value of -// the function. -// -// See also the upstream documentation: -// https://clang.llvm.org/docs/AttributeReference.html#lifetimebound -#if ABSL_HAVE_CPP_ATTRIBUTE(clang::lifetimebound) -#define ABSL_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]] -#elif ABSL_HAVE_ATTRIBUTE(lifetimebound) -#define ABSL_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound)) -#else -#define ABSL_ATTRIBUTE_LIFETIME_BOUND -#endif - +// ABSL_ATTRIBUTE_LIFETIME_BOUND indicates that a resource owned by a function +// parameter or implicit object parameter is retained by the return value of the +// annotated function (or, for a parameter of a constructor, in the value of the +// constructed object). This attribute causes warnings to be produced if a +// temporary object does not live long enough. +// +// When applied to a reference parameter, the referenced object is assumed to be +// retained by the return value of the function. When applied to a non-reference +// parameter (for example, a pointer or a class type), all temporaries +// referenced by the parameter are assumed to be retained by the return value of +// the function. +// +// See also the upstream documentation: +// https://clang.llvm.org/docs/AttributeReference.html#lifetimebound +#if ABSL_HAVE_CPP_ATTRIBUTE(clang::lifetimebound) +#define ABSL_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]] +#elif ABSL_HAVE_ATTRIBUTE(lifetimebound) +#define ABSL_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound)) +#else +#define ABSL_ATTRIBUTE_LIFETIME_BOUND +#endif + #endif // ABSL_BASE_ATTRIBUTES_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/config.h b/contrib/restricted/abseil-cpp/absl/base/config.h index 450d00bc4c..08c27e8641 100644 --- a/contrib/restricted/abseil-cpp/absl/base/config.h +++ b/contrib/restricted/abseil-cpp/absl/base/config.h @@ -66,35 +66,35 @@ #include "absl/base/options.h" #include "absl/base/policy_checks.h" -// Abseil long-term support (LTS) releases will define -// `ABSL_LTS_RELEASE_VERSION` to the integer representing the date string of the -// LTS release version, and will define `ABSL_LTS_RELEASE_PATCH_LEVEL` to the -// integer representing the patch-level for that release. -// -// For example, for LTS release version "20300401.2", this would give us -// ABSL_LTS_RELEASE_VERSION == 20300401 && ABSL_LTS_RELEASE_PATCH_LEVEL == 2 -// -// These symbols will not be defined in non-LTS code. -// -// Abseil recommends that clients live-at-head. Therefore, if you are using -// these symbols to assert a minimum version requirement, we recommend you do it -// as -// -// #if defined(ABSL_LTS_RELEASE_VERSION) && ABSL_LTS_RELEASE_VERSION < 20300401 -// #error Project foo requires Abseil LTS version >= 20300401 -// #endif -// -// The `defined(ABSL_LTS_RELEASE_VERSION)` part of the check excludes -// live-at-head clients from the minimum version assertion. -// -// See https://abseil.io/about/releases for more information on Abseil release -// management. -// -// LTS releases can be obtained from -// https://github.com/abseil/abseil-cpp/releases. -#define ABSL_LTS_RELEASE_VERSION 20211102 -#define ABSL_LTS_RELEASE_PATCH_LEVEL 0 - +// Abseil long-term support (LTS) releases will define +// `ABSL_LTS_RELEASE_VERSION` to the integer representing the date string of the +// LTS release version, and will define `ABSL_LTS_RELEASE_PATCH_LEVEL` to the +// integer representing the patch-level for that release. +// +// For example, for LTS release version "20300401.2", this would give us +// ABSL_LTS_RELEASE_VERSION == 20300401 && ABSL_LTS_RELEASE_PATCH_LEVEL == 2 +// +// These symbols will not be defined in non-LTS code. +// +// Abseil recommends that clients live-at-head. Therefore, if you are using +// these symbols to assert a minimum version requirement, we recommend you do it +// as +// +// #if defined(ABSL_LTS_RELEASE_VERSION) && ABSL_LTS_RELEASE_VERSION < 20300401 +// #error Project foo requires Abseil LTS version >= 20300401 +// #endif +// +// The `defined(ABSL_LTS_RELEASE_VERSION)` part of the check excludes +// live-at-head clients from the minimum version assertion. +// +// See https://abseil.io/about/releases for more information on Abseil release +// management. +// +// LTS releases can be obtained from +// https://github.com/abseil/abseil-cpp/releases. +#define ABSL_LTS_RELEASE_VERSION 20211102 +#define ABSL_LTS_RELEASE_PATCH_LEVEL 0 + // Helper macro to convert a CPP variable to a string literal. #define ABSL_INTERNAL_DO_TOKEN_STR(x) #x #define ABSL_INTERNAL_TOKEN_STR(x) ABSL_INTERNAL_DO_TOKEN_STR(x) @@ -195,22 +195,22 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #define ABSL_HAVE_FEATURE(f) 0 #endif -// Portable check for GCC minimum version: -// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html -#if defined(__GNUC__) && defined(__GNUC_MINOR__) -#define ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(x, y) \ - (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y)) -#else -#define ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(x, y) 0 -#endif - -#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__) -#define ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(x, y) \ - (__clang_major__ > (x) || __clang_major__ == (x) && __clang_minor__ >= (y)) -#else -#define ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(x, y) 0 -#endif - +// Portable check for GCC minimum version: +// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html +#if defined(__GNUC__) && defined(__GNUC_MINOR__) +#define ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(x, y) \ + (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y)) +#else +#define ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(x, y) 0 +#endif + +#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__) +#define ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(x, y) \ + (__clang_major__ > (x) || __clang_major__ == (x) && __clang_minor__ >= (y)) +#else +#define ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(x, y) 0 +#endif + // ABSL_HAVE_TLS is defined to 1 when __thread should be supported. // We assume __thread is supported on Linux when compiled with Clang or compiled // against libstdc++ with _GLIBCXX_HAVE_TLS defined. @@ -228,9 +228,9 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || // gcc >= 4.8.1 using libstdc++, and Visual Studio. #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE #error ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE cannot be directly set -#elif defined(_LIBCPP_VERSION) || defined(_MSC_VER) || \ - (!defined(__clang__) && defined(__GLIBCXX__) && \ - ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(4, 8)) +#elif defined(_LIBCPP_VERSION) || defined(_MSC_VER) || \ + (!defined(__clang__) && defined(__GLIBCXX__) && \ + ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(4, 8)) #define ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 1 #endif @@ -243,17 +243,17 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || // // Checks whether `std::is_trivially_copy_assignable<T>` is supported. -// Notes: Clang with libc++ supports these features, as does gcc >= 7.4 with -// libstdc++, or gcc >= 8.2 with libc++, and Visual Studio (but not NVCC). +// Notes: Clang with libc++ supports these features, as does gcc >= 7.4 with +// libstdc++, or gcc >= 8.2 with libc++, and Visual Studio (but not NVCC). #if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) #error ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE cannot be directly set #elif defined(ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE) #error ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE cannot directly set -#elif (defined(__clang__) && defined(_LIBCPP_VERSION)) || \ - (!defined(__clang__) && \ - ((ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(7, 4) && defined(__GLIBCXX__)) || \ - (ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(8, 2) && \ - defined(_LIBCPP_VERSION)))) || \ +#elif (defined(__clang__) && defined(_LIBCPP_VERSION)) || \ + (!defined(__clang__) && \ + ((ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(7, 4) && defined(__GLIBCXX__)) || \ + (ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(8, 2) && \ + defined(_LIBCPP_VERSION)))) || \ (defined(_MSC_VER) && !defined(__NVCC__)) #define ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 1 #define ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 1 @@ -267,7 +267,7 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #if ABSL_INTERNAL_HAS_KEYWORD(__builtin_LINE) && \ ABSL_INTERNAL_HAS_KEYWORD(__builtin_FILE) #define ABSL_HAVE_SOURCE_LOCATION_CURRENT 1 -#elif ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(5, 0) +#elif ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(5, 0) #define ABSL_HAVE_SOURCE_LOCATION_CURRENT 1 #endif #endif @@ -364,21 +364,21 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || // For further details, consult the compiler's documentation. #ifdef ABSL_HAVE_EXCEPTIONS #error ABSL_HAVE_EXCEPTIONS cannot be directly set. -#elif ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(3, 6) +#elif ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(3, 6) // Clang >= 3.6 #if ABSL_HAVE_FEATURE(cxx_exceptions) #define ABSL_HAVE_EXCEPTIONS 1 #endif // ABSL_HAVE_FEATURE(cxx_exceptions) -#elif defined(__clang__) +#elif defined(__clang__) // Clang < 3.6 // http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro #if defined(__EXCEPTIONS) && ABSL_HAVE_FEATURE(cxx_exceptions) #define ABSL_HAVE_EXCEPTIONS 1 #endif // defined(__EXCEPTIONS) && ABSL_HAVE_FEATURE(cxx_exceptions) // Handle remaining special cases and default to exceptions being supported. -#elif !(defined(__GNUC__) && (__GNUC__ < 5) && !defined(__EXCEPTIONS)) && \ - !(ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(5, 0) && \ - !defined(__cpp_exceptions)) && \ +#elif !(defined(__GNUC__) && (__GNUC__ < 5) && !defined(__EXCEPTIONS)) && \ + !(ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(5, 0) && \ + !defined(__cpp_exceptions)) && \ !(defined(_MSC_VER) && !defined(_CPPUNWIND)) #define ABSL_HAVE_EXCEPTIONS 1 #endif @@ -410,11 +410,11 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || // POSIX.1-2001. #ifdef ABSL_HAVE_MMAP #error ABSL_HAVE_MMAP cannot be directly set -#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ - defined(_AIX) || defined(__ros__) || defined(__native_client__) || \ - defined(__asmjs__) || defined(__wasm__) || defined(__Fuchsia__) || \ - defined(__sun) || defined(__ASYLO__) || defined(__myriad2__) || \ - defined(__HAIKU__) +#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ + defined(_AIX) || defined(__ros__) || defined(__native_client__) || \ + defined(__asmjs__) || defined(__wasm__) || defined(__Fuchsia__) || \ + defined(__sun) || defined(__ASYLO__) || defined(__myriad2__) || \ + defined(__HAIKU__) #define ABSL_HAVE_MMAP 1 #endif @@ -425,7 +425,7 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #ifdef ABSL_HAVE_PTHREAD_GETSCHEDPARAM #error ABSL_HAVE_PTHREAD_GETSCHEDPARAM cannot be directly set #elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ - defined(_AIX) || defined(__ros__) + defined(_AIX) || defined(__ros__) #define ABSL_HAVE_PTHREAD_GETSCHEDPARAM 1 #endif diff --git a/contrib/restricted/abseil-cpp/absl/base/dynamic_annotations.h b/contrib/restricted/abseil-cpp/absl/base/dynamic_annotations.h index 3ea7c1568c..4842102b96 100644 --- a/contrib/restricted/abseil-cpp/absl/base/dynamic_annotations.h +++ b/contrib/restricted/abseil-cpp/absl/base/dynamic_annotations.h @@ -446,7 +446,7 @@ ABSL_NAMESPACE_END __sanitizer_annotate_contiguous_container(beg, end, old_mid, new_mid) #define ABSL_ADDRESS_SANITIZER_REDZONE(name) \ struct { \ - alignas(8) char x[8]; \ + alignas(8) char x[8]; \ } name #else diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/exception_safety_testing.h b/contrib/restricted/abseil-cpp/absl/base/internal/exception_safety_testing.h index 77a5aec642..bf2f65cee2 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/exception_safety_testing.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/exception_safety_testing.h @@ -536,22 +536,22 @@ class ThrowingValue : private exceptions_internal::TrackedObject { } // Memory management operators - static void* operator new(size_t s) noexcept( - IsSpecified(TypeSpec::kNoThrowNew)) { - if (!IsSpecified(TypeSpec::kNoThrowNew)) { - exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION, true); - } - return ::operator new(s); - } - - static void* operator new[](size_t s) noexcept( - IsSpecified(TypeSpec::kNoThrowNew)) { - if (!IsSpecified(TypeSpec::kNoThrowNew)) { - exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION, true); - } - return ::operator new[](s); - } - + static void* operator new(size_t s) noexcept( + IsSpecified(TypeSpec::kNoThrowNew)) { + if (!IsSpecified(TypeSpec::kNoThrowNew)) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION, true); + } + return ::operator new(s); + } + + static void* operator new[](size_t s) noexcept( + IsSpecified(TypeSpec::kNoThrowNew)) { + if (!IsSpecified(TypeSpec::kNoThrowNew)) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION, true); + } + return ::operator new[](s); + } + template <typename... Args> static void* operator new(size_t s, Args&&... args) noexcept( IsSpecified(TypeSpec::kNoThrowNew)) { @@ -736,7 +736,7 @@ class ThrowingAllocator : private exceptions_internal::TrackedObject { ThrowingAllocator select_on_container_copy_construction() noexcept( IsSpecified(AllocSpec::kNoThrowAllocate)) { ReadStateAndMaybeThrow(ABSL_PRETTY_FUNCTION); - return *this; + return *this; } template <typename U> diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/spinlock.h b/contrib/restricted/abseil-cpp/absl/base/internal/spinlock.h index ac40daff12..35986255b0 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/spinlock.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/spinlock.h @@ -16,15 +16,15 @@ // Most users requiring mutual exclusion should use Mutex. // SpinLock is provided for use in two situations: -// - for use by Abseil internal code that Mutex itself depends on +// - for use by Abseil internal code that Mutex itself depends on // - for async signal safety (see below) // SpinLock is async signal safe. If a spinlock is used within a signal // handler, all code that acquires the lock must ensure that the signal cannot // arrive while they are holding the lock. Typically, this is done by blocking // the signal. -// -// Threads waiting on a SpinLock may be woken in an arbitrary order. +// +// Threads waiting on a SpinLock may be woken in an arbitrary order. #ifndef ABSL_BASE_INTERNAL_SPINLOCK_H_ #define ABSL_BASE_INTERNAL_SPINLOCK_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait.h b/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait.h index 9a1adcda5e..efb9deff95 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait.h @@ -39,8 +39,8 @@ struct SpinLockWaitTransition { // satisfying 0<=i<n && trans[i].done, atomically make the transition, // then return the old value of *w. Make any other atomic transitions // where !trans[i].done, but continue waiting. -// -// Wakeups for threads blocked on SpinLockWait do not respect priorities. +// +// Wakeups for threads blocked on SpinLockWait do not respect priorities. uint32_t SpinLockWait(std::atomic<uint32_t> *w, int n, const SpinLockWaitTransition trans[], SchedulingMode scheduling_mode); diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/sysinfo.cc b/contrib/restricted/abseil-cpp/absl/base/internal/sysinfo.cc index 8c2e6c87fa..4a366bb356 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/sysinfo.cc +++ b/contrib/restricted/abseil-cpp/absl/base/internal/sysinfo.cc @@ -61,78 +61,78 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace base_internal { -namespace { - -#if defined(_WIN32) - -// Returns number of bits set in `bitMask` -DWORD Win32CountSetBits(ULONG_PTR bitMask) { - for (DWORD bitSetCount = 0; ; ++bitSetCount) { - if (bitMask == 0) return bitSetCount; - bitMask &= bitMask - 1; - } -} - -// Returns the number of logical CPUs using GetLogicalProcessorInformation(), or -// 0 if the number of processors is not available or can not be computed. -// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlogicalprocessorinformation -int Win32NumCPUs() { -#pragma comment(lib, "kernel32.lib") - using Info = SYSTEM_LOGICAL_PROCESSOR_INFORMATION; - - DWORD info_size = sizeof(Info); - Info* info(static_cast<Info*>(malloc(info_size))); - if (info == nullptr) return 0; - - bool success = GetLogicalProcessorInformation(info, &info_size); - if (!success && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { - free(info); - info = static_cast<Info*>(malloc(info_size)); - if (info == nullptr) return 0; - success = GetLogicalProcessorInformation(info, &info_size); - } - - DWORD logicalProcessorCount = 0; - if (success) { - Info* ptr = info; - DWORD byteOffset = 0; - while (byteOffset + sizeof(Info) <= info_size) { - switch (ptr->Relationship) { - case RelationProcessorCore: - logicalProcessorCount += Win32CountSetBits(ptr->ProcessorMask); - break; - - case RelationNumaNode: - case RelationCache: - case RelationProcessorPackage: - // Ignore other entries - break; - - default: - // Ignore unknown entries - break; - } - byteOffset += sizeof(Info); - ptr++; - } - } - free(info); - return logicalProcessorCount; -} - -#endif - -} // namespace - - +namespace { + +#if defined(_WIN32) + +// Returns number of bits set in `bitMask` +DWORD Win32CountSetBits(ULONG_PTR bitMask) { + for (DWORD bitSetCount = 0; ; ++bitSetCount) { + if (bitMask == 0) return bitSetCount; + bitMask &= bitMask - 1; + } +} + +// Returns the number of logical CPUs using GetLogicalProcessorInformation(), or +// 0 if the number of processors is not available or can not be computed. +// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlogicalprocessorinformation +int Win32NumCPUs() { +#pragma comment(lib, "kernel32.lib") + using Info = SYSTEM_LOGICAL_PROCESSOR_INFORMATION; + + DWORD info_size = sizeof(Info); + Info* info(static_cast<Info*>(malloc(info_size))); + if (info == nullptr) return 0; + + bool success = GetLogicalProcessorInformation(info, &info_size); + if (!success && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + free(info); + info = static_cast<Info*>(malloc(info_size)); + if (info == nullptr) return 0; + success = GetLogicalProcessorInformation(info, &info_size); + } + + DWORD logicalProcessorCount = 0; + if (success) { + Info* ptr = info; + DWORD byteOffset = 0; + while (byteOffset + sizeof(Info) <= info_size) { + switch (ptr->Relationship) { + case RelationProcessorCore: + logicalProcessorCount += Win32CountSetBits(ptr->ProcessorMask); + break; + + case RelationNumaNode: + case RelationCache: + case RelationProcessorPackage: + // Ignore other entries + break; + + default: + // Ignore unknown entries + break; + } + byteOffset += sizeof(Info); + ptr++; + } + } + free(info); + return logicalProcessorCount; +} + +#endif + +} // namespace + + static int GetNumCPUs() { #if defined(__myriad2__) return 1; -#elif defined(_WIN32) - const unsigned hardware_concurrency = Win32NumCPUs(); - return hardware_concurrency ? hardware_concurrency : 1; -#elif defined(_AIX) - return sysconf(_SC_NPROCESSORS_ONLN); +#elif defined(_WIN32) + const unsigned hardware_concurrency = Win32NumCPUs(); + return hardware_concurrency ? hardware_concurrency : 1; +#elif defined(_AIX) + return sysconf(_SC_NPROCESSORS_ONLN); #else // Other possibilities: // - Read /sys/devices/system/cpu/online and use cpumask_parse() diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/thread_identity.h b/contrib/restricted/abseil-cpp/absl/base/internal/thread_identity.h index 659694b326..b0f7ff9c87 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/thread_identity.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/thread_identity.h @@ -188,25 +188,25 @@ void ClearCurrentThreadIdentity(); // May be chosen at compile time via: -DABSL_FORCE_THREAD_IDENTITY_MODE=<mode // index> #ifdef ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC -#error ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC cannot be directly set +#error ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC cannot be directly set #else #define ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC 0 #endif #ifdef ABSL_THREAD_IDENTITY_MODE_USE_TLS -#error ABSL_THREAD_IDENTITY_MODE_USE_TLS cannot be directly set +#error ABSL_THREAD_IDENTITY_MODE_USE_TLS cannot be directly set #else #define ABSL_THREAD_IDENTITY_MODE_USE_TLS 1 #endif #ifdef ABSL_THREAD_IDENTITY_MODE_USE_CPP11 -#error ABSL_THREAD_IDENTITY_MODE_USE_CPP11 cannot be directly set +#error ABSL_THREAD_IDENTITY_MODE_USE_CPP11 cannot be directly set #else #define ABSL_THREAD_IDENTITY_MODE_USE_CPP11 2 #endif #ifdef ABSL_THREAD_IDENTITY_MODE -#error ABSL_THREAD_IDENTITY_MODE cannot be directly set +#error ABSL_THREAD_IDENTITY_MODE cannot be directly set #elif defined(ABSL_FORCE_THREAD_IDENTITY_MODE) #define ABSL_THREAD_IDENTITY_MODE ABSL_FORCE_THREAD_IDENTITY_MODE #elif defined(_WIN32) && !defined(__MINGW32__) diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.cc b/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.cc index 4d352bd110..2d17799acf 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.cc +++ b/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.cc @@ -87,10 +87,10 @@ int64_t UnscaledCycleClock::Now() { double UnscaledCycleClock::Frequency() { #ifdef __GLIBC__ return __ppc_get_timebase_freq(); -#elif defined(_AIX) - // This is the same constant value as returned by - // __ppc_get_timebase_freq(). - return static_cast<double>(512000000); +#elif defined(_AIX) + // This is the same constant value as returned by + // __ppc_get_timebase_freq(). + return static_cast<double>(512000000); #elif defined(__FreeBSD__) static once_flag init_timebase_frequency_once; static double timebase_frequency = 0.0; @@ -123,18 +123,18 @@ double UnscaledCycleClock::Frequency() { return aarch64_timer_frequency; } -#elif defined(__riscv) - -int64_t UnscaledCycleClock::Now() { - int64_t virtual_timer_value; - asm volatile("rdcycle %0" : "=r"(virtual_timer_value)); - return virtual_timer_value; -} - -double UnscaledCycleClock::Frequency() { - return base_internal::NominalCPUFrequency(); -} - +#elif defined(__riscv) + +int64_t UnscaledCycleClock::Now() { + int64_t virtual_timer_value; + asm volatile("rdcycle %0" : "=r"(virtual_timer_value)); + return virtual_timer_value; +} + +double UnscaledCycleClock::Frequency() { + return base_internal::NominalCPUFrequency(); +} + #elif defined(_M_IX86) || defined(_M_X64) #pragma intrinsic(__rdtsc) diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.h b/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.h index 681ff8f996..0ff907e3bb 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.h @@ -46,8 +46,8 @@ // The following platforms have an implementation of a hardware counter. #if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) || \ - defined(__powerpc__) || defined(__ppc__) || defined(__riscv) || \ - defined(_M_IX86) || defined(_M_X64) + defined(__powerpc__) || defined(__ppc__) || defined(__riscv) || \ + defined(_M_IX86) || defined(_M_X64) #define ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION 1 #else #define ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION 0 @@ -80,8 +80,8 @@ // This macro can be used to test if UnscaledCycleClock::Frequency() // is NominalCPUFrequency() on a particular platform. -#if (defined(__i386__) || defined(__x86_64__) || defined(__riscv) || \ - defined(_M_IX86) || defined(_M_X64)) +#if (defined(__i386__) || defined(__x86_64__) || defined(__riscv) || \ + defined(_M_IX86) || defined(_M_X64)) #define ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY #endif diff --git a/contrib/restricted/abseil-cpp/absl/base/options.h b/contrib/restricted/abseil-cpp/absl/base/options.h index 56b4e36ee0..a4e6d99f0b 100644 --- a/contrib/restricted/abseil-cpp/absl/base/options.h +++ b/contrib/restricted/abseil-cpp/absl/base/options.h @@ -206,7 +206,7 @@ // allowed. #define ABSL_OPTION_USE_INLINE_NAMESPACE 1 -#define ABSL_OPTION_INLINE_NAMESPACE_NAME lts_20211102 +#define ABSL_OPTION_INLINE_NAMESPACE_NAME lts_20211102 // ABSL_OPTION_HARDENED // diff --git a/contrib/restricted/abseil-cpp/absl/cleanup/cleanup.h b/contrib/restricted/abseil-cpp/absl/cleanup/cleanup.h index 960ccd080e..14e99a9f08 100644 --- a/contrib/restricted/abseil-cpp/absl/cleanup/cleanup.h +++ b/contrib/restricted/abseil-cpp/absl/cleanup/cleanup.h @@ -86,25 +86,25 @@ class ABSL_MUST_USE_RESULT Cleanup final { "Callbacks that return values are not supported."); public: - Cleanup(Callback callback) : storage_(std::move(callback)) {} // NOLINT + Cleanup(Callback callback) : storage_(std::move(callback)) {} // NOLINT Cleanup(Cleanup&& other) = default; void Cancel() && { ABSL_HARDENING_ASSERT(storage_.IsCallbackEngaged()); - storage_.DestroyCallback(); + storage_.DestroyCallback(); } void Invoke() && { ABSL_HARDENING_ASSERT(storage_.IsCallbackEngaged()); storage_.InvokeCallback(); - storage_.DestroyCallback(); + storage_.DestroyCallback(); } ~Cleanup() { if (storage_.IsCallbackEngaged()) { storage_.InvokeCallback(); - storage_.DestroyCallback(); + storage_.DestroyCallback(); } } diff --git a/contrib/restricted/abseil-cpp/absl/cleanup/internal/cleanup.h b/contrib/restricted/abseil-cpp/absl/cleanup/internal/cleanup.h index 2783fcb7c1..753da5b899 100644 --- a/contrib/restricted/abseil-cpp/absl/cleanup/internal/cleanup.h +++ b/contrib/restricted/abseil-cpp/absl/cleanup/internal/cleanup.h @@ -15,12 +15,12 @@ #ifndef ABSL_CLEANUP_INTERNAL_CLEANUP_H_ #define ABSL_CLEANUP_INTERNAL_CLEANUP_H_ -#include <new> +#include <new> #include <type_traits> #include <utility> #include "absl/base/internal/invoke.h" -#include "absl/base/macros.h" +#include "absl/base/macros.h" #include "absl/base/thread_annotations.h" #include "absl/utility/utility.h" @@ -47,49 +47,49 @@ class Storage { public: Storage() = delete; - explicit Storage(Callback callback) { - // Placement-new into a character buffer is used for eager destruction when - // the cleanup is invoked or cancelled. To ensure this optimizes well, the - // behavior is implemented locally instead of using an absl::optional. - ::new (GetCallbackBuffer()) Callback(std::move(callback)); - is_callback_engaged_ = true; - } - - Storage(Storage&& other) { - ABSL_HARDENING_ASSERT(other.IsCallbackEngaged()); - - ::new (GetCallbackBuffer()) Callback(std::move(other.GetCallback())); - is_callback_engaged_ = true; - - other.DestroyCallback(); - } - + explicit Storage(Callback callback) { + // Placement-new into a character buffer is used for eager destruction when + // the cleanup is invoked or cancelled. To ensure this optimizes well, the + // behavior is implemented locally instead of using an absl::optional. + ::new (GetCallbackBuffer()) Callback(std::move(callback)); + is_callback_engaged_ = true; + } + + Storage(Storage&& other) { + ABSL_HARDENING_ASSERT(other.IsCallbackEngaged()); + + ::new (GetCallbackBuffer()) Callback(std::move(other.GetCallback())); + is_callback_engaged_ = true; + + other.DestroyCallback(); + } + Storage(const Storage& other) = delete; Storage& operator=(Storage&& other) = delete; Storage& operator=(const Storage& other) = delete; - void* GetCallbackBuffer() { return static_cast<void*>(+callback_buffer_); } - - Callback& GetCallback() { - return *reinterpret_cast<Callback*>(GetCallbackBuffer()); - } - + void* GetCallbackBuffer() { return static_cast<void*>(+callback_buffer_); } + + Callback& GetCallback() { + return *reinterpret_cast<Callback*>(GetCallbackBuffer()); + } + bool IsCallbackEngaged() const { return is_callback_engaged_; } - void DestroyCallback() { - is_callback_engaged_ = false; - GetCallback().~Callback(); - } + void DestroyCallback() { + is_callback_engaged_ = false; + GetCallback().~Callback(); + } void InvokeCallback() ABSL_NO_THREAD_SAFETY_ANALYSIS { - std::move(GetCallback())(); + std::move(GetCallback())(); } private: bool is_callback_engaged_; - alignas(Callback) char callback_buffer_[sizeof(Callback)]; + alignas(Callback) char callback_buffer_[sizeof(Callback)]; }; } // namespace cleanup_internal diff --git a/contrib/restricted/abseil-cpp/absl/container/btree_map.h b/contrib/restricted/abseil-cpp/absl/container/btree_map.h index f0a8d4a6a4..8fc0a768d7 100644 --- a/contrib/restricted/abseil-cpp/absl/container/btree_map.h +++ b/contrib/restricted/abseil-cpp/absl/container/btree_map.h @@ -366,8 +366,8 @@ class btree_map // Determines whether an element comparing equal to the given `key` exists // within the `btree_map`, returning `true` if so or `false` otherwise. // - // Supports heterogeneous lookup, provided that the map has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the map has a compatible + // heterogeneous comparator. using Base::contains; // btree_map::count() @@ -378,8 +378,8 @@ class btree_map // the `btree_map`. Note that this function will return either `1` or `0` // since duplicate elements are not allowed within a `btree_map`. // - // Supports heterogeneous lookup, provided that the map has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the map has a compatible + // heterogeneous comparator. using Base::count; // btree_map::equal_range() @@ -395,34 +395,34 @@ class btree_map // // Finds an element with the passed `key` within the `btree_map`. // - // Supports heterogeneous lookup, provided that the map has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the map has a compatible + // heterogeneous comparator. using Base::find; - // btree_map::lower_bound() - // - // template <typename K> iterator lower_bound(const K& key): - // template <typename K> const_iterator lower_bound(const K& key) const: - // - // Finds the first element with a key that is not less than `key` within the - // `btree_map`. - // - // Supports heterogeneous lookup, provided that the map has a compatible - // heterogeneous comparator. - using Base::lower_bound; - - // btree_map::upper_bound() - // - // template <typename K> iterator upper_bound(const K& key): - // template <typename K> const_iterator upper_bound(const K& key) const: - // - // Finds the first element with a key that is greater than `key` within the - // `btree_map`. - // - // Supports heterogeneous lookup, provided that the map has a compatible - // heterogeneous comparator. - using Base::upper_bound; - + // btree_map::lower_bound() + // + // template <typename K> iterator lower_bound(const K& key): + // template <typename K> const_iterator lower_bound(const K& key) const: + // + // Finds the first element with a key that is not less than `key` within the + // `btree_map`. + // + // Supports heterogeneous lookup, provided that the map has a compatible + // heterogeneous comparator. + using Base::lower_bound; + + // btree_map::upper_bound() + // + // template <typename K> iterator upper_bound(const K& key): + // template <typename K> const_iterator upper_bound(const K& key) const: + // + // Finds the first element with a key that is greater than `key` within the + // `btree_map`. + // + // Supports heterogeneous lookup, provided that the map has a compatible + // heterogeneous comparator. + using Base::upper_bound; + // btree_map::operator[]() // // Returns a reference to the value mapped to the passed key within the @@ -693,8 +693,8 @@ class btree_multimap // btree_multimap::merge() // - // Extracts all elements from a given `source` btree_multimap into this - // `btree_multimap`. + // Extracts all elements from a given `source` btree_multimap into this + // `btree_multimap`. using Base::merge; // btree_multimap::swap(btree_multimap& other) @@ -714,8 +714,8 @@ class btree_multimap // Determines whether an element comparing equal to the given `key` exists // within the `btree_multimap`, returning `true` if so or `false` otherwise. // - // Supports heterogeneous lookup, provided that the map has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the map has a compatible + // heterogeneous comparator. using Base::contains; // btree_multimap::count() @@ -725,8 +725,8 @@ class btree_multimap // Returns the number of elements comparing equal to the given `key` within // the `btree_multimap`. // - // Supports heterogeneous lookup, provided that the map has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the map has a compatible + // heterogeneous comparator. using Base::count; // btree_multimap::equal_range() @@ -743,34 +743,34 @@ class btree_multimap // // Finds an element with the passed `key` within the `btree_multimap`. // - // Supports heterogeneous lookup, provided that the map has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the map has a compatible + // heterogeneous comparator. using Base::find; - // btree_multimap::lower_bound() - // - // template <typename K> iterator lower_bound(const K& key): - // template <typename K> const_iterator lower_bound(const K& key) const: - // - // Finds the first element with a key that is not less than `key` within the - // `btree_multimap`. - // - // Supports heterogeneous lookup, provided that the map has a compatible - // heterogeneous comparator. - using Base::lower_bound; - - // btree_multimap::upper_bound() - // - // template <typename K> iterator upper_bound(const K& key): - // template <typename K> const_iterator upper_bound(const K& key) const: - // - // Finds the first element with a key that is greater than `key` within the - // `btree_multimap`. - // - // Supports heterogeneous lookup, provided that the map has a compatible - // heterogeneous comparator. - using Base::upper_bound; - + // btree_multimap::lower_bound() + // + // template <typename K> iterator lower_bound(const K& key): + // template <typename K> const_iterator lower_bound(const K& key) const: + // + // Finds the first element with a key that is not less than `key` within the + // `btree_multimap`. + // + // Supports heterogeneous lookup, provided that the map has a compatible + // heterogeneous comparator. + using Base::lower_bound; + + // btree_multimap::upper_bound() + // + // template <typename K> iterator upper_bound(const K& key): + // template <typename K> const_iterator upper_bound(const K& key) const: + // + // Finds the first element with a key that is greater than `key` within the + // `btree_multimap`. + // + // Supports heterogeneous lookup, provided that the map has a compatible + // heterogeneous comparator. + using Base::upper_bound; + // btree_multimap::get_allocator() // // Returns the allocator function associated with this `btree_multimap`. diff --git a/contrib/restricted/abseil-cpp/absl/container/btree_set.h b/contrib/restricted/abseil-cpp/absl/container/btree_set.h index 8973900693..b516a4c71c 100644 --- a/contrib/restricted/abseil-cpp/absl/container/btree_set.h +++ b/contrib/restricted/abseil-cpp/absl/container/btree_set.h @@ -300,8 +300,8 @@ class btree_set // Determines whether an element comparing equal to the given `key` exists // within the `btree_set`, returning `true` if so or `false` otherwise. // - // Supports heterogeneous lookup, provided that the set has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the set has a compatible + // heterogeneous comparator. using Base::contains; // btree_set::count() @@ -312,8 +312,8 @@ class btree_set // the `btree_set`. Note that this function will return either `1` or `0` // since duplicate elements are not allowed within a `btree_set`. // - // Supports heterogeneous lookup, provided that the set has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the set has a compatible + // heterogeneous comparator. using Base::count; // btree_set::equal_range() @@ -330,32 +330,32 @@ class btree_set // // Finds an element with the passed `key` within the `btree_set`. // - // Supports heterogeneous lookup, provided that the set has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the set has a compatible + // heterogeneous comparator. using Base::find; - // btree_set::lower_bound() - // - // template <typename K> iterator lower_bound(const K& key): - // template <typename K> const_iterator lower_bound(const K& key) const: - // - // Finds the first element that is not less than `key` within the `btree_set`. - // - // Supports heterogeneous lookup, provided that the set has a compatible - // heterogeneous comparator. - using Base::lower_bound; - - // btree_set::upper_bound() - // - // template <typename K> iterator upper_bound(const K& key): - // template <typename K> const_iterator upper_bound(const K& key) const: - // - // Finds the first element that is greater than `key` within the `btree_set`. - // - // Supports heterogeneous lookup, provided that the set has a compatible - // heterogeneous comparator. - using Base::upper_bound; - + // btree_set::lower_bound() + // + // template <typename K> iterator lower_bound(const K& key): + // template <typename K> const_iterator lower_bound(const K& key) const: + // + // Finds the first element that is not less than `key` within the `btree_set`. + // + // Supports heterogeneous lookup, provided that the set has a compatible + // heterogeneous comparator. + using Base::lower_bound; + + // btree_set::upper_bound() + // + // template <typename K> iterator upper_bound(const K& key): + // template <typename K> const_iterator upper_bound(const K& key) const: + // + // Finds the first element that is greater than `key` within the `btree_set`. + // + // Supports heterogeneous lookup, provided that the set has a compatible + // heterogeneous comparator. + using Base::upper_bound; + // btree_set::get_allocator() // // Returns the allocator function associated with this `btree_set`. @@ -604,8 +604,8 @@ class btree_multiset // btree_multiset::merge() // - // Extracts all elements from a given `source` btree_multiset into this - // `btree_multiset`. + // Extracts all elements from a given `source` btree_multiset into this + // `btree_multiset`. using Base::merge; // btree_multiset::swap(btree_multiset& other) @@ -625,8 +625,8 @@ class btree_multiset // Determines whether an element comparing equal to the given `key` exists // within the `btree_multiset`, returning `true` if so or `false` otherwise. // - // Supports heterogeneous lookup, provided that the set has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the set has a compatible + // heterogeneous comparator. using Base::contains; // btree_multiset::count() @@ -636,8 +636,8 @@ class btree_multiset // Returns the number of elements comparing equal to the given `key` within // the `btree_multiset`. // - // Supports heterogeneous lookup, provided that the set has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the set has a compatible + // heterogeneous comparator. using Base::count; // btree_multiset::equal_range() @@ -654,34 +654,34 @@ class btree_multiset // // Finds an element with the passed `key` within the `btree_multiset`. // - // Supports heterogeneous lookup, provided that the set has a compatible - // heterogeneous comparator. + // Supports heterogeneous lookup, provided that the set has a compatible + // heterogeneous comparator. using Base::find; - // btree_multiset::lower_bound() - // - // template <typename K> iterator lower_bound(const K& key): - // template <typename K> const_iterator lower_bound(const K& key) const: - // - // Finds the first element that is not less than `key` within the - // `btree_multiset`. - // - // Supports heterogeneous lookup, provided that the set has a compatible - // heterogeneous comparator. - using Base::lower_bound; - - // btree_multiset::upper_bound() - // - // template <typename K> iterator upper_bound(const K& key): - // template <typename K> const_iterator upper_bound(const K& key) const: - // - // Finds the first element that is greater than `key` within the - // `btree_multiset`. - // - // Supports heterogeneous lookup, provided that the set has a compatible - // heterogeneous comparator. - using Base::upper_bound; - + // btree_multiset::lower_bound() + // + // template <typename K> iterator lower_bound(const K& key): + // template <typename K> const_iterator lower_bound(const K& key) const: + // + // Finds the first element that is not less than `key` within the + // `btree_multiset`. + // + // Supports heterogeneous lookup, provided that the set has a compatible + // heterogeneous comparator. + using Base::lower_bound; + + // btree_multiset::upper_bound() + // + // template <typename K> iterator upper_bound(const K& key): + // template <typename K> const_iterator upper_bound(const K& key) const: + // + // Finds the first element that is greater than `key` within the + // `btree_multiset`. + // + // Supports heterogeneous lookup, provided that the set has a compatible + // heterogeneous comparator. + using Base::upper_bound; + // btree_multiset::get_allocator() // // Returns the allocator function associated with this `btree_multiset`. diff --git a/contrib/restricted/abseil-cpp/absl/container/inlined_vector.h b/contrib/restricted/abseil-cpp/absl/container/inlined_vector.h index df9e09917d..81a07d22df 100644 --- a/contrib/restricted/abseil-cpp/absl/container/inlined_vector.h +++ b/contrib/restricted/abseil-cpp/absl/container/inlined_vector.h @@ -72,43 +72,43 @@ class InlinedVector { using Storage = inlined_vector_internal::Storage<T, N, A>; - template <typename TheA> - using AllocatorTraits = inlined_vector_internal::AllocatorTraits<TheA>; - template <typename TheA> - using MoveIterator = inlined_vector_internal::MoveIterator<TheA>; - template <typename TheA> - using IsMemcpyOk = inlined_vector_internal::IsMemcpyOk<TheA>; - - template <typename TheA, typename Iterator> + template <typename TheA> + using AllocatorTraits = inlined_vector_internal::AllocatorTraits<TheA>; + template <typename TheA> + using MoveIterator = inlined_vector_internal::MoveIterator<TheA>; + template <typename TheA> + using IsMemcpyOk = inlined_vector_internal::IsMemcpyOk<TheA>; + + template <typename TheA, typename Iterator> using IteratorValueAdapter = - inlined_vector_internal::IteratorValueAdapter<TheA, Iterator>; - template <typename TheA> - using CopyValueAdapter = inlined_vector_internal::CopyValueAdapter<TheA>; - template <typename TheA> - using DefaultValueAdapter = - inlined_vector_internal::DefaultValueAdapter<TheA>; + inlined_vector_internal::IteratorValueAdapter<TheA, Iterator>; + template <typename TheA> + using CopyValueAdapter = inlined_vector_internal::CopyValueAdapter<TheA>; + template <typename TheA> + using DefaultValueAdapter = + inlined_vector_internal::DefaultValueAdapter<TheA>; template <typename Iterator> using EnableIfAtLeastForwardIterator = absl::enable_if_t< - inlined_vector_internal::IsAtLeastForwardIterator<Iterator>::value, int>; + inlined_vector_internal::IsAtLeastForwardIterator<Iterator>::value, int>; template <typename Iterator> using DisableIfAtLeastForwardIterator = absl::enable_if_t< - !inlined_vector_internal::IsAtLeastForwardIterator<Iterator>::value, int>; + !inlined_vector_internal::IsAtLeastForwardIterator<Iterator>::value, int>; public: - using allocator_type = A; - using value_type = inlined_vector_internal::ValueType<A>; - using pointer = inlined_vector_internal::Pointer<A>; - using const_pointer = inlined_vector_internal::ConstPointer<A>; - using size_type = inlined_vector_internal::SizeType<A>; - using difference_type = inlined_vector_internal::DifferenceType<A>; - using reference = inlined_vector_internal::Reference<A>; - using const_reference = inlined_vector_internal::ConstReference<A>; - using iterator = inlined_vector_internal::Iterator<A>; - using const_iterator = inlined_vector_internal::ConstIterator<A>; - using reverse_iterator = inlined_vector_internal::ReverseIterator<A>; - using const_reverse_iterator = - inlined_vector_internal::ConstReverseIterator<A>; + using allocator_type = A; + using value_type = inlined_vector_internal::ValueType<A>; + using pointer = inlined_vector_internal::Pointer<A>; + using const_pointer = inlined_vector_internal::ConstPointer<A>; + using size_type = inlined_vector_internal::SizeType<A>; + using difference_type = inlined_vector_internal::DifferenceType<A>; + using reference = inlined_vector_internal::Reference<A>; + using const_reference = inlined_vector_internal::ConstReference<A>; + using iterator = inlined_vector_internal::Iterator<A>; + using const_iterator = inlined_vector_internal::ConstIterator<A>; + using reverse_iterator = inlined_vector_internal::ReverseIterator<A>; + using const_reverse_iterator = + inlined_vector_internal::ConstReverseIterator<A>; // --------------------------------------------------------------------------- // InlinedVector Constructors and Destructor @@ -117,28 +117,28 @@ class InlinedVector { // Creates an empty inlined vector with a value-initialized allocator. InlinedVector() noexcept(noexcept(allocator_type())) : storage_() {} - // Creates an empty inlined vector with a copy of `allocator`. - explicit InlinedVector(const allocator_type& allocator) noexcept - : storage_(allocator) {} + // Creates an empty inlined vector with a copy of `allocator`. + explicit InlinedVector(const allocator_type& allocator) noexcept + : storage_(allocator) {} // Creates an inlined vector with `n` copies of `value_type()`. explicit InlinedVector(size_type n, - const allocator_type& allocator = allocator_type()) - : storage_(allocator) { - storage_.Initialize(DefaultValueAdapter<A>(), n); + const allocator_type& allocator = allocator_type()) + : storage_(allocator) { + storage_.Initialize(DefaultValueAdapter<A>(), n); } // Creates an inlined vector with `n` copies of `v`. InlinedVector(size_type n, const_reference v, - const allocator_type& allocator = allocator_type()) - : storage_(allocator) { - storage_.Initialize(CopyValueAdapter<A>(std::addressof(v)), n); + const allocator_type& allocator = allocator_type()) + : storage_(allocator) { + storage_.Initialize(CopyValueAdapter<A>(std::addressof(v)), n); } // Creates an inlined vector with copies of the elements of `list`. InlinedVector(std::initializer_list<value_type> list, - const allocator_type& allocator = allocator_type()) - : InlinedVector(list.begin(), list.end(), allocator) {} + const allocator_type& allocator = allocator_type()) + : InlinedVector(list.begin(), list.end(), allocator) {} // Creates an inlined vector with elements constructed from the provided // forward iterator range [`first`, `last`). @@ -147,36 +147,36 @@ class InlinedVector { // this constructor with two integral arguments and a call to the above // `InlinedVector(size_type, const_reference)` constructor. template <typename ForwardIterator, - EnableIfAtLeastForwardIterator<ForwardIterator> = 0> + EnableIfAtLeastForwardIterator<ForwardIterator> = 0> InlinedVector(ForwardIterator first, ForwardIterator last, - const allocator_type& allocator = allocator_type()) - : storage_(allocator) { - storage_.Initialize(IteratorValueAdapter<A, ForwardIterator>(first), + const allocator_type& allocator = allocator_type()) + : storage_(allocator) { + storage_.Initialize(IteratorValueAdapter<A, ForwardIterator>(first), std::distance(first, last)); } // Creates an inlined vector with elements constructed from the provided input // iterator range [`first`, `last`). template <typename InputIterator, - DisableIfAtLeastForwardIterator<InputIterator> = 0> + DisableIfAtLeastForwardIterator<InputIterator> = 0> InlinedVector(InputIterator first, InputIterator last, - const allocator_type& allocator = allocator_type()) - : storage_(allocator) { + const allocator_type& allocator = allocator_type()) + : storage_(allocator) { std::copy(first, last, std::back_inserter(*this)); } // Creates an inlined vector by copying the contents of `other` using // `other`'s allocator. InlinedVector(const InlinedVector& other) - : InlinedVector(other, other.storage_.GetAllocator()) {} + : InlinedVector(other, other.storage_.GetAllocator()) {} - // Creates an inlined vector by copying the contents of `other` using the - // provided `allocator`. - InlinedVector(const InlinedVector& other, const allocator_type& allocator) - : storage_(allocator) { + // Creates an inlined vector by copying the contents of `other` using the + // provided `allocator`. + InlinedVector(const InlinedVector& other, const allocator_type& allocator) + : storage_(allocator) { if (other.empty()) { // Empty; nothing to do. - } else if (IsMemcpyOk<A>::value && !other.storage_.GetIsAllocated()) { + } else if (IsMemcpyOk<A>::value && !other.storage_.GetIsAllocated()) { // Memcpy-able and do not need allocation. storage_.MemcpyFrom(other.storage_); } else { @@ -201,23 +201,23 @@ class InlinedVector { InlinedVector(InlinedVector&& other) noexcept( absl::allocator_is_nothrow<allocator_type>::value || std::is_nothrow_move_constructible<value_type>::value) - : storage_(other.storage_.GetAllocator()) { - if (IsMemcpyOk<A>::value) { + : storage_(other.storage_.GetAllocator()) { + if (IsMemcpyOk<A>::value) { storage_.MemcpyFrom(other.storage_); other.storage_.SetInlinedSize(0); } else if (other.storage_.GetIsAllocated()) { - storage_.SetAllocation({other.storage_.GetAllocatedData(), - other.storage_.GetAllocatedCapacity()}); + storage_.SetAllocation({other.storage_.GetAllocatedData(), + other.storage_.GetAllocatedCapacity()}); storage_.SetAllocatedSize(other.storage_.GetSize()); other.storage_.SetInlinedSize(0); } else { - IteratorValueAdapter<A, MoveIterator<A>> other_values( - MoveIterator<A>(other.storage_.GetInlinedData())); + IteratorValueAdapter<A, MoveIterator<A>> other_values( + MoveIterator<A>(other.storage_.GetInlinedData())); - inlined_vector_internal::ConstructElements<A>( - storage_.GetAllocator(), storage_.GetInlinedData(), other_values, + inlined_vector_internal::ConstructElements<A>( + storage_.GetAllocator(), storage_.GetInlinedData(), other_values, other.storage_.GetSize()); storage_.SetInlinedSize(other.storage_.GetSize()); @@ -225,32 +225,32 @@ class InlinedVector { } // Creates an inlined vector by moving in the contents of `other` with a copy - // of `allocator`. + // of `allocator`. // - // NOTE: if `other`'s allocator is not equal to `allocator`, even if `other` + // NOTE: if `other`'s allocator is not equal to `allocator`, even if `other` // contains allocated memory, this move constructor will still allocate. Since // allocation is performed, this constructor can only be `noexcept` if the // specified allocator is also `noexcept`. - InlinedVector( - InlinedVector&& other, - const allocator_type& allocator) - noexcept(absl::allocator_is_nothrow<allocator_type>::value) - : storage_(allocator) { - if (IsMemcpyOk<A>::value) { + InlinedVector( + InlinedVector&& other, + const allocator_type& allocator) + noexcept(absl::allocator_is_nothrow<allocator_type>::value) + : storage_(allocator) { + if (IsMemcpyOk<A>::value) { storage_.MemcpyFrom(other.storage_); other.storage_.SetInlinedSize(0); - } else if ((storage_.GetAllocator() == other.storage_.GetAllocator()) && + } else if ((storage_.GetAllocator() == other.storage_.GetAllocator()) && other.storage_.GetIsAllocated()) { - storage_.SetAllocation({other.storage_.GetAllocatedData(), - other.storage_.GetAllocatedCapacity()}); + storage_.SetAllocation({other.storage_.GetAllocatedData(), + other.storage_.GetAllocatedCapacity()}); storage_.SetAllocatedSize(other.storage_.GetSize()); other.storage_.SetInlinedSize(0); } else { - storage_.Initialize(IteratorValueAdapter<A, MoveIterator<A>>( - MoveIterator<A>(other.data())), - other.size()); + storage_.Initialize(IteratorValueAdapter<A, MoveIterator<A>>( + MoveIterator<A>(other.data())), + other.size()); } } @@ -451,7 +451,7 @@ class InlinedVector { // `InlinedVector::get_allocator()` // // Returns a copy of the inlined vector's allocator. - allocator_type get_allocator() const { return storage_.GetAllocator(); } + allocator_type get_allocator() const { return storage_.GetAllocator(); } // --------------------------------------------------------------------------- // InlinedVector Member Mutators @@ -485,16 +485,16 @@ class InlinedVector { // unspecified state. InlinedVector& operator=(InlinedVector&& other) { if (ABSL_PREDICT_TRUE(this != std::addressof(other))) { - if (IsMemcpyOk<A>::value || other.storage_.GetIsAllocated()) { - inlined_vector_internal::DestroyElements<A>(storage_.GetAllocator(), - data(), size()); + if (IsMemcpyOk<A>::value || other.storage_.GetIsAllocated()) { + inlined_vector_internal::DestroyElements<A>(storage_.GetAllocator(), + data(), size()); storage_.DeallocateIfAllocated(); storage_.MemcpyFrom(other.storage_); other.storage_.SetInlinedSize(0); } else { - storage_.Assign(IteratorValueAdapter<A, MoveIterator<A>>( - MoveIterator<A>(other.storage_.GetInlinedData())), + storage_.Assign(IteratorValueAdapter<A, MoveIterator<A>>( + MoveIterator<A>(other.storage_.GetInlinedData())), other.size()); } } @@ -506,7 +506,7 @@ class InlinedVector { // // Replaces the contents of the inlined vector with `n` copies of `v`. void assign(size_type n, const_reference v) { - storage_.Assign(CopyValueAdapter<A>(std::addressof(v)), n); + storage_.Assign(CopyValueAdapter<A>(std::addressof(v)), n); } // Overload of `InlinedVector::assign(...)` that replaces the contents of the @@ -520,9 +520,9 @@ class InlinedVector { // // NOTE: this overload is for iterators that are "forward" category or better. template <typename ForwardIterator, - EnableIfAtLeastForwardIterator<ForwardIterator> = 0> + EnableIfAtLeastForwardIterator<ForwardIterator> = 0> void assign(ForwardIterator first, ForwardIterator last) { - storage_.Assign(IteratorValueAdapter<A, ForwardIterator>(first), + storage_.Assign(IteratorValueAdapter<A, ForwardIterator>(first), std::distance(first, last)); } @@ -531,7 +531,7 @@ class InlinedVector { // // NOTE: this overload is for iterators that are "input" category. template <typename InputIterator, - DisableIfAtLeastForwardIterator<InputIterator> = 0> + DisableIfAtLeastForwardIterator<InputIterator> = 0> void assign(InputIterator first, InputIterator last) { size_type i = 0; for (; i < size() && first != last; ++i, static_cast<void>(++first)) { @@ -550,7 +550,7 @@ class InlinedVector { // is larger than `size()`, new elements are value-initialized. void resize(size_type n) { ABSL_HARDENING_ASSERT(n <= max_size()); - storage_.Resize(DefaultValueAdapter<A>(), n); + storage_.Resize(DefaultValueAdapter<A>(), n); } // Overload of `InlinedVector::resize(...)` that resizes the inlined vector to @@ -560,7 +560,7 @@ class InlinedVector { // is larger than `size()`, new elements are copied-constructed from `v`. void resize(size_type n, const_reference v) { ABSL_HARDENING_ASSERT(n <= max_size()); - storage_.Resize(CopyValueAdapter<A>(std::addressof(v)), n); + storage_.Resize(CopyValueAdapter<A>(std::addressof(v)), n); } // `InlinedVector::insert(...)` @@ -573,7 +573,7 @@ class InlinedVector { // Overload of `InlinedVector::insert(...)` that inserts `v` at `pos` using // move semantics, returning an `iterator` to the newly inserted element. - iterator insert(const_iterator pos, value_type&& v) { + iterator insert(const_iterator pos, value_type&& v) { return emplace(pos, std::move(v)); } @@ -586,8 +586,8 @@ class InlinedVector { if (ABSL_PREDICT_TRUE(n != 0)) { value_type dealias = v; - return storage_.Insert(pos, CopyValueAdapter<A>(std::addressof(dealias)), - n); + return storage_.Insert(pos, CopyValueAdapter<A>(std::addressof(dealias)), + n); } else { return const_cast<iterator>(pos); } @@ -606,15 +606,15 @@ class InlinedVector { // // NOTE: this overload is for iterators that are "forward" category or better. template <typename ForwardIterator, - EnableIfAtLeastForwardIterator<ForwardIterator> = 0> + EnableIfAtLeastForwardIterator<ForwardIterator> = 0> iterator insert(const_iterator pos, ForwardIterator first, ForwardIterator last) { ABSL_HARDENING_ASSERT(pos >= begin()); ABSL_HARDENING_ASSERT(pos <= end()); if (ABSL_PREDICT_TRUE(first != last)) { - return storage_.Insert(pos, - IteratorValueAdapter<A, ForwardIterator>(first), + return storage_.Insert(pos, + IteratorValueAdapter<A, ForwardIterator>(first), std::distance(first, last)); } else { return const_cast<iterator>(pos); @@ -627,7 +627,7 @@ class InlinedVector { // // NOTE: this overload is for iterators that are "input" category. template <typename InputIterator, - DisableIfAtLeastForwardIterator<InputIterator> = 0> + DisableIfAtLeastForwardIterator<InputIterator> = 0> iterator insert(const_iterator pos, InputIterator first, InputIterator last) { ABSL_HARDENING_ASSERT(pos >= begin()); ABSL_HARDENING_ASSERT(pos <= end()); @@ -651,8 +651,8 @@ class InlinedVector { value_type dealias(std::forward<Args>(args)...); return storage_.Insert(pos, - IteratorValueAdapter<A, MoveIterator<A>>( - MoveIterator<A>(std::addressof(dealias))), + IteratorValueAdapter<A, MoveIterator<A>>( + MoveIterator<A>(std::addressof(dealias))), 1); } @@ -672,7 +672,7 @@ class InlinedVector { // Overload of `InlinedVector::push_back(...)` for inserting `v` at `end()` // using move semantics. - void push_back(value_type&& v) { + void push_back(value_type&& v) { static_cast<void>(emplace_back(std::move(v))); } @@ -682,7 +682,7 @@ class InlinedVector { void pop_back() noexcept { ABSL_HARDENING_ASSERT(!empty()); - AllocatorTraits<A>::destroy(storage_.GetAllocator(), data() + (size() - 1)); + AllocatorTraits<A>::destroy(storage_.GetAllocator(), data() + (size() - 1)); storage_.SubtractSize(1); } @@ -721,8 +721,8 @@ class InlinedVector { // Destroys all elements in the inlined vector, setting the size to `0` and // deallocating any held memory. void clear() noexcept { - inlined_vector_internal::DestroyElements<A>(storage_.GetAllocator(), data(), - size()); + inlined_vector_internal::DestroyElements<A>(storage_.GetAllocator(), data(), + size()); storage_.DeallocateIfAllocated(); storage_.SetInlinedSize(0); @@ -735,12 +735,12 @@ class InlinedVector { // `InlinedVector::shrink_to_fit()` // - // Attempts to reduce memory usage by moving elements to (or keeping elements - // in) the smallest available buffer sufficient for containing `size()` - // elements. + // Attempts to reduce memory usage by moving elements to (or keeping elements + // in) the smallest available buffer sufficient for containing `size()` + // elements. // - // If `size()` is sufficiently small, the elements will be moved into (or kept - // in) the inlined space. + // If `size()` is sufficiently small, the elements will be moved into (or kept + // in) the inlined space. void shrink_to_fit() { if (storage_.GetIsAllocated()) { storage_.ShrinkToFit(); diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/absl_hashtablez_sampler/ya.make b/contrib/restricted/abseil-cpp/absl/container/internal/absl_hashtablez_sampler/ya.make index 1933289a6d..8dedf52f5a 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/absl_hashtablez_sampler/ya.make +++ b/contrib/restricted/abseil-cpp/absl/container/internal/absl_hashtablez_sampler/ya.make @@ -10,24 +10,24 @@ LICENSE(Apache-2.0) PEERDIR( contrib/restricted/abseil-cpp/absl/base - contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc contrib/restricted/abseil-cpp/absl/base/internal/raw_logging contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/debugging - contrib/restricted/abseil-cpp/absl/debugging/stacktrace - contrib/restricted/abseil-cpp/absl/debugging/symbolize - contrib/restricted/abseil-cpp/absl/demangle + contrib/restricted/abseil-cpp/absl/debugging + contrib/restricted/abseil-cpp/absl/debugging/stacktrace + contrib/restricted/abseil-cpp/absl/debugging/symbolize + contrib/restricted/abseil-cpp/absl/demangle contrib/restricted/abseil-cpp/absl/numeric - contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp/absl/synchronization - contrib/restricted/abseil-cpp/absl/synchronization/internal - contrib/restricted/abseil-cpp/absl/time - contrib/restricted/abseil-cpp/absl/time/civil_time - contrib/restricted/abseil-cpp/absl/time/time_zone + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/synchronization + contrib/restricted/abseil-cpp/absl/synchronization/internal + contrib/restricted/abseil-cpp/absl/time + contrib/restricted/abseil-cpp/absl/time/civil_time + contrib/restricted/abseil-cpp/absl/time/time_zone ) ADDINCL( @@ -42,11 +42,11 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/container/internal) +SRCDIR(contrib/restricted/abseil-cpp/absl/container/internal) SRCS( - hashtablez_sampler.cc - hashtablez_sampler_force_weak_definition.cc + hashtablez_sampler.cc + hashtablez_sampler_force_weak_definition.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/btree.h b/contrib/restricted/abseil-cpp/absl/container/internal/btree.h index f636c5fc73..ec2a5622d8 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/btree.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/btree.h @@ -88,13 +88,13 @@ struct StringBtreeDefaultLess { // Compatibility constructor. StringBtreeDefaultLess(std::less<std::string>) {} // NOLINT - StringBtreeDefaultLess(std::less<absl::string_view>) {} // NOLINT - - // Allow converting to std::less for use in key_comp()/value_comp(). - explicit operator std::less<std::string>() const { return {}; } - explicit operator std::less<absl::string_view>() const { return {}; } - explicit operator std::less<absl::Cord>() const { return {}; } + StringBtreeDefaultLess(std::less<absl::string_view>) {} // NOLINT + // Allow converting to std::less for use in key_comp()/value_comp(). + explicit operator std::less<std::string>() const { return {}; } + explicit operator std::less<absl::string_view>() const { return {}; } + explicit operator std::less<absl::Cord>() const { return {}; } + absl::weak_ordering operator()(absl::string_view lhs, absl::string_view rhs) const { return compare_internal::compare_result_as_ordering(lhs.compare(rhs)); @@ -120,13 +120,13 @@ struct StringBtreeDefaultGreater { StringBtreeDefaultGreater() = default; StringBtreeDefaultGreater(std::greater<std::string>) {} // NOLINT - StringBtreeDefaultGreater(std::greater<absl::string_view>) {} // NOLINT - - // Allow converting to std::greater for use in key_comp()/value_comp(). - explicit operator std::greater<std::string>() const { return {}; } - explicit operator std::greater<absl::string_view>() const { return {}; } - explicit operator std::greater<absl::Cord>() const { return {}; } + StringBtreeDefaultGreater(std::greater<absl::string_view>) {} // NOLINT + // Allow converting to std::greater for use in key_comp()/value_comp(). + explicit operator std::greater<std::string>() const { return {}; } + explicit operator std::greater<absl::string_view>() const { return {}; } + explicit operator std::greater<absl::Cord>() const { return {}; } + absl::weak_ordering operator()(absl::string_view lhs, absl::string_view rhs) const { return compare_internal::compare_result_as_ordering(rhs.compare(lhs)); @@ -227,8 +227,8 @@ struct prefers_linear_node_search< template <typename Key, typename Compare, typename Alloc, int TargetNodeSize, bool Multi, typename SlotPolicy> struct common_params { - using original_key_compare = Compare; - + using original_key_compare = Compare; + // If Compare is a common comparator for a string-like type, then we adapt it // to use heterogeneous lookup and to be a key-compare-to comparator. using key_compare = typename key_compare_to_adapter<Compare>::type; @@ -329,21 +329,21 @@ struct map_params : common_params<Key, Compare, Alloc, TargetNodeSize, Multi, using value_type = typename super_type::value_type; using init_type = typename super_type::init_type; - using original_key_compare = typename super_type::original_key_compare; - // Reference: https://en.cppreference.com/w/cpp/container/map/value_compare - class value_compare { - template <typename Params> - friend class btree; - - protected: - explicit value_compare(original_key_compare c) : comp(std::move(c)) {} - - original_key_compare comp; // NOLINT - - public: - auto operator()(const value_type &lhs, const value_type &rhs) const - -> decltype(comp(lhs.first, rhs.first)) { - return comp(lhs.first, rhs.first); + using original_key_compare = typename super_type::original_key_compare; + // Reference: https://en.cppreference.com/w/cpp/container/map/value_compare + class value_compare { + template <typename Params> + friend class btree; + + protected: + explicit value_compare(original_key_compare c) : comp(std::move(c)) {} + + original_key_compare comp; // NOLINT + + public: + auto operator()(const value_type &lhs, const value_type &rhs) const + -> decltype(comp(lhs.first, rhs.first)) { + return comp(lhs.first, rhs.first); } }; using is_map_container = std::true_type; @@ -409,8 +409,8 @@ struct set_params : common_params<Key, Compare, Alloc, TargetNodeSize, Multi, set_slot_policy<Key>> { using value_type = Key; using slot_type = typename set_params::common_params::slot_type; - using value_compare = - typename set_params::common_params::original_key_compare; + using value_compare = + typename set_params::common_params::original_key_compare; using is_map_container = std::false_type; template <typename V> @@ -502,8 +502,8 @@ class btree_node { std::is_same<std::greater<key_type>, key_compare>::value)>; - // This class is organized by absl::container_internal::Layout as if it had - // the following structure: + // This class is organized by absl::container_internal::Layout as if it had + // the following structure: // // A pointer to the node's parent. // btree_node *parent; // @@ -1147,7 +1147,7 @@ class btree { using size_type = typename Params::size_type; using difference_type = typename Params::difference_type; using key_compare = typename Params::key_compare; - using original_key_compare = typename Params::original_key_compare; + using original_key_compare = typename Params::original_key_compare; using value_compare = typename Params::value_compare; using allocator_type = typename Params::allocator_type; using reference = typename Params::reference; @@ -1357,9 +1357,9 @@ class btree { return compare_internal::compare_result_as_less_than(key_comp()(a, b)); } - value_compare value_comp() const { - return value_compare(original_key_compare(key_comp())); - } + value_compare value_comp() const { + return value_compare(original_key_compare(key_comp())); + } // Verifies the structure of the btree. void verify() const; diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/btree_container.h b/contrib/restricted/abseil-cpp/absl/container/internal/btree_container.h index a99668c713..c569ab1489 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/btree_container.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/btree_container.h @@ -20,7 +20,7 @@ #include <iterator> #include <utility> -#include "absl/base/attributes.h" +#include "absl/base/attributes.h" #include "absl/base/internal/throw_delegate.h" #include "absl/container/internal/btree.h" // IWYU pragma: export #include "absl/container/internal/common.h" @@ -52,7 +52,7 @@ class btree_container { using value_type = typename Tree::value_type; using size_type = typename Tree::size_type; using difference_type = typename Tree::difference_type; - using key_compare = typename Tree::original_key_compare; + using key_compare = typename Tree::original_key_compare; using value_compare = typename Tree::value_compare; using allocator_type = typename Tree::allocator_type; using reference = typename Tree::reference; @@ -177,7 +177,7 @@ class btree_container { } // Utility routines. - ABSL_ATTRIBUTE_REINITIALIZES void clear() { tree_.clear(); } + ABSL_ATTRIBUTE_REINITIALIZES void clear() { tree_.clear(); } void swap(btree_container &other) { tree_.swap(other.tree_); } void verify() const { tree_.verify(); } @@ -215,7 +215,7 @@ class btree_container { allocator_type get_allocator() const { return tree_.get_allocator(); } // The key comparator used by the btree. - key_compare key_comp() const { return key_compare(tree_.key_comp()); } + key_compare key_comp() const { return key_compare(tree_.key_comp()); } value_compare value_comp() const { return tree_.value_comp(); } // Support absl::Hash. @@ -248,7 +248,7 @@ class btree_set_container : public btree_container<Tree> { using key_type = typename Tree::key_type; using value_type = typename Tree::value_type; using size_type = typename Tree::size_type; - using key_compare = typename Tree::original_key_compare; + using key_compare = typename Tree::original_key_compare; using allocator_type = typename Tree::allocator_type; using iterator = typename Tree::iterator; using const_iterator = typename Tree::const_iterator; @@ -399,7 +399,7 @@ class btree_map_container : public btree_set_container<Tree> { using key_type = typename Tree::key_type; using mapped_type = typename params_type::mapped_type; using value_type = typename Tree::value_type; - using key_compare = typename Tree::original_key_compare; + using key_compare = typename Tree::original_key_compare; using allocator_type = typename Tree::allocator_type; using iterator = typename Tree::iterator; using const_iterator = typename Tree::const_iterator; @@ -544,7 +544,7 @@ class btree_multiset_container : public btree_container<Tree> { using key_type = typename Tree::key_type; using value_type = typename Tree::value_type; using size_type = typename Tree::size_type; - using key_compare = typename Tree::original_key_compare; + using key_compare = typename Tree::original_key_compare; using allocator_type = typename Tree::allocator_type; using iterator = typename Tree::iterator; using const_iterator = typename Tree::const_iterator; diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/hash_function_defaults.h b/contrib/restricted/abseil-cpp/absl/container/internal/hash_function_defaults.h index 250e662c9d..d3c650fb97 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/hash_function_defaults.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/hash_function_defaults.h @@ -78,26 +78,26 @@ struct StringHash { } }; -struct StringEq { - using is_transparent = void; - bool operator()(absl::string_view lhs, absl::string_view rhs) const { - return lhs == rhs; - } - bool operator()(const absl::Cord& lhs, const absl::Cord& rhs) const { - return lhs == rhs; - } - bool operator()(const absl::Cord& lhs, absl::string_view rhs) const { - return lhs == rhs; - } - bool operator()(absl::string_view lhs, const absl::Cord& rhs) const { - return lhs == rhs; - } -}; - +struct StringEq { + using is_transparent = void; + bool operator()(absl::string_view lhs, absl::string_view rhs) const { + return lhs == rhs; + } + bool operator()(const absl::Cord& lhs, const absl::Cord& rhs) const { + return lhs == rhs; + } + bool operator()(const absl::Cord& lhs, absl::string_view rhs) const { + return lhs == rhs; + } + bool operator()(absl::string_view lhs, const absl::Cord& rhs) const { + return lhs == rhs; + } +}; + // Supports heterogeneous lookup for string-like elements. struct StringHashEq { using Hash = StringHash; - using Eq = StringEq; + using Eq = StringEq; }; template <> diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/hash_generator_testing.h b/contrib/restricted/abseil-cpp/absl/container/internal/hash_generator_testing.h index f1f555a5c1..0fd1d161a0 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/hash_generator_testing.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/hash_generator_testing.h @@ -21,13 +21,13 @@ #include <stdint.h> #include <algorithm> -#include <cassert> +#include <cassert> #include <iosfwd> #include <random> #include <tuple> #include <type_traits> #include <utility> -#include <vector> +#include <vector> #include "absl/container/internal/hash_policy_testing.h" #include "absl/memory/memory.h" @@ -155,25 +155,25 @@ using GeneratedType = decltype( typename Container::value_type, typename Container::key_type>::type>&>()()); -// Naive wrapper that performs a linear search of previous values. -// Beware this is O(SQR), which is reasonable for smaller kMaxValues. -template <class T, size_t kMaxValues = 64, class E = void> -struct UniqueGenerator { - Generator<T, E> gen; - std::vector<T> values; - - T operator()() { - assert(values.size() < kMaxValues); - for (;;) { - T value = gen(); - if (std::find(values.begin(), values.end(), value) == values.end()) { - values.push_back(value); - return value; - } - } - } -}; - +// Naive wrapper that performs a linear search of previous values. +// Beware this is O(SQR), which is reasonable for smaller kMaxValues. +template <class T, size_t kMaxValues = 64, class E = void> +struct UniqueGenerator { + Generator<T, E> gen; + std::vector<T> values; + + T operator()() { + assert(values.size() < kMaxValues); + for (;;) { + T value = gen(); + if (std::find(values.begin(), values.end(), value) == values.end()) { + values.push_back(value); + return value; + } + } + } +}; + } // namespace hash_internal } // namespace container_internal ABSL_NAMESPACE_END diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler.cc b/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler.cc index 40cce0479e..d283d98d9e 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +++ b/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler.cc @@ -24,8 +24,8 @@ #include "absl/container/internal/have_sse.h" #include "absl/debugging/stacktrace.h" #include "absl/memory/memory.h" -#include "absl/profiling/internal/exponential_biased.h" -#include "absl/profiling/internal/sample_recorder.h" +#include "absl/profiling/internal/exponential_biased.h" +#include "absl/profiling/internal/sample_recorder.h" #include "absl/synchronization/mutex.h" namespace absl { @@ -40,7 +40,7 @@ ABSL_CONST_INIT std::atomic<bool> g_hashtablez_enabled{ ABSL_CONST_INIT std::atomic<int32_t> g_hashtablez_sample_parameter{1 << 10}; #if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) -ABSL_PER_THREAD_TLS_KEYWORD absl::profiling_internal::ExponentialBiased +ABSL_PER_THREAD_TLS_KEYWORD absl::profiling_internal::ExponentialBiased g_exponential_biased_generator; #endif @@ -50,14 +50,14 @@ ABSL_PER_THREAD_TLS_KEYWORD absl::profiling_internal::ExponentialBiased ABSL_PER_THREAD_TLS_KEYWORD int64_t global_next_sample = 0; #endif // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) -HashtablezSampler& GlobalHashtablezSampler() { +HashtablezSampler& GlobalHashtablezSampler() { static auto* sampler = new HashtablezSampler(); return *sampler; } -// TODO(bradleybear): The comments at this constructors declaration say that the -// fields are not initialized, but this definition does initialize the fields. -// Something needs to be cleaned up. +// TODO(bradleybear): The comments at this constructors declaration say that the +// fields are not initialized, but this definition does initialize the fields. +// Something needs to be cleaned up. HashtablezInfo::HashtablezInfo() { PrepareForSampling(); } HashtablezInfo::~HashtablezInfo() = default; @@ -71,7 +71,7 @@ void HashtablezInfo::PrepareForSampling() { hashes_bitwise_or.store(0, std::memory_order_relaxed); hashes_bitwise_and.store(~size_t{}, std::memory_order_relaxed); hashes_bitwise_xor.store(0, std::memory_order_relaxed); - max_reserve.store(0, std::memory_order_relaxed); + max_reserve.store(0, std::memory_order_relaxed); create_time = absl::Now(); // The inliner makes hardcoded skip_count difficult (especially when combined @@ -101,12 +101,12 @@ static bool ShouldForceSampling() { return state == kForce; } -HashtablezInfo* SampleSlow(int64_t* next_sample, size_t inline_element_size) { +HashtablezInfo* SampleSlow(int64_t* next_sample, size_t inline_element_size) { if (ABSL_PREDICT_FALSE(ShouldForceSampling())) { *next_sample = 1; - HashtablezInfo* result = GlobalHashtablezSampler().Register(); - result->inline_element_size = inline_element_size; - return result; + HashtablezInfo* result = GlobalHashtablezSampler().Register(); + result->inline_element_size = inline_element_size; + return result; } #if !defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) @@ -128,17 +128,17 @@ HashtablezInfo* SampleSlow(int64_t* next_sample, size_t inline_element_size) { // that case. if (first) { if (ABSL_PREDICT_TRUE(--*next_sample > 0)) return nullptr; - return SampleSlow(next_sample, inline_element_size); + return SampleSlow(next_sample, inline_element_size); } - HashtablezInfo* result = GlobalHashtablezSampler().Register(); - result->inline_element_size = inline_element_size; - return result; + HashtablezInfo* result = GlobalHashtablezSampler().Register(); + result->inline_element_size = inline_element_size; + return result; #endif } void UnsampleSlow(HashtablezInfo* info) { - GlobalHashtablezSampler().Unregister(info); + GlobalHashtablezSampler().Unregister(info); } void RecordInsertSlow(HashtablezInfo* info, size_t hash, @@ -178,7 +178,7 @@ void SetHashtablezSampleParameter(int32_t rate) { void SetHashtablezMaxSamples(int32_t max) { if (max > 0) { - GlobalHashtablezSampler().SetMaxSamples(max); + GlobalHashtablezSampler().SetMaxSamples(max); } else { ABSL_RAW_LOG(ERROR, "Invalid hashtablez max samples: %lld", static_cast<long long>(max)); // NOLINT(runtime/int) diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler.h b/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler.h index 91fcdb34a3..7919c05079 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler.h @@ -47,7 +47,7 @@ #include "absl/base/internal/per_thread_tls.h" #include "absl/base/optimization.h" #include "absl/container/internal/have_sse.h" -#include "absl/profiling/internal/sample_recorder.h" +#include "absl/profiling/internal/sample_recorder.h" #include "absl/synchronization/mutex.h" #include "absl/utility/utility.h" @@ -58,7 +58,7 @@ namespace container_internal { // Stores information about a sampled hashtable. All mutations to this *must* // be made through `Record*` functions below. All reads from this *must* only // occur in the callback to `HashtablezSampler::Iterate`. -struct HashtablezInfo : public profiling_internal::Sample<HashtablezInfo> { +struct HashtablezInfo : public profiling_internal::Sample<HashtablezInfo> { // Constructs the object but does not fill in any fields. HashtablezInfo(); ~HashtablezInfo(); @@ -80,7 +80,7 @@ struct HashtablezInfo : public profiling_internal::Sample<HashtablezInfo> { std::atomic<size_t> hashes_bitwise_or; std::atomic<size_t> hashes_bitwise_and; std::atomic<size_t> hashes_bitwise_xor; - std::atomic<size_t> max_reserve; + std::atomic<size_t> max_reserve; // All of the fields below are set by `PrepareForSampling`, they must not be // mutated in `Record*` functions. They are logically `const` in that sense. @@ -91,7 +91,7 @@ struct HashtablezInfo : public profiling_internal::Sample<HashtablezInfo> { absl::Time create_time; int32_t depth; void* stack[kMaxStackDepth]; - size_t inline_element_size; + size_t inline_element_size; }; inline void RecordRehashSlow(HashtablezInfo* info, size_t total_probe_length) { @@ -109,18 +109,18 @@ inline void RecordRehashSlow(HashtablezInfo* info, size_t total_probe_length) { std::memory_order_relaxed); } -inline void RecordReservationSlow(HashtablezInfo* info, - size_t target_capacity) { - info->max_reserve.store( - (std::max)(info->max_reserve.load(std::memory_order_relaxed), - target_capacity), - std::memory_order_relaxed); -} - -inline void RecordClearedReservationSlow(HashtablezInfo* info) { - info->max_reserve.store(0, std::memory_order_relaxed); -} - +inline void RecordReservationSlow(HashtablezInfo* info, + size_t target_capacity) { + info->max_reserve.store( + (std::max)(info->max_reserve.load(std::memory_order_relaxed), + target_capacity), + std::memory_order_relaxed); +} + +inline void RecordClearedReservationSlow(HashtablezInfo* info) { + info->max_reserve.store(0, std::memory_order_relaxed); +} + inline void RecordStorageChangedSlow(HashtablezInfo* info, size_t size, size_t capacity) { info->size.store(size, std::memory_order_relaxed); @@ -144,7 +144,7 @@ inline void RecordEraseSlow(HashtablezInfo* info) { std::memory_order_relaxed); } -HashtablezInfo* SampleSlow(int64_t* next_sample, size_t inline_element_size); +HashtablezInfo* SampleSlow(int64_t* next_sample, size_t inline_element_size); void UnsampleSlow(HashtablezInfo* info); #if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) @@ -184,16 +184,16 @@ class HashtablezInfoHandle { RecordRehashSlow(info_, total_probe_length); } - inline void RecordReservation(size_t target_capacity) { - if (ABSL_PREDICT_TRUE(info_ == nullptr)) return; - RecordReservationSlow(info_, target_capacity); - } - - inline void RecordClearedReservation() { - if (ABSL_PREDICT_TRUE(info_ == nullptr)) return; - RecordClearedReservationSlow(info_); - } - + inline void RecordReservation(size_t target_capacity) { + if (ABSL_PREDICT_TRUE(info_ == nullptr)) return; + RecordReservationSlow(info_, target_capacity); + } + + inline void RecordClearedReservation() { + if (ABSL_PREDICT_TRUE(info_ == nullptr)) return; + RecordClearedReservationSlow(info_); + } + inline void RecordInsert(size_t hash, size_t distance_from_desired) { if (ABSL_PREDICT_TRUE(info_ == nullptr)) return; RecordInsertSlow(info_, hash, distance_from_desired); @@ -223,8 +223,8 @@ class HashtablezInfoHandle { inline void RecordStorageChanged(size_t /*size*/, size_t /*capacity*/) {} inline void RecordRehash(size_t /*total_probe_length*/) {} - inline void RecordReservation(size_t /*target_capacity*/) {} - inline void RecordClearedReservation() {} + inline void RecordReservation(size_t /*target_capacity*/) {} + inline void RecordClearedReservation() {} inline void RecordInsert(size_t /*hash*/, size_t /*distance_from_desired*/) {} inline void RecordErase() {} @@ -239,24 +239,24 @@ extern ABSL_PER_THREAD_TLS_KEYWORD int64_t global_next_sample; // Returns an RAII sampling handle that manages registration and unregistation // with the global sampler. -inline HashtablezInfoHandle Sample( - size_t inline_element_size ABSL_ATTRIBUTE_UNUSED) { +inline HashtablezInfoHandle Sample( + size_t inline_element_size ABSL_ATTRIBUTE_UNUSED) { #if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) if (ABSL_PREDICT_TRUE(--global_next_sample > 0)) { return HashtablezInfoHandle(nullptr); } - return HashtablezInfoHandle( - SampleSlow(&global_next_sample, inline_element_size)); + return HashtablezInfoHandle( + SampleSlow(&global_next_sample, inline_element_size)); #else return HashtablezInfoHandle(nullptr); #endif // !ABSL_PER_THREAD_TLS } -using HashtablezSampler = - ::absl::profiling_internal::SampleRecorder<HashtablezInfo>; +using HashtablezSampler = + ::absl::profiling_internal::SampleRecorder<HashtablezInfo>; -// Returns a global Sampler. -HashtablezSampler& GlobalHashtablezSampler(); +// Returns a global Sampler. +HashtablezSampler& GlobalHashtablezSampler(); // Enables or disables sampling for Swiss tables. void SetHashtablezEnabled(bool enabled); diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/inlined_vector.h b/contrib/restricted/abseil-cpp/absl/container/internal/inlined_vector.h index 1d7d6cda72..f43d5e500d 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/inlined_vector.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/inlined_vector.h @@ -21,11 +21,11 @@ #include <iterator> #include <limits> #include <memory> -#include <new> -#include <type_traits> +#include <new> +#include <type_traits> #include <utility> -#include "absl/base/attributes.h" +#include "absl/base/attributes.h" #include "absl/base/macros.h" #include "absl/container/internal/compressed_tuple.h" #include "absl/memory/memory.h" @@ -39,132 +39,132 @@ namespace inlined_vector_internal { // GCC does not deal very well with the below code #if !defined(__clang__) && defined(__GNUC__) #pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Warray-bounds" +#pragma GCC diagnostic ignored "-Warray-bounds" #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif -template <typename A> -using AllocatorTraits = std::allocator_traits<A>; -template <typename A> -using ValueType = typename AllocatorTraits<A>::value_type; -template <typename A> -using SizeType = typename AllocatorTraits<A>::size_type; -template <typename A> -using Pointer = typename AllocatorTraits<A>::pointer; -template <typename A> -using ConstPointer = typename AllocatorTraits<A>::const_pointer; -template <typename A> -using SizeType = typename AllocatorTraits<A>::size_type; -template <typename A> -using DifferenceType = typename AllocatorTraits<A>::difference_type; -template <typename A> -using Reference = ValueType<A>&; -template <typename A> -using ConstReference = const ValueType<A>&; -template <typename A> -using Iterator = Pointer<A>; -template <typename A> -using ConstIterator = ConstPointer<A>; -template <typename A> -using ReverseIterator = typename std::reverse_iterator<Iterator<A>>; -template <typename A> -using ConstReverseIterator = typename std::reverse_iterator<ConstIterator<A>>; -template <typename A> -using MoveIterator = typename std::move_iterator<Iterator<A>>; - +template <typename A> +using AllocatorTraits = std::allocator_traits<A>; +template <typename A> +using ValueType = typename AllocatorTraits<A>::value_type; +template <typename A> +using SizeType = typename AllocatorTraits<A>::size_type; +template <typename A> +using Pointer = typename AllocatorTraits<A>::pointer; +template <typename A> +using ConstPointer = typename AllocatorTraits<A>::const_pointer; +template <typename A> +using SizeType = typename AllocatorTraits<A>::size_type; +template <typename A> +using DifferenceType = typename AllocatorTraits<A>::difference_type; +template <typename A> +using Reference = ValueType<A>&; +template <typename A> +using ConstReference = const ValueType<A>&; +template <typename A> +using Iterator = Pointer<A>; +template <typename A> +using ConstIterator = ConstPointer<A>; +template <typename A> +using ReverseIterator = typename std::reverse_iterator<Iterator<A>>; +template <typename A> +using ConstReverseIterator = typename std::reverse_iterator<ConstIterator<A>>; +template <typename A> +using MoveIterator = typename std::move_iterator<Iterator<A>>; + template <typename Iterator> using IsAtLeastForwardIterator = std::is_convertible< typename std::iterator_traits<Iterator>::iterator_category, std::forward_iterator_tag>; -template <typename A> +template <typename A> using IsMemcpyOk = - absl::conjunction<std::is_same<A, std::allocator<ValueType<A>>>, - absl::is_trivially_copy_constructible<ValueType<A>>, - absl::is_trivially_copy_assignable<ValueType<A>>, - absl::is_trivially_destructible<ValueType<A>>>; - -template <typename T> -struct TypeIdentity { - using type = T; -}; - -// Used for function arguments in template functions to prevent ADL by forcing -// callers to explicitly specify the template parameter. -template <typename T> -using NoTypeDeduction = typename TypeIdentity<T>::type; - -template <typename A> -void DestroyElements(NoTypeDeduction<A>& allocator, Pointer<A> destroy_first, - SizeType<A> destroy_size) { + absl::conjunction<std::is_same<A, std::allocator<ValueType<A>>>, + absl::is_trivially_copy_constructible<ValueType<A>>, + absl::is_trivially_copy_assignable<ValueType<A>>, + absl::is_trivially_destructible<ValueType<A>>>; + +template <typename T> +struct TypeIdentity { + using type = T; +}; + +// Used for function arguments in template functions to prevent ADL by forcing +// callers to explicitly specify the template parameter. +template <typename T> +using NoTypeDeduction = typename TypeIdentity<T>::type; + +template <typename A> +void DestroyElements(NoTypeDeduction<A>& allocator, Pointer<A> destroy_first, + SizeType<A> destroy_size) { if (destroy_first != nullptr) { - for (SizeType<A> i = destroy_size; i != 0;) { + for (SizeType<A> i = destroy_size; i != 0;) { --i; - AllocatorTraits<A>::destroy(allocator, destroy_first + i); + AllocatorTraits<A>::destroy(allocator, destroy_first + i); } } } -template <typename A> -struct Allocation { - Pointer<A> data; - SizeType<A> capacity; -}; - -template <typename A, - bool IsOverAligned = - (alignof(ValueType<A>) > ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT)> -struct MallocAdapter { - static Allocation<A> Allocate(A& allocator, SizeType<A> requested_capacity) { - return {AllocatorTraits<A>::allocate(allocator, requested_capacity), - requested_capacity}; - } - - static void Deallocate(A& allocator, Pointer<A> pointer, - SizeType<A> capacity) { - AllocatorTraits<A>::deallocate(allocator, pointer, capacity); - } -}; - -template <typename A, typename ValueAdapter> -void ConstructElements(NoTypeDeduction<A>& allocator, - Pointer<A> construct_first, ValueAdapter& values, - SizeType<A> construct_size) { - for (SizeType<A> i = 0; i < construct_size; ++i) { - ABSL_INTERNAL_TRY { values.ConstructNext(allocator, construct_first + i); } +template <typename A> +struct Allocation { + Pointer<A> data; + SizeType<A> capacity; +}; + +template <typename A, + bool IsOverAligned = + (alignof(ValueType<A>) > ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT)> +struct MallocAdapter { + static Allocation<A> Allocate(A& allocator, SizeType<A> requested_capacity) { + return {AllocatorTraits<A>::allocate(allocator, requested_capacity), + requested_capacity}; + } + + static void Deallocate(A& allocator, Pointer<A> pointer, + SizeType<A> capacity) { + AllocatorTraits<A>::deallocate(allocator, pointer, capacity); + } +}; + +template <typename A, typename ValueAdapter> +void ConstructElements(NoTypeDeduction<A>& allocator, + Pointer<A> construct_first, ValueAdapter& values, + SizeType<A> construct_size) { + for (SizeType<A> i = 0; i < construct_size; ++i) { + ABSL_INTERNAL_TRY { values.ConstructNext(allocator, construct_first + i); } ABSL_INTERNAL_CATCH_ANY { - DestroyElements<A>(allocator, construct_first, i); + DestroyElements<A>(allocator, construct_first, i); ABSL_INTERNAL_RETHROW; } } } -template <typename A, typename ValueAdapter> -void AssignElements(Pointer<A> assign_first, ValueAdapter& values, - SizeType<A> assign_size) { - for (SizeType<A> i = 0; i < assign_size; ++i) { - values.AssignNext(assign_first + i); +template <typename A, typename ValueAdapter> +void AssignElements(Pointer<A> assign_first, ValueAdapter& values, + SizeType<A> assign_size) { + for (SizeType<A> i = 0; i < assign_size; ++i) { + values.AssignNext(assign_first + i); } } -template <typename A> +template <typename A> struct StorageView { - Pointer<A> data; - SizeType<A> size; - SizeType<A> capacity; + Pointer<A> data; + SizeType<A> size; + SizeType<A> capacity; }; -template <typename A, typename Iterator> +template <typename A, typename Iterator> class IteratorValueAdapter { public: explicit IteratorValueAdapter(const Iterator& it) : it_(it) {} - void ConstructNext(A& allocator, Pointer<A> construct_at) { - AllocatorTraits<A>::construct(allocator, construct_at, *it_); + void ConstructNext(A& allocator, Pointer<A> construct_at) { + AllocatorTraits<A>::construct(allocator, construct_at, *it_); ++it_; } - void AssignNext(Pointer<A> assign_at) { + void AssignNext(Pointer<A> assign_at) { *assign_at = *it_; ++it_; } @@ -173,123 +173,123 @@ class IteratorValueAdapter { Iterator it_; }; -template <typename A> +template <typename A> class CopyValueAdapter { public: - explicit CopyValueAdapter(ConstPointer<A> p) : ptr_(p) {} + explicit CopyValueAdapter(ConstPointer<A> p) : ptr_(p) {} - void ConstructNext(A& allocator, Pointer<A> construct_at) { - AllocatorTraits<A>::construct(allocator, construct_at, *ptr_); + void ConstructNext(A& allocator, Pointer<A> construct_at) { + AllocatorTraits<A>::construct(allocator, construct_at, *ptr_); } - void AssignNext(Pointer<A> assign_at) { *assign_at = *ptr_; } + void AssignNext(Pointer<A> assign_at) { *assign_at = *ptr_; } private: - ConstPointer<A> ptr_; + ConstPointer<A> ptr_; }; -template <typename A> +template <typename A> class DefaultValueAdapter { public: explicit DefaultValueAdapter() {} - void ConstructNext(A& allocator, Pointer<A> construct_at) { - AllocatorTraits<A>::construct(allocator, construct_at); + void ConstructNext(A& allocator, Pointer<A> construct_at) { + AllocatorTraits<A>::construct(allocator, construct_at); } - void AssignNext(Pointer<A> assign_at) { *assign_at = ValueType<A>(); } + void AssignNext(Pointer<A> assign_at) { *assign_at = ValueType<A>(); } }; -template <typename A> +template <typename A> class AllocationTransaction { public: - explicit AllocationTransaction(A& allocator) - : allocator_data_(allocator, nullptr), capacity_(0) {} + explicit AllocationTransaction(A& allocator) + : allocator_data_(allocator, nullptr), capacity_(0) {} ~AllocationTransaction() { if (DidAllocate()) { - MallocAdapter<A>::Deallocate(GetAllocator(), GetData(), GetCapacity()); + MallocAdapter<A>::Deallocate(GetAllocator(), GetData(), GetCapacity()); } } AllocationTransaction(const AllocationTransaction&) = delete; void operator=(const AllocationTransaction&) = delete; - A& GetAllocator() { return allocator_data_.template get<0>(); } - Pointer<A>& GetData() { return allocator_data_.template get<1>(); } - SizeType<A>& GetCapacity() { return capacity_; } + A& GetAllocator() { return allocator_data_.template get<0>(); } + Pointer<A>& GetData() { return allocator_data_.template get<1>(); } + SizeType<A>& GetCapacity() { return capacity_; } bool DidAllocate() { return GetData() != nullptr; } - - Pointer<A> Allocate(SizeType<A> requested_capacity) { - Allocation<A> result = - MallocAdapter<A>::Allocate(GetAllocator(), requested_capacity); - GetData() = result.data; - GetCapacity() = result.capacity; - return result.data; - } - - ABSL_MUST_USE_RESULT Allocation<A> Release() && { - Allocation<A> result = {GetData(), GetCapacity()}; - Reset(); - return result; - } - - private: + + Pointer<A> Allocate(SizeType<A> requested_capacity) { + Allocation<A> result = + MallocAdapter<A>::Allocate(GetAllocator(), requested_capacity); + GetData() = result.data; + GetCapacity() = result.capacity; + return result.data; + } + + ABSL_MUST_USE_RESULT Allocation<A> Release() && { + Allocation<A> result = {GetData(), GetCapacity()}; + Reset(); + return result; + } + + private: void Reset() { GetData() = nullptr; GetCapacity() = 0; } - container_internal::CompressedTuple<A, Pointer<A>> allocator_data_; - SizeType<A> capacity_; + container_internal::CompressedTuple<A, Pointer<A>> allocator_data_; + SizeType<A> capacity_; }; -template <typename A> +template <typename A> class ConstructionTransaction { public: - explicit ConstructionTransaction(A& allocator) - : allocator_data_(allocator, nullptr), size_(0) {} + explicit ConstructionTransaction(A& allocator) + : allocator_data_(allocator, nullptr), size_(0) {} ~ConstructionTransaction() { if (DidConstruct()) { - DestroyElements<A>(GetAllocator(), GetData(), GetSize()); + DestroyElements<A>(GetAllocator(), GetData(), GetSize()); } } ConstructionTransaction(const ConstructionTransaction&) = delete; void operator=(const ConstructionTransaction&) = delete; - A& GetAllocator() { return allocator_data_.template get<0>(); } - Pointer<A>& GetData() { return allocator_data_.template get<1>(); } - SizeType<A>& GetSize() { return size_; } + A& GetAllocator() { return allocator_data_.template get<0>(); } + Pointer<A>& GetData() { return allocator_data_.template get<1>(); } + SizeType<A>& GetSize() { return size_; } bool DidConstruct() { return GetData() != nullptr; } template <typename ValueAdapter> - void Construct(Pointer<A> data, ValueAdapter& values, SizeType<A> size) { - ConstructElements<A>(GetAllocator(), data, values, size); + void Construct(Pointer<A> data, ValueAdapter& values, SizeType<A> size) { + ConstructElements<A>(GetAllocator(), data, values, size); GetData() = data; GetSize() = size; } - void Commit() && { + void Commit() && { GetData() = nullptr; GetSize() = 0; } private: - container_internal::CompressedTuple<A, Pointer<A>> allocator_data_; - SizeType<A> size_; + container_internal::CompressedTuple<A, Pointer<A>> allocator_data_; + SizeType<A> size_; }; template <typename T, size_t N, typename A> class Storage { public: - static SizeType<A> NextCapacity(SizeType<A> current_capacity) { + static SizeType<A> NextCapacity(SizeType<A> current_capacity) { return current_capacity * 2; } - static SizeType<A> ComputeCapacity(SizeType<A> current_capacity, - SizeType<A> requested_capacity) { + static SizeType<A> ComputeCapacity(SizeType<A> current_capacity, + SizeType<A> requested_capacity) { return (std::max)(NextCapacity(current_capacity), requested_capacity); } @@ -297,15 +297,15 @@ class Storage { // Storage Constructors and Destructor // --------------------------------------------------------------------------- - Storage() : metadata_(A(), /* size and is_allocated */ 0) {} + Storage() : metadata_(A(), /* size and is_allocated */ 0) {} - explicit Storage(const A& allocator) - : metadata_(allocator, /* size and is_allocated */ 0) {} + explicit Storage(const A& allocator) + : metadata_(allocator, /* size and is_allocated */ 0) {} ~Storage() { if (GetSizeAndIsAllocated() == 0) { // Empty and not allocated; nothing to do. - } else if (IsMemcpyOk<A>::value) { + } else if (IsMemcpyOk<A>::value) { // No destructors need to be run; just deallocate if necessary. DeallocateIfAllocated(); } else { @@ -317,48 +317,48 @@ class Storage { // Storage Member Accessors // --------------------------------------------------------------------------- - SizeType<A>& GetSizeAndIsAllocated() { return metadata_.template get<1>(); } + SizeType<A>& GetSizeAndIsAllocated() { return metadata_.template get<1>(); } - const SizeType<A>& GetSizeAndIsAllocated() const { + const SizeType<A>& GetSizeAndIsAllocated() const { return metadata_.template get<1>(); } - SizeType<A> GetSize() const { return GetSizeAndIsAllocated() >> 1; } + SizeType<A> GetSize() const { return GetSizeAndIsAllocated() >> 1; } bool GetIsAllocated() const { return GetSizeAndIsAllocated() & 1; } - Pointer<A> GetAllocatedData() { return data_.allocated.allocated_data; } + Pointer<A> GetAllocatedData() { return data_.allocated.allocated_data; } - ConstPointer<A> GetAllocatedData() const { + ConstPointer<A> GetAllocatedData() const { return data_.allocated.allocated_data; } - Pointer<A> GetInlinedData() { - return reinterpret_cast<Pointer<A>>( + Pointer<A> GetInlinedData() { + return reinterpret_cast<Pointer<A>>( std::addressof(data_.inlined.inlined_data[0])); } - ConstPointer<A> GetInlinedData() const { - return reinterpret_cast<ConstPointer<A>>( + ConstPointer<A> GetInlinedData() const { + return reinterpret_cast<ConstPointer<A>>( std::addressof(data_.inlined.inlined_data[0])); } - SizeType<A> GetAllocatedCapacity() const { + SizeType<A> GetAllocatedCapacity() const { return data_.allocated.allocated_capacity; } - SizeType<A> GetInlinedCapacity() const { return static_cast<SizeType<A>>(N); } + SizeType<A> GetInlinedCapacity() const { return static_cast<SizeType<A>>(N); } - StorageView<A> MakeStorageView() { - return GetIsAllocated() ? StorageView<A>{GetAllocatedData(), GetSize(), - GetAllocatedCapacity()} - : StorageView<A>{GetInlinedData(), GetSize(), - GetInlinedCapacity()}; + StorageView<A> MakeStorageView() { + return GetIsAllocated() ? StorageView<A>{GetAllocatedData(), GetSize(), + GetAllocatedCapacity()} + : StorageView<A>{GetInlinedData(), GetSize(), + GetInlinedCapacity()}; } - A& GetAllocator() { return metadata_.template get<0>(); } + A& GetAllocator() { return metadata_.template get<0>(); } - const A& GetAllocator() const { return metadata_.template get<0>(); } + const A& GetAllocator() const { return metadata_.template get<0>(); } // --------------------------------------------------------------------------- // Storage Member Mutators @@ -367,67 +367,67 @@ class Storage { ABSL_ATTRIBUTE_NOINLINE void InitFrom(const Storage& other); template <typename ValueAdapter> - void Initialize(ValueAdapter values, SizeType<A> new_size); + void Initialize(ValueAdapter values, SizeType<A> new_size); template <typename ValueAdapter> - void Assign(ValueAdapter values, SizeType<A> new_size); + void Assign(ValueAdapter values, SizeType<A> new_size); template <typename ValueAdapter> - void Resize(ValueAdapter values, SizeType<A> new_size); + void Resize(ValueAdapter values, SizeType<A> new_size); template <typename ValueAdapter> - Iterator<A> Insert(ConstIterator<A> pos, ValueAdapter values, - SizeType<A> insert_count); + Iterator<A> Insert(ConstIterator<A> pos, ValueAdapter values, + SizeType<A> insert_count); template <typename... Args> - Reference<A> EmplaceBack(Args&&... args); + Reference<A> EmplaceBack(Args&&... args); - Iterator<A> Erase(ConstIterator<A> from, ConstIterator<A> to); + Iterator<A> Erase(ConstIterator<A> from, ConstIterator<A> to); - void Reserve(SizeType<A> requested_capacity); + void Reserve(SizeType<A> requested_capacity); void ShrinkToFit(); void Swap(Storage* other_storage_ptr); void SetIsAllocated() { - GetSizeAndIsAllocated() |= static_cast<SizeType<A>>(1); + GetSizeAndIsAllocated() |= static_cast<SizeType<A>>(1); } void UnsetIsAllocated() { - GetSizeAndIsAllocated() &= ((std::numeric_limits<SizeType<A>>::max)() - 1); + GetSizeAndIsAllocated() &= ((std::numeric_limits<SizeType<A>>::max)() - 1); } - void SetSize(SizeType<A> size) { + void SetSize(SizeType<A> size) { GetSizeAndIsAllocated() = - (size << 1) | static_cast<SizeType<A>>(GetIsAllocated()); + (size << 1) | static_cast<SizeType<A>>(GetIsAllocated()); } - void SetAllocatedSize(SizeType<A> size) { - GetSizeAndIsAllocated() = (size << 1) | static_cast<SizeType<A>>(1); + void SetAllocatedSize(SizeType<A> size) { + GetSizeAndIsAllocated() = (size << 1) | static_cast<SizeType<A>>(1); } - void SetInlinedSize(SizeType<A> size) { - GetSizeAndIsAllocated() = size << static_cast<SizeType<A>>(1); + void SetInlinedSize(SizeType<A> size) { + GetSizeAndIsAllocated() = size << static_cast<SizeType<A>>(1); } - void AddSize(SizeType<A> count) { - GetSizeAndIsAllocated() += count << static_cast<SizeType<A>>(1); + void AddSize(SizeType<A> count) { + GetSizeAndIsAllocated() += count << static_cast<SizeType<A>>(1); } - void SubtractSize(SizeType<A> count) { + void SubtractSize(SizeType<A> count) { assert(count <= GetSize()); - GetSizeAndIsAllocated() -= count << static_cast<SizeType<A>>(1); + GetSizeAndIsAllocated() -= count << static_cast<SizeType<A>>(1); } - void SetAllocation(Allocation<A> allocation) { - data_.allocated.allocated_data = allocation.data; - data_.allocated.allocated_capacity = allocation.capacity; + void SetAllocation(Allocation<A> allocation) { + data_.allocated.allocated_data = allocation.data; + data_.allocated.allocated_capacity = allocation.capacity; } void MemcpyFrom(const Storage& other_storage) { - assert(IsMemcpyOk<A>::value || other_storage.GetIsAllocated()); + assert(IsMemcpyOk<A>::value || other_storage.GetIsAllocated()); GetSizeAndIsAllocated() = other_storage.GetSizeAndIsAllocated(); data_ = other_storage.data_; @@ -435,23 +435,23 @@ class Storage { void DeallocateIfAllocated() { if (GetIsAllocated()) { - MallocAdapter<A>::Deallocate(GetAllocator(), GetAllocatedData(), - GetAllocatedCapacity()); + MallocAdapter<A>::Deallocate(GetAllocator(), GetAllocatedData(), + GetAllocatedCapacity()); } } private: ABSL_ATTRIBUTE_NOINLINE void DestroyContents(); - using Metadata = container_internal::CompressedTuple<A, SizeType<A>>; + using Metadata = container_internal::CompressedTuple<A, SizeType<A>>; struct Allocated { - Pointer<A> allocated_data; - SizeType<A> allocated_capacity; + Pointer<A> allocated_data; + SizeType<A> allocated_capacity; }; struct Inlined { - alignas(ValueType<A>) char inlined_data[sizeof(ValueType<A>[N])]; + alignas(ValueType<A>) char inlined_data[sizeof(ValueType<A>[N])]; }; union Data { @@ -460,7 +460,7 @@ class Storage { }; template <typename... Args> - ABSL_ATTRIBUTE_NOINLINE Reference<A> EmplaceBackSlow(Args&&... args); + ABSL_ATTRIBUTE_NOINLINE Reference<A> EmplaceBackSlow(Args&&... args); Metadata metadata_; Data data_; @@ -468,17 +468,17 @@ class Storage { template <typename T, size_t N, typename A> void Storage<T, N, A>::DestroyContents() { - Pointer<A> data = GetIsAllocated() ? GetAllocatedData() : GetInlinedData(); - DestroyElements<A>(GetAllocator(), data, GetSize()); + Pointer<A> data = GetIsAllocated() ? GetAllocatedData() : GetInlinedData(); + DestroyElements<A>(GetAllocator(), data, GetSize()); DeallocateIfAllocated(); } template <typename T, size_t N, typename A> void Storage<T, N, A>::InitFrom(const Storage& other) { - const SizeType<A> n = other.GetSize(); + const SizeType<A> n = other.GetSize(); assert(n > 0); // Empty sources handled handled in caller. - ConstPointer<A> src; - Pointer<A> dst; + ConstPointer<A> src; + Pointer<A> dst; if (!other.GetIsAllocated()) { dst = GetInlinedData(); src = other.GetInlinedData(); @@ -486,48 +486,48 @@ void Storage<T, N, A>::InitFrom(const Storage& other) { // Because this is only called from the `InlinedVector` constructors, it's // safe to take on the allocation with size `0`. If `ConstructElements(...)` // throws, deallocation will be automatically handled by `~Storage()`. - SizeType<A> requested_capacity = ComputeCapacity(GetInlinedCapacity(), n); - Allocation<A> allocation = - MallocAdapter<A>::Allocate(GetAllocator(), requested_capacity); - SetAllocation(allocation); - dst = allocation.data; + SizeType<A> requested_capacity = ComputeCapacity(GetInlinedCapacity(), n); + Allocation<A> allocation = + MallocAdapter<A>::Allocate(GetAllocator(), requested_capacity); + SetAllocation(allocation); + dst = allocation.data; src = other.GetAllocatedData(); } - if (IsMemcpyOk<A>::value) { - std::memcpy(reinterpret_cast<char*>(dst), - reinterpret_cast<const char*>(src), n * sizeof(ValueType<A>)); + if (IsMemcpyOk<A>::value) { + std::memcpy(reinterpret_cast<char*>(dst), + reinterpret_cast<const char*>(src), n * sizeof(ValueType<A>)); } else { - auto values = IteratorValueAdapter<A, ConstPointer<A>>(src); - ConstructElements<A>(GetAllocator(), dst, values, n); + auto values = IteratorValueAdapter<A, ConstPointer<A>>(src); + ConstructElements<A>(GetAllocator(), dst, values, n); } GetSizeAndIsAllocated() = other.GetSizeAndIsAllocated(); } template <typename T, size_t N, typename A> template <typename ValueAdapter> -auto Storage<T, N, A>::Initialize(ValueAdapter values, SizeType<A> new_size) +auto Storage<T, N, A>::Initialize(ValueAdapter values, SizeType<A> new_size) -> void { // Only callable from constructors! assert(!GetIsAllocated()); assert(GetSize() == 0); - Pointer<A> construct_data; + Pointer<A> construct_data; if (new_size > GetInlinedCapacity()) { // Because this is only called from the `InlinedVector` constructors, it's // safe to take on the allocation with size `0`. If `ConstructElements(...)` // throws, deallocation will be automatically handled by `~Storage()`. - SizeType<A> requested_capacity = - ComputeCapacity(GetInlinedCapacity(), new_size); - Allocation<A> allocation = - MallocAdapter<A>::Allocate(GetAllocator(), requested_capacity); - construct_data = allocation.data; - SetAllocation(allocation); + SizeType<A> requested_capacity = + ComputeCapacity(GetInlinedCapacity(), new_size); + Allocation<A> allocation = + MallocAdapter<A>::Allocate(GetAllocator(), requested_capacity); + construct_data = allocation.data; + SetAllocation(allocation); SetIsAllocated(); } else { construct_data = GetInlinedData(); } - ConstructElements<A>(GetAllocator(), construct_data, values, new_size); + ConstructElements<A>(GetAllocator(), construct_data, values, new_size); // Since the initial size was guaranteed to be `0` and the allocated bit is // already correct for either case, *adding* `new_size` gives us the correct @@ -537,20 +537,20 @@ auto Storage<T, N, A>::Initialize(ValueAdapter values, SizeType<A> new_size) template <typename T, size_t N, typename A> template <typename ValueAdapter> -auto Storage<T, N, A>::Assign(ValueAdapter values, SizeType<A> new_size) - -> void { - StorageView<A> storage_view = MakeStorageView(); +auto Storage<T, N, A>::Assign(ValueAdapter values, SizeType<A> new_size) + -> void { + StorageView<A> storage_view = MakeStorageView(); - AllocationTransaction<A> allocation_tx(GetAllocator()); + AllocationTransaction<A> allocation_tx(GetAllocator()); - absl::Span<ValueType<A>> assign_loop; - absl::Span<ValueType<A>> construct_loop; - absl::Span<ValueType<A>> destroy_loop; + absl::Span<ValueType<A>> assign_loop; + absl::Span<ValueType<A>> construct_loop; + absl::Span<ValueType<A>> destroy_loop; if (new_size > storage_view.capacity) { - SizeType<A> requested_capacity = - ComputeCapacity(storage_view.capacity, new_size); - construct_loop = {allocation_tx.Allocate(requested_capacity), new_size}; + SizeType<A> requested_capacity = + ComputeCapacity(storage_view.capacity, new_size); + construct_loop = {allocation_tx.Allocate(requested_capacity), new_size}; destroy_loop = {storage_view.data, storage_view.size}; } else if (new_size > storage_view.size) { assign_loop = {storage_view.data, storage_view.size}; @@ -561,16 +561,16 @@ auto Storage<T, N, A>::Assign(ValueAdapter values, SizeType<A> new_size) destroy_loop = {storage_view.data + new_size, storage_view.size - new_size}; } - AssignElements<A>(assign_loop.data(), values, assign_loop.size()); + AssignElements<A>(assign_loop.data(), values, assign_loop.size()); - ConstructElements<A>(GetAllocator(), construct_loop.data(), values, - construct_loop.size()); + ConstructElements<A>(GetAllocator(), construct_loop.data(), values, + construct_loop.size()); - DestroyElements<A>(GetAllocator(), destroy_loop.data(), destroy_loop.size()); + DestroyElements<A>(GetAllocator(), destroy_loop.data(), destroy_loop.size()); if (allocation_tx.DidAllocate()) { DeallocateIfAllocated(); - SetAllocation(std::move(allocation_tx).Release()); + SetAllocation(std::move(allocation_tx).Release()); SetIsAllocated(); } @@ -579,18 +579,18 @@ auto Storage<T, N, A>::Assign(ValueAdapter values, SizeType<A> new_size) template <typename T, size_t N, typename A> template <typename ValueAdapter> -auto Storage<T, N, A>::Resize(ValueAdapter values, SizeType<A> new_size) - -> void { - StorageView<A> storage_view = MakeStorageView(); - Pointer<A> const base = storage_view.data; - const SizeType<A> size = storage_view.size; - A& alloc = GetAllocator(); +auto Storage<T, N, A>::Resize(ValueAdapter values, SizeType<A> new_size) + -> void { + StorageView<A> storage_view = MakeStorageView(); + Pointer<A> const base = storage_view.data; + const SizeType<A> size = storage_view.size; + A& alloc = GetAllocator(); if (new_size <= size) { // Destroy extra old elements. - DestroyElements<A>(alloc, base + new_size, size - new_size); + DestroyElements<A>(alloc, base + new_size, size - new_size); } else if (new_size <= storage_view.capacity) { // Construct new elements in place. - ConstructElements<A>(alloc, base + size, values, new_size - size); + ConstructElements<A>(alloc, base + size, values, new_size - size); } else { // Steps: // a. Allocate new backing store. @@ -599,22 +599,22 @@ auto Storage<T, N, A>::Resize(ValueAdapter values, SizeType<A> new_size) // d. Destroy all elements in old backing store. // Use transactional wrappers for the first two steps so we can roll // back if necessary due to exceptions. - AllocationTransaction<A> allocation_tx(alloc); - SizeType<A> requested_capacity = - ComputeCapacity(storage_view.capacity, new_size); - Pointer<A> new_data = allocation_tx.Allocate(requested_capacity); + AllocationTransaction<A> allocation_tx(alloc); + SizeType<A> requested_capacity = + ComputeCapacity(storage_view.capacity, new_size); + Pointer<A> new_data = allocation_tx.Allocate(requested_capacity); - ConstructionTransaction<A> construction_tx(alloc); - construction_tx.Construct(new_data + size, values, new_size - size); + ConstructionTransaction<A> construction_tx(alloc); + construction_tx.Construct(new_data + size, values, new_size - size); - IteratorValueAdapter<A, MoveIterator<A>> move_values( - (MoveIterator<A>(base))); - ConstructElements<A>(alloc, new_data, move_values, size); + IteratorValueAdapter<A, MoveIterator<A>> move_values( + (MoveIterator<A>(base))); + ConstructElements<A>(alloc, new_data, move_values, size); - DestroyElements<A>(alloc, base, size); - std::move(construction_tx).Commit(); + DestroyElements<A>(alloc, base, size); + std::move(construction_tx).Commit(); DeallocateIfAllocated(); - SetAllocation(std::move(allocation_tx).Release()); + SetAllocation(std::move(allocation_tx).Release()); SetIsAllocated(); } SetSize(new_size); @@ -622,76 +622,76 @@ auto Storage<T, N, A>::Resize(ValueAdapter values, SizeType<A> new_size) template <typename T, size_t N, typename A> template <typename ValueAdapter> -auto Storage<T, N, A>::Insert(ConstIterator<A> pos, ValueAdapter values, - SizeType<A> insert_count) -> Iterator<A> { - StorageView<A> storage_view = MakeStorageView(); +auto Storage<T, N, A>::Insert(ConstIterator<A> pos, ValueAdapter values, + SizeType<A> insert_count) -> Iterator<A> { + StorageView<A> storage_view = MakeStorageView(); - SizeType<A> insert_index = - std::distance(ConstIterator<A>(storage_view.data), pos); - SizeType<A> insert_end_index = insert_index + insert_count; - SizeType<A> new_size = storage_view.size + insert_count; + SizeType<A> insert_index = + std::distance(ConstIterator<A>(storage_view.data), pos); + SizeType<A> insert_end_index = insert_index + insert_count; + SizeType<A> new_size = storage_view.size + insert_count; if (new_size > storage_view.capacity) { - AllocationTransaction<A> allocation_tx(GetAllocator()); - ConstructionTransaction<A> construction_tx(GetAllocator()); - ConstructionTransaction<A> move_construction_tx(GetAllocator()); + AllocationTransaction<A> allocation_tx(GetAllocator()); + ConstructionTransaction<A> construction_tx(GetAllocator()); + ConstructionTransaction<A> move_construction_tx(GetAllocator()); - IteratorValueAdapter<A, MoveIterator<A>> move_values( - MoveIterator<A>(storage_view.data)); + IteratorValueAdapter<A, MoveIterator<A>> move_values( + MoveIterator<A>(storage_view.data)); - SizeType<A> requested_capacity = - ComputeCapacity(storage_view.capacity, new_size); - Pointer<A> new_data = allocation_tx.Allocate(requested_capacity); + SizeType<A> requested_capacity = + ComputeCapacity(storage_view.capacity, new_size); + Pointer<A> new_data = allocation_tx.Allocate(requested_capacity); - construction_tx.Construct(new_data + insert_index, values, insert_count); + construction_tx.Construct(new_data + insert_index, values, insert_count); - move_construction_tx.Construct(new_data, move_values, insert_index); + move_construction_tx.Construct(new_data, move_values, insert_index); - ConstructElements<A>(GetAllocator(), new_data + insert_end_index, - move_values, storage_view.size - insert_index); + ConstructElements<A>(GetAllocator(), new_data + insert_end_index, + move_values, storage_view.size - insert_index); - DestroyElements<A>(GetAllocator(), storage_view.data, storage_view.size); + DestroyElements<A>(GetAllocator(), storage_view.data, storage_view.size); - std::move(construction_tx).Commit(); - std::move(move_construction_tx).Commit(); + std::move(construction_tx).Commit(); + std::move(move_construction_tx).Commit(); DeallocateIfAllocated(); - SetAllocation(std::move(allocation_tx).Release()); + SetAllocation(std::move(allocation_tx).Release()); SetAllocatedSize(new_size); - return Iterator<A>(new_data + insert_index); + return Iterator<A>(new_data + insert_index); } else { - SizeType<A> move_construction_destination_index = + SizeType<A> move_construction_destination_index = (std::max)(insert_end_index, storage_view.size); - ConstructionTransaction<A> move_construction_tx(GetAllocator()); + ConstructionTransaction<A> move_construction_tx(GetAllocator()); - IteratorValueAdapter<A, MoveIterator<A>> move_construction_values( - MoveIterator<A>(storage_view.data + - (move_construction_destination_index - insert_count))); - absl::Span<ValueType<A>> move_construction = { + IteratorValueAdapter<A, MoveIterator<A>> move_construction_values( + MoveIterator<A>(storage_view.data + + (move_construction_destination_index - insert_count))); + absl::Span<ValueType<A>> move_construction = { storage_view.data + move_construction_destination_index, new_size - move_construction_destination_index}; - Pointer<A> move_assignment_values = storage_view.data + insert_index; - absl::Span<ValueType<A>> move_assignment = { + Pointer<A> move_assignment_values = storage_view.data + insert_index; + absl::Span<ValueType<A>> move_assignment = { storage_view.data + insert_end_index, move_construction_destination_index - insert_end_index}; - absl::Span<ValueType<A>> insert_assignment = {move_assignment_values, - move_construction.size()}; + absl::Span<ValueType<A>> insert_assignment = {move_assignment_values, + move_construction.size()}; - absl::Span<ValueType<A>> insert_construction = { + absl::Span<ValueType<A>> insert_construction = { insert_assignment.data() + insert_assignment.size(), insert_count - insert_assignment.size()}; move_construction_tx.Construct(move_construction.data(), - move_construction_values, + move_construction_values, move_construction.size()); - for (Pointer<A> - destination = move_assignment.data() + move_assignment.size(), - last_destination = move_assignment.data(), - source = move_assignment_values + move_assignment.size(); + for (Pointer<A> + destination = move_assignment.data() + move_assignment.size(), + last_destination = move_assignment.data(), + source = move_assignment_values + move_assignment.size(); ;) { --destination; --source; @@ -699,29 +699,29 @@ auto Storage<T, N, A>::Insert(ConstIterator<A> pos, ValueAdapter values, *destination = std::move(*source); } - AssignElements<A>(insert_assignment.data(), values, - insert_assignment.size()); + AssignElements<A>(insert_assignment.data(), values, + insert_assignment.size()); - ConstructElements<A>(GetAllocator(), insert_construction.data(), values, - insert_construction.size()); + ConstructElements<A>(GetAllocator(), insert_construction.data(), values, + insert_construction.size()); - std::move(move_construction_tx).Commit(); + std::move(move_construction_tx).Commit(); AddSize(insert_count); - return Iterator<A>(storage_view.data + insert_index); + return Iterator<A>(storage_view.data + insert_index); } } template <typename T, size_t N, typename A> template <typename... Args> -auto Storage<T, N, A>::EmplaceBack(Args&&... args) -> Reference<A> { - StorageView<A> storage_view = MakeStorageView(); - const SizeType<A> n = storage_view.size; +auto Storage<T, N, A>::EmplaceBack(Args&&... args) -> Reference<A> { + StorageView<A> storage_view = MakeStorageView(); + const SizeType<A> n = storage_view.size; if (ABSL_PREDICT_TRUE(n != storage_view.capacity)) { // Fast path; new element fits. - Pointer<A> last_ptr = storage_view.data + n; - AllocatorTraits<A>::construct(GetAllocator(), last_ptr, - std::forward<Args>(args)...); + Pointer<A> last_ptr = storage_view.data + n; + AllocatorTraits<A>::construct(GetAllocator(), last_ptr, + std::forward<Args>(args)...); AddSize(1); return *last_ptr; } @@ -731,83 +731,83 @@ auto Storage<T, N, A>::EmplaceBack(Args&&... args) -> Reference<A> { template <typename T, size_t N, typename A> template <typename... Args> -auto Storage<T, N, A>::EmplaceBackSlow(Args&&... args) -> Reference<A> { - StorageView<A> storage_view = MakeStorageView(); - AllocationTransaction<A> allocation_tx(GetAllocator()); - IteratorValueAdapter<A, MoveIterator<A>> move_values( - MoveIterator<A>(storage_view.data)); - SizeType<A> requested_capacity = NextCapacity(storage_view.capacity); - Pointer<A> construct_data = allocation_tx.Allocate(requested_capacity); - Pointer<A> last_ptr = construct_data + storage_view.size; +auto Storage<T, N, A>::EmplaceBackSlow(Args&&... args) -> Reference<A> { + StorageView<A> storage_view = MakeStorageView(); + AllocationTransaction<A> allocation_tx(GetAllocator()); + IteratorValueAdapter<A, MoveIterator<A>> move_values( + MoveIterator<A>(storage_view.data)); + SizeType<A> requested_capacity = NextCapacity(storage_view.capacity); + Pointer<A> construct_data = allocation_tx.Allocate(requested_capacity); + Pointer<A> last_ptr = construct_data + storage_view.size; // Construct new element. - AllocatorTraits<A>::construct(GetAllocator(), last_ptr, - std::forward<Args>(args)...); + AllocatorTraits<A>::construct(GetAllocator(), last_ptr, + std::forward<Args>(args)...); // Move elements from old backing store to new backing store. ABSL_INTERNAL_TRY { - ConstructElements<A>(GetAllocator(), allocation_tx.GetData(), move_values, - storage_view.size); + ConstructElements<A>(GetAllocator(), allocation_tx.GetData(), move_values, + storage_view.size); } ABSL_INTERNAL_CATCH_ANY { - AllocatorTraits<A>::destroy(GetAllocator(), last_ptr); + AllocatorTraits<A>::destroy(GetAllocator(), last_ptr); ABSL_INTERNAL_RETHROW; } // Destroy elements in old backing store. - DestroyElements<A>(GetAllocator(), storage_view.data, storage_view.size); + DestroyElements<A>(GetAllocator(), storage_view.data, storage_view.size); DeallocateIfAllocated(); - SetAllocation(std::move(allocation_tx).Release()); + SetAllocation(std::move(allocation_tx).Release()); SetIsAllocated(); AddSize(1); return *last_ptr; } template <typename T, size_t N, typename A> -auto Storage<T, N, A>::Erase(ConstIterator<A> from, ConstIterator<A> to) - -> Iterator<A> { - StorageView<A> storage_view = MakeStorageView(); +auto Storage<T, N, A>::Erase(ConstIterator<A> from, ConstIterator<A> to) + -> Iterator<A> { + StorageView<A> storage_view = MakeStorageView(); - SizeType<A> erase_size = std::distance(from, to); - SizeType<A> erase_index = - std::distance(ConstIterator<A>(storage_view.data), from); - SizeType<A> erase_end_index = erase_index + erase_size; + SizeType<A> erase_size = std::distance(from, to); + SizeType<A> erase_index = + std::distance(ConstIterator<A>(storage_view.data), from); + SizeType<A> erase_end_index = erase_index + erase_size; - IteratorValueAdapter<A, MoveIterator<A>> move_values( - MoveIterator<A>(storage_view.data + erase_end_index)); + IteratorValueAdapter<A, MoveIterator<A>> move_values( + MoveIterator<A>(storage_view.data + erase_end_index)); - AssignElements<A>(storage_view.data + erase_index, move_values, - storage_view.size - erase_end_index); + AssignElements<A>(storage_view.data + erase_index, move_values, + storage_view.size - erase_end_index); - DestroyElements<A>(GetAllocator(), - storage_view.data + (storage_view.size - erase_size), - erase_size); + DestroyElements<A>(GetAllocator(), + storage_view.data + (storage_view.size - erase_size), + erase_size); SubtractSize(erase_size); - return Iterator<A>(storage_view.data + erase_index); + return Iterator<A>(storage_view.data + erase_index); } template <typename T, size_t N, typename A> -auto Storage<T, N, A>::Reserve(SizeType<A> requested_capacity) -> void { - StorageView<A> storage_view = MakeStorageView(); +auto Storage<T, N, A>::Reserve(SizeType<A> requested_capacity) -> void { + StorageView<A> storage_view = MakeStorageView(); if (ABSL_PREDICT_FALSE(requested_capacity <= storage_view.capacity)) return; - AllocationTransaction<A> allocation_tx(GetAllocator()); + AllocationTransaction<A> allocation_tx(GetAllocator()); - IteratorValueAdapter<A, MoveIterator<A>> move_values( - MoveIterator<A>(storage_view.data)); + IteratorValueAdapter<A, MoveIterator<A>> move_values( + MoveIterator<A>(storage_view.data)); - SizeType<A> new_requested_capacity = + SizeType<A> new_requested_capacity = ComputeCapacity(storage_view.capacity, requested_capacity); - Pointer<A> new_data = allocation_tx.Allocate(new_requested_capacity); + Pointer<A> new_data = allocation_tx.Allocate(new_requested_capacity); - ConstructElements<A>(GetAllocator(), new_data, move_values, - storage_view.size); + ConstructElements<A>(GetAllocator(), new_data, move_values, + storage_view.size); - DestroyElements<A>(GetAllocator(), storage_view.data, storage_view.size); + DestroyElements<A>(GetAllocator(), storage_view.data, storage_view.size); DeallocateIfAllocated(); - SetAllocation(std::move(allocation_tx).Release()); + SetAllocation(std::move(allocation_tx).Release()); SetIsAllocated(); } @@ -816,44 +816,44 @@ auto Storage<T, N, A>::ShrinkToFit() -> void { // May only be called on allocated instances! assert(GetIsAllocated()); - StorageView<A> storage_view{GetAllocatedData(), GetSize(), - GetAllocatedCapacity()}; + StorageView<A> storage_view{GetAllocatedData(), GetSize(), + GetAllocatedCapacity()}; if (ABSL_PREDICT_FALSE(storage_view.size == storage_view.capacity)) return; - AllocationTransaction<A> allocation_tx(GetAllocator()); + AllocationTransaction<A> allocation_tx(GetAllocator()); - IteratorValueAdapter<A, MoveIterator<A>> move_values( - MoveIterator<A>(storage_view.data)); + IteratorValueAdapter<A, MoveIterator<A>> move_values( + MoveIterator<A>(storage_view.data)); - Pointer<A> construct_data; + Pointer<A> construct_data; if (storage_view.size > GetInlinedCapacity()) { - SizeType<A> requested_capacity = storage_view.size; - construct_data = allocation_tx.Allocate(requested_capacity); - if (allocation_tx.GetCapacity() >= storage_view.capacity) { - // Already using the smallest available heap allocation. - return; - } + SizeType<A> requested_capacity = storage_view.size; + construct_data = allocation_tx.Allocate(requested_capacity); + if (allocation_tx.GetCapacity() >= storage_view.capacity) { + // Already using the smallest available heap allocation. + return; + } } else { construct_data = GetInlinedData(); } ABSL_INTERNAL_TRY { - ConstructElements<A>(GetAllocator(), construct_data, move_values, - storage_view.size); + ConstructElements<A>(GetAllocator(), construct_data, move_values, + storage_view.size); } ABSL_INTERNAL_CATCH_ANY { - SetAllocation({storage_view.data, storage_view.capacity}); + SetAllocation({storage_view.data, storage_view.capacity}); ABSL_INTERNAL_RETHROW; } - DestroyElements<A>(GetAllocator(), storage_view.data, storage_view.size); + DestroyElements<A>(GetAllocator(), storage_view.data, storage_view.size); - MallocAdapter<A>::Deallocate(GetAllocator(), storage_view.data, - storage_view.capacity); + MallocAdapter<A>::Deallocate(GetAllocator(), storage_view.data, + storage_view.capacity); if (allocation_tx.DidAllocate()) { - SetAllocation(std::move(allocation_tx).Release()); + SetAllocation(std::move(allocation_tx).Release()); } else { UnsetIsAllocated(); } @@ -871,56 +871,56 @@ auto Storage<T, N, A>::Swap(Storage* other_storage_ptr) -> void { Storage* large_ptr = other_storage_ptr; if (small_ptr->GetSize() > large_ptr->GetSize()) swap(small_ptr, large_ptr); - for (SizeType<A> i = 0; i < small_ptr->GetSize(); ++i) { + for (SizeType<A> i = 0; i < small_ptr->GetSize(); ++i) { swap(small_ptr->GetInlinedData()[i], large_ptr->GetInlinedData()[i]); } - IteratorValueAdapter<A, MoveIterator<A>> move_values( - MoveIterator<A>(large_ptr->GetInlinedData() + small_ptr->GetSize())); + IteratorValueAdapter<A, MoveIterator<A>> move_values( + MoveIterator<A>(large_ptr->GetInlinedData() + small_ptr->GetSize())); - ConstructElements<A>(large_ptr->GetAllocator(), - small_ptr->GetInlinedData() + small_ptr->GetSize(), - move_values, - large_ptr->GetSize() - small_ptr->GetSize()); + ConstructElements<A>(large_ptr->GetAllocator(), + small_ptr->GetInlinedData() + small_ptr->GetSize(), + move_values, + large_ptr->GetSize() - small_ptr->GetSize()); - DestroyElements<A>(large_ptr->GetAllocator(), - large_ptr->GetInlinedData() + small_ptr->GetSize(), - large_ptr->GetSize() - small_ptr->GetSize()); + DestroyElements<A>(large_ptr->GetAllocator(), + large_ptr->GetInlinedData() + small_ptr->GetSize(), + large_ptr->GetSize() - small_ptr->GetSize()); } else { Storage* allocated_ptr = this; Storage* inlined_ptr = other_storage_ptr; if (!allocated_ptr->GetIsAllocated()) swap(allocated_ptr, inlined_ptr); - StorageView<A> allocated_storage_view{ - allocated_ptr->GetAllocatedData(), allocated_ptr->GetSize(), - allocated_ptr->GetAllocatedCapacity()}; + StorageView<A> allocated_storage_view{ + allocated_ptr->GetAllocatedData(), allocated_ptr->GetSize(), + allocated_ptr->GetAllocatedCapacity()}; - IteratorValueAdapter<A, MoveIterator<A>> move_values( - MoveIterator<A>(inlined_ptr->GetInlinedData())); + IteratorValueAdapter<A, MoveIterator<A>> move_values( + MoveIterator<A>(inlined_ptr->GetInlinedData())); ABSL_INTERNAL_TRY { - ConstructElements<A>(inlined_ptr->GetAllocator(), - allocated_ptr->GetInlinedData(), move_values, - inlined_ptr->GetSize()); + ConstructElements<A>(inlined_ptr->GetAllocator(), + allocated_ptr->GetInlinedData(), move_values, + inlined_ptr->GetSize()); } ABSL_INTERNAL_CATCH_ANY { - allocated_ptr->SetAllocation( - {allocated_storage_view.data, allocated_storage_view.capacity}); + allocated_ptr->SetAllocation( + {allocated_storage_view.data, allocated_storage_view.capacity}); ABSL_INTERNAL_RETHROW; } - DestroyElements<A>(inlined_ptr->GetAllocator(), - inlined_ptr->GetInlinedData(), inlined_ptr->GetSize()); + DestroyElements<A>(inlined_ptr->GetAllocator(), + inlined_ptr->GetInlinedData(), inlined_ptr->GetSize()); - inlined_ptr->SetAllocation( - {allocated_storage_view.data, allocated_storage_view.capacity}); + inlined_ptr->SetAllocation( + {allocated_storage_view.data, allocated_storage_view.capacity}); } swap(GetSizeAndIsAllocated(), other_storage_ptr->GetSizeAndIsAllocated()); - swap(GetAllocator(), other_storage_ptr->GetAllocator()); + swap(GetAllocator(), other_storage_ptr->GetAllocator()); } -// End ignore "array-bounds" and "maybe-uninitialized" +// End ignore "array-bounds" and "maybe-uninitialized" #if !defined(__clang__) && defined(__GNUC__) #pragma GCC diagnostic pop #endif diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_map.h b/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_map.h index c7df2efc62..3722cddb64 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_map.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_map.h @@ -51,9 +51,9 @@ class raw_hash_map : public raw_hash_set<Policy, Hash, Eq, Alloc> { using key_arg = typename KeyArgImpl::template type<K, key_type>; static_assert(!std::is_reference<key_type>::value, ""); - - // TODO(b/187807849): Evaluate whether to support reference mapped_type and - // remove this assertion if/when it is supported. + + // TODO(b/187807849): Evaluate whether to support reference mapped_type and + // remove this assertion if/when it is supported. static_assert(!std::is_reference<mapped_type>::value, ""); using iterator = typename raw_hash_map::raw_hash_set::iterator; diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set.cc b/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set.cc index 687bcb8a4d..8173b7fcdb 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set.cc +++ b/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set.cc @@ -23,12 +23,12 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace container_internal { -alignas(16) ABSL_CONST_INIT ABSL_DLL const ctrl_t kEmptyGroup[16] = { - ctrl_t::kSentinel, ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, - ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, - ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, - ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty}; - +alignas(16) ABSL_CONST_INIT ABSL_DLL const ctrl_t kEmptyGroup[16] = { + ctrl_t::kSentinel, ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, + ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, + ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, + ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty}; + constexpr size_t Group::kWidth; // Returns "random" seed. @@ -43,24 +43,24 @@ inline size_t RandomSeed() { return value ^ static_cast<size_t>(reinterpret_cast<uintptr_t>(&counter)); } -bool ShouldInsertBackwards(size_t hash, const ctrl_t* ctrl) { +bool ShouldInsertBackwards(size_t hash, const ctrl_t* ctrl) { // To avoid problems with weak hashes and single bit tests, we use % 13. // TODO(kfm,sbenza): revisit after we do unconditional mixing return (H1(hash, ctrl) ^ RandomSeed()) % 13 > 6; } -void ConvertDeletedToEmptyAndFullToDeleted(ctrl_t* ctrl, size_t capacity) { - assert(ctrl[capacity] == ctrl_t::kSentinel); +void ConvertDeletedToEmptyAndFullToDeleted(ctrl_t* ctrl, size_t capacity) { + assert(ctrl[capacity] == ctrl_t::kSentinel); assert(IsValidCapacity(capacity)); - for (ctrl_t* pos = ctrl; pos < ctrl + capacity; pos += Group::kWidth) { + for (ctrl_t* pos = ctrl; pos < ctrl + capacity; pos += Group::kWidth) { Group{pos}.ConvertSpecialToEmptyAndFullToDeleted(pos); } // Copy the cloned ctrl bytes. - std::memcpy(ctrl + capacity + 1, ctrl, NumClonedBytes()); - ctrl[capacity] = ctrl_t::kSentinel; + std::memcpy(ctrl + capacity + 1, ctrl, NumClonedBytes()); + ctrl[capacity] = ctrl_t::kSentinel; } -// Extern template instantiotion for inline function. -template FindInfo find_first_non_full(const ctrl_t*, size_t, size_t); +// Extern template instantiotion for inline function. +template FindInfo find_first_non_full(const ctrl_t*, size_t, size_t); } // namespace container_internal ABSL_NAMESPACE_END diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set.h b/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set.h index 12682b3532..fdda6ad9bf 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set.h @@ -87,17 +87,17 @@ // // This probing function guarantees that after N probes, all the groups of the // table will be probed exactly once. -// -// The control state and slot array are stored contiguously in a shared heap -// allocation. The layout of this allocation is: `capacity()` control bytes, -// one sentinel control byte, `Group::kWidth - 1` cloned control bytes, -// <possible padding>, `capacity()` slots. The sentinel control byte is used in -// iteration so we know when we reach the end of the table. The cloned control -// bytes at the end of the table are cloned from the beginning of the table so -// groups that begin near the end of the table can see a full group. In cases in -// which there are more than `capacity()` cloned control bytes, the extra bytes -// are `kEmpty`, and these ensure that we always see at least one empty slot and -// can stop an unsuccessful search. +// +// The control state and slot array are stored contiguously in a shared heap +// allocation. The layout of this allocation is: `capacity()` control bytes, +// one sentinel control byte, `Group::kWidth - 1` cloned control bytes, +// <possible padding>, `capacity()` slots. The sentinel control byte is used in +// iteration so we know when we reach the end of the table. The cloned control +// bytes at the end of the table are cloned from the beginning of the table so +// groups that begin near the end of the table can see a full group. In cases in +// which there are more than `capacity()` cloned control bytes, the extra bytes +// are `kEmpty`, and these ensure that we always see at least one empty slot and +// can stop an unsuccessful search. #ifndef ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_ #define ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_ @@ -265,50 +265,50 @@ class BitMask { using h2_t = uint8_t; // The values here are selected for maximum performance. See the static asserts -// below for details. We use an enum class so that when strict aliasing is -// enabled, the compiler knows ctrl_t doesn't alias other types. -enum class ctrl_t : int8_t { +// below for details. We use an enum class so that when strict aliasing is +// enabled, the compiler knows ctrl_t doesn't alias other types. +enum class ctrl_t : int8_t { kEmpty = -128, // 0b10000000 kDeleted = -2, // 0b11111110 kSentinel = -1, // 0b11111111 }; static_assert( - (static_cast<int8_t>(ctrl_t::kEmpty) & - static_cast<int8_t>(ctrl_t::kDeleted) & - static_cast<int8_t>(ctrl_t::kSentinel) & 0x80) != 0, + (static_cast<int8_t>(ctrl_t::kEmpty) & + static_cast<int8_t>(ctrl_t::kDeleted) & + static_cast<int8_t>(ctrl_t::kSentinel) & 0x80) != 0, "Special markers need to have the MSB to make checking for them efficient"); -static_assert( - ctrl_t::kEmpty < ctrl_t::kSentinel && ctrl_t::kDeleted < ctrl_t::kSentinel, - "ctrl_t::kEmpty and ctrl_t::kDeleted must be smaller than " - "ctrl_t::kSentinel to make the SIMD test of IsEmptyOrDeleted() efficient"); -static_assert( - ctrl_t::kSentinel == static_cast<ctrl_t>(-1), - "ctrl_t::kSentinel must be -1 to elide loading it from memory into SIMD " - "registers (pcmpeqd xmm, xmm)"); -static_assert(ctrl_t::kEmpty == static_cast<ctrl_t>(-128), - "ctrl_t::kEmpty must be -128 to make the SIMD check for its " +static_assert( + ctrl_t::kEmpty < ctrl_t::kSentinel && ctrl_t::kDeleted < ctrl_t::kSentinel, + "ctrl_t::kEmpty and ctrl_t::kDeleted must be smaller than " + "ctrl_t::kSentinel to make the SIMD test of IsEmptyOrDeleted() efficient"); +static_assert( + ctrl_t::kSentinel == static_cast<ctrl_t>(-1), + "ctrl_t::kSentinel must be -1 to elide loading it from memory into SIMD " + "registers (pcmpeqd xmm, xmm)"); +static_assert(ctrl_t::kEmpty == static_cast<ctrl_t>(-128), + "ctrl_t::kEmpty must be -128 to make the SIMD check for its " "existence efficient (psignb xmm, xmm)"); -static_assert( - (~static_cast<int8_t>(ctrl_t::kEmpty) & - ~static_cast<int8_t>(ctrl_t::kDeleted) & - static_cast<int8_t>(ctrl_t::kSentinel) & 0x7F) != 0, - "ctrl_t::kEmpty and ctrl_t::kDeleted must share an unset bit that is not " - "shared by ctrl_t::kSentinel to make the scalar test for " - "MatchEmptyOrDeleted() efficient"); -static_assert(ctrl_t::kDeleted == static_cast<ctrl_t>(-2), - "ctrl_t::kDeleted must be -2 to make the implementation of " +static_assert( + (~static_cast<int8_t>(ctrl_t::kEmpty) & + ~static_cast<int8_t>(ctrl_t::kDeleted) & + static_cast<int8_t>(ctrl_t::kSentinel) & 0x7F) != 0, + "ctrl_t::kEmpty and ctrl_t::kDeleted must share an unset bit that is not " + "shared by ctrl_t::kSentinel to make the scalar test for " + "MatchEmptyOrDeleted() efficient"); +static_assert(ctrl_t::kDeleted == static_cast<ctrl_t>(-2), + "ctrl_t::kDeleted must be -2 to make the implementation of " "ConvertSpecialToEmptyAndFullToDeleted efficient"); // A single block of empty control bytes for tables without any slots allocated. // This enables removing a branch in the hot path of find(). -ABSL_DLL extern const ctrl_t kEmptyGroup[16]; +ABSL_DLL extern const ctrl_t kEmptyGroup[16]; inline ctrl_t* EmptyGroup() { - return const_cast<ctrl_t*>(kEmptyGroup); + return const_cast<ctrl_t*>(kEmptyGroup); } // Mixes a randomly generated per-process seed with `hash` and `ctrl` to // randomize insertion order within groups. -bool ShouldInsertBackwards(size_t hash, const ctrl_t* ctrl); +bool ShouldInsertBackwards(size_t hash, const ctrl_t* ctrl); // Returns a hash seed. // @@ -324,12 +324,12 @@ inline size_t HashSeed(const ctrl_t* ctrl) { inline size_t H1(size_t hash, const ctrl_t* ctrl) { return (hash >> 7) ^ HashSeed(ctrl); } -inline h2_t H2(size_t hash) { return hash & 0x7F; } +inline h2_t H2(size_t hash) { return hash & 0x7F; } -inline bool IsEmpty(ctrl_t c) { return c == ctrl_t::kEmpty; } -inline bool IsFull(ctrl_t c) { return c >= static_cast<ctrl_t>(0); } -inline bool IsDeleted(ctrl_t c) { return c == ctrl_t::kDeleted; } -inline bool IsEmptyOrDeleted(ctrl_t c) { return c < ctrl_t::kSentinel; } +inline bool IsEmpty(ctrl_t c) { return c == ctrl_t::kEmpty; } +inline bool IsFull(ctrl_t c) { return c >= static_cast<ctrl_t>(0); } +inline bool IsDeleted(ctrl_t c) { return c == ctrl_t::kDeleted; } +inline bool IsEmptyOrDeleted(ctrl_t c) { return c < ctrl_t::kSentinel; } #if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 @@ -366,24 +366,24 @@ struct GroupSse2Impl { // Returns a bitmask representing the positions of empty slots. BitMask<uint32_t, kWidth> MatchEmpty() const { #if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 - // This only works because ctrl_t::kEmpty is -128. + // This only works because ctrl_t::kEmpty is -128. return BitMask<uint32_t, kWidth>( _mm_movemask_epi8(_mm_sign_epi8(ctrl, ctrl))); #else - return Match(static_cast<h2_t>(ctrl_t::kEmpty)); + return Match(static_cast<h2_t>(ctrl_t::kEmpty)); #endif } // Returns a bitmask representing the positions of empty or deleted slots. BitMask<uint32_t, kWidth> MatchEmptyOrDeleted() const { - auto special = _mm_set1_epi8(static_cast<int8_t>(ctrl_t::kSentinel)); + auto special = _mm_set1_epi8(static_cast<int8_t>(ctrl_t::kSentinel)); return BitMask<uint32_t, kWidth>( _mm_movemask_epi8(_mm_cmpgt_epi8_fixed(special, ctrl))); } // Returns the number of trailing empty or deleted elements in the group. uint32_t CountLeadingEmptyOrDeleted() const { - auto special = _mm_set1_epi8(static_cast<int8_t>(ctrl_t::kSentinel)); + auto special = _mm_set1_epi8(static_cast<int8_t>(ctrl_t::kSentinel)); return TrailingZeros(static_cast<uint32_t>( _mm_movemask_epi8(_mm_cmpgt_epi8_fixed(special, ctrl)) + 1)); } @@ -418,7 +418,7 @@ struct GroupPortableImpl { // // Caveat: there are false positives but: // - they only occur if there is a real match - // - they never occur on ctrl_t::kEmpty, ctrl_t::kDeleted, ctrl_t::kSentinel + // - they never occur on ctrl_t::kEmpty, ctrl_t::kDeleted, ctrl_t::kSentinel // - they will be handled gracefully by subsequent checks in code // // Example: @@ -463,10 +463,10 @@ using Group = GroupSse2Impl; using Group = GroupPortableImpl; #endif -// The number of cloned control bytes that we copy from the beginning to the -// end of the control bytes array. -constexpr size_t NumClonedBytes() { return Group::kWidth - 1; } - +// The number of cloned control bytes that we copy from the beginning to the +// end of the control bytes array. +constexpr size_t NumClonedBytes() { return Group::kWidth - 1; } + template <class Policy, class Hash, class Eq, class Alloc> class raw_hash_set; @@ -474,8 +474,8 @@ inline bool IsValidCapacity(size_t n) { return ((n + 1) & n) == 0 && n > 0; } // PRECONDITION: // IsValidCapacity(capacity) -// ctrl[capacity] == ctrl_t::kSentinel -// ctrl[i] != ctrl_t::kSentinel for all i < capacity +// ctrl[capacity] == ctrl_t::kSentinel +// ctrl[i] != ctrl_t::kSentinel for all i < capacity // Applies mapping for every byte in ctrl: // DELETED -> EMPTY // EMPTY -> EMPTY @@ -517,22 +517,22 @@ inline size_t GrowthToLowerboundCapacity(size_t growth) { return growth + static_cast<size_t>((static_cast<int64_t>(growth) - 1) / 7); } -template <class InputIter> -size_t SelectBucketCountForIterRange(InputIter first, InputIter last, - size_t bucket_count) { - if (bucket_count != 0) { - return bucket_count; - } - using InputIterCategory = - typename std::iterator_traits<InputIter>::iterator_category; - if (std::is_base_of<std::random_access_iterator_tag, - InputIterCategory>::value) { - return GrowthToLowerboundCapacity( - static_cast<size_t>(std::distance(first, last))); - } - return 0; -} - +template <class InputIter> +size_t SelectBucketCountForIterRange(InputIter first, InputIter last, + size_t bucket_count) { + if (bucket_count != 0) { + return bucket_count; + } + using InputIterCategory = + typename std::iterator_traits<InputIter>::iterator_category; + if (std::is_base_of<std::random_access_iterator_tag, + InputIterCategory>::value) { + return GrowthToLowerboundCapacity( + static_cast<size_t>(std::distance(first, last))); + } + return 0; +} + inline void AssertIsFull(ctrl_t* ctrl) { ABSL_HARDENING_ASSERT((ctrl != nullptr && IsFull(*ctrl)) && "Invalid operation on iterator. The element might have " @@ -560,29 +560,29 @@ struct FindInfo { // This is important to make 1 a valid capacity. // // - In small mode only the first `capacity()` control bytes after the -// sentinel are valid. The rest contain dummy ctrl_t::kEmpty values that do not +// sentinel are valid. The rest contain dummy ctrl_t::kEmpty values that do not // represent a real slot. This is important to take into account on // find_first_non_full(), where we never try ShouldInsertBackwards() for // small tables. inline bool is_small(size_t capacity) { return capacity < Group::kWidth - 1; } -inline probe_seq<Group::kWidth> probe(const ctrl_t* ctrl, size_t hash, +inline probe_seq<Group::kWidth> probe(const ctrl_t* ctrl, size_t hash, size_t capacity) { return probe_seq<Group::kWidth>(H1(hash, ctrl), capacity); } // Probes the raw_hash_set with the probe sequence for hash and returns the // pointer to the first empty or deleted slot. -// NOTE: this function must work with tables having both ctrl_t::kEmpty and -// ctrl_t::kDeleted in one group. Such tables appears during -// drop_deletes_without_resize. +// NOTE: this function must work with tables having both ctrl_t::kEmpty and +// ctrl_t::kDeleted in one group. Such tables appears during +// drop_deletes_without_resize. // // This function is very useful when insertions happen and: // - the input is already a set // - there are enough slots // - the element with the hash is not in the table -template <typename = void> -inline FindInfo find_first_non_full(const ctrl_t* ctrl, size_t hash, +template <typename = void> +inline FindInfo find_first_non_full(const ctrl_t* ctrl, size_t hash, size_t capacity) { auto seq = probe(ctrl, hash, capacity); while (true) { @@ -601,60 +601,60 @@ inline FindInfo find_first_non_full(const ctrl_t* ctrl, size_t hash, return {seq.offset(mask.LowestBitSet()), seq.index()}; } seq.next(); - assert(seq.index() <= capacity && "full table!"); - } -} - -// Extern template for inline function keep possibility of inlining. -// When compiler decided to not inline, no symbols will be added to the -// corresponding translation unit. -extern template FindInfo find_first_non_full(const ctrl_t*, size_t, size_t); - -// Reset all ctrl bytes back to ctrl_t::kEmpty, except the sentinel. -inline void ResetCtrl(size_t capacity, ctrl_t* ctrl, const void* slot, - size_t slot_size) { - std::memset(ctrl, static_cast<int8_t>(ctrl_t::kEmpty), - capacity + 1 + NumClonedBytes()); - ctrl[capacity] = ctrl_t::kSentinel; - SanitizerPoisonMemoryRegion(slot, slot_size * capacity); -} - -// Sets the control byte, and if `i < NumClonedBytes()`, set the cloned byte -// at the end too. -inline void SetCtrl(size_t i, ctrl_t h, size_t capacity, ctrl_t* ctrl, - const void* slot, size_t slot_size) { - assert(i < capacity); - - auto* slot_i = static_cast<const char*>(slot) + i * slot_size; - if (IsFull(h)) { - SanitizerUnpoisonMemoryRegion(slot_i, slot_size); - } else { - SanitizerPoisonMemoryRegion(slot_i, slot_size); + assert(seq.index() <= capacity && "full table!"); } - - ctrl[i] = h; - ctrl[((i - NumClonedBytes()) & capacity) + (NumClonedBytes() & capacity)] = h; -} - -inline void SetCtrl(size_t i, h2_t h, size_t capacity, ctrl_t* ctrl, - const void* slot, size_t slot_size) { - SetCtrl(i, static_cast<ctrl_t>(h), capacity, ctrl, slot, slot_size); -} - -// The allocated block consists of `capacity + 1 + NumClonedBytes()` control -// bytes followed by `capacity` slots, which must be aligned to `slot_align`. -// SlotOffset returns the offset of the slots into the allocated block. -inline size_t SlotOffset(size_t capacity, size_t slot_align) { - assert(IsValidCapacity(capacity)); - const size_t num_control_bytes = capacity + 1 + NumClonedBytes(); - return (num_control_bytes + slot_align - 1) & (~slot_align + 1); -} - -// Returns the size of the allocated block. See also above comment. -inline size_t AllocSize(size_t capacity, size_t slot_size, size_t slot_align) { - return SlotOffset(capacity, slot_align) + capacity * slot_size; } +// Extern template for inline function keep possibility of inlining. +// When compiler decided to not inline, no symbols will be added to the +// corresponding translation unit. +extern template FindInfo find_first_non_full(const ctrl_t*, size_t, size_t); + +// Reset all ctrl bytes back to ctrl_t::kEmpty, except the sentinel. +inline void ResetCtrl(size_t capacity, ctrl_t* ctrl, const void* slot, + size_t slot_size) { + std::memset(ctrl, static_cast<int8_t>(ctrl_t::kEmpty), + capacity + 1 + NumClonedBytes()); + ctrl[capacity] = ctrl_t::kSentinel; + SanitizerPoisonMemoryRegion(slot, slot_size * capacity); +} + +// Sets the control byte, and if `i < NumClonedBytes()`, set the cloned byte +// at the end too. +inline void SetCtrl(size_t i, ctrl_t h, size_t capacity, ctrl_t* ctrl, + const void* slot, size_t slot_size) { + assert(i < capacity); + + auto* slot_i = static_cast<const char*>(slot) + i * slot_size; + if (IsFull(h)) { + SanitizerUnpoisonMemoryRegion(slot_i, slot_size); + } else { + SanitizerPoisonMemoryRegion(slot_i, slot_size); + } + + ctrl[i] = h; + ctrl[((i - NumClonedBytes()) & capacity) + (NumClonedBytes() & capacity)] = h; +} + +inline void SetCtrl(size_t i, h2_t h, size_t capacity, ctrl_t* ctrl, + const void* slot, size_t slot_size) { + SetCtrl(i, static_cast<ctrl_t>(h), capacity, ctrl, slot, slot_size); +} + +// The allocated block consists of `capacity + 1 + NumClonedBytes()` control +// bytes followed by `capacity` slots, which must be aligned to `slot_align`. +// SlotOffset returns the offset of the slots into the allocated block. +inline size_t SlotOffset(size_t capacity, size_t slot_align) { + assert(IsValidCapacity(capacity)); + const size_t num_control_bytes = capacity + 1 + NumClonedBytes(); + return (num_control_bytes + slot_align - 1) & (~slot_align + 1); +} + +// Returns the size of the allocated block. See also above comment. +inline size_t AllocSize(size_t capacity, size_t slot_size, size_t slot_align) { + return SlotOffset(capacity, slot_align) + capacity * slot_size; +} + // Policy: a policy defines how to perform different operations on // the slots of the hashtable (see hash_policy_traits.h for the full interface // of policy). @@ -813,7 +813,7 @@ class raw_hash_set { ctrl_ += shift; slot_ += shift; } - if (ABSL_PREDICT_FALSE(*ctrl_ == ctrl_t::kSentinel)) ctrl_ = nullptr; + if (ABSL_PREDICT_FALSE(*ctrl_ == ctrl_t::kSentinel)) ctrl_ = nullptr; } ctrl_t* ctrl_ = nullptr; @@ -894,8 +894,8 @@ class raw_hash_set { raw_hash_set(InputIter first, InputIter last, size_t bucket_count = 0, const hasher& hash = hasher(), const key_equal& eq = key_equal(), const allocator_type& alloc = allocator_type()) - : raw_hash_set(SelectBucketCountForIterRange(first, last, bucket_count), - hash, eq, alloc) { + : raw_hash_set(SelectBucketCountForIterRange(first, last, bucket_count), + hash, eq, alloc) { insert(first, last); } @@ -983,8 +983,8 @@ class raw_hash_set { for (const auto& v : that) { const size_t hash = PolicyTraits::apply(HashElement{hash_ref()}, v); auto target = find_first_non_full(ctrl_, hash, capacity_); - SetCtrl(target.offset, H2(hash), capacity_, ctrl_, slots_, - sizeof(slot_type)); + SetCtrl(target.offset, H2(hash), capacity_, ctrl_, slots_, + sizeof(slot_type)); emplace_at(target.offset, v); infoz().RecordInsert(hash, target.probe_length); } @@ -1080,8 +1080,8 @@ class raw_hash_set { // past that we simply deallocate the array. if (capacity_ > 127) { destroy_slots(); - - infoz().RecordClearedReservation(); + + infoz().RecordClearedReservation(); } else if (capacity_) { for (size_t i = 0; i != capacity_; ++i) { if (IsFull(ctrl_[i])) { @@ -1089,7 +1089,7 @@ class raw_hash_set { } } size_ = 0; - ResetCtrl(capacity_, ctrl_, slots_, sizeof(slot_type)); + ResetCtrl(capacity_, ctrl_, slots_, sizeof(slot_type)); reset_growth_left(); } assert(empty()); @@ -1395,31 +1395,31 @@ class raw_hash_set { if (n == 0 && size_ == 0) { destroy_slots(); infoz().RecordStorageChanged(0, 0); - infoz().RecordClearedReservation(); + infoz().RecordClearedReservation(); return; } - + // bitor is a faster way of doing `max` here. We will round up to the next // power-of-2-minus-1, so bitor is good enough. auto m = NormalizeCapacity(n | GrowthToLowerboundCapacity(size())); // n == 0 unconditionally rehashes as per the standard. if (n == 0 || m > capacity_) { resize(m); - - // This is after resize, to ensure that we have completed the allocation - // and have potentially sampled the hashtable. - infoz().RecordReservation(n); + + // This is after resize, to ensure that we have completed the allocation + // and have potentially sampled the hashtable. + infoz().RecordReservation(n); } } void reserve(size_t n) { - if (n > size() + growth_left()) { - size_t m = GrowthToLowerboundCapacity(n); + if (n > size() + growth_left()) { + size_t m = GrowthToLowerboundCapacity(n); resize(NormalizeCapacity(m)); - - // This is after resize, to ensure that we have completed the allocation - // and have potentially sampled the hashtable. - infoz().RecordReservation(n); + + // This is after resize, to ensure that we have completed the allocation + // and have potentially sampled the hashtable. + infoz().RecordReservation(n); } } @@ -1446,7 +1446,7 @@ class raw_hash_set { void prefetch(const key_arg<K>& key) const { (void)key; #if defined(__GNUC__) - prefetch_heap_block(); + prefetch_heap_block(); auto seq = probe(ctrl_, hash_ref()(key), capacity_); __builtin_prefetch(static_cast<const void*>(ctrl_ + seq.offset())); __builtin_prefetch(static_cast<const void*>(slots_ + seq.offset())); @@ -1473,12 +1473,12 @@ class raw_hash_set { } if (ABSL_PREDICT_TRUE(g.MatchEmpty())) return end(); seq.next(); - assert(seq.index() <= capacity_ && "full table!"); + assert(seq.index() <= capacity_ && "full table!"); } } template <class K = key_type> iterator find(const key_arg<K>& key) { - prefetch_heap_block(); + prefetch_heap_block(); return find(key, hash_ref()(key)); } @@ -1488,7 +1488,7 @@ class raw_hash_set { } template <class K = key_type> const_iterator find(const key_arg<K>& key) const { - prefetch_heap_block(); + prefetch_heap_block(); return find(key, hash_ref()(key)); } @@ -1623,8 +1623,8 @@ class raw_hash_set { static_cast<size_t>(empty_after.TrailingZeros() + empty_before.LeadingZeros()) < Group::kWidth; - SetCtrl(index, was_never_full ? ctrl_t::kEmpty : ctrl_t::kDeleted, - capacity_, ctrl_, slots_, sizeof(slot_type)); + SetCtrl(index, was_never_full ? ctrl_t::kEmpty : ctrl_t::kDeleted, + capacity_, ctrl_, slots_, sizeof(slot_type)); growth_left() += was_never_full; infoz().RecordErase(); } @@ -1643,16 +1643,16 @@ class raw_hash_set { // bound more carefully. if (std::is_same<SlotAlloc, std::allocator<slot_type>>::value && slots_ == nullptr) { - infoz() = Sample(sizeof(slot_type)); + infoz() = Sample(sizeof(slot_type)); } - char* mem = static_cast<char*>(Allocate<alignof(slot_type)>( - &alloc_ref(), - AllocSize(capacity_, sizeof(slot_type), alignof(slot_type)))); - ctrl_ = reinterpret_cast<ctrl_t*>(mem); - slots_ = reinterpret_cast<slot_type*>( - mem + SlotOffset(capacity_, alignof(slot_type))); - ResetCtrl(capacity_, ctrl_, slots_, sizeof(slot_type)); + char* mem = static_cast<char*>(Allocate<alignof(slot_type)>( + &alloc_ref(), + AllocSize(capacity_, sizeof(slot_type), alignof(slot_type)))); + ctrl_ = reinterpret_cast<ctrl_t*>(mem); + slots_ = reinterpret_cast<slot_type*>( + mem + SlotOffset(capacity_, alignof(slot_type))); + ResetCtrl(capacity_, ctrl_, slots_, sizeof(slot_type)); reset_growth_left(); infoz().RecordStorageChanged(size_, capacity_); } @@ -1664,12 +1664,12 @@ class raw_hash_set { PolicyTraits::destroy(&alloc_ref(), slots_ + i); } } - + // Unpoison before returning the memory to the allocator. SanitizerUnpoisonMemoryRegion(slots_, sizeof(slot_type) * capacity_); - Deallocate<alignof(slot_type)>( - &alloc_ref(), ctrl_, - AllocSize(capacity_, sizeof(slot_type), alignof(slot_type))); + Deallocate<alignof(slot_type)>( + &alloc_ref(), ctrl_, + AllocSize(capacity_, sizeof(slot_type), alignof(slot_type))); ctrl_ = EmptyGroup(); slots_ = nullptr; size_ = 0; @@ -1693,16 +1693,16 @@ class raw_hash_set { auto target = find_first_non_full(ctrl_, hash, capacity_); size_t new_i = target.offset; total_probe_length += target.probe_length; - SetCtrl(new_i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type)); + SetCtrl(new_i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type)); PolicyTraits::transfer(&alloc_ref(), slots_ + new_i, old_slots + i); } } if (old_capacity) { SanitizerUnpoisonMemoryRegion(old_slots, sizeof(slot_type) * old_capacity); - Deallocate<alignof(slot_type)>( - &alloc_ref(), old_ctrl, - AllocSize(old_capacity, sizeof(slot_type), alignof(slot_type))); + Deallocate<alignof(slot_type)>( + &alloc_ref(), old_ctrl, + AllocSize(old_capacity, sizeof(slot_type), alignof(slot_type))); } infoz().RecordRehash(total_probe_length); } @@ -1732,35 +1732,35 @@ class raw_hash_set { slot_type* slot = reinterpret_cast<slot_type*>(&raw); for (size_t i = 0; i != capacity_; ++i) { if (!IsDeleted(ctrl_[i])) continue; - const size_t hash = PolicyTraits::apply( - HashElement{hash_ref()}, PolicyTraits::element(slots_ + i)); - const FindInfo target = find_first_non_full(ctrl_, hash, capacity_); - const size_t new_i = target.offset; + const size_t hash = PolicyTraits::apply( + HashElement{hash_ref()}, PolicyTraits::element(slots_ + i)); + const FindInfo target = find_first_non_full(ctrl_, hash, capacity_); + const size_t new_i = target.offset; total_probe_length += target.probe_length; // Verify if the old and new i fall within the same group wrt the hash. // If they do, we don't need to move the object as it falls already in the // best probe we can. - const size_t probe_offset = probe(ctrl_, hash, capacity_).offset(); - const auto probe_index = [probe_offset, this](size_t pos) { - return ((pos - probe_offset) & capacity_) / Group::kWidth; + const size_t probe_offset = probe(ctrl_, hash, capacity_).offset(); + const auto probe_index = [probe_offset, this](size_t pos) { + return ((pos - probe_offset) & capacity_) / Group::kWidth; }; // Element doesn't move. if (ABSL_PREDICT_TRUE(probe_index(new_i) == probe_index(i))) { - SetCtrl(i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type)); + SetCtrl(i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type)); continue; } if (IsEmpty(ctrl_[new_i])) { // Transfer element to the empty spot. - // SetCtrl poisons/unpoisons the slots so we have to call it at the + // SetCtrl poisons/unpoisons the slots so we have to call it at the // right time. - SetCtrl(new_i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type)); + SetCtrl(new_i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type)); PolicyTraits::transfer(&alloc_ref(), slots_ + new_i, slots_ + i); - SetCtrl(i, ctrl_t::kEmpty, capacity_, ctrl_, slots_, sizeof(slot_type)); + SetCtrl(i, ctrl_t::kEmpty, capacity_, ctrl_, slots_, sizeof(slot_type)); } else { assert(IsDeleted(ctrl_[new_i])); - SetCtrl(new_i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type)); + SetCtrl(new_i, H2(hash), capacity_, ctrl_, slots_, sizeof(slot_type)); // Until we are done rehashing, DELETED marks previously FULL slots. // Swap i and new_i elements. PolicyTraits::transfer(&alloc_ref(), slot, slots_ + i); @@ -1776,50 +1776,50 @@ class raw_hash_set { void rehash_and_grow_if_necessary() { if (capacity_ == 0) { resize(1); - } else if (capacity_ > Group::kWidth && - // Do these calcuations in 64-bit to avoid overflow. - size() * uint64_t{32} <= capacity_ * uint64_t{25}) { + } else if (capacity_ > Group::kWidth && + // Do these calcuations in 64-bit to avoid overflow. + size() * uint64_t{32} <= capacity_ * uint64_t{25}) { // Squash DELETED without growing if there is enough capacity. - // - // Rehash in place if the current size is <= 25/32 of capacity_. - // Rationale for such a high factor: 1) drop_deletes_without_resize() is - // faster than resize, and 2) it takes quite a bit of work to add - // tombstones. In the worst case, seems to take approximately 4 - // insert/erase pairs to create a single tombstone and so if we are - // rehashing because of tombstones, we can afford to rehash-in-place as - // long as we are reclaiming at least 1/8 the capacity without doing more - // than 2X the work. (Where "work" is defined to be size() for rehashing - // or rehashing in place, and 1 for an insert or erase.) But rehashing in - // place is faster per operation than inserting or even doubling the size - // of the table, so we actually afford to reclaim even less space from a - // resize-in-place. The decision is to rehash in place if we can reclaim - // at about 1/8th of the usable capacity (specifically 3/28 of the - // capacity) which means that the total cost of rehashing will be a small - // fraction of the total work. - // - // Here is output of an experiment using the BM_CacheInSteadyState - // benchmark running the old case (where we rehash-in-place only if we can - // reclaim at least 7/16*capacity_) vs. this code (which rehashes in place - // if we can recover 3/32*capacity_). - // - // Note that although in the worst-case number of rehashes jumped up from - // 15 to 190, but the number of operations per second is almost the same. - // - // Abridged output of running BM_CacheInSteadyState benchmark from - // raw_hash_set_benchmark. N is the number of insert/erase operations. - // - // | OLD (recover >= 7/16 | NEW (recover >= 3/32) - // size | N/s LoadFactor NRehashes | N/s LoadFactor NRehashes - // 448 | 145284 0.44 18 | 140118 0.44 19 - // 493 | 152546 0.24 11 | 151417 0.48 28 - // 538 | 151439 0.26 11 | 151152 0.53 38 - // 583 | 151765 0.28 11 | 150572 0.57 50 - // 628 | 150241 0.31 11 | 150853 0.61 66 - // 672 | 149602 0.33 12 | 150110 0.66 90 - // 717 | 149998 0.35 12 | 149531 0.70 129 - // 762 | 149836 0.37 13 | 148559 0.74 190 - // 807 | 149736 0.39 14 | 151107 0.39 14 - // 852 | 150204 0.42 15 | 151019 0.42 15 + // + // Rehash in place if the current size is <= 25/32 of capacity_. + // Rationale for such a high factor: 1) drop_deletes_without_resize() is + // faster than resize, and 2) it takes quite a bit of work to add + // tombstones. In the worst case, seems to take approximately 4 + // insert/erase pairs to create a single tombstone and so if we are + // rehashing because of tombstones, we can afford to rehash-in-place as + // long as we are reclaiming at least 1/8 the capacity without doing more + // than 2X the work. (Where "work" is defined to be size() for rehashing + // or rehashing in place, and 1 for an insert or erase.) But rehashing in + // place is faster per operation than inserting or even doubling the size + // of the table, so we actually afford to reclaim even less space from a + // resize-in-place. The decision is to rehash in place if we can reclaim + // at about 1/8th of the usable capacity (specifically 3/28 of the + // capacity) which means that the total cost of rehashing will be a small + // fraction of the total work. + // + // Here is output of an experiment using the BM_CacheInSteadyState + // benchmark running the old case (where we rehash-in-place only if we can + // reclaim at least 7/16*capacity_) vs. this code (which rehashes in place + // if we can recover 3/32*capacity_). + // + // Note that although in the worst-case number of rehashes jumped up from + // 15 to 190, but the number of operations per second is almost the same. + // + // Abridged output of running BM_CacheInSteadyState benchmark from + // raw_hash_set_benchmark. N is the number of insert/erase operations. + // + // | OLD (recover >= 7/16 | NEW (recover >= 3/32) + // size | N/s LoadFactor NRehashes | N/s LoadFactor NRehashes + // 448 | 145284 0.44 18 | 140118 0.44 19 + // 493 | 152546 0.24 11 | 151417 0.48 28 + // 538 | 151439 0.26 11 | 151152 0.53 38 + // 583 | 151765 0.28 11 | 150572 0.57 50 + // 628 | 150241 0.31 11 | 150853 0.61 66 + // 672 | 149602 0.33 12 | 150110 0.66 90 + // 717 | 149998 0.35 12 | 149531 0.70 129 + // 762 | 149836 0.37 13 | 148559 0.74 190 + // 807 | 149736 0.39 14 | 151107 0.39 14 + // 852 | 150204 0.42 15 | 151019 0.42 15 drop_deletes_without_resize(); } else { // Otherwise grow the container. @@ -1839,7 +1839,7 @@ class raw_hash_set { } if (ABSL_PREDICT_TRUE(g.MatchEmpty())) return false; seq.next(); - assert(seq.index() <= capacity_ && "full table!"); + assert(seq.index() <= capacity_ && "full table!"); } return false; } @@ -1859,7 +1859,7 @@ class raw_hash_set { protected: template <class K> std::pair<size_t, bool> find_or_prepare_insert(const K& key) { - prefetch_heap_block(); + prefetch_heap_block(); auto hash = hash_ref()(key); auto seq = probe(ctrl_, hash, capacity_); while (true) { @@ -1872,7 +1872,7 @@ class raw_hash_set { } if (ABSL_PREDICT_TRUE(g.MatchEmpty())) break; seq.next(); - assert(seq.index() <= capacity_ && "full table!"); + assert(seq.index() <= capacity_ && "full table!"); } return {prepare_insert(hash), true}; } @@ -1886,8 +1886,8 @@ class raw_hash_set { } ++size_; growth_left() -= IsEmpty(ctrl_[target.offset]); - SetCtrl(target.offset, H2(hash), capacity_, ctrl_, slots_, - sizeof(slot_type)); + SetCtrl(target.offset, H2(hash), capacity_, ctrl_, slots_, + sizeof(slot_type)); infoz().RecordInsert(hash, target.probe_length); return target.offset; } @@ -1920,15 +1920,15 @@ class raw_hash_set { growth_left() = CapacityToGrowth(capacity()) - size_; } - size_t& growth_left() { return settings_.template get<0>(); } + size_t& growth_left() { return settings_.template get<0>(); } - void prefetch_heap_block() const { - // Prefetch the heap-allocated memory region to resolve potential TLB - // misses. This is intended to overlap with execution of calculating the - // hash for a key. -#if defined(__GNUC__) - __builtin_prefetch(static_cast<const void*>(ctrl_), 0, 1); -#endif // __GNUC__ + void prefetch_heap_block() const { + // Prefetch the heap-allocated memory region to resolve potential TLB + // misses. This is intended to overlap with execution of calculating the + // hash for a key. +#if defined(__GNUC__) + __builtin_prefetch(static_cast<const void*>(ctrl_), 0, 1); +#endif // __GNUC__ } HashtablezInfoHandle& infoz() { return settings_.template get<1>(); } @@ -1945,10 +1945,10 @@ class raw_hash_set { // TODO(alkis): Investigate removing some of these fields: // - ctrl/slots can be derived from each other // - size can be moved into the slot array - ctrl_t* ctrl_ = EmptyGroup(); // [(capacity + 1 + NumClonedBytes()) * ctrl_t] - slot_type* slots_ = nullptr; // [capacity * slot_type] - size_t size_ = 0; // number of full slots - size_t capacity_ = 0; // total number of slots + ctrl_t* ctrl_ = EmptyGroup(); // [(capacity + 1 + NumClonedBytes()) * ctrl_t] + slot_type* slots_ = nullptr; // [capacity * slot_type] + size_t size_ = 0; // number of full slots + size_t capacity_ = 0; // total number of slots absl::container_internal::CompressedTuple<size_t /* growth_left */, HashtablezInfoHandle, hasher, key_equal, allocator_type> @@ -1958,12 +1958,12 @@ class raw_hash_set { // Erases all elements that satisfy the predicate `pred` from the container `c`. template <typename P, typename H, typename E, typename A, typename Predicate> -void EraseIf(Predicate& pred, raw_hash_set<P, H, E, A>* c) { +void EraseIf(Predicate& pred, raw_hash_set<P, H, E, A>* c) { for (auto it = c->begin(), last = c->end(); it != last;) { - if (pred(*it)) { - c->erase(it++); - } else { - ++it; + if (pred(*it)) { + c->erase(it++); + } else { + ++it; } } } @@ -1998,7 +1998,7 @@ struct HashtableDebugAccess<Set, absl::void_t<typename Set::raw_hash_set>> { static size_t AllocatedByteSize(const Set& c) { size_t capacity = c.capacity_; if (capacity == 0) return 0; - size_t m = AllocSize(capacity, sizeof(Slot), alignof(Slot)); + size_t m = AllocSize(capacity, sizeof(Slot), alignof(Slot)); size_t per_slot = Traits::space_used(static_cast<const Slot*>(nullptr)); if (per_slot != ~size_t{}) { @@ -2016,8 +2016,8 @@ struct HashtableDebugAccess<Set, absl::void_t<typename Set::raw_hash_set>> { static size_t LowerBoundAllocatedByteSize(size_t size) { size_t capacity = GrowthToLowerboundCapacity(size); if (capacity == 0) return 0; - size_t m = - AllocSize(NormalizeCapacity(capacity), sizeof(Slot), alignof(Slot)); + size_t m = + AllocSize(NormalizeCapacity(capacity), sizeof(Slot), alignof(Slot)); size_t per_slot = Traits::space_used(static_cast<const Slot*>(nullptr)); if (per_slot != ~size_t{}) { m += per_slot * size; diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set/ya.make b/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set/ya.make index 3fe7e7b5c0..19ff37aae3 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set/ya.make +++ b/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set/ya.make @@ -10,26 +10,26 @@ LICENSE(Apache-2.0) PEERDIR( contrib/restricted/abseil-cpp/absl/base - contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc contrib/restricted/abseil-cpp/absl/base/internal/raw_logging contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/container/internal/absl_hashtablez_sampler - contrib/restricted/abseil-cpp/absl/debugging - contrib/restricted/abseil-cpp/absl/debugging/stacktrace - contrib/restricted/abseil-cpp/absl/debugging/symbolize - contrib/restricted/abseil-cpp/absl/demangle - contrib/restricted/abseil-cpp/absl/hash + contrib/restricted/abseil-cpp/absl/container/internal/absl_hashtablez_sampler + contrib/restricted/abseil-cpp/absl/debugging + contrib/restricted/abseil-cpp/absl/debugging/stacktrace + contrib/restricted/abseil-cpp/absl/debugging/symbolize + contrib/restricted/abseil-cpp/absl/demangle + contrib/restricted/abseil-cpp/absl/hash contrib/restricted/abseil-cpp/absl/numeric - contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp/absl/synchronization - contrib/restricted/abseil-cpp/absl/synchronization/internal - contrib/restricted/abseil-cpp/absl/time - contrib/restricted/abseil-cpp/absl/time/civil_time - contrib/restricted/abseil-cpp/absl/time/time_zone + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/synchronization + contrib/restricted/abseil-cpp/absl/synchronization/internal + contrib/restricted/abseil-cpp/absl/time + contrib/restricted/abseil-cpp/absl/time/civil_time + contrib/restricted/abseil-cpp/absl/time/time_zone contrib/restricted/abseil-cpp/absl/types contrib/restricted/abseil-cpp/absl/types/bad_optional_access ) @@ -46,10 +46,10 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/container/internal) +SRCDIR(contrib/restricted/abseil-cpp/absl/container/internal) SRCS( - raw_hash_set.cc + raw_hash_set.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_constructor_test.h b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_constructor_test.h index c1d20f3c52..639567de48 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_constructor_test.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_constructor_test.h @@ -179,7 +179,7 @@ TYPED_TEST_P(ConstructorTest, InputIteratorBucketHashEqualAlloc) { A alloc(0); std::vector<T> values; std::generate_n(std::back_inserter(values), 10, - hash_internal::UniqueGenerator<T>()); + hash_internal::UniqueGenerator<T>()); TypeParam m(values.begin(), values.end(), 123, hasher, equal, alloc); EXPECT_EQ(m.hash_function(), hasher); EXPECT_EQ(m.key_eq(), equal); @@ -198,7 +198,7 @@ void InputIteratorBucketAllocTest(std::true_type) { A alloc(0); std::vector<T> values; std::generate_n(std::back_inserter(values), 10, - hash_internal::UniqueGenerator<T>()); + hash_internal::UniqueGenerator<T>()); TypeParam m(values.begin(), values.end(), 123, alloc); EXPECT_EQ(m.get_allocator(), alloc); EXPECT_THAT(items(m), ::testing::UnorderedElementsAreArray(values)); @@ -221,7 +221,7 @@ void InputIteratorBucketHashAllocTest(std::true_type) { A alloc(0); std::vector<T> values; std::generate_n(std::back_inserter(values), 10, - hash_internal::UniqueGenerator<T>()); + hash_internal::UniqueGenerator<T>()); TypeParam m(values.begin(), values.end(), 123, hasher, alloc); EXPECT_EQ(m.hash_function(), hasher); EXPECT_EQ(m.get_allocator(), alloc); @@ -241,9 +241,9 @@ TYPED_TEST_P(ConstructorTest, CopyConstructor) { H hasher; E equal; A alloc(0); - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; TypeParam m(123, hasher, equal, alloc); - for (size_t i = 0; i != 10; ++i) m.insert(gen()); + for (size_t i = 0; i != 10; ++i) m.insert(gen()); TypeParam n(m); EXPECT_EQ(m.hash_function(), n.hash_function()); EXPECT_EQ(m.key_eq(), n.key_eq()); @@ -263,9 +263,9 @@ void CopyConstructorAllocTest(std::true_type) { H hasher; E equal; A alloc(0); - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; TypeParam m(123, hasher, equal, alloc); - for (size_t i = 0; i != 10; ++i) m.insert(gen()); + for (size_t i = 0; i != 10; ++i) m.insert(gen()); TypeParam n(m, A(11)); EXPECT_EQ(m.hash_function(), n.hash_function()); EXPECT_EQ(m.key_eq(), n.key_eq()); @@ -287,9 +287,9 @@ TYPED_TEST_P(ConstructorTest, MoveConstructor) { H hasher; E equal; A alloc(0); - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; TypeParam m(123, hasher, equal, alloc); - for (size_t i = 0; i != 10; ++i) m.insert(gen()); + for (size_t i = 0; i != 10; ++i) m.insert(gen()); TypeParam t(m); TypeParam n(std::move(t)); EXPECT_EQ(m.hash_function(), n.hash_function()); @@ -310,9 +310,9 @@ void MoveConstructorAllocTest(std::true_type) { H hasher; E equal; A alloc(0); - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; TypeParam m(123, hasher, equal, alloc); - for (size_t i = 0; i != 10; ++i) m.insert(gen()); + for (size_t i = 0; i != 10; ++i) m.insert(gen()); TypeParam t(m); TypeParam n(std::move(t), A(1)); EXPECT_EQ(m.hash_function(), n.hash_function()); @@ -329,7 +329,7 @@ TYPED_TEST_P(ConstructorTest, MoveConstructorAlloc) { TYPED_TEST_P(ConstructorTest, InitializerListBucketHashEqualAlloc) { using T = hash_internal::GeneratedType<TypeParam>; - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()}; using H = typename TypeParam::hasher; using E = typename TypeParam::key_equal; @@ -352,7 +352,7 @@ template <typename TypeParam> void InitializerListBucketAllocTest(std::true_type) { using T = hash_internal::GeneratedType<TypeParam>; using A = typename TypeParam::allocator_type; - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()}; A alloc(0); TypeParam m(values, 123, alloc); @@ -375,7 +375,7 @@ void InitializerListBucketHashAllocTest(std::true_type) { using A = typename TypeParam::allocator_type; H hasher; A alloc(0); - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()}; TypeParam m(values, 123, hasher, alloc); EXPECT_EQ(m.hash_function(), hasher); @@ -396,7 +396,7 @@ TYPED_TEST_P(ConstructorTest, Assignment) { H hasher; E equal; A alloc(0); - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; TypeParam m({gen(), gen(), gen()}, 123, hasher, equal, alloc); TypeParam n; n = m; @@ -416,7 +416,7 @@ TYPED_TEST_P(ConstructorTest, MoveAssignment) { H hasher; E equal; A alloc(0); - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; TypeParam m({gen(), gen(), gen()}, 123, hasher, equal, alloc); TypeParam t(m); TypeParam n; @@ -428,7 +428,7 @@ TYPED_TEST_P(ConstructorTest, MoveAssignment) { TYPED_TEST_P(ConstructorTest, AssignmentFromInitializerList) { using T = hash_internal::GeneratedType<TypeParam>; - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()}; TypeParam m; m = values; @@ -437,7 +437,7 @@ TYPED_TEST_P(ConstructorTest, AssignmentFromInitializerList) { TYPED_TEST_P(ConstructorTest, AssignmentOverwritesExisting) { using T = hash_internal::GeneratedType<TypeParam>; - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; TypeParam m({gen(), gen(), gen()}); TypeParam n({gen()}); n = m; @@ -446,7 +446,7 @@ TYPED_TEST_P(ConstructorTest, AssignmentOverwritesExisting) { TYPED_TEST_P(ConstructorTest, MoveAssignmentOverwritesExisting) { using T = hash_internal::GeneratedType<TypeParam>; - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; TypeParam m({gen(), gen(), gen()}); TypeParam t(m); TypeParam n({gen()}); @@ -456,7 +456,7 @@ TYPED_TEST_P(ConstructorTest, MoveAssignmentOverwritesExisting) { TYPED_TEST_P(ConstructorTest, AssignmentFromInitializerListOverwritesExisting) { using T = hash_internal::GeneratedType<TypeParam>; - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()}; TypeParam m; m = values; @@ -465,7 +465,7 @@ TYPED_TEST_P(ConstructorTest, AssignmentFromInitializerListOverwritesExisting) { TYPED_TEST_P(ConstructorTest, AssignmentOnSelf) { using T = hash_internal::GeneratedType<TypeParam>; - hash_internal::UniqueGenerator<T> gen; + hash_internal::UniqueGenerator<T> gen; std::initializer_list<T> values = {gen(), gen(), gen(), gen(), gen()}; TypeParam m(values); m = *&m; // Avoid -Wself-assign diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_modifiers_test.h b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_modifiers_test.h index d3543936f7..b7676bbc9a 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_modifiers_test.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_modifiers_test.h @@ -81,38 +81,38 @@ TYPED_TEST_P(ModifiersTest, InsertRange) { ASSERT_THAT(items(m), ::testing::UnorderedElementsAreArray(values)); } -TYPED_TEST_P(ModifiersTest, InsertWithinCapacity) { - using T = hash_internal::GeneratedType<TypeParam>; - using V = typename TypeParam::mapped_type; - T val = hash_internal::Generator<T>()(); - TypeParam m; - m.reserve(10); - const size_t original_capacity = m.bucket_count(); - m.insert(val); - EXPECT_EQ(m.bucket_count(), original_capacity); - T val2 = {val.first, hash_internal::Generator<V>()()}; - m.insert(val2); - EXPECT_EQ(m.bucket_count(), original_capacity); -} - -TYPED_TEST_P(ModifiersTest, InsertRangeWithinCapacity) { -#if !defined(__GLIBCXX__) - using T = hash_internal::GeneratedType<TypeParam>; - std::vector<T> base_values; - std::generate_n(std::back_inserter(base_values), 10, - hash_internal::Generator<T>()); - std::vector<T> values; - while (values.size() != 100) { - std::copy_n(base_values.begin(), 10, std::back_inserter(values)); - } - TypeParam m; - m.reserve(10); - const size_t original_capacity = m.bucket_count(); - m.insert(values.begin(), values.end()); - EXPECT_EQ(m.bucket_count(), original_capacity); -#endif -} - +TYPED_TEST_P(ModifiersTest, InsertWithinCapacity) { + using T = hash_internal::GeneratedType<TypeParam>; + using V = typename TypeParam::mapped_type; + T val = hash_internal::Generator<T>()(); + TypeParam m; + m.reserve(10); + const size_t original_capacity = m.bucket_count(); + m.insert(val); + EXPECT_EQ(m.bucket_count(), original_capacity); + T val2 = {val.first, hash_internal::Generator<V>()()}; + m.insert(val2); + EXPECT_EQ(m.bucket_count(), original_capacity); +} + +TYPED_TEST_P(ModifiersTest, InsertRangeWithinCapacity) { +#if !defined(__GLIBCXX__) + using T = hash_internal::GeneratedType<TypeParam>; + std::vector<T> base_values; + std::generate_n(std::back_inserter(base_values), 10, + hash_internal::Generator<T>()); + std::vector<T> values; + while (values.size() != 100) { + std::copy_n(base_values.begin(), 10, std::back_inserter(values)); + } + TypeParam m; + m.reserve(10); + const size_t original_capacity = m.bucket_count(); + m.insert(values.begin(), values.end()); + EXPECT_EQ(m.bucket_count(), original_capacity); +#endif +} + TYPED_TEST_P(ModifiersTest, InsertOrAssign) { #ifdef UNORDERED_MAP_CXX17 using std::get; @@ -298,10 +298,10 @@ TYPED_TEST_P(ModifiersTest, Swap) { // TODO(alkis): Write tests for merge. REGISTER_TYPED_TEST_CASE_P(ModifiersTest, Clear, Insert, InsertHint, - InsertRange, InsertWithinCapacity, - InsertRangeWithinCapacity, InsertOrAssign, - InsertOrAssignHint, Emplace, EmplaceHint, TryEmplace, - TryEmplaceHint, Erase, EraseRange, EraseKey, Swap); + InsertRange, InsertWithinCapacity, + InsertRangeWithinCapacity, InsertOrAssign, + InsertOrAssignHint, Emplace, EmplaceHint, TryEmplace, + TryEmplaceHint, Erase, EraseRange, EraseKey, Swap); template <typename Type> struct is_unique_ptr : std::false_type {}; diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_set_modifiers_test.h b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_set_modifiers_test.h index 6e473e45da..68b0c77eff 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_set_modifiers_test.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_set_modifiers_test.h @@ -74,36 +74,36 @@ TYPED_TEST_P(ModifiersTest, InsertRange) { ASSERT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values)); } -TYPED_TEST_P(ModifiersTest, InsertWithinCapacity) { - using T = hash_internal::GeneratedType<TypeParam>; - T val = hash_internal::Generator<T>()(); - TypeParam m; - m.reserve(10); - const size_t original_capacity = m.bucket_count(); - m.insert(val); - EXPECT_EQ(m.bucket_count(), original_capacity); - m.insert(val); - EXPECT_EQ(m.bucket_count(), original_capacity); -} - -TYPED_TEST_P(ModifiersTest, InsertRangeWithinCapacity) { -#if !defined(__GLIBCXX__) - using T = hash_internal::GeneratedType<TypeParam>; - std::vector<T> base_values; - std::generate_n(std::back_inserter(base_values), 10, - hash_internal::Generator<T>()); - std::vector<T> values; - while (values.size() != 100) { - values.insert(values.end(), base_values.begin(), base_values.end()); - } - TypeParam m; - m.reserve(10); - const size_t original_capacity = m.bucket_count(); - m.insert(values.begin(), values.end()); - EXPECT_EQ(m.bucket_count(), original_capacity); -#endif -} - +TYPED_TEST_P(ModifiersTest, InsertWithinCapacity) { + using T = hash_internal::GeneratedType<TypeParam>; + T val = hash_internal::Generator<T>()(); + TypeParam m; + m.reserve(10); + const size_t original_capacity = m.bucket_count(); + m.insert(val); + EXPECT_EQ(m.bucket_count(), original_capacity); + m.insert(val); + EXPECT_EQ(m.bucket_count(), original_capacity); +} + +TYPED_TEST_P(ModifiersTest, InsertRangeWithinCapacity) { +#if !defined(__GLIBCXX__) + using T = hash_internal::GeneratedType<TypeParam>; + std::vector<T> base_values; + std::generate_n(std::back_inserter(base_values), 10, + hash_internal::Generator<T>()); + std::vector<T> values; + while (values.size() != 100) { + values.insert(values.end(), base_values.begin(), base_values.end()); + } + TypeParam m; + m.reserve(10); + const size_t original_capacity = m.bucket_count(); + m.insert(values.begin(), values.end()); + EXPECT_EQ(m.bucket_count(), original_capacity); +#endif +} + TYPED_TEST_P(ModifiersTest, Emplace) { using T = hash_internal::GeneratedType<TypeParam>; T val = hash_internal::Generator<T>()(); @@ -210,9 +210,9 @@ TYPED_TEST_P(ModifiersTest, Swap) { // TODO(alkis): Write tests for merge. REGISTER_TYPED_TEST_CASE_P(ModifiersTest, Clear, Insert, InsertHint, - InsertRange, InsertWithinCapacity, - InsertRangeWithinCapacity, Emplace, EmplaceHint, - Erase, EraseRange, EraseKey, Swap); + InsertRange, InsertWithinCapacity, + InsertRangeWithinCapacity, Emplace, EmplaceHint, + Erase, EraseRange, EraseKey, Swap); } // namespace container_internal ABSL_NAMESPACE_END diff --git a/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.cc b/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.cc index 689e5979e7..cd050c638d 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.cc +++ b/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.cc @@ -367,7 +367,7 @@ static void AbslFailureSignalHandler(int signo, siginfo_t*, void* ucontext) { // goes after this point. if (fsh_options.writerfn != nullptr) { WriteFailureInfo(signo, ucontext, my_cpu, fsh_options.writerfn); - fsh_options.writerfn(nullptr); + fsh_options.writerfn(nullptr); } if (fsh_options.call_previous_handler) { diff --git a/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.h b/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.h index 500115c0ab..1f5d55a30c 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.h +++ b/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.h @@ -90,7 +90,7 @@ struct FailureSignalHandlerOptions { // If non-null, indicates a pointer to a callback function that will be called // upon failure, with a string argument containing failure data. This function // may be used as a hook to write failure data to a secondary location, such - // as a log file. This function will also be called with null data, as a hint + // as a log file. This function will also be called with null data, as a hint // to flush any buffered data before the program may be terminated. Consider // flushing any buffered data in all calls to this function. // diff --git a/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler/ya.make b/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler/ya.make index 62217bae8f..7654c1cc68 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler/ya.make +++ b/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler/ya.make @@ -10,19 +10,19 @@ LICENSE(Apache-2.0) PEERDIR( contrib/restricted/abseil-cpp/absl/base - contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc contrib/restricted/abseil-cpp/absl/base/internal/raw_logging contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/debugging - contrib/restricted/abseil-cpp/absl/debugging/internal - contrib/restricted/abseil-cpp/absl/debugging/stacktrace - contrib/restricted/abseil-cpp/absl/debugging/symbolize - contrib/restricted/abseil-cpp/absl/demangle + contrib/restricted/abseil-cpp/absl/debugging + contrib/restricted/abseil-cpp/absl/debugging/internal + contrib/restricted/abseil-cpp/absl/debugging/stacktrace + contrib/restricted/abseil-cpp/absl/debugging/symbolize + contrib/restricted/abseil-cpp/absl/demangle contrib/restricted/abseil-cpp/absl/numeric contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal ) ADDINCL( @@ -37,10 +37,10 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/debugging) +SRCDIR(contrib/restricted/abseil-cpp/absl/debugging) SRCS( - failure_signal_handler.cc + failure_signal_handler.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/.yandex_meta/licenses.list.txt b/contrib/restricted/abseil-cpp/absl/debugging/internal/.yandex_meta/licenses.list.txt index aac6c71d05..68f928b27c 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/.yandex_meta/licenses.list.txt +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/.yandex_meta/licenses.list.txt @@ -1,18 +1,18 @@ ====================Apache-2.0==================== - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - - -====================Apache-2.0==================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + + +====================Apache-2.0==================== // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.cc b/contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.cc index 93ae32796c..8380325c30 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.cc +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.cc @@ -1617,7 +1617,7 @@ static bool ParseUnresolvedName(State *state) { // ::= <2-ary operator-name> <expression> <expression> // ::= <3-ary operator-name> <expression> <expression> <expression> // ::= cl <expression>+ E -// ::= cp <simple-id> <expression>* E # Clang-specific. +// ::= cp <simple-id> <expression>* E # Clang-specific. // ::= cv <type> <expression> # type (expression) // ::= cv <type> _ <expression>* E # type (expr-list) // ::= st <type> @@ -1640,8 +1640,8 @@ static bool ParseExpression(State *state) { return true; } - ParseState copy = state->parse_state; - + ParseState copy = state->parse_state; + // Object/function call expression. if (ParseTwoCharToken(state, "cl") && OneOrMore(ParseExpression, state) && ParseOneCharToken(state, 'E')) { @@ -1649,14 +1649,14 @@ static bool ParseExpression(State *state) { } state->parse_state = copy; - // Clang-specific "cp <simple-id> <expression>* E" - // https://clang.llvm.org/doxygen/ItaniumMangle_8cpp_source.html#l04338 - if (ParseTwoCharToken(state, "cp") && ParseSimpleId(state) && - ZeroOrMore(ParseExpression, state) && ParseOneCharToken(state, 'E')) { - return true; - } - state->parse_state = copy; - + // Clang-specific "cp <simple-id> <expression>* E" + // https://clang.llvm.org/doxygen/ItaniumMangle_8cpp_source.html#l04338 + if (ParseTwoCharToken(state, "cp") && ParseSimpleId(state) && + ZeroOrMore(ParseExpression, state) && ParseOneCharToken(state, 'E')) { + return true; + } + state->parse_state = copy; + // Function-param expression (level 0). if (ParseTwoCharToken(state, "fp") && Optional(ParseCVQualifiers(state)) && Optional(ParseNumber(state, nullptr)) && ParseOneCharToken(state, '_')) { diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/elf_mem_image.cc b/contrib/restricted/abseil-cpp/absl/debugging/internal/elf_mem_image.cc index 29a281812b..1e1b771be9 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/elf_mem_image.cc +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/elf_mem_image.cc @@ -22,7 +22,7 @@ #include <string.h> #include <cassert> #include <cstddef> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/base/internal/raw_logging.h" // From binutils/include/elf/common.h (this doesn't appear to be documented @@ -44,11 +44,11 @@ namespace debugging_internal { namespace { -#if __SIZEOF_POINTER__ == 4 +#if __SIZEOF_POINTER__ == 4 const int kElfClass = ELFCLASS32; int ElfBind(const ElfW(Sym) *symbol) { return ELF32_ST_BIND(symbol->st_info); } int ElfType(const ElfW(Sym) *symbol) { return ELF32_ST_TYPE(symbol->st_info); } -#elif __SIZEOF_POINTER__ == 8 +#elif __SIZEOF_POINTER__ == 8 const int kElfClass = ELFCLASS64; int ElfBind(const ElfW(Sym) *symbol) { return ELF64_ST_BIND(symbol->st_info); } int ElfType(const ElfW(Sym) *symbol) { return ELF64_ST_TYPE(symbol->st_info); } @@ -176,17 +176,17 @@ void ElfMemImage::Init(const void *base) { } switch (base_as_char[EI_DATA]) { case ELFDATA2LSB: { -#ifndef ABSL_IS_LITTLE_ENDIAN - assert(false); - return; -#endif +#ifndef ABSL_IS_LITTLE_ENDIAN + assert(false); + return; +#endif break; } case ELFDATA2MSB: { -#ifndef ABSL_IS_BIG_ENDIAN - assert(false); - return; -#endif +#ifndef ABSL_IS_BIG_ENDIAN + assert(false); + return; +#endif break; } default: { @@ -222,7 +222,7 @@ void ElfMemImage::Init(const void *base) { reinterpret_cast<ElfW(Dyn) *>(dynamic_program_header->p_vaddr + relocation); for (; dynamic_entry->d_tag != DT_NULL; ++dynamic_entry) { - const auto value = dynamic_entry->d_un.d_val + relocation; + const auto value = dynamic_entry->d_un.d_val + relocation; switch (dynamic_entry->d_tag) { case DT_HASH: hash_ = reinterpret_cast<ElfW(Word) *>(value); diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/elf_mem_image.h b/contrib/restricted/abseil-cpp/absl/debugging/internal/elf_mem_image.h index a894bd423e..5224604405 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/elf_mem_image.h +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/elf_mem_image.h @@ -31,8 +31,8 @@ #error ABSL_HAVE_ELF_MEM_IMAGE cannot be directly set #endif -#if defined(__ELF__) && !defined(__native_client__) && !defined(__asmjs__) && \ - !defined(__wasm__) +#if defined(__ELF__) && !defined(__native_client__) && !defined(__asmjs__) && \ + !defined(__wasm__) #define ABSL_HAVE_ELF_MEM_IMAGE 1 #endif @@ -40,10 +40,10 @@ #include <link.h> // for ElfW -#if defined(__FreeBSD__) && !defined(ElfW) -#define ElfW(x) __ElfN(x) -#endif - +#if defined(__FreeBSD__) && !defined(ElfW) +#define ElfW(x) __ElfN(x) +#endif + namespace absl { ABSL_NAMESPACE_BEGIN namespace debugging_internal { diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/stack_consumption.h b/contrib/restricted/abseil-cpp/absl/debugging/internal/stack_consumption.h index f41b64c39d..cb3eebc66f 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/stack_consumption.h +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/stack_consumption.h @@ -26,7 +26,7 @@ #error ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION cannot be set directly #elif !defined(__APPLE__) && !defined(_WIN32) && \ (defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || \ - defined(__aarch64__) || defined(__riscv)) + defined(__aarch64__) || defined(__riscv)) #define ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION 1 namespace absl { diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_config.h b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_config.h index ff21b719a0..a99259602a 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_config.h +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_config.h @@ -35,12 +35,12 @@ // Thread local support required for UnwindImpl. #define ABSL_STACKTRACE_INL_HEADER \ "absl/debugging/internal/stacktrace_generic-inl.inc" -#endif // defined(ABSL_HAVE_THREAD_LOCAL) - -#elif defined(__EMSCRIPTEN__) -#define ABSL_STACKTRACE_INL_HEADER \ - "absl/debugging/internal/stacktrace_emscripten-inl.inc" +#endif // defined(ABSL_HAVE_THREAD_LOCAL) +#elif defined(__EMSCRIPTEN__) +#define ABSL_STACKTRACE_INL_HEADER \ + "absl/debugging/internal/stacktrace_emscripten-inl.inc" + #elif defined(__linux__) && !defined(__ANDROID__) #if defined(NO_FRAME_POINTER) && \ @@ -55,7 +55,7 @@ // Note: When using glibc this may require -funwind-tables to function properly. #define ABSL_STACKTRACE_INL_HEADER \ "absl/debugging/internal/stacktrace_generic-inl.inc" -#endif // __has_include(<execinfo.h>) +#endif // __has_include(<execinfo.h>) #elif defined(__i386__) || defined(__x86_64__) #define ABSL_STACKTRACE_INL_HEADER \ "absl/debugging/internal/stacktrace_x86-inl.inc" @@ -65,18 +65,18 @@ #elif defined(__aarch64__) #define ABSL_STACKTRACE_INL_HEADER \ "absl/debugging/internal/stacktrace_aarch64-inl.inc" -#elif defined(__riscv) -#define ABSL_STACKTRACE_INL_HEADER \ - "absl/debugging/internal/stacktrace_riscv-inl.inc" +#elif defined(__riscv) +#define ABSL_STACKTRACE_INL_HEADER \ + "absl/debugging/internal/stacktrace_riscv-inl.inc" #elif defined(__has_include) #if __has_include(<execinfo.h>) // Note: When using glibc this may require -funwind-tables to function properly. #define ABSL_STACKTRACE_INL_HEADER \ "absl/debugging/internal/stacktrace_generic-inl.inc" -#endif // __has_include(<execinfo.h>) -#endif // defined(__has_include) +#endif // __has_include(<execinfo.h>) +#endif // defined(__has_include) -#endif // defined(__linux__) && !defined(__ANDROID__) +#endif // defined(__linux__) && !defined(__ANDROID__) // Fallback to the empty implementation. #if !defined(ABSL_STACKTRACE_INL_HEADER) diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_emscripten-inl.inc b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_emscripten-inl.inc index 16522102f6..750f6464b8 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_emscripten-inl.inc +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_emscripten-inl.inc @@ -1,110 +1,110 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Portable implementation - just use glibc -// -// Note: The glibc implementation may cause a call to malloc. -// This can cause a deadlock in HeapProfiler. - -#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_EMSCRIPTEN_INL_H_ -#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_EMSCRIPTEN_INL_H_ - -#error #include <emscripten.h> - -#include <atomic> -#include <cstring> - -#include "absl/base/attributes.h" -#include "absl/debugging/stacktrace.h" - -extern "C" { -uintptr_t emscripten_stack_snapshot(); -uint32_t emscripten_stack_unwind_buffer(uintptr_t pc, void *buffer, - uint32_t depth); -} - -// Sometimes, we can try to get a stack trace from within a stack -// trace, which can cause a self-deadlock. -// Protect against such reentrant call by failing to get a stack trace. -// -// We use __thread here because the code here is extremely low level -- it is -// called while collecting stack traces from within malloc and mmap, and thus -// can not call anything which might call malloc or mmap itself. -static __thread int recursive = 0; - -// The stack trace function might be invoked very early in the program's -// execution (e.g. from the very first malloc). -// As such, we suppress usage of backtrace during this early stage of execution. -static std::atomic<bool> disable_stacktraces(true); // Disabled until healthy. -// Waiting until static initializers run seems to be late enough. -// This file is included into stacktrace.cc so this will only run once. -ABSL_ATTRIBUTE_UNUSED static int stacktraces_enabler = []() { - // Check if we can even create stacktraces. If not, bail early and leave - // disable_stacktraces set as-is. - // clang-format off - if (!EM_ASM_INT({ return (typeof wasmOffsetConverter !== 'undefined'); })) { - return 0; - } - // clang-format on - disable_stacktraces.store(false, std::memory_order_relaxed); - return 0; -}(); - -template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> -static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count, - const void *ucp, int *min_dropped_frames) { - if (recursive || disable_stacktraces.load(std::memory_order_relaxed)) { - return 0; - } - ++recursive; - - static_cast<void>(ucp); // Unused. - constexpr int kStackLength = 64; - void *stack[kStackLength]; - - int size; - uintptr_t pc = emscripten_stack_snapshot(); - size = emscripten_stack_unwind_buffer(pc, stack, kStackLength); - - int result_count = size - skip_count; - if (result_count < 0) result_count = 0; - if (result_count > max_depth) result_count = max_depth; - for (int i = 0; i < result_count; i++) result[i] = stack[i + skip_count]; - - if (IS_STACK_FRAMES) { - // No implementation for finding out the stack frame sizes yet. - memset(sizes, 0, sizeof(*sizes) * result_count); - } - if (min_dropped_frames != nullptr) { - if (size - skip_count - max_depth > 0) { - *min_dropped_frames = size - skip_count - max_depth; - } else { - *min_dropped_frames = 0; - } - } - - --recursive; - - return result_count; -} - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace debugging_internal { -bool StackTraceWorksForTest() { return true; } -} // namespace debugging_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_EMSCRIPTEN_INL_H_ +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Portable implementation - just use glibc +// +// Note: The glibc implementation may cause a call to malloc. +// This can cause a deadlock in HeapProfiler. + +#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_EMSCRIPTEN_INL_H_ +#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_EMSCRIPTEN_INL_H_ + +#error #include <emscripten.h> + +#include <atomic> +#include <cstring> + +#include "absl/base/attributes.h" +#include "absl/debugging/stacktrace.h" + +extern "C" { +uintptr_t emscripten_stack_snapshot(); +uint32_t emscripten_stack_unwind_buffer(uintptr_t pc, void *buffer, + uint32_t depth); +} + +// Sometimes, we can try to get a stack trace from within a stack +// trace, which can cause a self-deadlock. +// Protect against such reentrant call by failing to get a stack trace. +// +// We use __thread here because the code here is extremely low level -- it is +// called while collecting stack traces from within malloc and mmap, and thus +// can not call anything which might call malloc or mmap itself. +static __thread int recursive = 0; + +// The stack trace function might be invoked very early in the program's +// execution (e.g. from the very first malloc). +// As such, we suppress usage of backtrace during this early stage of execution. +static std::atomic<bool> disable_stacktraces(true); // Disabled until healthy. +// Waiting until static initializers run seems to be late enough. +// This file is included into stacktrace.cc so this will only run once. +ABSL_ATTRIBUTE_UNUSED static int stacktraces_enabler = []() { + // Check if we can even create stacktraces. If not, bail early and leave + // disable_stacktraces set as-is. + // clang-format off + if (!EM_ASM_INT({ return (typeof wasmOffsetConverter !== 'undefined'); })) { + return 0; + } + // clang-format on + disable_stacktraces.store(false, std::memory_order_relaxed); + return 0; +}(); + +template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> +static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count, + const void *ucp, int *min_dropped_frames) { + if (recursive || disable_stacktraces.load(std::memory_order_relaxed)) { + return 0; + } + ++recursive; + + static_cast<void>(ucp); // Unused. + constexpr int kStackLength = 64; + void *stack[kStackLength]; + + int size; + uintptr_t pc = emscripten_stack_snapshot(); + size = emscripten_stack_unwind_buffer(pc, stack, kStackLength); + + int result_count = size - skip_count; + if (result_count < 0) result_count = 0; + if (result_count > max_depth) result_count = max_depth; + for (int i = 0; i < result_count; i++) result[i] = stack[i + skip_count]; + + if (IS_STACK_FRAMES) { + // No implementation for finding out the stack frame sizes yet. + memset(sizes, 0, sizeof(*sizes) * result_count); + } + if (min_dropped_frames != nullptr) { + if (size - skip_count - max_depth > 0) { + *min_dropped_frames = size - skip_count - max_depth; + } else { + *min_dropped_frames = 0; + } + } + + --recursive; + + return result_count; +} + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace debugging_internal { +bool StackTraceWorksForTest() { return true; } +} // namespace debugging_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_EMSCRIPTEN_INL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc index 8cbc78548c..933c2d3015 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc @@ -1,234 +1,234 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_RISCV_INL_H_ -#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_RISCV_INL_H_ - -// Generate stack trace for riscv - -#include <sys/ucontext.h> - -#include "absl/base/config.h" -#if defined(__linux__) -#include <sys/mman.h> -#include <ucontext.h> -#include <unistd.h> -#endif - -#include <atomic> -#include <cassert> -#include <cstdint> -#include <iostream> - -#include "absl/base/attributes.h" -#include "absl/debugging/internal/address_is_readable.h" -#include "absl/debugging/internal/vdso_support.h" -#include "absl/debugging/stacktrace.h" - -static const uintptr_t kUnknownFrameSize = 0; - -#if defined(__linux__) -// Returns the address of the VDSO __kernel_rt_sigreturn function, if present. -static const unsigned char *GetKernelRtSigreturnAddress() { - constexpr uintptr_t kImpossibleAddress = 0; - ABSL_CONST_INIT static std::atomic<uintptr_t> memoized(kImpossibleAddress); - uintptr_t address = memoized.load(std::memory_order_relaxed); - if (address != kImpossibleAddress) { - return reinterpret_cast<const unsigned char *>(address); - } - - address = reinterpret_cast<uintptr_t>(nullptr); - -#if ABSL_HAVE_VDSO_SUPPORT - absl::debugging_internal::VDSOSupport vdso; - if (vdso.IsPresent()) { - absl::debugging_internal::VDSOSupport::SymbolInfo symbol_info; - // Symbol versioning pulled from arch/riscv/kernel/vdso/vdso.lds at v5.10. - auto lookup = [&](int type) { - return vdso.LookupSymbol("__kernel_rt_sigreturn", "LINUX_4.15", type, - &symbol_info); - }; - if ((!lookup(STT_FUNC) && !lookup(STT_NOTYPE)) || - symbol_info.address == nullptr) { - // Unexpected: VDSO is present, yet the expected symbol is missing or - // null. - assert(false && "VDSO is present, but doesn't have expected symbol"); - } else { - if (reinterpret_cast<uintptr_t>(symbol_info.address) != - kImpossibleAddress) { - address = reinterpret_cast<uintptr_t>(symbol_info.address); - } else { - assert(false && "VDSO returned invalid address"); - } - } - } -#endif - - memoized.store(address, std::memory_order_relaxed); - return reinterpret_cast<const unsigned char *>(address); -} -#endif // __linux__ - -// Compute the size of a stack frame in [low..high). We assume that low < high. -// Return size of kUnknownFrameSize. -template <typename T> -static inline uintptr_t ComputeStackFrameSize(const T *low, const T *high) { - const char *low_char_ptr = reinterpret_cast<const char *>(low); - const char *high_char_ptr = reinterpret_cast<const char *>(high); - return low < high ? high_char_ptr - low_char_ptr : kUnknownFrameSize; -} - -// Given a pointer to a stack frame, locate and return the calling stackframe, -// or return null if no stackframe can be found. Perform sanity checks (the -// strictness of which is controlled by the boolean parameter -// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned. -template <bool STRICT_UNWINDING, bool WITH_CONTEXT> -ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack. -ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack. -static void ** NextStackFrame(void **old_frame_pointer, const void *uc) { - // . - // . - // . - // +-> +----------------+ - // | | return address | - // | | previous fp | - // | | ... | - // | +----------------+ <-+ - // | | return address | | - // +---|- previous fp | | - // | ... | | - // $fp ->|----------------+ | - // | return address | | - // | previous fp -|---+ - // $sp ->| ... | - // +----------------+ - void **new_frame_pointer = reinterpret_cast<void **>(old_frame_pointer[-2]); - bool check_frame_size = true; - -#if defined(__linux__) - if (WITH_CONTEXT && uc != nullptr) { - // Check to see if next frame's return address is __kernel_rt_sigreturn. - if (old_frame_pointer[-1] == GetKernelRtSigreturnAddress()) { - const ucontext_t *ucv = static_cast<const ucontext_t *>(uc); - // old_frame_pointer is not suitable for unwinding, look at ucontext to - // discover frame pointer before signal. - // - // RISCV ELF psABI has the frame pointer at x8/fp/s0. - // -- RISCV psABI Table 18.2 - void **const pre_signal_frame_pointer = - reinterpret_cast<void **>(ucv->uc_mcontext.__gregs[8]); - - // Check the alleged frame pointer is actually readable. This is to - // prevent "double fault" in case we hit the first fault due to stack - // corruption. - if (!absl::debugging_internal::AddressIsReadable( - pre_signal_frame_pointer)) - return nullptr; - - // Alleged frame pointer is readable, use it for further unwinding. - new_frame_pointer = pre_signal_frame_pointer; - - // Skip frame size check if we return from a signal. We may be using an - // alterate stack for signals. - check_frame_size = false; - } - } -#endif - - // The RISCV ELF psABI mandates that the stack pointer is always 16-byte - // aligned. - // FIXME(abdulras) this doesn't hold for ILP32E which only mandates a 4-byte - // alignment. - if ((reinterpret_cast<uintptr_t>(new_frame_pointer) & 15) != 0) - return nullptr; - - // Check frame size. In strict mode, we assume frames to be under 100,000 - // bytes. In non-strict mode, we relax the limit to 1MB. - if (check_frame_size) { - const uintptr_t max_size = STRICT_UNWINDING ? 100000 : 1000000; - const uintptr_t frame_size = - ComputeStackFrameSize(old_frame_pointer, new_frame_pointer); - if (frame_size == kUnknownFrameSize || frame_size > max_size) - return nullptr; - } - - return new_frame_pointer; -} - -template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> -ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack. -ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack. -static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count, - const void *ucp, int *min_dropped_frames) { -#if defined(__GNUC__) - void **frame_pointer = reinterpret_cast<void **>(__builtin_frame_address(0)); -#else -#error reading stack pointer not yet supported on this platform -#endif - - skip_count++; // Skip the frame for this function. - int n = 0; - - // The `frame_pointer` that is computed here points to the top of the frame. - // The two words preceding the address are the return address and the previous - // frame pointer. To find a PC value associated with the current frame, we - // need to go down a level in the call chain. So we remember the return - // address of the last frame seen. This does not work for the first stack - // frame, which belongs to `UnwindImp()` but we skip the frame for - // `UnwindImp()` anyway. - void *prev_return_address = nullptr; - - while (frame_pointer && n < max_depth) { - // The absl::GetStackFrames routine si called when we are in some - // informational context (the failure signal handler for example). Use the - // non-strict unwinding rules to produce a stack trace that is as complete - // as possible (even if it contains a few bogus entries in some rare cases). - void **next_frame_pointer = - NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(frame_pointer, ucp); - - if (skip_count > 0) { - skip_count--; - } else { - result[n] = prev_return_address; - if (IS_STACK_FRAMES) { - sizes[n] = ComputeStackFrameSize(frame_pointer, next_frame_pointer); - } - n++; - } - prev_return_address = frame_pointer[-1]; - frame_pointer = next_frame_pointer; - } - if (min_dropped_frames != nullptr) { - // Implementation detail: we clamp the max of frames we are willing to - // count, so as not to spend too much time in the loop below. - const int kMaxUnwind = 200; - int j = 0; - for (; frame_pointer != nullptr && j < kMaxUnwind; j++) { - frame_pointer = - NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(frame_pointer, ucp); - } - *min_dropped_frames = j; - } - return n; -} - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace debugging_internal { -bool StackTraceWorksForTest() { return true; } -} // namespace debugging_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_RISCV_INL_H_ +#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_RISCV_INL_H_ + +// Generate stack trace for riscv + +#include <sys/ucontext.h> + +#include "absl/base/config.h" +#if defined(__linux__) +#include <sys/mman.h> +#include <ucontext.h> +#include <unistd.h> +#endif + +#include <atomic> +#include <cassert> +#include <cstdint> +#include <iostream> + +#include "absl/base/attributes.h" +#include "absl/debugging/internal/address_is_readable.h" +#include "absl/debugging/internal/vdso_support.h" +#include "absl/debugging/stacktrace.h" + +static const uintptr_t kUnknownFrameSize = 0; + +#if defined(__linux__) +// Returns the address of the VDSO __kernel_rt_sigreturn function, if present. +static const unsigned char *GetKernelRtSigreturnAddress() { + constexpr uintptr_t kImpossibleAddress = 0; + ABSL_CONST_INIT static std::atomic<uintptr_t> memoized(kImpossibleAddress); + uintptr_t address = memoized.load(std::memory_order_relaxed); + if (address != kImpossibleAddress) { + return reinterpret_cast<const unsigned char *>(address); + } + + address = reinterpret_cast<uintptr_t>(nullptr); + +#if ABSL_HAVE_VDSO_SUPPORT + absl::debugging_internal::VDSOSupport vdso; + if (vdso.IsPresent()) { + absl::debugging_internal::VDSOSupport::SymbolInfo symbol_info; + // Symbol versioning pulled from arch/riscv/kernel/vdso/vdso.lds at v5.10. + auto lookup = [&](int type) { + return vdso.LookupSymbol("__kernel_rt_sigreturn", "LINUX_4.15", type, + &symbol_info); + }; + if ((!lookup(STT_FUNC) && !lookup(STT_NOTYPE)) || + symbol_info.address == nullptr) { + // Unexpected: VDSO is present, yet the expected symbol is missing or + // null. + assert(false && "VDSO is present, but doesn't have expected symbol"); + } else { + if (reinterpret_cast<uintptr_t>(symbol_info.address) != + kImpossibleAddress) { + address = reinterpret_cast<uintptr_t>(symbol_info.address); + } else { + assert(false && "VDSO returned invalid address"); + } + } + } +#endif + + memoized.store(address, std::memory_order_relaxed); + return reinterpret_cast<const unsigned char *>(address); +} +#endif // __linux__ + +// Compute the size of a stack frame in [low..high). We assume that low < high. +// Return size of kUnknownFrameSize. +template <typename T> +static inline uintptr_t ComputeStackFrameSize(const T *low, const T *high) { + const char *low_char_ptr = reinterpret_cast<const char *>(low); + const char *high_char_ptr = reinterpret_cast<const char *>(high); + return low < high ? high_char_ptr - low_char_ptr : kUnknownFrameSize; +} + +// Given a pointer to a stack frame, locate and return the calling stackframe, +// or return null if no stackframe can be found. Perform sanity checks (the +// strictness of which is controlled by the boolean parameter +// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned. +template <bool STRICT_UNWINDING, bool WITH_CONTEXT> +ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack. +ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack. +static void ** NextStackFrame(void **old_frame_pointer, const void *uc) { + // . + // . + // . + // +-> +----------------+ + // | | return address | + // | | previous fp | + // | | ... | + // | +----------------+ <-+ + // | | return address | | + // +---|- previous fp | | + // | ... | | + // $fp ->|----------------+ | + // | return address | | + // | previous fp -|---+ + // $sp ->| ... | + // +----------------+ + void **new_frame_pointer = reinterpret_cast<void **>(old_frame_pointer[-2]); + bool check_frame_size = true; + +#if defined(__linux__) + if (WITH_CONTEXT && uc != nullptr) { + // Check to see if next frame's return address is __kernel_rt_sigreturn. + if (old_frame_pointer[-1] == GetKernelRtSigreturnAddress()) { + const ucontext_t *ucv = static_cast<const ucontext_t *>(uc); + // old_frame_pointer is not suitable for unwinding, look at ucontext to + // discover frame pointer before signal. + // + // RISCV ELF psABI has the frame pointer at x8/fp/s0. + // -- RISCV psABI Table 18.2 + void **const pre_signal_frame_pointer = + reinterpret_cast<void **>(ucv->uc_mcontext.__gregs[8]); + + // Check the alleged frame pointer is actually readable. This is to + // prevent "double fault" in case we hit the first fault due to stack + // corruption. + if (!absl::debugging_internal::AddressIsReadable( + pre_signal_frame_pointer)) + return nullptr; + + // Alleged frame pointer is readable, use it for further unwinding. + new_frame_pointer = pre_signal_frame_pointer; + + // Skip frame size check if we return from a signal. We may be using an + // alterate stack for signals. + check_frame_size = false; + } + } +#endif + + // The RISCV ELF psABI mandates that the stack pointer is always 16-byte + // aligned. + // FIXME(abdulras) this doesn't hold for ILP32E which only mandates a 4-byte + // alignment. + if ((reinterpret_cast<uintptr_t>(new_frame_pointer) & 15) != 0) + return nullptr; + + // Check frame size. In strict mode, we assume frames to be under 100,000 + // bytes. In non-strict mode, we relax the limit to 1MB. + if (check_frame_size) { + const uintptr_t max_size = STRICT_UNWINDING ? 100000 : 1000000; + const uintptr_t frame_size = + ComputeStackFrameSize(old_frame_pointer, new_frame_pointer); + if (frame_size == kUnknownFrameSize || frame_size > max_size) + return nullptr; + } + + return new_frame_pointer; +} + +template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> +ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack. +ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack. +static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count, + const void *ucp, int *min_dropped_frames) { +#if defined(__GNUC__) + void **frame_pointer = reinterpret_cast<void **>(__builtin_frame_address(0)); +#else +#error reading stack pointer not yet supported on this platform +#endif + + skip_count++; // Skip the frame for this function. + int n = 0; + + // The `frame_pointer` that is computed here points to the top of the frame. + // The two words preceding the address are the return address and the previous + // frame pointer. To find a PC value associated with the current frame, we + // need to go down a level in the call chain. So we remember the return + // address of the last frame seen. This does not work for the first stack + // frame, which belongs to `UnwindImp()` but we skip the frame for + // `UnwindImp()` anyway. + void *prev_return_address = nullptr; + + while (frame_pointer && n < max_depth) { + // The absl::GetStackFrames routine si called when we are in some + // informational context (the failure signal handler for example). Use the + // non-strict unwinding rules to produce a stack trace that is as complete + // as possible (even if it contains a few bogus entries in some rare cases). + void **next_frame_pointer = + NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(frame_pointer, ucp); + + if (skip_count > 0) { + skip_count--; + } else { + result[n] = prev_return_address; + if (IS_STACK_FRAMES) { + sizes[n] = ComputeStackFrameSize(frame_pointer, next_frame_pointer); + } + n++; + } + prev_return_address = frame_pointer[-1]; + frame_pointer = next_frame_pointer; + } + if (min_dropped_frames != nullptr) { + // Implementation detail: we clamp the max of frames we are willing to + // count, so as not to spend too much time in the loop below. + const int kMaxUnwind = 200; + int j = 0; + for (; frame_pointer != nullptr && j < kMaxUnwind; j++) { + frame_pointer = + NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(frame_pointer, ucp); + } + *min_dropped_frames = j; + } + return n; +} + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace debugging_internal { +bool StackTraceWorksForTest() { return true; } +} // namespace debugging_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc index 847a547359..95ee730e56 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc @@ -27,7 +27,7 @@ #include <cassert> #include <cstdint> -#include <limits> +#include <limits> #include "absl/base/macros.h" #include "absl/base/port.h" @@ -133,8 +133,8 @@ static uintptr_t GetFP(const void *vuc) { const uintptr_t bp = 0; const uintptr_t sp = 0; #endif - // Sanity-check that the base pointer is valid. It's possible that some - // code in the process is compiled with --copt=-fomit-frame-pointer or + // Sanity-check that the base pointer is valid. It's possible that some + // code in the process is compiled with --copt=-fomit-frame-pointer or // --copt=-momit-leaf-frame-pointer. // // TODO(bcmills): -momit-leaf-frame-pointer is currently the default @@ -159,8 +159,8 @@ static uintptr_t GetFP(const void *vuc) { template <bool STRICT_UNWINDING, bool WITH_CONTEXT> ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack. ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack. -static void **NextStackFrame(void **old_fp, const void *uc, - size_t stack_low, size_t stack_high) { +static void **NextStackFrame(void **old_fp, const void *uc, + size_t stack_low, size_t stack_high) { void **new_fp = (void **)*old_fp; #if defined(__linux__) && defined(__i386__) @@ -248,7 +248,7 @@ static void **NextStackFrame(void **old_fp, const void *uc, // using an alternate signal stack. // // TODO(bcmills): The GetFP call should be completely unnecessary when - // ENABLE_COMBINED_UNWINDER is set (because we should be back in the thread's + // ENABLE_COMBINED_UNWINDER is set (because we should be back in the thread's // stack by this point), but it is empirically still needed (e.g. when the // stack includes a call to abort). unw_get_reg returns UNW_EBADREG for some // frames. Figure out why GetValidFrameAddr and/or libunwind isn't doing what @@ -259,18 +259,18 @@ static void **NextStackFrame(void **old_fp, const void *uc, // at a greater address that the current one. if (new_fp_u <= old_fp_u) return nullptr; if (new_fp_u - old_fp_u > kMaxFrameBytes) return nullptr; - - if (stack_low < old_fp_u && old_fp_u <= stack_high) { - // Old BP was in the expected stack region... - if (!(stack_low < new_fp_u && new_fp_u <= stack_high)) { - // ... but new BP is outside of expected stack region. - // It is most likely bogus. - return nullptr; - } - } else { - // We may be here if we are executing in a co-routine with a - // separate stack. We can't do safety checks in this case. - } + + if (stack_low < old_fp_u && old_fp_u <= stack_high) { + // Old BP was in the expected stack region... + if (!(stack_low < new_fp_u && new_fp_u <= stack_high)) { + // ... but new BP is outside of expected stack region. + // It is most likely bogus. + return nullptr; + } + } else { + // We may be here if we are executing in a co-routine with a + // separate stack. We can't do safety checks in this case. + } } else { if (new_fp == nullptr) return nullptr; // skip AddressIsReadable() below // In the non-strict mode, allow discontiguous stack frames. @@ -310,17 +310,17 @@ static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count, int n = 0; void **fp = reinterpret_cast<void **>(__builtin_frame_address(0)); - size_t stack_low = getpagesize(); // Assume that the first page is not stack. - size_t stack_high = std::numeric_limits<size_t>::max() - sizeof(void *); - + size_t stack_low = getpagesize(); // Assume that the first page is not stack. + size_t stack_high = std::numeric_limits<size_t>::max() - sizeof(void *); + while (fp && n < max_depth) { if (*(fp + 1) == reinterpret_cast<void *>(0)) { // In 64-bit code, we often see a frame that // points to itself and has a return address of 0. break; } - void **next_fp = NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>( - fp, ucp, stack_low, stack_high); + void **next_fp = NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>( + fp, ucp, stack_low, stack_high); if (skip_count > 0) { skip_count--; } else { @@ -343,8 +343,8 @@ static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count, const int kMaxUnwind = 1000; int j = 0; for (; fp != nullptr && j < kMaxUnwind; j++) { - fp = NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(fp, ucp, stack_low, - stack_high); + fp = NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(fp, ucp, stack_low, + stack_high); } *min_dropped_frames = j; } diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/symbolize.h b/contrib/restricted/abseil-cpp/absl/debugging/internal/symbolize.h index 27d5e6521e..926d5bdd82 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/symbolize.h +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/symbolize.h @@ -28,8 +28,8 @@ #ifdef ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE #error ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE cannot be directly set -#elif defined(__ELF__) && defined(__GLIBC__) && !defined(__native_client__) \ - && !defined(__asmjs__) && !defined(__wasm__) +#elif defined(__ELF__) && defined(__GLIBC__) && !defined(__native_client__) \ + && !defined(__asmjs__) && !defined(__wasm__) #define ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE 1 #include <elf.h> @@ -68,12 +68,12 @@ ABSL_NAMESPACE_END #define ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE 1 #endif -#ifdef ABSL_INTERNAL_HAVE_EMSCRIPTEN_SYMBOLIZE -#error ABSL_INTERNAL_HAVE_EMSCRIPTEN_SYMBOLIZE cannot be directly set -#elif defined(__EMSCRIPTEN__) -#define ABSL_INTERNAL_HAVE_EMSCRIPTEN_SYMBOLIZE 1 -#endif - +#ifdef ABSL_INTERNAL_HAVE_EMSCRIPTEN_SYMBOLIZE +#error ABSL_INTERNAL_HAVE_EMSCRIPTEN_SYMBOLIZE cannot be directly set +#elif defined(__EMSCRIPTEN__) +#define ABSL_INTERNAL_HAVE_EMSCRIPTEN_SYMBOLIZE 1 +#endif + namespace absl { ABSL_NAMESPACE_BEGIN namespace debugging_internal { diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/vdso_support.cc b/contrib/restricted/abseil-cpp/absl/debugging/internal/vdso_support.cc index 977a9f6b3c..41644ad7a9 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/vdso_support.cc +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/vdso_support.cc @@ -20,25 +20,25 @@ #ifdef ABSL_HAVE_VDSO_SUPPORT // defined in vdso_support.h -#if !defined(__has_include) -#define __has_include(header) 0 -#endif - +#if !defined(__has_include) +#define __has_include(header) 0 +#endif + #include <errno.h> #include <fcntl.h> -#if __has_include(<syscall.h>) -#include <syscall.h> -#elif __has_include(<sys/syscall.h>) +#if __has_include(<syscall.h>) +#include <syscall.h> +#elif __has_include(<sys/syscall.h>) #include <sys/syscall.h> -#endif +#endif #include <unistd.h> -#if defined(__GLIBC__) && \ - (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 16)) -#define ABSL_HAVE_GETAUXVAL -#endif - -#ifdef ABSL_HAVE_GETAUXVAL +#if defined(__GLIBC__) && \ + (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 16)) +#define ABSL_HAVE_GETAUXVAL +#endif + +#ifdef ABSL_HAVE_GETAUXVAL #include <sys/auxv.h> #endif @@ -50,11 +50,11 @@ #define AT_SYSINFO_EHDR 33 // for crosstoolv10 #endif -#if defined(__FreeBSD__) -using Elf64_auxv_t = Elf64_Auxinfo; -using Elf32_auxv_t = Elf32_Auxinfo; -#endif - +#if defined(__FreeBSD__) +using Elf64_auxv_t = Elf64_Auxinfo; +using Elf32_auxv_t = Elf32_Auxinfo; +#endif + namespace absl { ABSL_NAMESPACE_BEGIN namespace debugging_internal { @@ -83,7 +83,7 @@ VDSOSupport::VDSOSupport() // the operation should be idempotent. const void *VDSOSupport::Init() { const auto kInvalidBase = debugging_internal::ElfMemImage::kInvalidBase; -#ifdef ABSL_HAVE_GETAUXVAL +#ifdef ABSL_HAVE_GETAUXVAL if (vdso_base_.load(std::memory_order_relaxed) == kInvalidBase) { errno = 0; const void *const sysinfo_ehdr = @@ -92,7 +92,7 @@ const void *VDSOSupport::Init() { vdso_base_.store(sysinfo_ehdr, std::memory_order_relaxed); } } -#endif // ABSL_HAVE_GETAUXVAL +#endif // ABSL_HAVE_GETAUXVAL if (vdso_base_.load(std::memory_order_relaxed) == kInvalidBase) { int fd = open("/proc/self/auxv", O_RDONLY); if (fd == -1) { diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/ya.make b/contrib/restricted/abseil-cpp/absl/debugging/internal/ya.make index ef1dcbf7dd..b2cce7275c 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/ya.make +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/ya.make @@ -6,22 +6,22 @@ OWNER(g:cpp-contrib) LICENSE(Apache-2.0) -LICENSE_TEXTS(.yandex_meta/licenses.list.txt) - +LICENSE_TEXTS(.yandex_meta/licenses.list.txt) + PEERDIR( contrib/restricted/abseil-cpp/absl/base - contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc contrib/restricted/abseil-cpp/absl/base/internal/raw_logging contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/debugging - contrib/restricted/abseil-cpp/absl/debugging/stacktrace - contrib/restricted/abseil-cpp/absl/debugging/symbolize - contrib/restricted/abseil-cpp/absl/demangle + contrib/restricted/abseil-cpp/absl/debugging + contrib/restricted/abseil-cpp/absl/debugging/stacktrace + contrib/restricted/abseil-cpp/absl/debugging/symbolize + contrib/restricted/abseil-cpp/absl/demangle contrib/restricted/abseil-cpp/absl/numeric contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal ) ADDINCL( @@ -37,7 +37,7 @@ CFLAGS( ) SRCS( - examine_stack.cc + examine_stack.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/debugging/stacktrace.cc b/contrib/restricted/abseil-cpp/absl/debugging/stacktrace.cc index ff8069f843..531b6b433b 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/stacktrace.cc +++ b/contrib/restricted/abseil-cpp/absl/debugging/stacktrace.cc @@ -49,10 +49,10 @@ # include "absl/debugging/internal/stacktrace_aarch64-inl.inc" # include "absl/debugging/internal/stacktrace_arm-inl.inc" -# include "absl/debugging/internal/stacktrace_emscripten-inl.inc" +# include "absl/debugging/internal/stacktrace_emscripten-inl.inc" # include "absl/debugging/internal/stacktrace_generic-inl.inc" # include "absl/debugging/internal/stacktrace_powerpc-inl.inc" -# include "absl/debugging/internal/stacktrace_riscv-inl.inc" +# include "absl/debugging/internal/stacktrace_riscv-inl.inc" # include "absl/debugging/internal/stacktrace_unimplemented-inl.inc" # include "absl/debugging/internal/stacktrace_win32-inl.inc" # include "absl/debugging/internal/stacktrace_x86-inl.inc" diff --git a/contrib/restricted/abseil-cpp/absl/debugging/symbolize.cc b/contrib/restricted/abseil-cpp/absl/debugging/symbolize.cc index f1abdfda59..de8a381a0d 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/symbolize.cc +++ b/contrib/restricted/abseil-cpp/absl/debugging/symbolize.cc @@ -31,8 +31,8 @@ #include "absl/debugging/symbolize_win32.inc" #elif defined(__APPLE__) #include "absl/debugging/symbolize_darwin.inc" -#elif defined(__EMSCRIPTEN__) -#include "absl/debugging/symbolize_emscripten.inc" +#elif defined(__EMSCRIPTEN__) +#include "absl/debugging/symbolize_emscripten.inc" #else #include "absl/debugging/symbolize_unimplemented.inc" #endif diff --git a/contrib/restricted/abseil-cpp/absl/debugging/symbolize/ya.make b/contrib/restricted/abseil-cpp/absl/debugging/symbolize/ya.make index 5c25223100..1c5b008d69 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/symbolize/ya.make +++ b/contrib/restricted/abseil-cpp/absl/debugging/symbolize/ya.make @@ -10,16 +10,16 @@ LICENSE(Apache-2.0) PEERDIR( contrib/restricted/abseil-cpp/absl/base - contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc contrib/restricted/abseil-cpp/absl/base/internal/raw_logging contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/debugging - contrib/restricted/abseil-cpp/absl/demangle + contrib/restricted/abseil-cpp/absl/debugging + contrib/restricted/abseil-cpp/absl/demangle contrib/restricted/abseil-cpp/absl/numeric contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal ) ADDINCL( @@ -34,10 +34,10 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/debugging) +SRCDIR(contrib/restricted/abseil-cpp/absl/debugging) SRCS( - symbolize.cc + symbolize.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc b/contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc index 3ff343d64f..514bedbeb5 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc +++ b/contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc @@ -77,10 +77,10 @@ #include "absl/debugging/internal/vdso_support.h" #include "absl/strings/string_view.h" -#if defined(__FreeBSD__) && !defined(ElfW) -#define ElfW(x) __ElfN(x) -#endif - +#if defined(__FreeBSD__) && !defined(ElfW) +#define ElfW(x) __ElfN(x) +#endif + namespace absl { ABSL_NAMESPACE_BEGIN @@ -705,16 +705,16 @@ static ABSL_ATTRIBUTE_NOINLINE FindSymbolResult FindSymbol( const char *start_address = ComputeOffset(original_start_address, relocation); -#ifdef __arm__ - // ARM functions are always aligned to multiples of two bytes; the - // lowest-order bit in start_address is ignored by the CPU and indicates - // whether the function contains ARM (0) or Thumb (1) code. We don't care - // about what encoding is being used; we just want the real start address - // of the function. - start_address = reinterpret_cast<const char *>( - reinterpret_cast<uintptr_t>(start_address) & ~1); -#endif - +#ifdef __arm__ + // ARM functions are always aligned to multiples of two bytes; the + // lowest-order bit in start_address is ignored by the CPU and indicates + // whether the function contains ARM (0) or Thumb (1) code. We don't care + // about what encoding is being used; we just want the real start address + // of the function. + start_address = reinterpret_cast<const char *>( + reinterpret_cast<uintptr_t>(start_address) & ~1); +#endif + if (deref_function_descriptor_pointer && InSection(original_start_address, opd)) { // The opd section is mapped into memory. Just dereference diff --git a/contrib/restricted/abseil-cpp/absl/debugging/symbolize_emscripten.inc b/contrib/restricted/abseil-cpp/absl/debugging/symbolize_emscripten.inc index 3a51c91fe9..00e61086a6 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/symbolize_emscripten.inc +++ b/contrib/restricted/abseil-cpp/absl/debugging/symbolize_emscripten.inc @@ -1,72 +1,72 @@ -// Copyright 2020 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <cxxabi.h> -#error #include <emscripten.h> - -#include <algorithm> -#include <cstring> - -#include "absl/base/internal/raw_logging.h" -#include "absl/debugging/internal/demangle.h" -#include "absl/strings/numbers.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" - -extern "C" { -const char* emscripten_pc_get_function(const void* pc); -} - -// clang-format off -EM_JS(bool, HaveOffsetConverter, (), - { return typeof wasmOffsetConverter !== 'undefined'; }); -// clang-format on - -namespace absl { -ABSL_NAMESPACE_BEGIN - -void InitializeSymbolizer(const char*) { - if (!HaveOffsetConverter()) { - ABSL_RAW_LOG(INFO, - "Symbolization unavailable. Rebuild with -sWASM=1 " - "and -sUSE_OFFSET_CONVERTER=1."); - } -} - -bool Symbolize(const void* pc, char* out, int out_size) { - // Check if we have the offset converter necessary for pc_get_function. - // Without it, the program will abort(). - if (!HaveOffsetConverter()) { - return false; - } - const char* func_name = emscripten_pc_get_function(pc); - if (func_name == nullptr) { - return false; - } - - strncpy(out, func_name, out_size); - - if (out[out_size - 1] != '\0') { - // strncpy() does not '\0' terminate when it truncates. - static constexpr char kEllipsis[] = "..."; - int ellipsis_size = std::min<int>(sizeof(kEllipsis) - 1, out_size - 1); - memcpy(out + out_size - ellipsis_size - 1, kEllipsis, ellipsis_size); - out[out_size - 1] = '\0'; - } - - return true; -} - -ABSL_NAMESPACE_END -} // namespace absl +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <cxxabi.h> +#error #include <emscripten.h> + +#include <algorithm> +#include <cstring> + +#include "absl/base/internal/raw_logging.h" +#include "absl/debugging/internal/demangle.h" +#include "absl/strings/numbers.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" + +extern "C" { +const char* emscripten_pc_get_function(const void* pc); +} + +// clang-format off +EM_JS(bool, HaveOffsetConverter, (), + { return typeof wasmOffsetConverter !== 'undefined'; }); +// clang-format on + +namespace absl { +ABSL_NAMESPACE_BEGIN + +void InitializeSymbolizer(const char*) { + if (!HaveOffsetConverter()) { + ABSL_RAW_LOG(INFO, + "Symbolization unavailable. Rebuild with -sWASM=1 " + "and -sUSE_OFFSET_CONVERTER=1."); + } +} + +bool Symbolize(const void* pc, char* out, int out_size) { + // Check if we have the offset converter necessary for pc_get_function. + // Without it, the program will abort(). + if (!HaveOffsetConverter()) { + return false; + } + const char* func_name = emscripten_pc_get_function(pc); + if (func_name == nullptr) { + return false; + } + + strncpy(out, func_name, out_size); + + if (out[out_size - 1] != '\0') { + // strncpy() does not '\0' terminate when it truncates. + static constexpr char kEllipsis[] = "..."; + int ellipsis_size = std::min<int>(sizeof(kEllipsis) - 1, out_size - 1); + memcpy(out + out_size - ellipsis_size - 1, kEllipsis, ellipsis_size); + out[out_size - 1] = '\0'; + } + + return true; +} + +ABSL_NAMESPACE_END +} // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/flags/commandlineflag/ya.make b/contrib/restricted/abseil-cpp/absl/flags/commandlineflag/ya.make index 4eef7c0237..86f270627a 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/commandlineflag/ya.make +++ b/contrib/restricted/abseil-cpp/absl/flags/commandlineflag/ya.make @@ -14,10 +14,10 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag + contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag contrib/restricted/abseil-cpp/absl/numeric contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal contrib/restricted/abseil-cpp/absl/types/bad_optional_access ) @@ -33,10 +33,10 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/flags) +SRCDIR(contrib/restricted/abseil-cpp/absl/flags) SRCS( - commandlineflag.cc + commandlineflag.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/flags/flag.h b/contrib/restricted/abseil-cpp/absl/flags/flag.h index a724ccc97d..9b0e686556 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/flag.h +++ b/contrib/restricted/abseil-cpp/absl/flags/flag.h @@ -71,7 +71,7 @@ ABSL_NAMESPACE_BEGIN template <typename T> using Flag = flags_internal::Flag<T>; #else -#include "absl/flags/internal/flag_msvc.inc" +#include "absl/flags/internal/flag_msvc.inc" #endif // GetFlag() @@ -171,8 +171,8 @@ ABSL_NAMESPACE_END // // ABSL_FLAG(T, name, default_value, help).OnUpdate(callback); // -// `callback` should be convertible to `void (*)()`. -// +// `callback` should be convertible to `void (*)()`. +// // After any setting of the flag value, the callback will be called at least // once. A rapid sequence of changes may be merged together into the same // callback. No concurrent calls to the callback will be made for the same @@ -241,8 +241,8 @@ ABSL_NAMESPACE_END /* default value argument. That keeps temporaries alive */ \ /* long enough for NonConst to work correctly. */ \ static constexpr absl::string_view Value( \ - absl::string_view absl_flag_help = ABSL_FLAG_IMPL_FLAGHELP(txt)) { \ - return absl_flag_help; \ + absl::string_view absl_flag_help = ABSL_FLAG_IMPL_FLAGHELP(txt)) { \ + return absl_flag_help; \ } \ static std::string NonConst() { return std::string(Value()); } \ }; \ @@ -254,8 +254,8 @@ ABSL_NAMESPACE_END #define ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value) \ struct AbslFlagDefaultGenFor##name { \ Type value = absl::flags_internal::InitDefaultValue<Type>(default_value); \ - static void Gen(void* absl_flag_default_loc) { \ - new (absl_flag_default_loc) Type(AbslFlagDefaultGenFor##name{}.value); \ + static void Gen(void* absl_flag_default_loc) { \ + new (absl_flag_default_loc) Type(AbslFlagDefaultGenFor##name{}.value); \ } \ }; diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/flag.cc b/contrib/restricted/abseil-cpp/absl/flags/internal/flag.cc index 1515022d11..b35493630a 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/flag.cc +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/flag.cc @@ -145,7 +145,7 @@ void FlagImpl::Init() { auto def_kind = static_cast<FlagDefaultKind>(def_kind_); switch (ValueStorageKind()) { - case FlagValueStorageKind::kValueAndInitBit: + case FlagValueStorageKind::kValueAndInitBit: case FlagValueStorageKind::kOneWordAtomic: { alignas(int64_t) std::array<char, sizeof(int64_t)> buf{}; if (def_kind == FlagDefaultKind::kGenFunc) { @@ -154,12 +154,12 @@ void FlagImpl::Init() { assert(def_kind != FlagDefaultKind::kDynamicValue); std::memcpy(buf.data(), &default_value_, Sizeof(op_)); } - if (ValueStorageKind() == FlagValueStorageKind::kValueAndInitBit) { - // We presume here the memory layout of FlagValueAndInitBit struct. - uint8_t initialized = 1; - std::memcpy(buf.data() + Sizeof(op_), &initialized, - sizeof(initialized)); - } + if (ValueStorageKind() == FlagValueStorageKind::kValueAndInitBit) { + // We presume here the memory layout of FlagValueAndInitBit struct. + uint8_t initialized = 1; + std::memcpy(buf.data() + Sizeof(op_), &initialized, + sizeof(initialized)); + } OneWordValue().store(absl::bit_cast<int64_t>(buf), std::memory_order_release); break; @@ -171,12 +171,12 @@ void FlagImpl::Init() { (*default_value_.gen_func)(AtomicBufferValue()); break; } - case FlagValueStorageKind::kAlignedBuffer: - // For this storage kind the default_value_ always points to gen_func - // during initialization. - assert(def_kind == FlagDefaultKind::kGenFunc); - (*default_value_.gen_func)(AlignedBufferValue()); - break; + case FlagValueStorageKind::kAlignedBuffer: + // For this storage kind the default_value_ always points to gen_func + // during initialization. + assert(def_kind == FlagDefaultKind::kGenFunc); + (*default_value_.gen_func)(AlignedBufferValue()); + break; } seq_lock_.MarkInitialized(); } @@ -233,10 +233,10 @@ std::unique_ptr<void, DynValueDeleter> FlagImpl::MakeInitValue() const { void FlagImpl::StoreValue(const void* src) { switch (ValueStorageKind()) { - case FlagValueStorageKind::kValueAndInitBit: + case FlagValueStorageKind::kValueAndInitBit: case FlagValueStorageKind::kOneWordAtomic: { - // Load the current value to avoid setting 'init' bit manualy. - int64_t one_word_val = OneWordValue().load(std::memory_order_acquire); + // Load the current value to avoid setting 'init' bit manualy. + int64_t one_word_val = OneWordValue().load(std::memory_order_acquire); std::memcpy(&one_word_val, src, Sizeof(op_)); OneWordValue().store(one_word_val, std::memory_order_release); seq_lock_.IncrementModificationCount(); @@ -246,10 +246,10 @@ void FlagImpl::StoreValue(const void* src) { seq_lock_.Write(AtomicBufferValue(), src, Sizeof(op_)); break; } - case FlagValueStorageKind::kAlignedBuffer: - Copy(op_, src, AlignedBufferValue()); - seq_lock_.IncrementModificationCount(); - break; + case FlagValueStorageKind::kAlignedBuffer: + Copy(op_, src, AlignedBufferValue()); + seq_lock_.IncrementModificationCount(); + break; } modified_ = true; InvokeCallback(); @@ -289,7 +289,7 @@ std::string FlagImpl::DefaultValue() const { std::string FlagImpl::CurrentValue() const { auto* guard = DataGuard(); // Make sure flag initialized switch (ValueStorageKind()) { - case FlagValueStorageKind::kValueAndInitBit: + case FlagValueStorageKind::kValueAndInitBit: case FlagValueStorageKind::kOneWordAtomic: { const auto one_word_val = absl::bit_cast<std::array<char, sizeof(int64_t)>>( @@ -302,10 +302,10 @@ std::string FlagImpl::CurrentValue() const { ReadSequenceLockedData(cloned.get()); return flags_internal::Unparse(op_, cloned.get()); } - case FlagValueStorageKind::kAlignedBuffer: { - absl::MutexLock l(guard); - return flags_internal::Unparse(op_, AlignedBufferValue()); - } + case FlagValueStorageKind::kAlignedBuffer: { + absl::MutexLock l(guard); + return flags_internal::Unparse(op_, AlignedBufferValue()); + } } return ""; @@ -351,7 +351,7 @@ std::unique_ptr<FlagStateInterface> FlagImpl::SaveState() { bool modified = modified_; bool on_command_line = on_command_line_; switch (ValueStorageKind()) { - case FlagValueStorageKind::kValueAndInitBit: + case FlagValueStorageKind::kValueAndInitBit: case FlagValueStorageKind::kOneWordAtomic: { return absl::make_unique<FlagState>( *this, OneWordValue().load(std::memory_order_acquire), modified, @@ -367,11 +367,11 @@ std::unique_ptr<FlagStateInterface> FlagImpl::SaveState() { return absl::make_unique<FlagState>(*this, cloned, modified, on_command_line, ModificationCount()); } - case FlagValueStorageKind::kAlignedBuffer: { - return absl::make_unique<FlagState>( - *this, flags_internal::Clone(op_, AlignedBufferValue()), modified, - on_command_line, ModificationCount()); - } + case FlagValueStorageKind::kAlignedBuffer: { + return absl::make_unique<FlagState>( + *this, flags_internal::Clone(op_, AlignedBufferValue()), modified, + on_command_line, ModificationCount()); + } } return nullptr; } @@ -383,11 +383,11 @@ bool FlagImpl::RestoreState(const FlagState& flag_state) { } switch (ValueStorageKind()) { - case FlagValueStorageKind::kValueAndInitBit: - case FlagValueStorageKind::kOneWordAtomic: - StoreValue(&flag_state.value_.one_word); - break; - case FlagValueStorageKind::kSequenceLocked: + case FlagValueStorageKind::kValueAndInitBit: + case FlagValueStorageKind::kOneWordAtomic: + StoreValue(&flag_state.value_.one_word); + break; + case FlagValueStorageKind::kSequenceLocked: case FlagValueStorageKind::kAlignedBuffer: StoreValue(flag_state.value_.heap_allocated); break; @@ -419,8 +419,8 @@ std::atomic<uint64_t>* FlagImpl::AtomicBufferValue() const { } std::atomic<int64_t>& FlagImpl::OneWordValue() const { - assert(ValueStorageKind() == FlagValueStorageKind::kOneWordAtomic || - ValueStorageKind() == FlagValueStorageKind::kValueAndInitBit); + assert(ValueStorageKind() == FlagValueStorageKind::kOneWordAtomic || + ValueStorageKind() == FlagValueStorageKind::kValueAndInitBit); return OffsetValue<FlagOneWordValue>()->value; } @@ -446,7 +446,7 @@ std::unique_ptr<void, DynValueDeleter> FlagImpl::TryParse( void FlagImpl::Read(void* dst) const { auto* guard = DataGuard(); // Make sure flag initialized switch (ValueStorageKind()) { - case FlagValueStorageKind::kValueAndInitBit: + case FlagValueStorageKind::kValueAndInitBit: case FlagValueStorageKind::kOneWordAtomic: { const int64_t one_word_val = OneWordValue().load(std::memory_order_acquire); @@ -457,31 +457,31 @@ void FlagImpl::Read(void* dst) const { ReadSequenceLockedData(dst); break; } - case FlagValueStorageKind::kAlignedBuffer: { - absl::MutexLock l(guard); - flags_internal::CopyConstruct(op_, AlignedBufferValue(), dst); - break; - } + case FlagValueStorageKind::kAlignedBuffer: { + absl::MutexLock l(guard); + flags_internal::CopyConstruct(op_, AlignedBufferValue(), dst); + break; + } } } -int64_t FlagImpl::ReadOneWord() const { - assert(ValueStorageKind() == FlagValueStorageKind::kOneWordAtomic || - ValueStorageKind() == FlagValueStorageKind::kValueAndInitBit); - auto* guard = DataGuard(); // Make sure flag initialized - (void)guard; - return OneWordValue().load(std::memory_order_acquire); -} - -bool FlagImpl::ReadOneBool() const { - assert(ValueStorageKind() == FlagValueStorageKind::kValueAndInitBit); - auto* guard = DataGuard(); // Make sure flag initialized - (void)guard; - return absl::bit_cast<FlagValueAndInitBit<bool>>( - OneWordValue().load(std::memory_order_acquire)) - .value; -} - +int64_t FlagImpl::ReadOneWord() const { + assert(ValueStorageKind() == FlagValueStorageKind::kOneWordAtomic || + ValueStorageKind() == FlagValueStorageKind::kValueAndInitBit); + auto* guard = DataGuard(); // Make sure flag initialized + (void)guard; + return OneWordValue().load(std::memory_order_acquire); +} + +bool FlagImpl::ReadOneBool() const { + assert(ValueStorageKind() == FlagValueStorageKind::kValueAndInitBit); + auto* guard = DataGuard(); // Make sure flag initialized + (void)guard; + return absl::bit_cast<FlagValueAndInitBit<bool>>( + OneWordValue().load(std::memory_order_acquire)) + .value; +} + void FlagImpl::ReadSequenceLockedData(void* dst) const { int size = Sizeof(op_); // Attempt to read using the sequence lock. diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/flag.h b/contrib/restricted/abseil-cpp/absl/flags/internal/flag.h index 124a2f1c03..34919c5cd5 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/flag.h +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/flag.h @@ -29,7 +29,7 @@ #include "absl/base/attributes.h" #include "absl/base/call_once.h" -#include "absl/base/casts.h" +#include "absl/base/casts.h" #include "absl/base/config.h" #include "absl/base/optimization.h" #include "absl/base/thread_annotations.h" @@ -290,7 +290,7 @@ constexpr T InitDefaultValue(EmptyBraces) { template <typename ValueT, typename GenT, typename std::enable_if<std::is_integral<ValueT>::value, int>::type = - ((void)GenT{}, 0)> + ((void)GenT{}, 0)> constexpr FlagDefaultArg DefaultArg(int) { return {FlagDefaultSrc(GenT{}.value), FlagDefaultKind::kOneWord}; } @@ -306,71 +306,71 @@ constexpr FlagDefaultArg DefaultArg(char) { constexpr int64_t UninitializedFlagValue() { return 0xababababababababll; } template <typename T> -using FlagUseValueAndInitBitStorage = std::integral_constant< - bool, absl::type_traits_internal::is_trivially_copyable<T>::value && - std::is_default_constructible<T>::value && (sizeof(T) < 8)>; - -template <typename T> +using FlagUseValueAndInitBitStorage = std::integral_constant< + bool, absl::type_traits_internal::is_trivially_copyable<T>::value && + std::is_default_constructible<T>::value && (sizeof(T) < 8)>; + +template <typename T> using FlagUseOneWordStorage = std::integral_constant< bool, absl::type_traits_internal::is_trivially_copyable<T>::value && (sizeof(T) <= 8)>; template <class T> -using FlagUseSequenceLockStorage = std::integral_constant< +using FlagUseSequenceLockStorage = std::integral_constant< bool, absl::type_traits_internal::is_trivially_copyable<T>::value && (sizeof(T) > 8)>; enum class FlagValueStorageKind : uint8_t { - kValueAndInitBit = 0, + kValueAndInitBit = 0, kOneWordAtomic = 1, kSequenceLocked = 2, - kAlignedBuffer = 3, + kAlignedBuffer = 3, }; template <typename T> static constexpr FlagValueStorageKind StorageKind() { - return FlagUseValueAndInitBitStorage<T>::value - ? FlagValueStorageKind::kValueAndInitBit - : FlagUseOneWordStorage<T>::value - ? FlagValueStorageKind::kOneWordAtomic - : FlagUseSequenceLockStorage<T>::value + return FlagUseValueAndInitBitStorage<T>::value + ? FlagValueStorageKind::kValueAndInitBit + : FlagUseOneWordStorage<T>::value + ? FlagValueStorageKind::kOneWordAtomic + : FlagUseSequenceLockStorage<T>::value ? FlagValueStorageKind::kSequenceLocked : FlagValueStorageKind::kAlignedBuffer; } struct FlagOneWordValue { - constexpr explicit FlagOneWordValue(int64_t v) : value(v) {} + constexpr explicit FlagOneWordValue(int64_t v) : value(v) {} std::atomic<int64_t> value; }; -template <typename T> -struct alignas(8) FlagValueAndInitBit { - T value; - // Use an int instead of a bool to guarantee that a non-zero value has - // a bit set. - uint8_t init; -}; - +template <typename T> +struct alignas(8) FlagValueAndInitBit { + T value; + // Use an int instead of a bool to guarantee that a non-zero value has + // a bit set. + uint8_t init; +}; + template <typename T, FlagValueStorageKind Kind = flags_internal::StorageKind<T>()> struct FlagValue; template <typename T> -struct FlagValue<T, FlagValueStorageKind::kValueAndInitBit> : FlagOneWordValue { - constexpr FlagValue() : FlagOneWordValue(0) {} - bool Get(const SequenceLock&, T& dst) const { - int64_t storage = value.load(std::memory_order_acquire); - if (ABSL_PREDICT_FALSE(storage == 0)) { - return false; - } - dst = absl::bit_cast<FlagValueAndInitBit<T>>(storage).value; - return true; - } +struct FlagValue<T, FlagValueStorageKind::kValueAndInitBit> : FlagOneWordValue { + constexpr FlagValue() : FlagOneWordValue(0) {} + bool Get(const SequenceLock&, T& dst) const { + int64_t storage = value.load(std::memory_order_acquire); + if (ABSL_PREDICT_FALSE(storage == 0)) { + return false; + } + dst = absl::bit_cast<FlagValueAndInitBit<T>>(storage).value; + return true; + } }; template <typename T> struct FlagValue<T, FlagValueStorageKind::kOneWordAtomic> : FlagOneWordValue { - constexpr FlagValue() : FlagOneWordValue(UninitializedFlagValue()) {} + constexpr FlagValue() : FlagOneWordValue(UninitializedFlagValue()) {} bool Get(const SequenceLock&, T& dst) const { int64_t one_word_val = value.load(std::memory_order_acquire); if (ABSL_PREDICT_FALSE(one_word_val == UninitializedFlagValue())) { @@ -394,13 +394,13 @@ struct FlagValue<T, FlagValueStorageKind::kSequenceLocked> { std::atomic<uint64_t>) std::atomic<uint64_t> value_words[kNumWords]; }; -template <typename T> -struct FlagValue<T, FlagValueStorageKind::kAlignedBuffer> { - bool Get(const SequenceLock&, T&) const { return false; } - - alignas(T) char value[sizeof(T)]; -}; - +template <typename T> +struct FlagValue<T, FlagValueStorageKind::kAlignedBuffer> { + bool Get(const SequenceLock&, T&) const { return false; } + + alignas(T) char value[sizeof(T)]; +}; + /////////////////////////////////////////////////////////////////////////////// // Flag callback auxiliary structs. @@ -446,27 +446,27 @@ class FlagImpl final : public CommandLineFlag { data_guard_{} {} // Constant access methods - int64_t ReadOneWord() const ABSL_LOCKS_EXCLUDED(*DataGuard()); - bool ReadOneBool() const ABSL_LOCKS_EXCLUDED(*DataGuard()); + int64_t ReadOneWord() const ABSL_LOCKS_EXCLUDED(*DataGuard()); + bool ReadOneBool() const ABSL_LOCKS_EXCLUDED(*DataGuard()); void Read(void* dst) const override ABSL_LOCKS_EXCLUDED(*DataGuard()); - void Read(bool* value) const ABSL_LOCKS_EXCLUDED(*DataGuard()) { - *value = ReadOneBool(); - } - template <typename T, - absl::enable_if_t<flags_internal::StorageKind<T>() == - FlagValueStorageKind::kOneWordAtomic, - int> = 0> - void Read(T* value) const ABSL_LOCKS_EXCLUDED(*DataGuard()) { - int64_t v = ReadOneWord(); - std::memcpy(value, static_cast<const void*>(&v), sizeof(T)); - } - template <typename T, - typename std::enable_if<flags_internal::StorageKind<T>() == - FlagValueStorageKind::kValueAndInitBit, - int>::type = 0> - void Read(T* value) const ABSL_LOCKS_EXCLUDED(*DataGuard()) { - *value = absl::bit_cast<FlagValueAndInitBit<T>>(ReadOneWord()).value; - } + void Read(bool* value) const ABSL_LOCKS_EXCLUDED(*DataGuard()) { + *value = ReadOneBool(); + } + template <typename T, + absl::enable_if_t<flags_internal::StorageKind<T>() == + FlagValueStorageKind::kOneWordAtomic, + int> = 0> + void Read(T* value) const ABSL_LOCKS_EXCLUDED(*DataGuard()) { + int64_t v = ReadOneWord(); + std::memcpy(value, static_cast<const void*>(&v), sizeof(T)); + } + template <typename T, + typename std::enable_if<flags_internal::StorageKind<T>() == + FlagValueStorageKind::kValueAndInitBit, + int>::type = 0> + void Read(T* value) const ABSL_LOCKS_EXCLUDED(*DataGuard()) { + *value = absl::bit_cast<FlagValueAndInitBit<T>>(ReadOneWord()).value; + } // Mutating access methods void Write(const void* src) ABSL_LOCKS_EXCLUDED(*DataGuard()); diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/flag/ya.make b/contrib/restricted/abseil-cpp/absl/flags/internal/flag/ya.make index 76f47ce655..2ac628a00e 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/flag/ya.make +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/flag/ya.make @@ -10,29 +10,29 @@ LICENSE(Apache-2.0) PEERDIR( contrib/restricted/abseil-cpp/absl/base - contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc contrib/restricted/abseil-cpp/absl/base/internal/raw_logging contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/debugging - contrib/restricted/abseil-cpp/absl/debugging/stacktrace - contrib/restricted/abseil-cpp/absl/debugging/symbolize - contrib/restricted/abseil-cpp/absl/demangle - contrib/restricted/abseil-cpp/absl/flags/commandlineflag - contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag - contrib/restricted/abseil-cpp/absl/flags/internal/program_name - contrib/restricted/abseil-cpp/absl/flags/marshalling - contrib/restricted/abseil-cpp/absl/flags/usage_config + contrib/restricted/abseil-cpp/absl/debugging + contrib/restricted/abseil-cpp/absl/debugging/stacktrace + contrib/restricted/abseil-cpp/absl/debugging/symbolize + contrib/restricted/abseil-cpp/absl/demangle + contrib/restricted/abseil-cpp/absl/flags/commandlineflag + contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag + contrib/restricted/abseil-cpp/absl/flags/internal/program_name + contrib/restricted/abseil-cpp/absl/flags/marshalling + contrib/restricted/abseil-cpp/absl/flags/usage_config contrib/restricted/abseil-cpp/absl/numeric contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp/absl/strings/internal/str_format - contrib/restricted/abseil-cpp/absl/synchronization - contrib/restricted/abseil-cpp/absl/synchronization/internal - contrib/restricted/abseil-cpp/absl/time - contrib/restricted/abseil-cpp/absl/time/civil_time - contrib/restricted/abseil-cpp/absl/time/time_zone + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/str_format + contrib/restricted/abseil-cpp/absl/synchronization + contrib/restricted/abseil-cpp/absl/synchronization/internal + contrib/restricted/abseil-cpp/absl/time + contrib/restricted/abseil-cpp/absl/time/civil_time + contrib/restricted/abseil-cpp/absl/time/time_zone contrib/restricted/abseil-cpp/absl/types/bad_optional_access ) @@ -48,10 +48,10 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/flags/internal) +SRCDIR(contrib/restricted/abseil-cpp/absl/flags/internal) SRCS( - flag.cc + flag.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/flag_msvc.inc b/contrib/restricted/abseil-cpp/absl/flags/internal/flag_msvc.inc index c31bd27fd8..253524f455 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/flag_msvc.inc +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/flag_msvc.inc @@ -1,116 +1,116 @@ -// -// Copyright 2021 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Do not include this file directly. -// Include absl/flags/flag.h instead. - -// MSVC debug builds do not implement initialization with constexpr constructors -// correctly. To work around this we add a level of indirection, so that the -// class `absl::Flag` contains an `internal::Flag*` (instead of being an alias -// to that class) and dynamically allocates an instance when necessary. We also -// forward all calls to internal::Flag methods via trampoline methods. In this -// setup the `absl::Flag` class does not have constructor and virtual methods, -// all the data members are public and thus MSVC is able to initialize it at -// link time. To deal with multiple threads accessing the flag for the first -// time concurrently we use an atomic boolean indicating if flag object is -// initialized. We also employ the double-checked locking pattern where the -// second level of protection is a global Mutex, so if two threads attempt to -// construct the flag concurrently only one wins. -// -// This solution is based on a recomendation here: -// https://developercommunity.visualstudio.com/content/problem/336946/class-with-constexpr-constructor-not-using-static.html?childToView=648454#comment-648454 - -namespace flags_internal { -absl::Mutex* GetGlobalConstructionGuard(); -} // namespace flags_internal - -// Public methods of `absl::Flag<T>` are NOT part of the Abseil Flags API. -// See https://abseil.io/docs/cpp/guides/flags -template <typename T> -class Flag { - public: - // No constructor and destructor to ensure this is an aggregate type. - // Visual Studio 2015 still requires the constructor for class to be - // constexpr initializable. -#if _MSC_VER <= 1900 - constexpr Flag(const char* name, const char* filename, - const flags_internal::HelpGenFunc help_gen, - const flags_internal::FlagDfltGenFunc default_value_gen) - : name_(name), - filename_(filename), - help_gen_(help_gen), - default_value_gen_(default_value_gen), - inited_(false), - impl_(nullptr) {} -#endif - - flags_internal::Flag<T>& GetImpl() const { - if (!inited_.load(std::memory_order_acquire)) { - absl::MutexLock l(flags_internal::GetGlobalConstructionGuard()); - - if (inited_.load(std::memory_order_acquire)) { - return *impl_; - } - - impl_ = new flags_internal::Flag<T>( - name_, filename_, - {flags_internal::FlagHelpMsg(help_gen_), - flags_internal::FlagHelpKind::kGenFunc}, - {flags_internal::FlagDefaultSrc(default_value_gen_), - flags_internal::FlagDefaultKind::kGenFunc}); - inited_.store(true, std::memory_order_release); - } - - return *impl_; - } - - // Public methods of `absl::Flag<T>` are NOT part of the Abseil Flags API. - // See https://abseil.io/docs/cpp/guides/flags - bool IsRetired() const { return GetImpl().IsRetired(); } - absl::string_view Name() const { return GetImpl().Name(); } - std::string Help() const { return GetImpl().Help(); } - bool IsModified() const { return GetImpl().IsModified(); } - bool IsSpecifiedOnCommandLine() const { - return GetImpl().IsSpecifiedOnCommandLine(); - } - std::string Filename() const { return GetImpl().Filename(); } - std::string DefaultValue() const { return GetImpl().DefaultValue(); } - std::string CurrentValue() const { return GetImpl().CurrentValue(); } - template <typename U> - inline bool IsOfType() const { - return GetImpl().template IsOfType<U>(); - } - T Get() const { - return flags_internal::FlagImplPeer::InvokeGet<T>(GetImpl()); - } - void Set(const T& v) { - flags_internal::FlagImplPeer::InvokeSet(GetImpl(), v); - } - void InvokeCallback() { GetImpl().InvokeCallback(); } - - const CommandLineFlag& Reflect() const { - return flags_internal::FlagImplPeer::InvokeReflect(GetImpl()); - } - - // The data members are logically private, but they need to be public for - // this to be an aggregate type. - const char* name_; - const char* filename_; - const flags_internal::HelpGenFunc help_gen_; - const flags_internal::FlagDfltGenFunc default_value_gen_; - - mutable std::atomic<bool> inited_; - mutable flags_internal::Flag<T>* impl_; -}; +// +// Copyright 2021 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Do not include this file directly. +// Include absl/flags/flag.h instead. + +// MSVC debug builds do not implement initialization with constexpr constructors +// correctly. To work around this we add a level of indirection, so that the +// class `absl::Flag` contains an `internal::Flag*` (instead of being an alias +// to that class) and dynamically allocates an instance when necessary. We also +// forward all calls to internal::Flag methods via trampoline methods. In this +// setup the `absl::Flag` class does not have constructor and virtual methods, +// all the data members are public and thus MSVC is able to initialize it at +// link time. To deal with multiple threads accessing the flag for the first +// time concurrently we use an atomic boolean indicating if flag object is +// initialized. We also employ the double-checked locking pattern where the +// second level of protection is a global Mutex, so if two threads attempt to +// construct the flag concurrently only one wins. +// +// This solution is based on a recomendation here: +// https://developercommunity.visualstudio.com/content/problem/336946/class-with-constexpr-constructor-not-using-static.html?childToView=648454#comment-648454 + +namespace flags_internal { +absl::Mutex* GetGlobalConstructionGuard(); +} // namespace flags_internal + +// Public methods of `absl::Flag<T>` are NOT part of the Abseil Flags API. +// See https://abseil.io/docs/cpp/guides/flags +template <typename T> +class Flag { + public: + // No constructor and destructor to ensure this is an aggregate type. + // Visual Studio 2015 still requires the constructor for class to be + // constexpr initializable. +#if _MSC_VER <= 1900 + constexpr Flag(const char* name, const char* filename, + const flags_internal::HelpGenFunc help_gen, + const flags_internal::FlagDfltGenFunc default_value_gen) + : name_(name), + filename_(filename), + help_gen_(help_gen), + default_value_gen_(default_value_gen), + inited_(false), + impl_(nullptr) {} +#endif + + flags_internal::Flag<T>& GetImpl() const { + if (!inited_.load(std::memory_order_acquire)) { + absl::MutexLock l(flags_internal::GetGlobalConstructionGuard()); + + if (inited_.load(std::memory_order_acquire)) { + return *impl_; + } + + impl_ = new flags_internal::Flag<T>( + name_, filename_, + {flags_internal::FlagHelpMsg(help_gen_), + flags_internal::FlagHelpKind::kGenFunc}, + {flags_internal::FlagDefaultSrc(default_value_gen_), + flags_internal::FlagDefaultKind::kGenFunc}); + inited_.store(true, std::memory_order_release); + } + + return *impl_; + } + + // Public methods of `absl::Flag<T>` are NOT part of the Abseil Flags API. + // See https://abseil.io/docs/cpp/guides/flags + bool IsRetired() const { return GetImpl().IsRetired(); } + absl::string_view Name() const { return GetImpl().Name(); } + std::string Help() const { return GetImpl().Help(); } + bool IsModified() const { return GetImpl().IsModified(); } + bool IsSpecifiedOnCommandLine() const { + return GetImpl().IsSpecifiedOnCommandLine(); + } + std::string Filename() const { return GetImpl().Filename(); } + std::string DefaultValue() const { return GetImpl().DefaultValue(); } + std::string CurrentValue() const { return GetImpl().CurrentValue(); } + template <typename U> + inline bool IsOfType() const { + return GetImpl().template IsOfType<U>(); + } + T Get() const { + return flags_internal::FlagImplPeer::InvokeGet<T>(GetImpl()); + } + void Set(const T& v) { + flags_internal::FlagImplPeer::InvokeSet(GetImpl(), v); + } + void InvokeCallback() { GetImpl().InvokeCallback(); } + + const CommandLineFlag& Reflect() const { + return flags_internal::FlagImplPeer::InvokeReflect(GetImpl()); + } + + // The data members are logically private, but they need to be public for + // this to be an aggregate type. + const char* name_; + const char* filename_; + const flags_internal::HelpGenFunc help_gen_; + const flags_internal::FlagDfltGenFunc default_value_gen_; + + mutable std::atomic<bool> inited_; + mutable flags_internal::Flag<T>* impl_; +}; diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor/ya.make b/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor/ya.make index 80a55d0f76..2471fa42c3 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor/ya.make +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor/ya.make @@ -2,8 +2,8 @@ LIBRARY() -WITHOUT_LICENSE_TEXTS() - +WITHOUT_LICENSE_TEXTS() + OWNER(g:cpp-contrib) LICENSE(Apache-2.0) @@ -14,12 +14,12 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/flags/commandlineflag - contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag + contrib/restricted/abseil-cpp/absl/flags/commandlineflag + contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag contrib/restricted/abseil-cpp/absl/numeric - contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp/absl/types/bad_optional_access + contrib/restricted/abseil-cpp/absl/strings + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/types/bad_optional_access ) ADDINCL( @@ -34,10 +34,10 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/flags/internal) - +SRCDIR(contrib/restricted/abseil-cpp/absl/flags/internal) + SRCS( - private_handle_accessor.cc + private_handle_accessor.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/program_name/ya.make b/contrib/restricted/abseil-cpp/absl/flags/internal/program_name/ya.make index 701fef73c0..bc8d9ab96e 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/program_name/ya.make +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/program_name/ya.make @@ -21,7 +21,7 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/demangle contrib/restricted/abseil-cpp/absl/numeric contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal contrib/restricted/abseil-cpp/absl/synchronization contrib/restricted/abseil-cpp/absl/synchronization/internal contrib/restricted/abseil-cpp/absl/time @@ -41,10 +41,10 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/flags/internal) +SRCDIR(contrib/restricted/abseil-cpp/absl/flags/internal) SRCS( - program_name.cc + program_name.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/sequence_lock.h b/contrib/restricted/abseil-cpp/absl/flags/internal/sequence_lock.h index 36318ab9d3..cc5285a4a2 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/sequence_lock.h +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/sequence_lock.h @@ -49,7 +49,7 @@ inline constexpr size_t AlignUp(size_t x, size_t align) { // The memory reads and writes protected by this lock must use the provided // `TryRead()` and `Write()` functions. These functions behave similarly to // `memcpy()`, with one oddity: the protected data must be an array of -// `std::atomic<uint64>`. This is to comply with the C++ standard, which +// `std::atomic<uint64>`. This is to comply with the C++ standard, which // considers data races on non-atomic objects to be undefined behavior. See "Can // Seqlocks Get Along With Programming Language Memory Models?"[1] by Hans J. // Boehm for more details. diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/usage.cc b/contrib/restricted/abseil-cpp/absl/flags/internal/usage.cc index 949709e883..6c9c02e1df 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/usage.cc +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/usage.cc @@ -245,7 +245,7 @@ void FlagsHelpImpl(std::ostream& out, PerFlagFilter filter_cb, << XMLElement("usage", program_usage_message) << '\n'; } - // Ordered map of package name to + // Ordered map of package name to // map of file name to // vector of flags in the file. // This map is used to output matching flags grouped by package and file @@ -273,26 +273,26 @@ void FlagsHelpImpl(std::ostream& out, PerFlagFilter filter_cb, absl::string_view package_separator; // controls blank lines between packages absl::string_view file_separator; // controls blank lines between files - for (auto& package : matching_flags) { + for (auto& package : matching_flags) { if (format == HelpFormat::kHumanReadable) { out << package_separator; package_separator = "\n\n"; } file_separator = ""; - for (auto& flags_in_file : package.second) { + for (auto& flags_in_file : package.second) { if (format == HelpFormat::kHumanReadable) { out << file_separator << " Flags from " << flags_in_file.first << ":\n"; file_separator = "\n"; } - std::sort(std::begin(flags_in_file.second), - std::end(flags_in_file.second), - [](const CommandLineFlag* lhs, const CommandLineFlag* rhs) { - return lhs->Name() < rhs->Name(); - }); - + std::sort(std::begin(flags_in_file.second), + std::end(flags_in_file.second), + [](const CommandLineFlag* lhs, const CommandLineFlag* rhs) { + return lhs->Name() < rhs->Name(); + }); + for (const auto* flag : flags_in_file.second) { flags_internal::FlagHelp(out, *flag, format); } diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/usage/ya.make b/contrib/restricted/abseil-cpp/absl/flags/internal/usage/ya.make index 358744df59..505ba08f96 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/usage/ya.make +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/usage/ya.make @@ -15,39 +15,39 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/city - contrib/restricted/abseil-cpp/absl/container/internal/absl_hashtablez_sampler - contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set + contrib/restricted/abseil-cpp/absl/city + contrib/restricted/abseil-cpp/absl/container/internal/absl_hashtablez_sampler + contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set contrib/restricted/abseil-cpp/absl/debugging contrib/restricted/abseil-cpp/absl/debugging/stacktrace contrib/restricted/abseil-cpp/absl/debugging/symbolize contrib/restricted/abseil-cpp/absl/demangle - contrib/restricted/abseil-cpp/absl/flags - contrib/restricted/abseil-cpp/absl/flags/commandlineflag - contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag - contrib/restricted/abseil-cpp/absl/flags/internal/flag - contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor - contrib/restricted/abseil-cpp/absl/flags/internal/program_name - contrib/restricted/abseil-cpp/absl/flags/marshalling - contrib/restricted/abseil-cpp/absl/flags/reflection - contrib/restricted/abseil-cpp/absl/flags/usage_config - contrib/restricted/abseil-cpp/absl/hash - contrib/restricted/abseil-cpp/absl/hash/internal + contrib/restricted/abseil-cpp/absl/flags + contrib/restricted/abseil-cpp/absl/flags/commandlineflag + contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag + contrib/restricted/abseil-cpp/absl/flags/internal/flag + contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor + contrib/restricted/abseil-cpp/absl/flags/internal/program_name + contrib/restricted/abseil-cpp/absl/flags/marshalling + contrib/restricted/abseil-cpp/absl/flags/reflection + contrib/restricted/abseil-cpp/absl/flags/usage_config + contrib/restricted/abseil-cpp/absl/hash + contrib/restricted/abseil-cpp/absl/hash/internal contrib/restricted/abseil-cpp/absl/numeric - contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/cord - contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info + contrib/restricted/abseil-cpp/absl/strings/cord + contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info contrib/restricted/abseil-cpp/absl/strings/internal/str_format - contrib/restricted/abseil-cpp/absl/synchronization - contrib/restricted/abseil-cpp/absl/synchronization/internal - contrib/restricted/abseil-cpp/absl/time - contrib/restricted/abseil-cpp/absl/time/civil_time - contrib/restricted/abseil-cpp/absl/time/time_zone + contrib/restricted/abseil-cpp/absl/synchronization + contrib/restricted/abseil-cpp/absl/synchronization/internal + contrib/restricted/abseil-cpp/absl/time + contrib/restricted/abseil-cpp/absl/time/civil_time + contrib/restricted/abseil-cpp/absl/time/time_zone contrib/restricted/abseil-cpp/absl/types/bad_optional_access contrib/restricted/abseil-cpp/absl/types/bad_variant_access ) @@ -64,10 +64,10 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/flags/internal) +SRCDIR(contrib/restricted/abseil-cpp/absl/flags/internal) SRCS( - usage.cc + usage.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/flags/marshalling/ya.make b/contrib/restricted/abseil-cpp/absl/flags/marshalling/ya.make index 1b02b87173..a9cbc530c6 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/marshalling/ya.make +++ b/contrib/restricted/abseil-cpp/absl/flags/marshalling/ya.make @@ -16,8 +16,8 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/base/log_severity contrib/restricted/abseil-cpp/absl/numeric contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp/absl/strings/internal/str_format + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/str_format ) ADDINCL( @@ -32,10 +32,10 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/flags) +SRCDIR(contrib/restricted/abseil-cpp/absl/flags) SRCS( - marshalling.cc + marshalling.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/flags/parse/ya.make b/contrib/restricted/abseil-cpp/absl/flags/parse/ya.make index 267b3e4a97..902a91d529 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/parse/ya.make +++ b/contrib/restricted/abseil-cpp/absl/flags/parse/ya.make @@ -15,43 +15,43 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/city - contrib/restricted/abseil-cpp/absl/container/internal/absl_hashtablez_sampler - contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set + contrib/restricted/abseil-cpp/absl/city + contrib/restricted/abseil-cpp/absl/container/internal/absl_hashtablez_sampler + contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set contrib/restricted/abseil-cpp/absl/debugging contrib/restricted/abseil-cpp/absl/debugging/stacktrace contrib/restricted/abseil-cpp/absl/debugging/symbolize contrib/restricted/abseil-cpp/absl/demangle - contrib/restricted/abseil-cpp/absl/flags - contrib/restricted/abseil-cpp/absl/flags/commandlineflag - contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag - contrib/restricted/abseil-cpp/absl/flags/internal/flag - contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor + contrib/restricted/abseil-cpp/absl/flags + contrib/restricted/abseil-cpp/absl/flags/commandlineflag + contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag + contrib/restricted/abseil-cpp/absl/flags/internal/flag + contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor contrib/restricted/abseil-cpp/absl/flags/internal/program_name - contrib/restricted/abseil-cpp/absl/flags/internal/usage - contrib/restricted/abseil-cpp/absl/flags/marshalling - contrib/restricted/abseil-cpp/absl/flags/reflection - contrib/restricted/abseil-cpp/absl/flags/usage - contrib/restricted/abseil-cpp/absl/flags/usage_config - contrib/restricted/abseil-cpp/absl/hash - contrib/restricted/abseil-cpp/absl/hash/internal + contrib/restricted/abseil-cpp/absl/flags/internal/usage + contrib/restricted/abseil-cpp/absl/flags/marshalling + contrib/restricted/abseil-cpp/absl/flags/reflection + contrib/restricted/abseil-cpp/absl/flags/usage + contrib/restricted/abseil-cpp/absl/flags/usage_config + contrib/restricted/abseil-cpp/absl/hash + contrib/restricted/abseil-cpp/absl/hash/internal contrib/restricted/abseil-cpp/absl/numeric - contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/cord - contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info - contrib/restricted/abseil-cpp/absl/strings/internal/str_format + contrib/restricted/abseil-cpp/absl/strings/cord + contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info + contrib/restricted/abseil-cpp/absl/strings/internal/str_format contrib/restricted/abseil-cpp/absl/synchronization contrib/restricted/abseil-cpp/absl/synchronization/internal contrib/restricted/abseil-cpp/absl/time contrib/restricted/abseil-cpp/absl/time/civil_time contrib/restricted/abseil-cpp/absl/time/time_zone - contrib/restricted/abseil-cpp/absl/types/bad_optional_access - contrib/restricted/abseil-cpp/absl/types/bad_variant_access + contrib/restricted/abseil-cpp/absl/types/bad_optional_access + contrib/restricted/abseil-cpp/absl/types/bad_variant_access ) ADDINCL( @@ -69,7 +69,7 @@ CFLAGS( SRCDIR(contrib/restricted/abseil-cpp/absl/flags) SRCS( - parse.cc + parse.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/flags/reflection.cc b/contrib/restricted/abseil-cpp/absl/flags/reflection.cc index dbce4032ab..7597e7b9ae 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/reflection.cc +++ b/contrib/restricted/abseil-cpp/absl/flags/reflection.cc @@ -22,7 +22,7 @@ #include "absl/base/config.h" #include "absl/base/thread_annotations.h" -#include "absl/container/flat_hash_map.h" +#include "absl/container/flat_hash_map.h" #include "absl/flags/commandlineflag.h" #include "absl/flags/internal/private_handle_accessor.h" #include "absl/flags/internal/registry.h" @@ -68,7 +68,7 @@ class FlagRegistry { friend void FinalizeRegistry(); // The map from name to flag, for FindFlag(). - using FlagMap = absl::flat_hash_map<absl::string_view, CommandLineFlag*>; + using FlagMap = absl::flat_hash_map<absl::string_view, CommandLineFlag*>; using FlagIterator = FlagMap::iterator; using FlagConstIterator = FlagMap::const_iterator; FlagMap flags_; @@ -204,10 +204,10 @@ void FinalizeRegistry() { for (const auto& f : registry.flags_) { registry.flat_flags_.push_back(f.second); } - std::sort(std::begin(registry.flat_flags_), std::end(registry.flat_flags_), - [](const CommandLineFlag* lhs, const CommandLineFlag* rhs) { - return lhs->Name() < rhs->Name(); - }); + std::sort(std::begin(registry.flat_flags_), std::end(registry.flat_flags_), + [](const CommandLineFlag* lhs, const CommandLineFlag* rhs) { + return lhs->Name() < rhs->Name(); + }); registry.flags_.clear(); registry.finalized_flags_.store(true, std::memory_order_release); } diff --git a/contrib/restricted/abseil-cpp/absl/flags/reflection/ya.make b/contrib/restricted/abseil-cpp/absl/flags/reflection/ya.make index f75bc1c67d..9f8cd1fddc 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/reflection/ya.make +++ b/contrib/restricted/abseil-cpp/absl/flags/reflection/ya.make @@ -15,34 +15,34 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/city - contrib/restricted/abseil-cpp/absl/container/internal/absl_hashtablez_sampler - contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set + contrib/restricted/abseil-cpp/absl/city + contrib/restricted/abseil-cpp/absl/container/internal/absl_hashtablez_sampler + contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set contrib/restricted/abseil-cpp/absl/debugging contrib/restricted/abseil-cpp/absl/debugging/stacktrace contrib/restricted/abseil-cpp/absl/debugging/symbolize contrib/restricted/abseil-cpp/absl/demangle - contrib/restricted/abseil-cpp/absl/flags/commandlineflag - contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag - contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor - contrib/restricted/abseil-cpp/absl/flags/internal/program_name - contrib/restricted/abseil-cpp/absl/flags/usage_config - contrib/restricted/abseil-cpp/absl/hash - contrib/restricted/abseil-cpp/absl/hash/internal + contrib/restricted/abseil-cpp/absl/flags/commandlineflag + contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag + contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor + contrib/restricted/abseil-cpp/absl/flags/internal/program_name + contrib/restricted/abseil-cpp/absl/flags/usage_config + contrib/restricted/abseil-cpp/absl/hash + contrib/restricted/abseil-cpp/absl/hash/internal contrib/restricted/abseil-cpp/absl/numeric - contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/cord - contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info - contrib/restricted/abseil-cpp/absl/synchronization - contrib/restricted/abseil-cpp/absl/synchronization/internal - contrib/restricted/abseil-cpp/absl/time - contrib/restricted/abseil-cpp/absl/time/civil_time - contrib/restricted/abseil-cpp/absl/time/time_zone + contrib/restricted/abseil-cpp/absl/strings/cord + contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info + contrib/restricted/abseil-cpp/absl/synchronization + contrib/restricted/abseil-cpp/absl/synchronization/internal + contrib/restricted/abseil-cpp/absl/time + contrib/restricted/abseil-cpp/absl/time/civil_time + contrib/restricted/abseil-cpp/absl/time/time_zone contrib/restricted/abseil-cpp/absl/types/bad_optional_access contrib/restricted/abseil-cpp/absl/types/bad_variant_access ) @@ -59,10 +59,10 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/flags) +SRCDIR(contrib/restricted/abseil-cpp/absl/flags) SRCS( - reflection.cc + reflection.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/flags/usage/ya.make b/contrib/restricted/abseil-cpp/absl/flags/usage/ya.make index f6b243c84c..64d9041e4f 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/usage/ya.make +++ b/contrib/restricted/abseil-cpp/absl/flags/usage/ya.make @@ -35,14 +35,14 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/hash contrib/restricted/abseil-cpp/absl/hash/internal contrib/restricted/abseil-cpp/absl/numeric - contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/cord - contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info + contrib/restricted/abseil-cpp/absl/strings/cord + contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info contrib/restricted/abseil-cpp/absl/strings/internal/str_format contrib/restricted/abseil-cpp/absl/synchronization contrib/restricted/abseil-cpp/absl/synchronization/internal diff --git a/contrib/restricted/abseil-cpp/absl/flags/usage_config/ya.make b/contrib/restricted/abseil-cpp/absl/flags/usage_config/ya.make index adeb527aee..39d59b6a23 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/usage_config/ya.make +++ b/contrib/restricted/abseil-cpp/absl/flags/usage_config/ya.make @@ -2,32 +2,32 @@ LIBRARY() -WITHOUT_LICENSE_TEXTS() - +WITHOUT_LICENSE_TEXTS() + OWNER(g:cpp-contrib) LICENSE(Apache-2.0) PEERDIR( contrib/restricted/abseil-cpp/absl/base - contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc contrib/restricted/abseil-cpp/absl/base/internal/raw_logging contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/debugging - contrib/restricted/abseil-cpp/absl/debugging/stacktrace - contrib/restricted/abseil-cpp/absl/debugging/symbolize - contrib/restricted/abseil-cpp/absl/demangle - contrib/restricted/abseil-cpp/absl/flags/internal/program_name + contrib/restricted/abseil-cpp/absl/debugging + contrib/restricted/abseil-cpp/absl/debugging/stacktrace + contrib/restricted/abseil-cpp/absl/debugging/symbolize + contrib/restricted/abseil-cpp/absl/demangle + contrib/restricted/abseil-cpp/absl/flags/internal/program_name contrib/restricted/abseil-cpp/absl/numeric - contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp/absl/synchronization - contrib/restricted/abseil-cpp/absl/synchronization/internal - contrib/restricted/abseil-cpp/absl/time - contrib/restricted/abseil-cpp/absl/time/civil_time - contrib/restricted/abseil-cpp/absl/time/time_zone + contrib/restricted/abseil-cpp/absl/strings + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/synchronization + contrib/restricted/abseil-cpp/absl/synchronization/internal + contrib/restricted/abseil-cpp/absl/time + contrib/restricted/abseil-cpp/absl/time/civil_time + contrib/restricted/abseil-cpp/absl/time/time_zone ) ADDINCL( @@ -42,10 +42,10 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/flags) - +SRCDIR(contrib/restricted/abseil-cpp/absl/flags) + SRCS( - usage_config.cc + usage_config.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/flags/ya.make b/contrib/restricted/abseil-cpp/absl/flags/ya.make index 983809b80c..8bd35b71f6 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/ya.make +++ b/contrib/restricted/abseil-cpp/absl/flags/ya.make @@ -6,49 +6,49 @@ OWNER(g:cpp-contrib) LICENSE(Apache-2.0) -LICENSE_TEXTS(.yandex_meta/licenses.list.txt) - +LICENSE_TEXTS(.yandex_meta/licenses.list.txt) + PEERDIR( contrib/restricted/abseil-cpp/absl/base - contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc contrib/restricted/abseil-cpp/absl/base/internal/raw_logging contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/city - contrib/restricted/abseil-cpp/absl/container/internal/absl_hashtablez_sampler - contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set - contrib/restricted/abseil-cpp/absl/debugging - contrib/restricted/abseil-cpp/absl/debugging/stacktrace - contrib/restricted/abseil-cpp/absl/debugging/symbolize - contrib/restricted/abseil-cpp/absl/demangle - contrib/restricted/abseil-cpp/absl/flags/commandlineflag - contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag - contrib/restricted/abseil-cpp/absl/flags/internal/flag - contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor - contrib/restricted/abseil-cpp/absl/flags/internal/program_name - contrib/restricted/abseil-cpp/absl/flags/marshalling - contrib/restricted/abseil-cpp/absl/flags/reflection - contrib/restricted/abseil-cpp/absl/flags/usage_config - contrib/restricted/abseil-cpp/absl/hash - contrib/restricted/abseil-cpp/absl/hash/internal + contrib/restricted/abseil-cpp/absl/city + contrib/restricted/abseil-cpp/absl/container/internal/absl_hashtablez_sampler + contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set + contrib/restricted/abseil-cpp/absl/debugging + contrib/restricted/abseil-cpp/absl/debugging/stacktrace + contrib/restricted/abseil-cpp/absl/debugging/symbolize + contrib/restricted/abseil-cpp/absl/demangle + contrib/restricted/abseil-cpp/absl/flags/commandlineflag + contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag + contrib/restricted/abseil-cpp/absl/flags/internal/flag + contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor + contrib/restricted/abseil-cpp/absl/flags/internal/program_name + contrib/restricted/abseil-cpp/absl/flags/marshalling + contrib/restricted/abseil-cpp/absl/flags/reflection + contrib/restricted/abseil-cpp/absl/flags/usage_config + contrib/restricted/abseil-cpp/absl/hash + contrib/restricted/abseil-cpp/absl/hash/internal contrib/restricted/abseil-cpp/absl/numeric - contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/cord - contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info - contrib/restricted/abseil-cpp/absl/strings/internal/str_format - contrib/restricted/abseil-cpp/absl/synchronization - contrib/restricted/abseil-cpp/absl/synchronization/internal - contrib/restricted/abseil-cpp/absl/time - contrib/restricted/abseil-cpp/absl/time/civil_time - contrib/restricted/abseil-cpp/absl/time/time_zone + contrib/restricted/abseil-cpp/absl/strings/cord + contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info + contrib/restricted/abseil-cpp/absl/strings/internal/str_format + contrib/restricted/abseil-cpp/absl/synchronization + contrib/restricted/abseil-cpp/absl/synchronization/internal + contrib/restricted/abseil-cpp/absl/time + contrib/restricted/abseil-cpp/absl/time/civil_time + contrib/restricted/abseil-cpp/absl/time/time_zone contrib/restricted/abseil-cpp/absl/types/bad_optional_access - contrib/restricted/abseil-cpp/absl/types/bad_variant_access + contrib/restricted/abseil-cpp/absl/types/bad_variant_access ) ADDINCL( @@ -64,7 +64,7 @@ CFLAGS( ) SRCS( - flag.cc + flag.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/functional/function_ref.h b/contrib/restricted/abseil-cpp/absl/functional/function_ref.h index 824e3cea9d..01813368a0 100644 --- a/contrib/restricted/abseil-cpp/absl/functional/function_ref.h +++ b/contrib/restricted/abseil-cpp/absl/functional/function_ref.h @@ -50,7 +50,7 @@ #include <functional> #include <type_traits> -#include "absl/base/attributes.h" +#include "absl/base/attributes.h" #include "absl/functional/internal/function_ref.h" #include "absl/meta/type_traits.h" @@ -99,8 +99,8 @@ class FunctionRef<R(Args...)> { public: // Constructs a FunctionRef from any invokable type. template <typename F, typename = EnableIfCompatible<const F&>> - // NOLINTNEXTLINE(runtime/explicit) - FunctionRef(const F& f ABSL_ATTRIBUTE_LIFETIME_BOUND) + // NOLINTNEXTLINE(runtime/explicit) + FunctionRef(const F& f ABSL_ATTRIBUTE_LIFETIME_BOUND) : invoker_(&absl::functional_internal::InvokeObject<F, R, Args...>) { absl::functional_internal::AssertNonNull(f); ptr_.obj = &f; @@ -124,7 +124,7 @@ class FunctionRef<R(Args...)> { // To help prevent subtle lifetime bugs, FunctionRef is not assignable. // Typically, it should only be used as an argument type. FunctionRef& operator=(const FunctionRef& rhs) = delete; - FunctionRef(const FunctionRef& rhs) = default; + FunctionRef(const FunctionRef& rhs) = default; // Call the underlying object. R operator()(Args... args) const { diff --git a/contrib/restricted/abseil-cpp/absl/hash/hash.h b/contrib/restricted/abseil-cpp/absl/hash/hash.h index 8282ea53c6..d26f1d0a9a 100644 --- a/contrib/restricted/abseil-cpp/absl/hash/hash.h +++ b/contrib/restricted/abseil-cpp/absl/hash/hash.h @@ -73,8 +73,8 @@ #ifndef ABSL_HASH_HASH_H_ #define ABSL_HASH_HASH_H_ -#include <tuple> - +#include <tuple> + #include "absl/hash/internal/hash.h" namespace absl { @@ -216,26 +216,26 @@ ABSL_NAMESPACE_BEGIN template <typename T> using Hash = absl::hash_internal::Hash<T>; -// HashOf -// -// absl::HashOf() is a helper that generates a hash from the values of its -// arguments. It dispatches to absl::Hash directly, as follows: -// * HashOf(t) == absl::Hash<T>{}(t) -// * HashOf(a, b, c) == HashOf(std::make_tuple(a, b, c)) -// -// HashOf(a1, a2, ...) == HashOf(b1, b2, ...) is guaranteed when -// * The argument lists have pairwise identical C++ types -// * a1 == b1 && a2 == b2 && ... -// -// The requirement that the arguments match in both type and value is critical. -// It means that `a == b` does not necessarily imply `HashOf(a) == HashOf(b)` if -// `a` and `b` have different types. For example, `HashOf(2) != HashOf(2.0)`. -template <int&... ExplicitArgumentBarrier, typename... Types> -size_t HashOf(const Types&... values) { - auto tuple = std::tie(values...); - return absl::Hash<decltype(tuple)>{}(tuple); -} - +// HashOf +// +// absl::HashOf() is a helper that generates a hash from the values of its +// arguments. It dispatches to absl::Hash directly, as follows: +// * HashOf(t) == absl::Hash<T>{}(t) +// * HashOf(a, b, c) == HashOf(std::make_tuple(a, b, c)) +// +// HashOf(a1, a2, ...) == HashOf(b1, b2, ...) is guaranteed when +// * The argument lists have pairwise identical C++ types +// * a1 == b1 && a2 == b2 && ... +// +// The requirement that the arguments match in both type and value is critical. +// It means that `a == b` does not necessarily imply `HashOf(a) == HashOf(b)` if +// `a` and `b` have different types. For example, `HashOf(2) != HashOf(2.0)`. +template <int&... ExplicitArgumentBarrier, typename... Types> +size_t HashOf(const Types&... values) { + auto tuple = std::tie(values...); + return absl::Hash<decltype(tuple)>{}(tuple); +} + // HashState // // A type erased version of the hash state concept, for use in user-defined diff --git a/contrib/restricted/abseil-cpp/absl/hash/internal/hash.cc b/contrib/restricted/abseil-cpp/absl/hash/internal/hash.cc index 11451e575c..6752d0f83f 100644 --- a/contrib/restricted/abseil-cpp/absl/hash/internal/hash.cc +++ b/contrib/restricted/abseil-cpp/absl/hash/internal/hash.cc @@ -18,12 +18,12 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace hash_internal { -uint64_t MixingHashState::CombineLargeContiguousImpl32( - uint64_t state, const unsigned char* first, size_t len) { +uint64_t MixingHashState::CombineLargeContiguousImpl32( + uint64_t state, const unsigned char* first, size_t len) { while (len >= PiecewiseChunkSize()) { - state = Mix(state, - hash_internal::CityHash32(reinterpret_cast<const char*>(first), - PiecewiseChunkSize())); + state = Mix(state, + hash_internal::CityHash32(reinterpret_cast<const char*>(first), + PiecewiseChunkSize())); len -= PiecewiseChunkSize(); first += PiecewiseChunkSize(); } @@ -32,8 +32,8 @@ uint64_t MixingHashState::CombineLargeContiguousImpl32( std::integral_constant<int, 4>{}); } -uint64_t MixingHashState::CombineLargeContiguousImpl64( - uint64_t state, const unsigned char* first, size_t len) { +uint64_t MixingHashState::CombineLargeContiguousImpl64( + uint64_t state, const unsigned char* first, size_t len) { while (len >= PiecewiseChunkSize()) { state = Mix(state, Hash64(first, PiecewiseChunkSize())); len -= PiecewiseChunkSize(); @@ -44,24 +44,24 @@ uint64_t MixingHashState::CombineLargeContiguousImpl64( std::integral_constant<int, 8>{}); } -ABSL_CONST_INIT const void* const MixingHashState::kSeed = &kSeed; +ABSL_CONST_INIT const void* const MixingHashState::kSeed = &kSeed; -// The salt array used by LowLevelHash. This array is NOT the mechanism used to -// make absl::Hash non-deterministic between program invocations. See `Seed()` -// for that mechanism. +// The salt array used by LowLevelHash. This array is NOT the mechanism used to +// make absl::Hash non-deterministic between program invocations. See `Seed()` +// for that mechanism. // // Any random values are fine. These values are just digits from the decimal // part of pi. // https://en.wikipedia.org/wiki/Nothing-up-my-sleeve_number -constexpr uint64_t kHashSalt[5] = { +constexpr uint64_t kHashSalt[5] = { uint64_t{0x243F6A8885A308D3}, uint64_t{0x13198A2E03707344}, uint64_t{0xA4093822299F31D0}, uint64_t{0x082EFA98EC4E6C89}, uint64_t{0x452821E638D01377}, }; -uint64_t MixingHashState::LowLevelHashImpl(const unsigned char* data, - size_t len) { - return LowLevelHash(data, len, Seed(), kHashSalt); +uint64_t MixingHashState::LowLevelHashImpl(const unsigned char* data, + size_t len) { + return LowLevelHash(data, len, Seed(), kHashSalt); } } // namespace hash_internal diff --git a/contrib/restricted/abseil-cpp/absl/hash/internal/hash.h b/contrib/restricted/abseil-cpp/absl/hash/internal/hash.h index b1e33caf4c..7b5ded8abe 100644 --- a/contrib/restricted/abseil-cpp/absl/hash/internal/hash.h +++ b/contrib/restricted/abseil-cpp/absl/hash/internal/hash.h @@ -21,7 +21,7 @@ #include <algorithm> #include <array> -#include <bitset> +#include <bitset> #include <cmath> #include <cstring> #include <deque> @@ -43,8 +43,8 @@ #include "absl/base/internal/unaligned_access.h" #include "absl/base/port.h" #include "absl/container/fixed_array.h" -#include "absl/hash/internal/city.h" -#include "absl/hash/internal/low_level_hash.h" +#include "absl/hash/internal/city.h" +#include "absl/hash/internal/low_level_hash.h" #include "absl/meta/type_traits.h" #include "absl/numeric/int128.h" #include "absl/strings/string_view.h" @@ -380,7 +380,7 @@ template <typename H, typename... Ts> // This SFINAE gets MSVC confused under some conditions. Let's just disable it // for now. H -#else // _MSC_VER +#else // _MSC_VER typename std::enable_if<absl::conjunction<is_hashable<Ts>...>::value, H>::type #endif // _MSC_VER AbslHashValue(H hash_state, const std::tuple<Ts...>& t) { @@ -490,9 +490,9 @@ typename std::enable_if<is_hashable<T>::value, H>::type AbslHashValue( // AbslHashValue for hashing std::vector // -// Do not use this for vector<bool> on platforms that have a working -// implementation of std::hash. It does not have a .data(), and a fallback for -// std::hash<> is most likely faster. +// Do not use this for vector<bool> on platforms that have a working +// implementation of std::hash. It does not have a .data(), and a fallback for +// std::hash<> is most likely faster. template <typename H, typename T, typename Allocator> typename std::enable_if<is_hashable<T>::value && !std::is_same<T, bool>::value, H>::type @@ -502,27 +502,27 @@ AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) { vector.size()); } -#if defined(ABSL_IS_BIG_ENDIAN) && \ - (defined(__GLIBCXX__) || defined(__GLIBCPP__)) -// AbslHashValue for hashing std::vector<bool> -// -// std::hash in libstdc++ does not work correctly with vector<bool> on Big -// Endian platforms therefore we need to implement a custom AbslHashValue for -// it. More details on the bug: -// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102531 -template <typename H, typename T, typename Allocator> -typename std::enable_if<is_hashable<T>::value && std::is_same<T, bool>::value, - H>::type -AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) { - typename H::AbslInternalPiecewiseCombiner combiner; - for (const auto& i : vector) { - unsigned char c = static_cast<unsigned char>(i); - hash_state = combiner.add_buffer(std::move(hash_state), &c, sizeof(c)); - } - return H::combine(combiner.finalize(std::move(hash_state)), vector.size()); -} -#endif - +#if defined(ABSL_IS_BIG_ENDIAN) && \ + (defined(__GLIBCXX__) || defined(__GLIBCPP__)) +// AbslHashValue for hashing std::vector<bool> +// +// std::hash in libstdc++ does not work correctly with vector<bool> on Big +// Endian platforms therefore we need to implement a custom AbslHashValue for +// it. More details on the bug: +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102531 +template <typename H, typename T, typename Allocator> +typename std::enable_if<is_hashable<T>::value && std::is_same<T, bool>::value, + H>::type +AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) { + typename H::AbslInternalPiecewiseCombiner combiner; + for (const auto& i : vector) { + unsigned char c = static_cast<unsigned char>(i); + hash_state = combiner.add_buffer(std::move(hash_state), &c, sizeof(c)); + } + return H::combine(combiner.finalize(std::move(hash_state)), vector.size()); +} +#endif + // ----------------------------------------------------------------------------- // AbslHashValue for Ordered Associative Containers // ----------------------------------------------------------------------------- @@ -615,29 +615,29 @@ AbslHashValue(H hash_state, const absl::variant<T...>& v) { // AbslHashValue for Other Types // ----------------------------------------------------------------------------- -// AbslHashValue for hashing std::bitset is not defined on Little Endian -// platforms, for the same reason as for vector<bool> (see std::vector above): -// It does not expose the raw bytes, and a fallback to std::hash<> is most -// likely faster. - -#if defined(ABSL_IS_BIG_ENDIAN) && \ - (defined(__GLIBCXX__) || defined(__GLIBCPP__)) -// AbslHashValue for hashing std::bitset -// -// std::hash in libstdc++ does not work correctly with std::bitset on Big Endian -// platforms therefore we need to implement a custom AbslHashValue for it. More -// details on the bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102531 -template <typename H, size_t N> -H AbslHashValue(H hash_state, const std::bitset<N>& set) { - typename H::AbslInternalPiecewiseCombiner combiner; - for (int i = 0; i < N; i++) { - unsigned char c = static_cast<unsigned char>(set[i]); - hash_state = combiner.add_buffer(std::move(hash_state), &c, sizeof(c)); - } - return H::combine(combiner.finalize(std::move(hash_state)), N); -} -#endif - +// AbslHashValue for hashing std::bitset is not defined on Little Endian +// platforms, for the same reason as for vector<bool> (see std::vector above): +// It does not expose the raw bytes, and a fallback to std::hash<> is most +// likely faster. + +#if defined(ABSL_IS_BIG_ENDIAN) && \ + (defined(__GLIBCXX__) || defined(__GLIBCPP__)) +// AbslHashValue for hashing std::bitset +// +// std::hash in libstdc++ does not work correctly with std::bitset on Big Endian +// platforms therefore we need to implement a custom AbslHashValue for it. More +// details on the bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102531 +template <typename H, size_t N> +H AbslHashValue(H hash_state, const std::bitset<N>& set) { + typename H::AbslInternalPiecewiseCombiner combiner; + for (int i = 0; i < N; i++) { + unsigned char c = static_cast<unsigned char>(set[i]); + hash_state = combiner.add_buffer(std::move(hash_state), &c, sizeof(c)); + } + return H::combine(combiner.finalize(std::move(hash_state)), N); +} +#endif + // ----------------------------------------------------------------------------- // hash_range_or_bytes() @@ -756,8 +756,8 @@ template <typename T> struct is_hashable : std::integral_constant<bool, HashSelect::template Apply<T>::value> {}; -// MixingHashState -class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> { +// MixingHashState +class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> { // absl::uint128 is not an alias or a thin wrapper around the intrinsic. // We use the intrinsic when available to improve performance. #ifdef ABSL_HAVE_INTRINSIC_INT128 @@ -776,23 +776,23 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> { public: // Move only - MixingHashState(MixingHashState&&) = default; - MixingHashState& operator=(MixingHashState&&) = default; + MixingHashState(MixingHashState&&) = default; + MixingHashState& operator=(MixingHashState&&) = default; - // MixingHashState::combine_contiguous() + // MixingHashState::combine_contiguous() // // Fundamental base case for hash recursion: mixes the given range of bytes // into the hash state. - static MixingHashState combine_contiguous(MixingHashState hash_state, - const unsigned char* first, - size_t size) { - return MixingHashState( + static MixingHashState combine_contiguous(MixingHashState hash_state, + const unsigned char* first, + size_t size) { + return MixingHashState( CombineContiguousImpl(hash_state.state_, first, size, std::integral_constant<int, sizeof(size_t)>{})); } - using MixingHashState::HashStateBase::combine_contiguous; + using MixingHashState::HashStateBase::combine_contiguous; - // MixingHashState::hash() + // MixingHashState::hash() // // For performance reasons in non-opt mode, we specialize this for // integral types. @@ -804,24 +804,24 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> { return static_cast<size_t>(Mix(Seed(), static_cast<uint64_t>(value))); } - // Overload of MixingHashState::hash() + // Overload of MixingHashState::hash() template <typename T, absl::enable_if_t<!IntegralFastPath<T>::value, int> = 0> static size_t hash(const T& value) { - return static_cast<size_t>(combine(MixingHashState{}, value).state_); + return static_cast<size_t>(combine(MixingHashState{}, value).state_); } private: // Invoked only once for a given argument; that plus the fact that this is // move-only ensures that there is only one non-moved-from object. - MixingHashState() : state_(Seed()) {} + MixingHashState() : state_(Seed()) {} // Workaround for MSVC bug. // We make the type copyable to fix the calling convention, even though we // never actually copy it. Keep it private to not affect the public API of the // type. - MixingHashState(const MixingHashState&) = default; + MixingHashState(const MixingHashState&) = default; - explicit MixingHashState(uint64_t state) : state_(state) {} + explicit MixingHashState(uint64_t state) : state_(state) {} // Implementation of the base case for combine_contiguous where we actually // mix the bytes into the state. @@ -898,15 +898,15 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> { } ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t Mix(uint64_t state, uint64_t v) { -#if defined(__aarch64__) - // On AArch64, calculating a 128-bit product is inefficient, because it - // requires a sequence of two instructions to calculate the upper and lower - // halves of the result. - using MultType = uint64_t; -#else +#if defined(__aarch64__) + // On AArch64, calculating a 128-bit product is inefficient, because it + // requires a sequence of two instructions to calculate the upper and lower + // halves of the result. + using MultType = uint64_t; +#else using MultType = absl::conditional_t<sizeof(size_t) == 4, uint64_t, uint128>; -#endif +#endif // We do the addition in 64-bit space to make sure the 128-bit // multiplication is fast. If we were to do it as MultType the compiler has // to assume that the high word is non-zero and needs to perform 2 @@ -916,16 +916,16 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> { return static_cast<uint64_t>(m ^ (m >> (sizeof(m) * 8 / 2))); } - // An extern to avoid bloat on a direct call to LowLevelHash() with fixed - // values for both the seed and salt parameters. - static uint64_t LowLevelHashImpl(const unsigned char* data, size_t len); + // An extern to avoid bloat on a direct call to LowLevelHash() with fixed + // values for both the seed and salt parameters. + static uint64_t LowLevelHashImpl(const unsigned char* data, size_t len); ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t Hash64(const unsigned char* data, size_t len) { #ifdef ABSL_HAVE_INTRINSIC_INT128 - return LowLevelHashImpl(data, len); + return LowLevelHashImpl(data, len); #else - return hash_internal::CityHash64(reinterpret_cast<const char*>(data), len); + return hash_internal::CityHash64(reinterpret_cast<const char*>(data), len); #endif } @@ -960,8 +960,8 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> { uint64_t state_; }; -// MixingHashState::CombineContiguousImpl() -inline uint64_t MixingHashState::CombineContiguousImpl( +// MixingHashState::CombineContiguousImpl() +inline uint64_t MixingHashState::CombineContiguousImpl( uint64_t state, const unsigned char* first, size_t len, std::integral_constant<int, 4> /* sizeof_size_t */) { // For large values we use CityHash, for small ones we just use a @@ -971,7 +971,7 @@ inline uint64_t MixingHashState::CombineContiguousImpl( if (ABSL_PREDICT_FALSE(len > PiecewiseChunkSize())) { return CombineLargeContiguousImpl32(state, first, len); } - v = hash_internal::CityHash32(reinterpret_cast<const char*>(first), len); + v = hash_internal::CityHash32(reinterpret_cast<const char*>(first), len); } else if (len >= 4) { v = Read4To8(first, len); } else if (len > 0) { @@ -983,12 +983,12 @@ inline uint64_t MixingHashState::CombineContiguousImpl( return Mix(state, v); } -// Overload of MixingHashState::CombineContiguousImpl() -inline uint64_t MixingHashState::CombineContiguousImpl( +// Overload of MixingHashState::CombineContiguousImpl() +inline uint64_t MixingHashState::CombineContiguousImpl( uint64_t state, const unsigned char* first, size_t len, std::integral_constant<int, 8> /* sizeof_size_t */) { - // For large values we use LowLevelHash or CityHash depending on the platform, - // for small ones we just use a multiplicative hash. + // For large values we use LowLevelHash or CityHash depending on the platform, + // for small ones we just use a multiplicative hash. uint64_t v; if (len > 16) { if (ABSL_PREDICT_FALSE(len > PiecewiseChunkSize())) { @@ -1025,9 +1025,9 @@ struct PoisonedHash : private AggregateBarrier { template <typename T> struct HashImpl { - size_t operator()(const T& value) const { - return MixingHashState::hash(value); - } + size_t operator()(const T& value) const { + return MixingHashState::hash(value); + } }; template <typename T> diff --git a/contrib/restricted/abseil-cpp/absl/hash/internal/low_level_hash.cc b/contrib/restricted/abseil-cpp/absl/hash/internal/low_level_hash.cc index 6f9cb9c7bf..9366fa8257 100644 --- a/contrib/restricted/abseil-cpp/absl/hash/internal/low_level_hash.cc +++ b/contrib/restricted/abseil-cpp/absl/hash/internal/low_level_hash.cc @@ -12,35 +12,35 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "absl/hash/internal/low_level_hash.h" +#include "absl/hash/internal/low_level_hash.h" #include "absl/base/internal/unaligned_access.h" -#include "absl/numeric/bits.h" +#include "absl/numeric/bits.h" #include "absl/numeric/int128.h" namespace absl { ABSL_NAMESPACE_BEGIN namespace hash_internal { -static uint64_t Mix(uint64_t v0, uint64_t v1) { -#if !defined(__aarch64__) - // The default bit-mixer uses 64x64->128-bit multiplication. +static uint64_t Mix(uint64_t v0, uint64_t v1) { +#if !defined(__aarch64__) + // The default bit-mixer uses 64x64->128-bit multiplication. absl::uint128 p = v0; p *= v1; return absl::Uint128Low64(p) ^ absl::Uint128High64(p); -#else - // The default bit-mixer above would perform poorly on some ARM microarchs, - // where calculating a 128-bit product requires a sequence of two - // instructions with a high combined latency and poor throughput. - // Instead, we mix bits using only 64-bit arithmetic, which is faster. - uint64_t p = v0 ^ absl::rotl(v1, 40); - p *= v1 ^ absl::rotl(v0, 39); - return p ^ (p >> 11); -#endif +#else + // The default bit-mixer above would perform poorly on some ARM microarchs, + // where calculating a 128-bit product requires a sequence of two + // instructions with a high combined latency and poor throughput. + // Instead, we mix bits using only 64-bit arithmetic, which is faster. + uint64_t p = v0 ^ absl::rotl(v1, 40); + p *= v1 ^ absl::rotl(v0, 39); + return p ^ (p >> 11); +#endif } -uint64_t LowLevelHash(const void* data, size_t len, uint64_t seed, - const uint64_t salt[]) { +uint64_t LowLevelHash(const void* data, size_t len, uint64_t seed, + const uint64_t salt[]) { const uint8_t* ptr = static_cast<const uint8_t*>(data); uint64_t starting_length = static_cast<uint64_t>(len); uint64_t current_state = seed ^ salt[0]; @@ -61,12 +61,12 @@ uint64_t LowLevelHash(const void* data, size_t len, uint64_t seed, uint64_t g = absl::base_internal::UnalignedLoad64(ptr + 48); uint64_t h = absl::base_internal::UnalignedLoad64(ptr + 56); - uint64_t cs0 = Mix(a ^ salt[1], b ^ current_state); - uint64_t cs1 = Mix(c ^ salt[2], d ^ current_state); + uint64_t cs0 = Mix(a ^ salt[1], b ^ current_state); + uint64_t cs1 = Mix(c ^ salt[2], d ^ current_state); current_state = (cs0 ^ cs1); - uint64_t ds0 = Mix(e ^ salt[3], f ^ duplicated_state); - uint64_t ds1 = Mix(g ^ salt[4], h ^ duplicated_state); + uint64_t ds0 = Mix(e ^ salt[3], f ^ duplicated_state); + uint64_t ds1 = Mix(g ^ salt[4], h ^ duplicated_state); duplicated_state = (ds0 ^ ds1); ptr += 64; @@ -82,7 +82,7 @@ uint64_t LowLevelHash(const void* data, size_t len, uint64_t seed, uint64_t a = absl::base_internal::UnalignedLoad64(ptr); uint64_t b = absl::base_internal::UnalignedLoad64(ptr + 8); - current_state = Mix(a ^ salt[1], b ^ current_state); + current_state = Mix(a ^ salt[1], b ^ current_state); ptr += 16; len -= 16; @@ -113,9 +113,9 @@ uint64_t LowLevelHash(const void* data, size_t len, uint64_t seed, b = 0; } - uint64_t w = Mix(a ^ salt[1], b ^ current_state); + uint64_t w = Mix(a ^ salt[1], b ^ current_state); uint64_t z = salt[1] ^ starting_length; - return Mix(w, z); + return Mix(w, z); } } // namespace hash_internal diff --git a/contrib/restricted/abseil-cpp/absl/hash/internal/low_level_hash.h b/contrib/restricted/abseil-cpp/absl/hash/internal/low_level_hash.h index 439968aa98..a915196b8a 100644 --- a/contrib/restricted/abseil-cpp/absl/hash/internal/low_level_hash.h +++ b/contrib/restricted/abseil-cpp/absl/hash/internal/low_level_hash.h @@ -12,18 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// This file provides the Google-internal implementation of LowLevelHash. +// This file provides the Google-internal implementation of LowLevelHash. // -// LowLevelHash is a fast hash function for hash tables, the fastest we've -// currently (late 2020) found that passes the SMHasher tests. The algorithm -// relies on intrinsic 128-bit multiplication for speed. This is not meant to be -// secure - just fast. -// -// It is closely based on a version of wyhash, but does not maintain or -// guarantee future compatibility with it. +// LowLevelHash is a fast hash function for hash tables, the fastest we've +// currently (late 2020) found that passes the SMHasher tests. The algorithm +// relies on intrinsic 128-bit multiplication for speed. This is not meant to be +// secure - just fast. +// +// It is closely based on a version of wyhash, but does not maintain or +// guarantee future compatibility with it. -#ifndef ABSL_HASH_INTERNAL_LOW_LEVEL_HASH_H_ -#define ABSL_HASH_INTERNAL_LOW_LEVEL_HASH_H_ +#ifndef ABSL_HASH_INTERNAL_LOW_LEVEL_HASH_H_ +#define ABSL_HASH_INTERNAL_LOW_LEVEL_HASH_H_ #include <stdint.h> #include <stdlib.h> @@ -38,13 +38,13 @@ namespace hash_internal { // integers are hashed into the result. // // To allow all hashable types (including string_view and Span) to depend on -// this algorithm, we keep the API low-level, with as few dependencies as +// this algorithm, we keep the API low-level, with as few dependencies as // possible. -uint64_t LowLevelHash(const void* data, size_t len, uint64_t seed, - const uint64_t salt[5]); +uint64_t LowLevelHash(const void* data, size_t len, uint64_t seed, + const uint64_t salt[5]); } // namespace hash_internal ABSL_NAMESPACE_END } // namespace absl -#endif // ABSL_HASH_INTERNAL_LOW_LEVEL_HASH_H_ +#endif // ABSL_HASH_INTERNAL_LOW_LEVEL_HASH_H_ diff --git a/contrib/restricted/abseil-cpp/absl/hash/internal/ya.make b/contrib/restricted/abseil-cpp/absl/hash/internal/ya.make index a46b84191e..f76ade4eda 100644 --- a/contrib/restricted/abseil-cpp/absl/hash/internal/ya.make +++ b/contrib/restricted/abseil-cpp/absl/hash/internal/ya.make @@ -6,14 +6,14 @@ OWNER(g:cpp-contrib) LICENSE(Apache-2.0) -LICENSE_TEXTS(.yandex_meta/licenses.list.txt) - +LICENSE_TEXTS(.yandex_meta/licenses.list.txt) + PEERDIR( - contrib/restricted/abseil-cpp/absl/base - contrib/restricted/abseil-cpp/absl/base/internal/raw_logging - contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait - contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/numeric + contrib/restricted/abseil-cpp/absl/base + contrib/restricted/abseil-cpp/absl/base/internal/raw_logging + contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait + contrib/restricted/abseil-cpp/absl/base/log_severity + contrib/restricted/abseil-cpp/absl/numeric ) ADDINCL( @@ -29,7 +29,7 @@ CFLAGS( ) SRCS( - low_level_hash.cc + low_level_hash.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/hash/ya.make b/contrib/restricted/abseil-cpp/absl/hash/ya.make index f71202900a..3007b14b2c 100644 --- a/contrib/restricted/abseil-cpp/absl/hash/ya.make +++ b/contrib/restricted/abseil-cpp/absl/hash/ya.make @@ -6,23 +6,23 @@ OWNER(g:cpp-contrib) LICENSE(Apache-2.0) -LICENSE_TEXTS(.yandex_meta/licenses.list.txt) - +LICENSE_TEXTS(.yandex_meta/licenses.list.txt) + PEERDIR( contrib/restricted/abseil-cpp/absl/base contrib/restricted/abseil-cpp/absl/base/internal/raw_logging contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/city - contrib/restricted/abseil-cpp/absl/hash/internal + contrib/restricted/abseil-cpp/absl/city + contrib/restricted/abseil-cpp/absl/hash/internal contrib/restricted/abseil-cpp/absl/numeric contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal contrib/restricted/abseil-cpp/absl/types contrib/restricted/abseil-cpp/absl/types/bad_optional_access - contrib/restricted/abseil-cpp/absl/types/bad_variant_access - contrib/restricted/abseil-cpp/absl/types/internal + contrib/restricted/abseil-cpp/absl/types/bad_variant_access + contrib/restricted/abseil-cpp/absl/types/internal ) ADDINCL( @@ -38,7 +38,7 @@ CFLAGS( ) SRCS( - internal/hash.cc + internal/hash.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/memory/memory.h b/contrib/restricted/abseil-cpp/absl/memory/memory.h index 7a5063ee69..25fc45a81c 100644 --- a/contrib/restricted/abseil-cpp/absl/memory/memory.h +++ b/contrib/restricted/abseil-cpp/absl/memory/memory.h @@ -97,7 +97,7 @@ struct MakeUniqueResult<T[N]> { // define make_unique. Other supported compilers either just define __cplusplus // as 201103 but have make_unique (msvc), or have make_unique whenever // __cplusplus > 201103 (clang). -#if defined(__cpp_lib_make_unique) +#if defined(__cpp_lib_make_unique) using std::make_unique; #else // ----------------------------------------------------------------------------- @@ -419,7 +419,7 @@ struct pointer_traits<T*> { // // A C++11 compatible implementation of C++17's std::allocator_traits. // -#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) using std::allocator_traits; #else // __cplusplus >= 201703L template <typename Alloc> diff --git a/contrib/restricted/abseil-cpp/absl/memory/ya.make b/contrib/restricted/abseil-cpp/absl/memory/ya.make index fff0c2665f..1a4f01e648 100644 --- a/contrib/restricted/abseil-cpp/absl/memory/ya.make +++ b/contrib/restricted/abseil-cpp/absl/memory/ya.make @@ -1,15 +1,15 @@ -# Generated by devtools/yamaker. - -LIBRARY() - -OWNER(g:cpp-contrib) - -LICENSE(Apache-2.0) - +# Generated by devtools/yamaker. + +LIBRARY() + +OWNER(g:cpp-contrib) + +LICENSE(Apache-2.0) + LICENSE_TEXTS(.yandex_meta/licenses.list.txt) -PEERDIR( - contrib/restricted/abseil-cpp/absl/meta -) - -END() +PEERDIR( + contrib/restricted/abseil-cpp/absl/meta +) + +END() diff --git a/contrib/restricted/abseil-cpp/absl/meta/type_traits.h b/contrib/restricted/abseil-cpp/absl/meta/type_traits.h index d886cb30a8..7791d766eb 100644 --- a/contrib/restricted/abseil-cpp/absl/meta/type_traits.h +++ b/contrib/restricted/abseil-cpp/absl/meta/type_traits.h @@ -35,7 +35,7 @@ #ifndef ABSL_META_TYPE_TRAITS_H_ #define ABSL_META_TYPE_TRAITS_H_ -#include <cstddef> +#include <cstddef> #include <functional> #include <type_traits> @@ -47,14 +47,14 @@ #define ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION 1 #endif -// Defines the default alignment. `__STDCPP_DEFAULT_NEW_ALIGNMENT__` is a C++17 -// feature. -#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) -#define ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT __STDCPP_DEFAULT_NEW_ALIGNMENT__ -#else // defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) -#define ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT alignof(std::max_align_t) -#endif // defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) - +// Defines the default alignment. `__STDCPP_DEFAULT_NEW_ALIGNMENT__` is a C++17 +// feature. +#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) +#define ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT __STDCPP_DEFAULT_NEW_ALIGNMENT__ +#else // defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) +#define ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT alignof(std::max_align_t) +#endif // defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) + namespace absl { ABSL_NAMESPACE_BEGIN @@ -507,27 +507,27 @@ struct is_trivially_copy_assignable #endif // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE }; -#if defined(__cpp_lib_remove_cvref) && __cpp_lib_remove_cvref >= 201711L -template <typename T> -using remove_cvref = std::remove_cvref<T>; - -template <typename T> -using remove_cvref_t = typename std::remove_cvref<T>::type; -#else -// remove_cvref() -// -// C++11 compatible implementation of std::remove_cvref which was added in -// C++20. -template <typename T> -struct remove_cvref { - using type = - typename std::remove_cv<typename std::remove_reference<T>::type>::type; -}; - -template <typename T> -using remove_cvref_t = typename remove_cvref<T>::type; -#endif - +#if defined(__cpp_lib_remove_cvref) && __cpp_lib_remove_cvref >= 201711L +template <typename T> +using remove_cvref = std::remove_cvref<T>; + +template <typename T> +using remove_cvref_t = typename std::remove_cvref<T>::type; +#else +// remove_cvref() +// +// C++11 compatible implementation of std::remove_cvref which was added in +// C++20. +template <typename T> +struct remove_cvref { + using type = + typename std::remove_cv<typename std::remove_reference<T>::type>::type; +}; + +template <typename T> +using remove_cvref_t = typename remove_cvref<T>::type; +#endif + namespace type_traits_internal { // is_trivially_copyable() // @@ -642,8 +642,8 @@ using underlying_type_t = typename std::underlying_type<T>::type; namespace type_traits_internal { -#if (defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703L) || \ - (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +#if (defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703L) || \ + (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) // std::result_of is deprecated (C++17) or removed (C++20) template<typename> struct result_of; template<typename F, typename... Args> diff --git a/contrib/restricted/abseil-cpp/absl/meta/ya.make b/contrib/restricted/abseil-cpp/absl/meta/ya.make index 28e1e1f4a1..13457b130b 100644 --- a/contrib/restricted/abseil-cpp/absl/meta/ya.make +++ b/contrib/restricted/abseil-cpp/absl/meta/ya.make @@ -1,15 +1,15 @@ -# Generated by devtools/yamaker. - -LIBRARY() - -OWNER(g:cpp-contrib) - -LICENSE(Apache-2.0) - +# Generated by devtools/yamaker. + +LIBRARY() + +OWNER(g:cpp-contrib) + +LICENSE(Apache-2.0) + LICENSE_TEXTS(.yandex_meta/licenses.list.txt) -PEERDIR( - contrib/restricted/abseil-cpp/absl/base -) - -END() +PEERDIR( + contrib/restricted/abseil-cpp/absl/base +) + +END() diff --git a/contrib/restricted/abseil-cpp/absl/numeric/int128.cc b/contrib/restricted/abseil-cpp/absl/numeric/int128.cc index 4f91e48463..f42f625d10 100644 --- a/contrib/restricted/abseil-cpp/absl/numeric/int128.cc +++ b/contrib/restricted/abseil-cpp/absl/numeric/int128.cc @@ -138,21 +138,21 @@ uint128::uint128(float v) : uint128(MakeUint128FromFloat(v)) {} uint128::uint128(double v) : uint128(MakeUint128FromFloat(v)) {} uint128::uint128(long double v) : uint128(MakeUint128FromFloat(v)) {} -#if !defined(ABSL_HAVE_INTRINSIC_INT128) +#if !defined(ABSL_HAVE_INTRINSIC_INT128) uint128 operator/(uint128 lhs, uint128 rhs) { uint128 quotient = 0; uint128 remainder = 0; DivModImpl(lhs, rhs, "ient, &remainder); return quotient; } - + uint128 operator%(uint128 lhs, uint128 rhs) { uint128 quotient = 0; uint128 remainder = 0; DivModImpl(lhs, rhs, "ient, &remainder); return remainder; } -#endif // !defined(ABSL_HAVE_INTRINSIC_INT128) +#endif // !defined(ABSL_HAVE_INTRINSIC_INT128) namespace { diff --git a/contrib/restricted/abseil-cpp/absl/numeric/int128.h b/contrib/restricted/abseil-cpp/absl/numeric/int128.h index c7ad96befd..bc47e0503e 100644 --- a/contrib/restricted/abseil-cpp/absl/numeric/int128.h +++ b/contrib/restricted/abseil-cpp/absl/numeric/int128.h @@ -18,10 +18,10 @@ // ----------------------------------------------------------------------------- // // This header file defines 128-bit integer types, `uint128` and `int128`. -// -// TODO(absl-team): This module is inconsistent as many inline `uint128` methods -// are defined in this file, while many inline `int128` methods are defined in -// the `int128_*_intrinsic.inc` files. +// +// TODO(absl-team): This module is inconsistent as many inline `uint128` methods +// are defined in this file, while many inline `int128` methods are defined in +// the `int128_*_intrinsic.inc` files. #ifndef ABSL_NUMERIC_INT128_H_ #define ABSL_NUMERIC_INT128_H_ @@ -586,10 +586,10 @@ inline uint128& uint128::operator=(int128 v) { // Arithmetic operators. -constexpr uint128 operator<<(uint128 lhs, int amount); -constexpr uint128 operator>>(uint128 lhs, int amount); -constexpr uint128 operator+(uint128 lhs, uint128 rhs); -constexpr uint128 operator-(uint128 lhs, uint128 rhs); +constexpr uint128 operator<<(uint128 lhs, int amount); +constexpr uint128 operator>>(uint128 lhs, int amount); +constexpr uint128 operator+(uint128 lhs, uint128 rhs); +constexpr uint128 operator-(uint128 lhs, uint128 rhs); uint128 operator*(uint128 lhs, uint128 rhs); uint128 operator/(uint128 lhs, uint128 rhs); uint128 operator%(uint128 lhs, uint128 rhs); @@ -786,19 +786,19 @@ inline uint128::operator long double() const { // Comparison operators. -constexpr bool operator==(uint128 lhs, uint128 rhs) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return static_cast<unsigned __int128>(lhs) == - static_cast<unsigned __int128>(rhs); -#else +constexpr bool operator==(uint128 lhs, uint128 rhs) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return static_cast<unsigned __int128>(lhs) == + static_cast<unsigned __int128>(rhs); +#else return (Uint128Low64(lhs) == Uint128Low64(rhs) && Uint128High64(lhs) == Uint128High64(rhs)); -#endif +#endif } -constexpr bool operator!=(uint128 lhs, uint128 rhs) { return !(lhs == rhs); } +constexpr bool operator!=(uint128 lhs, uint128 rhs) { return !(lhs == rhs); } -constexpr bool operator<(uint128 lhs, uint128 rhs) { +constexpr bool operator<(uint128 lhs, uint128 rhs) { #ifdef ABSL_HAVE_INTRINSIC_INT128 return static_cast<unsigned __int128>(lhs) < static_cast<unsigned __int128>(rhs); @@ -809,171 +809,171 @@ constexpr bool operator<(uint128 lhs, uint128 rhs) { #endif } -constexpr bool operator>(uint128 lhs, uint128 rhs) { return rhs < lhs; } +constexpr bool operator>(uint128 lhs, uint128 rhs) { return rhs < lhs; } -constexpr bool operator<=(uint128 lhs, uint128 rhs) { return !(rhs < lhs); } +constexpr bool operator<=(uint128 lhs, uint128 rhs) { return !(rhs < lhs); } -constexpr bool operator>=(uint128 lhs, uint128 rhs) { return !(lhs < rhs); } +constexpr bool operator>=(uint128 lhs, uint128 rhs) { return !(lhs < rhs); } // Unary operators. -constexpr inline uint128 operator+(uint128 val) { - return val; -} - -constexpr inline int128 operator+(int128 val) { - return val; -} - -constexpr uint128 operator-(uint128 val) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return -static_cast<unsigned __int128>(val); -#else - return MakeUint128( - ~Uint128High64(val) + static_cast<unsigned long>(Uint128Low64(val) == 0), - ~Uint128Low64(val) + 1); -#endif -} - -constexpr inline bool operator!(uint128 val) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return !static_cast<unsigned __int128>(val); -#else +constexpr inline uint128 operator+(uint128 val) { + return val; +} + +constexpr inline int128 operator+(int128 val) { + return val; +} + +constexpr uint128 operator-(uint128 val) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return -static_cast<unsigned __int128>(val); +#else + return MakeUint128( + ~Uint128High64(val) + static_cast<unsigned long>(Uint128Low64(val) == 0), + ~Uint128Low64(val) + 1); +#endif +} + +constexpr inline bool operator!(uint128 val) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return !static_cast<unsigned __int128>(val); +#else return !Uint128High64(val) && !Uint128Low64(val); -#endif +#endif } // Logical operators. -constexpr inline uint128 operator~(uint128 val) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return ~static_cast<unsigned __int128>(val); -#else +constexpr inline uint128 operator~(uint128 val) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return ~static_cast<unsigned __int128>(val); +#else return MakeUint128(~Uint128High64(val), ~Uint128Low64(val)); -#endif +#endif } -constexpr inline uint128 operator|(uint128 lhs, uint128 rhs) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return static_cast<unsigned __int128>(lhs) | - static_cast<unsigned __int128>(rhs); -#else +constexpr inline uint128 operator|(uint128 lhs, uint128 rhs) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return static_cast<unsigned __int128>(lhs) | + static_cast<unsigned __int128>(rhs); +#else return MakeUint128(Uint128High64(lhs) | Uint128High64(rhs), - Uint128Low64(lhs) | Uint128Low64(rhs)); -#endif + Uint128Low64(lhs) | Uint128Low64(rhs)); +#endif } -constexpr inline uint128 operator&(uint128 lhs, uint128 rhs) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return static_cast<unsigned __int128>(lhs) & - static_cast<unsigned __int128>(rhs); -#else +constexpr inline uint128 operator&(uint128 lhs, uint128 rhs) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return static_cast<unsigned __int128>(lhs) & + static_cast<unsigned __int128>(rhs); +#else return MakeUint128(Uint128High64(lhs) & Uint128High64(rhs), - Uint128Low64(lhs) & Uint128Low64(rhs)); -#endif + Uint128Low64(lhs) & Uint128Low64(rhs)); +#endif } -constexpr inline uint128 operator^(uint128 lhs, uint128 rhs) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return static_cast<unsigned __int128>(lhs) ^ - static_cast<unsigned __int128>(rhs); -#else +constexpr inline uint128 operator^(uint128 lhs, uint128 rhs) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return static_cast<unsigned __int128>(lhs) ^ + static_cast<unsigned __int128>(rhs); +#else return MakeUint128(Uint128High64(lhs) ^ Uint128High64(rhs), - Uint128Low64(lhs) ^ Uint128Low64(rhs)); -#endif + Uint128Low64(lhs) ^ Uint128Low64(rhs)); +#endif } inline uint128& uint128::operator|=(uint128 other) { - *this = *this | other; + *this = *this | other; return *this; } inline uint128& uint128::operator&=(uint128 other) { - *this = *this & other; + *this = *this & other; return *this; } inline uint128& uint128::operator^=(uint128 other) { - *this = *this ^ other; + *this = *this ^ other; return *this; } // Arithmetic operators. -constexpr uint128 operator<<(uint128 lhs, int amount) { +constexpr uint128 operator<<(uint128 lhs, int amount) { #ifdef ABSL_HAVE_INTRINSIC_INT128 return static_cast<unsigned __int128>(lhs) << amount; #else // uint64_t shifts of >= 64 are undefined, so we will need some // special-casing. - return amount >= 64 ? MakeUint128(Uint128Low64(lhs) << (amount - 64), 0) - : amount == 0 ? lhs - : MakeUint128((Uint128High64(lhs) << amount) | - (Uint128Low64(lhs) >> (64 - amount)), - Uint128Low64(lhs) << amount); + return amount >= 64 ? MakeUint128(Uint128Low64(lhs) << (amount - 64), 0) + : amount == 0 ? lhs + : MakeUint128((Uint128High64(lhs) << amount) | + (Uint128Low64(lhs) >> (64 - amount)), + Uint128Low64(lhs) << amount); #endif } -constexpr uint128 operator>>(uint128 lhs, int amount) { +constexpr uint128 operator>>(uint128 lhs, int amount) { #ifdef ABSL_HAVE_INTRINSIC_INT128 return static_cast<unsigned __int128>(lhs) >> amount; #else // uint64_t shifts of >= 64 are undefined, so we will need some // special-casing. - return amount >= 64 ? MakeUint128(0, Uint128High64(lhs) >> (amount - 64)) - : amount == 0 ? lhs - : MakeUint128(Uint128High64(lhs) >> amount, - (Uint128Low64(lhs) >> amount) | - (Uint128High64(lhs) << (64 - amount))); -#endif -} - -#if !defined(ABSL_HAVE_INTRINSIC_INT128) -namespace int128_internal { -constexpr uint128 AddResult(uint128 result, uint128 lhs) { - // check for carry - return (Uint128Low64(result) < Uint128Low64(lhs)) - ? MakeUint128(Uint128High64(result) + 1, Uint128Low64(result)) - : result; -} -} // namespace int128_internal -#endif - -constexpr uint128 operator+(uint128 lhs, uint128 rhs) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return static_cast<unsigned __int128>(lhs) + - static_cast<unsigned __int128>(rhs); -#else - return int128_internal::AddResult( - MakeUint128(Uint128High64(lhs) + Uint128High64(rhs), - Uint128Low64(lhs) + Uint128Low64(rhs)), - lhs); -#endif -} - -#if !defined(ABSL_HAVE_INTRINSIC_INT128) -namespace int128_internal { -constexpr uint128 SubstructResult(uint128 result, uint128 lhs, uint128 rhs) { - // check for carry - return (Uint128Low64(lhs) < Uint128Low64(rhs)) - ? MakeUint128(Uint128High64(result) - 1, Uint128Low64(result)) - : result; -} -} // namespace int128_internal -#endif - -constexpr uint128 operator-(uint128 lhs, uint128 rhs) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return static_cast<unsigned __int128>(lhs) - - static_cast<unsigned __int128>(rhs); -#else - return int128_internal::SubstructResult( - MakeUint128(Uint128High64(lhs) - Uint128High64(rhs), - Uint128Low64(lhs) - Uint128Low64(rhs)), - lhs, rhs); + return amount >= 64 ? MakeUint128(0, Uint128High64(lhs) >> (amount - 64)) + : amount == 0 ? lhs + : MakeUint128(Uint128High64(lhs) >> amount, + (Uint128Low64(lhs) >> amount) | + (Uint128High64(lhs) << (64 - amount))); #endif } +#if !defined(ABSL_HAVE_INTRINSIC_INT128) +namespace int128_internal { +constexpr uint128 AddResult(uint128 result, uint128 lhs) { + // check for carry + return (Uint128Low64(result) < Uint128Low64(lhs)) + ? MakeUint128(Uint128High64(result) + 1, Uint128Low64(result)) + : result; +} +} // namespace int128_internal +#endif + +constexpr uint128 operator+(uint128 lhs, uint128 rhs) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return static_cast<unsigned __int128>(lhs) + + static_cast<unsigned __int128>(rhs); +#else + return int128_internal::AddResult( + MakeUint128(Uint128High64(lhs) + Uint128High64(rhs), + Uint128Low64(lhs) + Uint128Low64(rhs)), + lhs); +#endif +} + +#if !defined(ABSL_HAVE_INTRINSIC_INT128) +namespace int128_internal { +constexpr uint128 SubstructResult(uint128 result, uint128 lhs, uint128 rhs) { + // check for carry + return (Uint128Low64(lhs) < Uint128Low64(rhs)) + ? MakeUint128(Uint128High64(result) - 1, Uint128Low64(result)) + : result; +} +} // namespace int128_internal +#endif + +constexpr uint128 operator-(uint128 lhs, uint128 rhs) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return static_cast<unsigned __int128>(lhs) - + static_cast<unsigned __int128>(rhs); +#else + return int128_internal::SubstructResult( + MakeUint128(Uint128High64(lhs) - Uint128High64(rhs), + Uint128Low64(lhs) - Uint128Low64(rhs)), + lhs, rhs); +#endif +} + inline uint128 operator*(uint128 lhs, uint128 rhs) { #if defined(ABSL_HAVE_INTRINSIC_INT128) // TODO(strel) Remove once alignment issues are resolved and unsigned __int128 @@ -1001,18 +1001,18 @@ inline uint128 operator*(uint128 lhs, uint128 rhs) { #endif // ABSL_HAVE_INTRINSIC128 } -#if defined(ABSL_HAVE_INTRINSIC_INT128) -inline uint128 operator/(uint128 lhs, uint128 rhs) { - return static_cast<unsigned __int128>(lhs) / - static_cast<unsigned __int128>(rhs); -} - -inline uint128 operator%(uint128 lhs, uint128 rhs) { - return static_cast<unsigned __int128>(lhs) % - static_cast<unsigned __int128>(rhs); -} -#endif - +#if defined(ABSL_HAVE_INTRINSIC_INT128) +inline uint128 operator/(uint128 lhs, uint128 rhs) { + return static_cast<unsigned __int128>(lhs) / + static_cast<unsigned __int128>(rhs); +} + +inline uint128 operator%(uint128 lhs, uint128 rhs) { + return static_cast<unsigned __int128>(lhs) % + static_cast<unsigned __int128>(rhs); +} +#endif + // Increment/decrement operators. inline uint128 uint128::operator++(int) { @@ -1070,17 +1070,17 @@ inline int128& int128::operator=(unsigned long long v) { } // Arithmetic operators. -constexpr int128 operator-(int128 v); -constexpr int128 operator+(int128 lhs, int128 rhs); -constexpr int128 operator-(int128 lhs, int128 rhs); +constexpr int128 operator-(int128 v); +constexpr int128 operator+(int128 lhs, int128 rhs); +constexpr int128 operator-(int128 lhs, int128 rhs); int128 operator*(int128 lhs, int128 rhs); int128 operator/(int128 lhs, int128 rhs); int128 operator%(int128 lhs, int128 rhs); -constexpr int128 operator|(int128 lhs, int128 rhs); -constexpr int128 operator&(int128 lhs, int128 rhs); -constexpr int128 operator^(int128 lhs, int128 rhs); -constexpr int128 operator<<(int128 lhs, int amount); -constexpr int128 operator>>(int128 lhs, int amount); +constexpr int128 operator|(int128 lhs, int128 rhs); +constexpr int128 operator&(int128 lhs, int128 rhs); +constexpr int128 operator^(int128 lhs, int128 rhs); +constexpr int128 operator<<(int128 lhs, int amount); +constexpr int128 operator>>(int128 lhs, int amount); inline int128& int128::operator+=(int128 other) { *this = *this + other; @@ -1132,9 +1132,9 @@ inline int128& int128::operator>>=(int amount) { return *this; } -// Forward declaration for comparison operators. -constexpr bool operator!=(int128 lhs, int128 rhs); - +// Forward declaration for comparison operators. +constexpr bool operator!=(int128 lhs, int128 rhs); + namespace int128_internal { // Casts from unsigned to signed while preserving the underlying binary diff --git a/contrib/restricted/abseil-cpp/absl/numeric/int128_have_intrinsic.inc b/contrib/restricted/abseil-cpp/absl/numeric/int128_have_intrinsic.inc index 3945fa2983..b6e31f8fa5 100644 --- a/contrib/restricted/abseil-cpp/absl/numeric/int128_have_intrinsic.inc +++ b/contrib/restricted/abseil-cpp/absl/numeric/int128_have_intrinsic.inc @@ -155,7 +155,7 @@ constexpr int128::operator unsigned __int128() const { #if defined(__clang__) && !defined(__ppc64__) inline int128::operator float() const { return static_cast<float>(v_); } -inline int128::operator double() const { return static_cast<double>(v_); } +inline int128::operator double() const { return static_cast<double>(v_); } inline int128::operator long double() const { return static_cast<long double>(v_); @@ -163,8 +163,8 @@ inline int128::operator long double() const { #else // Clang on PowerPC // Forward declaration for conversion operators to floating point types. -constexpr int128 operator-(int128 v); -constexpr bool operator!=(int128 lhs, int128 rhs); +constexpr int128 operator-(int128 v); +constexpr bool operator!=(int128 lhs, int128 rhs); inline int128::operator float() const { // We must convert the absolute value and then negate as needed, because @@ -199,45 +199,45 @@ inline int128::operator long double() const { // Comparison operators. -constexpr bool operator==(int128 lhs, int128 rhs) { +constexpr bool operator==(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) == static_cast<__int128>(rhs); } -constexpr bool operator!=(int128 lhs, int128 rhs) { +constexpr bool operator!=(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) != static_cast<__int128>(rhs); } -constexpr bool operator<(int128 lhs, int128 rhs) { +constexpr bool operator<(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) < static_cast<__int128>(rhs); } -constexpr bool operator>(int128 lhs, int128 rhs) { +constexpr bool operator>(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) > static_cast<__int128>(rhs); } -constexpr bool operator<=(int128 lhs, int128 rhs) { +constexpr bool operator<=(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) <= static_cast<__int128>(rhs); } -constexpr bool operator>=(int128 lhs, int128 rhs) { +constexpr bool operator>=(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) >= static_cast<__int128>(rhs); } // Unary operators. -constexpr int128 operator-(int128 v) { return -static_cast<__int128>(v); } +constexpr int128 operator-(int128 v) { return -static_cast<__int128>(v); } -constexpr bool operator!(int128 v) { return !static_cast<__int128>(v); } +constexpr bool operator!(int128 v) { return !static_cast<__int128>(v); } -constexpr int128 operator~(int128 val) { return ~static_cast<__int128>(val); } +constexpr int128 operator~(int128 val) { return ~static_cast<__int128>(val); } // Arithmetic operators. -constexpr int128 operator+(int128 lhs, int128 rhs) { +constexpr int128 operator+(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) + static_cast<__int128>(rhs); } -constexpr int128 operator-(int128 lhs, int128 rhs) { +constexpr int128 operator-(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) - static_cast<__int128>(rhs); } @@ -275,22 +275,22 @@ inline int128& int128::operator--() { return *this; } -constexpr int128 operator|(int128 lhs, int128 rhs) { +constexpr int128 operator|(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) | static_cast<__int128>(rhs); } -constexpr int128 operator&(int128 lhs, int128 rhs) { +constexpr int128 operator&(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) & static_cast<__int128>(rhs); } -constexpr int128 operator^(int128 lhs, int128 rhs) { +constexpr int128 operator^(int128 lhs, int128 rhs) { return static_cast<__int128>(lhs) ^ static_cast<__int128>(rhs); } -constexpr int128 operator<<(int128 lhs, int amount) { +constexpr int128 operator<<(int128 lhs, int amount) { return static_cast<__int128>(lhs) << amount; } -constexpr int128 operator>>(int128 lhs, int amount) { +constexpr int128 operator>>(int128 lhs, int amount) { return static_cast<__int128>(lhs) >> amount; } diff --git a/contrib/restricted/abseil-cpp/absl/numeric/int128_no_intrinsic.inc b/contrib/restricted/abseil-cpp/absl/numeric/int128_no_intrinsic.inc index 8834804cec..deb1c31c36 100644 --- a/contrib/restricted/abseil-cpp/absl/numeric/int128_no_intrinsic.inc +++ b/contrib/restricted/abseil-cpp/absl/numeric/int128_no_intrinsic.inc @@ -165,80 +165,80 @@ inline int128::operator long double() const { // Comparison operators. -constexpr bool operator==(int128 lhs, int128 rhs) { +constexpr bool operator==(int128 lhs, int128 rhs) { return (Int128Low64(lhs) == Int128Low64(rhs) && Int128High64(lhs) == Int128High64(rhs)); } -constexpr bool operator!=(int128 lhs, int128 rhs) { return !(lhs == rhs); } +constexpr bool operator!=(int128 lhs, int128 rhs) { return !(lhs == rhs); } -constexpr bool operator<(int128 lhs, int128 rhs) { +constexpr bool operator<(int128 lhs, int128 rhs) { return (Int128High64(lhs) == Int128High64(rhs)) ? (Int128Low64(lhs) < Int128Low64(rhs)) : (Int128High64(lhs) < Int128High64(rhs)); } -constexpr bool operator>(int128 lhs, int128 rhs) { +constexpr bool operator>(int128 lhs, int128 rhs) { return (Int128High64(lhs) == Int128High64(rhs)) ? (Int128Low64(lhs) > Int128Low64(rhs)) : (Int128High64(lhs) > Int128High64(rhs)); } -constexpr bool operator<=(int128 lhs, int128 rhs) { return !(lhs > rhs); } +constexpr bool operator<=(int128 lhs, int128 rhs) { return !(lhs > rhs); } -constexpr bool operator>=(int128 lhs, int128 rhs) { return !(lhs < rhs); } +constexpr bool operator>=(int128 lhs, int128 rhs) { return !(lhs < rhs); } // Unary operators. -constexpr int128 operator-(int128 v) { - return MakeInt128(~Int128High64(v) + (Int128Low64(v) == 0), - ~Int128Low64(v) + 1); +constexpr int128 operator-(int128 v) { + return MakeInt128(~Int128High64(v) + (Int128Low64(v) == 0), + ~Int128Low64(v) + 1); } -constexpr bool operator!(int128 v) { +constexpr bool operator!(int128 v) { return !Int128Low64(v) && !Int128High64(v); } -constexpr int128 operator~(int128 val) { +constexpr int128 operator~(int128 val) { return MakeInt128(~Int128High64(val), ~Int128Low64(val)); } // Arithmetic operators. -namespace int128_internal { -constexpr int128 SignedAddResult(int128 result, int128 lhs) { - // check for carry - return (Int128Low64(result) < Int128Low64(lhs)) - ? MakeInt128(Int128High64(result) + 1, Int128Low64(result)) - : result; -} -} // namespace int128_internal -constexpr int128 operator+(int128 lhs, int128 rhs) { - return int128_internal::SignedAddResult( - MakeInt128(Int128High64(lhs) + Int128High64(rhs), - Int128Low64(lhs) + Int128Low64(rhs)), - lhs); -} - -namespace int128_internal { -constexpr int128 SignedSubstructResult(int128 result, int128 lhs, int128 rhs) { - // check for carry - return (Int128Low64(lhs) < Int128Low64(rhs)) - ? MakeInt128(Int128High64(result) - 1, Int128Low64(result)) - : result; -} -} // namespace int128_internal -constexpr int128 operator-(int128 lhs, int128 rhs) { - return int128_internal::SignedSubstructResult( - MakeInt128(Int128High64(lhs) - Int128High64(rhs), - Int128Low64(lhs) - Int128Low64(rhs)), - lhs, rhs); -} +namespace int128_internal { +constexpr int128 SignedAddResult(int128 result, int128 lhs) { + // check for carry + return (Int128Low64(result) < Int128Low64(lhs)) + ? MakeInt128(Int128High64(result) + 1, Int128Low64(result)) + : result; +} +} // namespace int128_internal +constexpr int128 operator+(int128 lhs, int128 rhs) { + return int128_internal::SignedAddResult( + MakeInt128(Int128High64(lhs) + Int128High64(rhs), + Int128Low64(lhs) + Int128Low64(rhs)), + lhs); +} + +namespace int128_internal { +constexpr int128 SignedSubstructResult(int128 result, int128 lhs, int128 rhs) { + // check for carry + return (Int128Low64(lhs) < Int128Low64(rhs)) + ? MakeInt128(Int128High64(result) - 1, Int128Low64(result)) + : result; +} +} // namespace int128_internal +constexpr int128 operator-(int128 lhs, int128 rhs) { + return int128_internal::SignedSubstructResult( + MakeInt128(Int128High64(lhs) - Int128High64(rhs), + Int128Low64(lhs) - Int128Low64(rhs)), + lhs, rhs); +} inline int128 operator*(int128 lhs, int128 rhs) { - return MakeInt128( - int128_internal::BitCastToSigned(Uint128High64(uint128(lhs) * rhs)), - Uint128Low64(uint128(lhs) * rhs)); + return MakeInt128( + int128_internal::BitCastToSigned(Uint128High64(uint128(lhs) * rhs)), + Uint128Low64(uint128(lhs) * rhs)); } inline int128 int128::operator++(int) { @@ -263,49 +263,49 @@ inline int128& int128::operator--() { return *this; } -constexpr int128 operator|(int128 lhs, int128 rhs) { +constexpr int128 operator|(int128 lhs, int128 rhs) { return MakeInt128(Int128High64(lhs) | Int128High64(rhs), Int128Low64(lhs) | Int128Low64(rhs)); } -constexpr int128 operator&(int128 lhs, int128 rhs) { +constexpr int128 operator&(int128 lhs, int128 rhs) { return MakeInt128(Int128High64(lhs) & Int128High64(rhs), Int128Low64(lhs) & Int128Low64(rhs)); } -constexpr int128 operator^(int128 lhs, int128 rhs) { +constexpr int128 operator^(int128 lhs, int128 rhs) { return MakeInt128(Int128High64(lhs) ^ Int128High64(rhs), Int128Low64(lhs) ^ Int128Low64(rhs)); } -constexpr int128 operator<<(int128 lhs, int amount) { - // int64_t shifts of >= 64 are undefined, so we need some special-casing. - return amount >= 64 - ? MakeInt128( - static_cast<int64_t>(Int128Low64(lhs) << (amount - 64)), 0) - : amount == 0 - ? lhs - : MakeInt128( - (Int128High64(lhs) << amount) | - static_cast<int64_t>(Int128Low64(lhs) >> (64 - amount)), - Int128Low64(lhs) << amount); -} - -constexpr int128 operator>>(int128 lhs, int amount) { - // int64_t shifts of >= 64 are undefined, so we need some special-casing. - // The (Int128High64(lhs) >> 32) >> 32 "trick" causes the the most significant - // int64 to be inititialized with all zeros or all ones correctly. It takes - // into account whether the number is negative or positive, and whether the - // current architecture does arithmetic or logical right shifts for negative - // numbers. - return amount >= 64 - ? MakeInt128( - (Int128High64(lhs) >> 32) >> 32, - static_cast<uint64_t>(Int128High64(lhs) >> (amount - 64))) - : amount == 0 - ? lhs - : MakeInt128(Int128High64(lhs) >> amount, - (Int128Low64(lhs) >> amount) | - (static_cast<uint64_t>(Int128High64(lhs)) - << (64 - amount))); +constexpr int128 operator<<(int128 lhs, int amount) { + // int64_t shifts of >= 64 are undefined, so we need some special-casing. + return amount >= 64 + ? MakeInt128( + static_cast<int64_t>(Int128Low64(lhs) << (amount - 64)), 0) + : amount == 0 + ? lhs + : MakeInt128( + (Int128High64(lhs) << amount) | + static_cast<int64_t>(Int128Low64(lhs) >> (64 - amount)), + Int128Low64(lhs) << amount); +} + +constexpr int128 operator>>(int128 lhs, int amount) { + // int64_t shifts of >= 64 are undefined, so we need some special-casing. + // The (Int128High64(lhs) >> 32) >> 32 "trick" causes the the most significant + // int64 to be inititialized with all zeros or all ones correctly. It takes + // into account whether the number is negative or positive, and whether the + // current architecture does arithmetic or logical right shifts for negative + // numbers. + return amount >= 64 + ? MakeInt128( + (Int128High64(lhs) >> 32) >> 32, + static_cast<uint64_t>(Int128High64(lhs) >> (amount - 64))) + : amount == 0 + ? lhs + : MakeInt128(Int128High64(lhs) >> amount, + (Int128Low64(lhs) >> amount) | + (static_cast<uint64_t>(Int128High64(lhs)) + << (64 - amount))); } diff --git a/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.cc b/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.cc index 81d9a75765..666df2446a 100644 --- a/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.cc +++ b/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "absl/profiling/internal/exponential_biased.h" +#include "absl/profiling/internal/exponential_biased.h" #include <stdint.h> @@ -26,7 +26,7 @@ namespace absl { ABSL_NAMESPACE_BEGIN -namespace profiling_internal { +namespace profiling_internal { // The algorithm generates a random number between 0 and 1 and applies the // inverse cumulative distribution function for an exponential. Specifically: @@ -64,7 +64,7 @@ int64_t ExponentialBiased::GetSkipCount(int64_t mean) { // Assume huge values are bias neutral, retain bias for next call. return std::numeric_limits<int64_t>::max() / 2; } - double value = std::rint(interval); + double value = std::rint(interval); bias_ = interval - value; return value; } @@ -88,6 +88,6 @@ void ExponentialBiased::Initialize() { initialized_ = true; } -} // namespace profiling_internal +} // namespace profiling_internal ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.h b/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.h index d31f7782e8..b7940860b2 100644 --- a/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.h +++ b/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef ABSL_PROFILING_INTERNAL_EXPONENTIAL_BIASED_H_ -#define ABSL_PROFILING_INTERNAL_EXPONENTIAL_BIASED_H_ +#ifndef ABSL_PROFILING_INTERNAL_EXPONENTIAL_BIASED_H_ +#define ABSL_PROFILING_INTERNAL_EXPONENTIAL_BIASED_H_ #include <stdint.h> @@ -22,7 +22,7 @@ namespace absl { ABSL_NAMESPACE_BEGIN -namespace profiling_internal { +namespace profiling_internal { // ExponentialBiased provides a small and fast random number generator for a // rounded exponential distribution. This generator manages very little state, @@ -66,7 +66,7 @@ namespace profiling_internal { // Adjusting with rounding bias is relatively trivial: // // double value = bias_ + exponential_distribution(mean)(); -// double rounded_value = std::rint(value); +// double rounded_value = std::rint(value); // bias_ = value - rounded_value; // return rounded_value; // @@ -123,8 +123,8 @@ inline uint64_t ExponentialBiased::NextRandom(uint64_t rnd) { return (prng_mult * rnd + prng_add) & prng_mod_mask; } -} // namespace profiling_internal +} // namespace profiling_internal ABSL_NAMESPACE_END } // namespace absl -#endif // ABSL_PROFILING_INTERNAL_EXPONENTIAL_BIASED_H_ +#endif // ABSL_PROFILING_INTERNAL_EXPONENTIAL_BIASED_H_ diff --git a/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased/ya.make b/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased/ya.make index 14f60647fc..b77eb0d834 100644 --- a/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased/ya.make +++ b/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased/ya.make @@ -20,7 +20,7 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/profiling/internal) +SRCDIR(contrib/restricted/abseil-cpp/absl/profiling/internal) SRCS( exponential_biased.cc diff --git a/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.cc b/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.cc index a738a82c86..59e65b966c 100644 --- a/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.cc +++ b/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.cc @@ -12,15 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "absl/profiling/internal/periodic_sampler.h" +#include "absl/profiling/internal/periodic_sampler.h" #include <atomic> -#include "absl/profiling/internal/exponential_biased.h" +#include "absl/profiling/internal/exponential_biased.h" namespace absl { ABSL_NAMESPACE_BEGIN -namespace profiling_internal { +namespace profiling_internal { int64_t PeriodicSamplerBase::GetExponentialBiased(int period) noexcept { return rng_.GetStride(period); @@ -48,6 +48,6 @@ bool PeriodicSamplerBase::SubtleConfirmSample() noexcept { return true; } -} // namespace profiling_internal +} // namespace profiling_internal ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.h b/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.h index 54f0af452b..cde3161399 100644 --- a/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.h +++ b/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.h @@ -12,19 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef ABSL_PROFILING_INTERNAL_PERIODIC_SAMPLER_H_ -#define ABSL_PROFILING_INTERNAL_PERIODIC_SAMPLER_H_ +#ifndef ABSL_PROFILING_INTERNAL_PERIODIC_SAMPLER_H_ +#define ABSL_PROFILING_INTERNAL_PERIODIC_SAMPLER_H_ #include <stdint.h> #include <atomic> #include "absl/base/optimization.h" -#include "absl/profiling/internal/exponential_biased.h" +#include "absl/profiling/internal/exponential_biased.h" namespace absl { ABSL_NAMESPACE_BEGIN -namespace profiling_internal { +namespace profiling_internal { // PeriodicSamplerBase provides the basic period sampler implementation. // @@ -149,7 +149,7 @@ class PeriodicSamplerBase { // ICC x64 (OK) : https://gcc.godbolt.org/z/ptTNfD // MSVC x64 (OK) : https://gcc.godbolt.org/z/76j4-5 uint64_t stride_ = 0; - absl::profiling_internal::ExponentialBiased rng_; + absl::profiling_internal::ExponentialBiased rng_; }; inline bool PeriodicSamplerBase::SubtleMaybeSample() noexcept { @@ -204,8 +204,8 @@ class PeriodicSampler final : public PeriodicSamplerBase { template <typename Tag, int default_period> std::atomic<int> PeriodicSampler<Tag, default_period>::period_(default_period); -} // namespace profiling_internal +} // namespace profiling_internal ABSL_NAMESPACE_END } // namespace absl -#endif // ABSL_PROFILING_INTERNAL_PERIODIC_SAMPLER_H_ +#endif // ABSL_PROFILING_INTERNAL_PERIODIC_SAMPLER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler/ya.make b/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler/ya.make index 841a35bc53..bfa3498214 100644 --- a/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler/ya.make +++ b/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler/ya.make @@ -9,7 +9,7 @@ OWNER(g:cpp-contrib) LICENSE(Apache-2.0) PEERDIR( - contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased ) ADDINCL( @@ -24,7 +24,7 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/profiling/internal) +SRCDIR(contrib/restricted/abseil-cpp/absl/profiling/internal) SRCS( periodic_sampler.cc diff --git a/contrib/restricted/abseil-cpp/absl/profiling/internal/sample_recorder.h b/contrib/restricted/abseil-cpp/absl/profiling/internal/sample_recorder.h index 5e04a9cd19..652f65c490 100644 --- a/contrib/restricted/abseil-cpp/absl/profiling/internal/sample_recorder.h +++ b/contrib/restricted/abseil-cpp/absl/profiling/internal/sample_recorder.h @@ -1,230 +1,230 @@ -// Copyright 2018 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ----------------------------------------------------------------------------- -// File: sample_recorder.h -// ----------------------------------------------------------------------------- -// -// This header file defines a lock-free linked list for recording samples -// collected from a random/stochastic process. -// -// This utility is internal-only. Use at your own risk. - -#ifndef ABSL_PROFILING_INTERNAL_SAMPLE_RECORDER_H_ -#define ABSL_PROFILING_INTERNAL_SAMPLE_RECORDER_H_ - -#include <atomic> -#include <cstddef> -#include <functional> - -#include "absl/base/config.h" -#include "absl/base/thread_annotations.h" -#include "absl/synchronization/mutex.h" -#include "absl/time/time.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace profiling_internal { - -// Sample<T> that has members required for linking samples in the linked list of -// samples maintained by the SampleRecorder. Type T defines the sampled data. -template <typename T> -struct Sample { - // Guards the ability to restore the sample to a pristine state. This - // prevents races with sampling and resurrecting an object. - absl::Mutex init_mu; - T* next = nullptr; - T* dead ABSL_GUARDED_BY(init_mu) = nullptr; -}; - -// Holds samples and their associated stack traces with a soft limit of -// `SetHashtablezMaxSamples()`. -// -// Thread safe. -template <typename T> -class SampleRecorder { - public: - SampleRecorder(); - ~SampleRecorder(); - - // Registers for sampling. Returns an opaque registration info. - T* Register(); - - // Unregisters the sample. - void Unregister(T* sample); - - // The dispose callback will be called on all samples the moment they are - // being unregistered. Only affects samples that are unregistered after the - // callback has been set. - // Returns the previous callback. - using DisposeCallback = void (*)(const T&); - DisposeCallback SetDisposeCallback(DisposeCallback f); - - // Iterates over all the registered `StackInfo`s. Returning the number of - // samples that have been dropped. - int64_t Iterate(const std::function<void(const T& stack)>& f); - - void SetMaxSamples(int32_t max); - - private: - void PushNew(T* sample); - void PushDead(T* sample); - T* PopDead(); - - std::atomic<size_t> dropped_samples_; - std::atomic<size_t> size_estimate_; - std::atomic<int32_t> max_samples_{1 << 20}; - - // Intrusive lock free linked lists for tracking samples. - // - // `all_` records all samples (they are never removed from this list) and is - // terminated with a `nullptr`. - // - // `graveyard_.dead` is a circular linked list. When it is empty, - // `graveyard_.dead == &graveyard`. The list is circular so that - // every item on it (even the last) has a non-null dead pointer. This allows - // `Iterate` to determine if a given sample is live or dead using only - // information on the sample itself. - // - // For example, nodes [A, B, C, D, E] with [A, C, E] alive and [B, D] dead - // looks like this (G is the Graveyard): - // - // +---+ +---+ +---+ +---+ +---+ - // all -->| A |--->| B |--->| C |--->| D |--->| E | - // | | | | | | | | | | - // +---+ | | +->| |-+ | | +->| |-+ | | - // | G | +---+ | +---+ | +---+ | +---+ | +---+ - // | | | | | | - // | | --------+ +--------+ | - // +---+ | - // ^ | - // +--------------------------------------+ - // - std::atomic<T*> all_; - T graveyard_; - - std::atomic<DisposeCallback> dispose_; -}; - -template <typename T> -typename SampleRecorder<T>::DisposeCallback -SampleRecorder<T>::SetDisposeCallback(DisposeCallback f) { - return dispose_.exchange(f, std::memory_order_relaxed); -} - -template <typename T> -SampleRecorder<T>::SampleRecorder() - : dropped_samples_(0), size_estimate_(0), all_(nullptr), dispose_(nullptr) { - absl::MutexLock l(&graveyard_.init_mu); - graveyard_.dead = &graveyard_; -} - -template <typename T> -SampleRecorder<T>::~SampleRecorder() { - T* s = all_.load(std::memory_order_acquire); - while (s != nullptr) { - T* next = s->next; - delete s; - s = next; - } -} - -template <typename T> -void SampleRecorder<T>::PushNew(T* sample) { - sample->next = all_.load(std::memory_order_relaxed); - while (!all_.compare_exchange_weak(sample->next, sample, - std::memory_order_release, - std::memory_order_relaxed)) { - } -} - -template <typename T> -void SampleRecorder<T>::PushDead(T* sample) { - if (auto* dispose = dispose_.load(std::memory_order_relaxed)) { - dispose(*sample); - } - - absl::MutexLock graveyard_lock(&graveyard_.init_mu); - absl::MutexLock sample_lock(&sample->init_mu); - sample->dead = graveyard_.dead; - graveyard_.dead = sample; -} - -template <typename T> -T* SampleRecorder<T>::PopDead() { - absl::MutexLock graveyard_lock(&graveyard_.init_mu); - - // The list is circular, so eventually it collapses down to - // graveyard_.dead == &graveyard_ - // when it is empty. - T* sample = graveyard_.dead; - if (sample == &graveyard_) return nullptr; - - absl::MutexLock sample_lock(&sample->init_mu); - graveyard_.dead = sample->dead; - sample->dead = nullptr; - sample->PrepareForSampling(); - return sample; -} - -template <typename T> -T* SampleRecorder<T>::Register() { - int64_t size = size_estimate_.fetch_add(1, std::memory_order_relaxed); - if (size > max_samples_.load(std::memory_order_relaxed)) { - size_estimate_.fetch_sub(1, std::memory_order_relaxed); - dropped_samples_.fetch_add(1, std::memory_order_relaxed); - return nullptr; - } - - T* sample = PopDead(); - if (sample == nullptr) { - // Resurrection failed. Hire a new warlock. - sample = new T(); - PushNew(sample); - } - - return sample; -} - -template <typename T> -void SampleRecorder<T>::Unregister(T* sample) { - PushDead(sample); - size_estimate_.fetch_sub(1, std::memory_order_relaxed); -} - -template <typename T> -int64_t SampleRecorder<T>::Iterate( - const std::function<void(const T& stack)>& f) { - T* s = all_.load(std::memory_order_acquire); - while (s != nullptr) { - absl::MutexLock l(&s->init_mu); - if (s->dead == nullptr) { - f(*s); - } - s = s->next; - } - - return dropped_samples_.load(std::memory_order_relaxed); -} - -template <typename T> -void SampleRecorder<T>::SetMaxSamples(int32_t max) { - max_samples_.store(max, std::memory_order_release); -} - -} // namespace profiling_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_PROFILING_INTERNAL_SAMPLE_RECORDER_H_ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ----------------------------------------------------------------------------- +// File: sample_recorder.h +// ----------------------------------------------------------------------------- +// +// This header file defines a lock-free linked list for recording samples +// collected from a random/stochastic process. +// +// This utility is internal-only. Use at your own risk. + +#ifndef ABSL_PROFILING_INTERNAL_SAMPLE_RECORDER_H_ +#define ABSL_PROFILING_INTERNAL_SAMPLE_RECORDER_H_ + +#include <atomic> +#include <cstddef> +#include <functional> + +#include "absl/base/config.h" +#include "absl/base/thread_annotations.h" +#include "absl/synchronization/mutex.h" +#include "absl/time/time.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace profiling_internal { + +// Sample<T> that has members required for linking samples in the linked list of +// samples maintained by the SampleRecorder. Type T defines the sampled data. +template <typename T> +struct Sample { + // Guards the ability to restore the sample to a pristine state. This + // prevents races with sampling and resurrecting an object. + absl::Mutex init_mu; + T* next = nullptr; + T* dead ABSL_GUARDED_BY(init_mu) = nullptr; +}; + +// Holds samples and their associated stack traces with a soft limit of +// `SetHashtablezMaxSamples()`. +// +// Thread safe. +template <typename T> +class SampleRecorder { + public: + SampleRecorder(); + ~SampleRecorder(); + + // Registers for sampling. Returns an opaque registration info. + T* Register(); + + // Unregisters the sample. + void Unregister(T* sample); + + // The dispose callback will be called on all samples the moment they are + // being unregistered. Only affects samples that are unregistered after the + // callback has been set. + // Returns the previous callback. + using DisposeCallback = void (*)(const T&); + DisposeCallback SetDisposeCallback(DisposeCallback f); + + // Iterates over all the registered `StackInfo`s. Returning the number of + // samples that have been dropped. + int64_t Iterate(const std::function<void(const T& stack)>& f); + + void SetMaxSamples(int32_t max); + + private: + void PushNew(T* sample); + void PushDead(T* sample); + T* PopDead(); + + std::atomic<size_t> dropped_samples_; + std::atomic<size_t> size_estimate_; + std::atomic<int32_t> max_samples_{1 << 20}; + + // Intrusive lock free linked lists for tracking samples. + // + // `all_` records all samples (they are never removed from this list) and is + // terminated with a `nullptr`. + // + // `graveyard_.dead` is a circular linked list. When it is empty, + // `graveyard_.dead == &graveyard`. The list is circular so that + // every item on it (even the last) has a non-null dead pointer. This allows + // `Iterate` to determine if a given sample is live or dead using only + // information on the sample itself. + // + // For example, nodes [A, B, C, D, E] with [A, C, E] alive and [B, D] dead + // looks like this (G is the Graveyard): + // + // +---+ +---+ +---+ +---+ +---+ + // all -->| A |--->| B |--->| C |--->| D |--->| E | + // | | | | | | | | | | + // +---+ | | +->| |-+ | | +->| |-+ | | + // | G | +---+ | +---+ | +---+ | +---+ | +---+ + // | | | | | | + // | | --------+ +--------+ | + // +---+ | + // ^ | + // +--------------------------------------+ + // + std::atomic<T*> all_; + T graveyard_; + + std::atomic<DisposeCallback> dispose_; +}; + +template <typename T> +typename SampleRecorder<T>::DisposeCallback +SampleRecorder<T>::SetDisposeCallback(DisposeCallback f) { + return dispose_.exchange(f, std::memory_order_relaxed); +} + +template <typename T> +SampleRecorder<T>::SampleRecorder() + : dropped_samples_(0), size_estimate_(0), all_(nullptr), dispose_(nullptr) { + absl::MutexLock l(&graveyard_.init_mu); + graveyard_.dead = &graveyard_; +} + +template <typename T> +SampleRecorder<T>::~SampleRecorder() { + T* s = all_.load(std::memory_order_acquire); + while (s != nullptr) { + T* next = s->next; + delete s; + s = next; + } +} + +template <typename T> +void SampleRecorder<T>::PushNew(T* sample) { + sample->next = all_.load(std::memory_order_relaxed); + while (!all_.compare_exchange_weak(sample->next, sample, + std::memory_order_release, + std::memory_order_relaxed)) { + } +} + +template <typename T> +void SampleRecorder<T>::PushDead(T* sample) { + if (auto* dispose = dispose_.load(std::memory_order_relaxed)) { + dispose(*sample); + } + + absl::MutexLock graveyard_lock(&graveyard_.init_mu); + absl::MutexLock sample_lock(&sample->init_mu); + sample->dead = graveyard_.dead; + graveyard_.dead = sample; +} + +template <typename T> +T* SampleRecorder<T>::PopDead() { + absl::MutexLock graveyard_lock(&graveyard_.init_mu); + + // The list is circular, so eventually it collapses down to + // graveyard_.dead == &graveyard_ + // when it is empty. + T* sample = graveyard_.dead; + if (sample == &graveyard_) return nullptr; + + absl::MutexLock sample_lock(&sample->init_mu); + graveyard_.dead = sample->dead; + sample->dead = nullptr; + sample->PrepareForSampling(); + return sample; +} + +template <typename T> +T* SampleRecorder<T>::Register() { + int64_t size = size_estimate_.fetch_add(1, std::memory_order_relaxed); + if (size > max_samples_.load(std::memory_order_relaxed)) { + size_estimate_.fetch_sub(1, std::memory_order_relaxed); + dropped_samples_.fetch_add(1, std::memory_order_relaxed); + return nullptr; + } + + T* sample = PopDead(); + if (sample == nullptr) { + // Resurrection failed. Hire a new warlock. + sample = new T(); + PushNew(sample); + } + + return sample; +} + +template <typename T> +void SampleRecorder<T>::Unregister(T* sample) { + PushDead(sample); + size_estimate_.fetch_sub(1, std::memory_order_relaxed); +} + +template <typename T> +int64_t SampleRecorder<T>::Iterate( + const std::function<void(const T& stack)>& f) { + T* s = all_.load(std::memory_order_acquire); + while (s != nullptr) { + absl::MutexLock l(&s->init_mu); + if (s->dead == nullptr) { + f(*s); + } + s = s->next; + } + + return dropped_samples_.load(std::memory_order_relaxed); +} + +template <typename T> +void SampleRecorder<T>::SetMaxSamples(int32_t max) { + max_samples_.store(max, std::memory_order_release); +} + +} // namespace profiling_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_PROFILING_INTERNAL_SAMPLE_RECORDER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/absl_random_distributions/ya.make b/contrib/restricted/abseil-cpp/absl/random/absl_random_distributions/ya.make index 73d9caa424..3b415406a1 100644 --- a/contrib/restricted/abseil-cpp/absl/random/absl_random_distributions/ya.make +++ b/contrib/restricted/abseil-cpp/absl/random/absl_random_distributions/ya.make @@ -2,8 +2,8 @@ LIBRARY() -WITHOUT_LICENSE_TEXTS() - +WITHOUT_LICENSE_TEXTS() + OWNER(g:cpp-contrib) LICENSE(Apache-2.0) @@ -15,8 +15,8 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity contrib/restricted/abseil-cpp/absl/numeric - contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal ) ADDINCL( @@ -31,11 +31,11 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/random) - +SRCDIR(contrib/restricted/abseil-cpp/absl/random) + SRCS( - discrete_distribution.cc - gaussian_distribution.cc + discrete_distribution.cc + gaussian_distribution.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/absl_random_internal_distribution_test_util/ya.make b/contrib/restricted/abseil-cpp/absl/random/internal/absl_random_internal_distribution_test_util/ya.make index 340d08c827..d894a03582 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/absl_random_internal_distribution_test_util/ya.make +++ b/contrib/restricted/abseil-cpp/absl/random/internal/absl_random_internal_distribution_test_util/ya.make @@ -16,7 +16,7 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/base/log_severity contrib/restricted/abseil-cpp/absl/numeric contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal contrib/restricted/abseil-cpp/absl/strings/internal/str_format ) diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/explicit_seed_seq.h b/contrib/restricted/abseil-cpp/absl/random/internal/explicit_seed_seq.h index 25f791535f..fb99f21fb5 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/explicit_seed_seq.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/explicit_seed_seq.h @@ -74,7 +74,7 @@ class ExplicitSeedSeq { template <typename OutIterator> void generate(OutIterator begin, OutIterator end) { for (size_t index = 0; begin != end; begin++) { - *begin = state_.empty() ? 0 : state_[index++]; + *begin = state_.empty() ? 0 : state_[index++]; if (index >= state_.size()) { index = 0; } diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/generate_real.h b/contrib/restricted/abseil-cpp/absl/random/internal/generate_real.h index d5fbb44c24..fe7744c1e8 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/generate_real.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/generate_real.h @@ -127,8 +127,8 @@ inline RealType GenerateRealFromBits(uint64_t bits, int exp_bias = 0) { // Construct the 32-bit or 64-bit IEEE 754 floating-point value from // the individual fields: sign, exp, mantissa(bits). - uint_type val = sign | (static_cast<uint_type>(exp) << kExp) | - (static_cast<uint_type>(bits) & kMask); + uint_type val = sign | (static_cast<uint_type>(exp) << kExp) | + (static_cast<uint_type>(bits) & kMask); // bit_cast to the output-type real_type result; diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.cc b/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.cc index 725100a415..8cb46414ba 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.cc +++ b/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.cc @@ -194,10 +194,10 @@ RandenPoolEntry* PoolAlignedAlloc() { // Not all the platforms that we build for have std::aligned_alloc, however // since we never free these objects, we can over allocate and munge the // pointers to the correct alignment. - intptr_t x = reinterpret_cast<intptr_t>( - new char[sizeof(RandenPoolEntry) + kAlignment]); + intptr_t x = reinterpret_cast<intptr_t>( + new char[sizeof(RandenPoolEntry) + kAlignment]); auto y = x % kAlignment; - void* aligned = reinterpret_cast<void*>(y == 0 ? x : (x + kAlignment - y)); + void* aligned = reinterpret_cast<void*>(y == 0 ? x : (x + kAlignment - y)); return new (aligned) RandenPoolEntry(); } diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg/ya.make b/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg/ya.make index fd4e1c1f4d..ae82898889 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg/ya.make +++ b/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg/ya.make @@ -23,7 +23,7 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/random/internal/seed_material contrib/restricted/abseil-cpp/absl/random/seed_gen_exception contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal contrib/restricted/abseil-cpp/absl/types/bad_optional_access ) diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_engine.h b/contrib/restricted/abseil-cpp/absl/random/internal/randen_engine.h index 372c3ac2bd..2dab2cf4fc 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_engine.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_engine.h @@ -121,13 +121,13 @@ class alignas(16) randen_engine { const size_t requested_entropy = (entropy_size == 0) ? 8u : entropy_size; std::fill(std::begin(buffer) + requested_entropy, std::end(buffer), 0); seq.generate(std::begin(buffer), std::begin(buffer) + requested_entropy); -#ifdef ABSL_IS_BIG_ENDIAN - // Randen expects the seed buffer to be in Little Endian; reverse it on - // Big Endian platforms. - for (sequence_result_type& e : buffer) { - e = absl::little_endian::FromHost(e); - } -#endif +#ifdef ABSL_IS_BIG_ENDIAN + // Randen expects the seed buffer to be in Little Endian; reverse it on + // Big Endian platforms. + for (sequence_result_type& e : buffer) { + e = absl::little_endian::FromHost(e); + } +#endif // The Randen paper suggests preferentially initializing even-numbered // 128-bit vectors of the randen state (there are 16 such vectors). // The seed data is merged into the state offset by 128-bits, which diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.cc b/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.cc index fee6677cb4..3680ffb088 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.cc +++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.cc @@ -23,7 +23,7 @@ #include <cstring> #include "absl/base/attributes.h" -#include "absl/numeric/int128.h" +#include "absl/numeric/int128.h" #include "absl/random/internal/platform.h" #include "absl/random/internal/randen_traits.h" @@ -31,10 +31,10 @@ // a hardware accelerated implementation of randen, or whether it // will contain stubs that exit the process. #if ABSL_HAVE_ACCELERATED_AES -// The following plaforms have implemented RandenHwAes. -#if defined(ABSL_ARCH_X86_64) || defined(ABSL_ARCH_X86_32) || \ - defined(ABSL_ARCH_PPC) || defined(ABSL_ARCH_ARM) || \ - defined(ABSL_ARCH_AARCH64) +// The following plaforms have implemented RandenHwAes. +#if defined(ABSL_ARCH_X86_64) || defined(ABSL_ARCH_X86_32) || \ + defined(ABSL_ARCH_PPC) || defined(ABSL_ARCH_ARM) || \ + defined(ABSL_ARCH_AARCH64) #define ABSL_RANDEN_HWAES_IMPL 1 #endif #endif @@ -152,7 +152,7 @@ inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state, } // Enables native loads in the round loop by pre-swapping. -inline ABSL_TARGET_CRYPTO void SwapEndian(absl::uint128* state) { +inline ABSL_TARGET_CRYPTO void SwapEndian(absl::uint128* state) { for (uint32_t block = 0; block < RandenTraits::kFeistelBlocks; ++block) { Vector128Store(ReverseBytes(Vector128Load(state + block)), state + block); } @@ -211,7 +211,7 @@ inline ABSL_TARGET_CRYPTO void SwapEndian(void*) {} #elif defined(ABSL_ARCH_X86_64) || defined(ABSL_ARCH_X86_32) // On x86 we rely on the aesni instructions -#include <immintrin.h> +#include <immintrin.h> namespace { @@ -220,7 +220,7 @@ namespace { class Vector128 { public: // Convert from/to intrinsics. - inline explicit Vector128(const __m128i& v) : data_(v) {} + inline explicit Vector128(const __m128i& v) : data_(v) {} inline __m128i data() const { return data_; } @@ -277,7 +277,7 @@ namespace { // Block shuffles applies a shuffle to the entire state between AES rounds. // Improved odd-even shuffle from "New criterion for diffusion property". -inline ABSL_TARGET_CRYPTO void BlockShuffle(absl::uint128* state) { +inline ABSL_TARGET_CRYPTO void BlockShuffle(absl::uint128* state) { static_assert(RandenTraits::kFeistelBlocks == 16, "Expecting 16 FeistelBlocks."); @@ -324,9 +324,9 @@ inline ABSL_TARGET_CRYPTO void BlockShuffle(absl::uint128* state) { // per 16 bytes (vs. 10 for AES-CTR). Computing eight round functions in // parallel hides the 7-cycle AESNI latency on HSW. Note that the Feistel // XORs are 'free' (included in the second AES instruction). -inline ABSL_TARGET_CRYPTO const absl::uint128* FeistelRound( - absl::uint128* state, - const absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT keys) { +inline ABSL_TARGET_CRYPTO const absl::uint128* FeistelRound( + absl::uint128* state, + const absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT keys) { static_assert(RandenTraits::kFeistelBlocks == 16, "Expecting 16 FeistelBlocks."); @@ -387,8 +387,8 @@ inline ABSL_TARGET_CRYPTO const absl::uint128* FeistelRound( // 2^64 queries if the round function is a PRF. This is similar to the b=8 case // of Simpira v2, but more efficient than its generic construction for b=16. inline ABSL_TARGET_CRYPTO void Permute( - absl::uint128* state, - const absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT keys) { + absl::uint128* state, + const absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT keys) { // (Successfully unrolled; the first iteration jumps into the second half) #ifdef __clang__ #pragma clang loop unroll_count(2) @@ -425,11 +425,11 @@ void ABSL_TARGET_CRYPTO RandenHwAes::Absorb(const void* seed_void, static_assert(RandenTraits::kStateBytes / sizeof(Vector128) == 16, "Unexpected Randen kStateBlocks"); - auto* state = reinterpret_cast<absl::uint128 * ABSL_RANDOM_INTERNAL_RESTRICT>( - state_void); + auto* state = reinterpret_cast<absl::uint128 * ABSL_RANDOM_INTERNAL_RESTRICT>( + state_void); const auto* seed = - reinterpret_cast<const absl::uint128 * ABSL_RANDOM_INTERNAL_RESTRICT>( - seed_void); + reinterpret_cast<const absl::uint128 * ABSL_RANDOM_INTERNAL_RESTRICT>( + seed_void); Vector128 b1 = Vector128Load(state + 1); b1 ^= Vector128Load(seed + 0); @@ -498,8 +498,8 @@ void ABSL_TARGET_CRYPTO RandenHwAes::Generate(const void* keys_void, static_assert(RandenTraits::kCapacityBytes == sizeof(Vector128), "Capacity mismatch"); - auto* state = reinterpret_cast<absl::uint128*>(state_void); - const auto* keys = reinterpret_cast<const absl::uint128*>(keys_void); + auto* state = reinterpret_cast<absl::uint128*>(state_void); + const auto* keys = reinterpret_cast<const absl::uint128*>(keys_void); const Vector128 prev_inner = Vector128Load(state); diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.cc b/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.cc index 9bfd2a4092..69b33451cc 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.cc +++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.cc @@ -19,8 +19,8 @@ #include <cstring> #include "absl/base/attributes.h" -#include "absl/base/internal/endian.h" -#include "absl/numeric/int128.h" +#include "absl/base/internal/endian.h" +#include "absl/numeric/int128.h" #include "absl/random/internal/platform.h" #include "absl/random/internal/randen_traits.h" @@ -40,193 +40,193 @@ namespace { // AES portions based on rijndael-alg-fst.c, -// https://fastcrypto.org/front/misc/rijndael-alg-fst.c, and modified for -// platform-endianness. +// https://fastcrypto.org/front/misc/rijndael-alg-fst.c, and modified for +// platform-endianness. // // Implementation of // http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf constexpr uint32_t te0[256] = { - 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, 0xbd6b6bd6, - 0xb16f6fde, 0x54c5c591, 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, - 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, 0x45caca8f, 0x9d82821f, - 0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, - 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, - 0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, - 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, 0x5c343468, 0xf4a5a551, - 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, - 0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, - 0x0f05050a, 0xb59a9a2f, 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, - 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912, 0x9e83831d, - 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, - 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, - 0x712f2f5e, 0x97848413, 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, - 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d, - 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, - 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, - 0x55333366, 0x94858511, 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, - 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d, - 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, - 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5, - 0x0ef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, - 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, 0x57c4c493, 0xf2a7a755, - 0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, - 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, - 0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, - 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, 0x3be0e0db, 0x56323264, - 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8, - 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, - 0x37e4e4d3, 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, - 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8, 0xfa5656ac, - 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, - 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657, - 0xc7b4b473, 0x51c6c697, 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, - 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c, - 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c, - 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199, - 0x271d1d3a, 0xb99e9e27, 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, - 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c, - 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, - 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, - 0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, - 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c, + 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, 0xbd6b6bd6, + 0xb16f6fde, 0x54c5c591, 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, + 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, 0x45caca8f, 0x9d82821f, + 0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, + 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, + 0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, + 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, 0x5c343468, 0xf4a5a551, + 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, + 0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, + 0x0f05050a, 0xb59a9a2f, 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, + 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912, 0x9e83831d, + 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, + 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, + 0x712f2f5e, 0x97848413, 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, + 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d, + 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, + 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, + 0x55333366, 0x94858511, 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, + 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d, + 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, + 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5, + 0x0ef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, + 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, 0x57c4c493, 0xf2a7a755, + 0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, + 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, + 0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, + 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, 0x3be0e0db, 0x56323264, + 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8, + 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, + 0x37e4e4d3, 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, + 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8, 0xfa5656ac, + 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, + 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657, + 0xc7b4b473, 0x51c6c697, 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, + 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c, + 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c, + 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199, + 0x271d1d3a, 0xb99e9e27, 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, + 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c, + 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, + 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, + 0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, + 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c, }; constexpr uint32_t te1[256] = { - 0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, 0xf2f2ff0d, 0x6b6bd6bd, - 0x6f6fdeb1, 0xc5c59154, 0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d, - 0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, 0xcaca8f45, 0x82821f9d, - 0xc9c98940, 0x7d7dfa87, 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, - 0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, 0x9c9c23bf, 0xa4a453f7, - 0x7272e496, 0xc0c09b5b, 0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, - 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, 0x3434685c, 0xa5a551f4, - 0xe5e5d134, 0xf1f1f908, 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, - 0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, 0x18183028, 0x969637a1, - 0x05050a0f, 0x9a9a2fb5, 0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, - 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, 0x0909121b, 0x83831d9e, - 0x2c2c5874, 0x1a1a342e, 0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, - 0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, 0x2929527b, 0xe3e3dd3e, - 0x2f2f5e71, 0x84841397, 0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, - 0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, 0x6a6ad4be, 0xcbcb8d46, - 0xbebe67d9, 0x3939724b, 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, - 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, 0x434386c5, 0x4d4d9ad7, - 0x33336655, 0x85851194, 0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81, - 0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, 0x5151a2f3, 0xa3a35dfe, - 0x404080c0, 0x8f8f058a, 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, - 0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, 0x10102030, 0xffffe51a, - 0xf3f3fd0e, 0xd2d2bf6d, 0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f, - 0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, 0xc4c49357, 0xa7a755f2, - 0x7e7efc82, 0x3d3d7a47, 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, - 0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, 0x22224466, 0x2a2a547e, - 0x90903bab, 0x88880b83, 0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, - 0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76, 0xe0e0db3b, 0x32326456, - 0x3a3a744e, 0x0a0a141e, 0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4, - 0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, 0x919139a8, 0x959531a4, - 0xe4e4d337, 0x7979f28b, 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, - 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, 0x6c6cd8b4, 0x5656acfa, - 0xf4f4f307, 0xeaeacf25, 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018, - 0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, 0x1c1c3824, 0xa6a657f1, - 0xb4b473c7, 0xc6c69751, 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, - 0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, 0x7070e090, 0x3e3e7c42, - 0xb5b571c4, 0x6666ccaa, 0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12, - 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, 0x86861791, 0xc1c19958, - 0x1d1d3a27, 0x9e9e27b9, 0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, - 0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, 0x9b9b2db6, 0x1e1e3c22, - 0x87871592, 0xe9e9c920, 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, - 0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, 0xbfbf65da, 0xe6e6d731, - 0x424284c6, 0x6868d0b8, 0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11, - 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a, + 0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, 0xf2f2ff0d, 0x6b6bd6bd, + 0x6f6fdeb1, 0xc5c59154, 0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d, + 0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, 0xcaca8f45, 0x82821f9d, + 0xc9c98940, 0x7d7dfa87, 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, + 0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, 0x9c9c23bf, 0xa4a453f7, + 0x7272e496, 0xc0c09b5b, 0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, + 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, 0x3434685c, 0xa5a551f4, + 0xe5e5d134, 0xf1f1f908, 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, + 0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, 0x18183028, 0x969637a1, + 0x05050a0f, 0x9a9a2fb5, 0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, + 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, 0x0909121b, 0x83831d9e, + 0x2c2c5874, 0x1a1a342e, 0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, + 0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, 0x2929527b, 0xe3e3dd3e, + 0x2f2f5e71, 0x84841397, 0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, + 0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, 0x6a6ad4be, 0xcbcb8d46, + 0xbebe67d9, 0x3939724b, 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, + 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, 0x434386c5, 0x4d4d9ad7, + 0x33336655, 0x85851194, 0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81, + 0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, 0x5151a2f3, 0xa3a35dfe, + 0x404080c0, 0x8f8f058a, 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, + 0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, 0x10102030, 0xffffe51a, + 0xf3f3fd0e, 0xd2d2bf6d, 0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f, + 0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, 0xc4c49357, 0xa7a755f2, + 0x7e7efc82, 0x3d3d7a47, 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, + 0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, 0x22224466, 0x2a2a547e, + 0x90903bab, 0x88880b83, 0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, + 0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76, 0xe0e0db3b, 0x32326456, + 0x3a3a744e, 0x0a0a141e, 0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4, + 0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, 0x919139a8, 0x959531a4, + 0xe4e4d337, 0x7979f28b, 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, + 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, 0x6c6cd8b4, 0x5656acfa, + 0xf4f4f307, 0xeaeacf25, 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018, + 0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, 0x1c1c3824, 0xa6a657f1, + 0xb4b473c7, 0xc6c69751, 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, + 0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, 0x7070e090, 0x3e3e7c42, + 0xb5b571c4, 0x6666ccaa, 0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12, + 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, 0x86861791, 0xc1c19958, + 0x1d1d3a27, 0x9e9e27b9, 0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, + 0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, 0x9b9b2db6, 0x1e1e3c22, + 0x87871592, 0xe9e9c920, 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, + 0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, 0xbfbf65da, 0xe6e6d731, + 0x424284c6, 0x6868d0b8, 0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11, + 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a, }; constexpr uint32_t te2[256] = { - 0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, 0xf2ff0df2, 0x6bd6bd6b, - 0x6fdeb16f, 0xc59154c5, 0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b, - 0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, 0xca8f45ca, 0x821f9d82, - 0xc98940c9, 0x7dfa877d, 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, - 0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, 0x9c23bf9c, 0xa453f7a4, - 0x72e49672, 0xc09b5bc0, 0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, - 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, 0x34685c34, 0xa551f4a5, - 0xe5d134e5, 0xf1f908f1, 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, - 0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, 0x18302818, 0x9637a196, - 0x050a0f05, 0x9a2fb59a, 0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, - 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, 0x09121b09, 0x831d9e83, - 0x2c58742c, 0x1a342e1a, 0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, - 0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, 0x29527b29, 0xe3dd3ee3, - 0x2f5e712f, 0x84139784, 0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced, - 0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, 0x6ad4be6a, 0xcb8d46cb, - 0xbe67d9be, 0x39724b39, 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, - 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, 0x4386c543, 0x4d9ad74d, - 0x33665533, 0x85119485, 0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f, - 0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, 0x51a2f351, 0xa35dfea3, - 0x4080c040, 0x8f058a8f, 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, - 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, 0x10203010, 0xffe51aff, - 0xf3fd0ef3, 0xd2bf6dd2, 0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec, - 0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, 0xc49357c4, 0xa755f2a7, - 0x7efc827e, 0x3d7a473d, 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, - 0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, 0x22446622, 0x2a547e2a, - 0x903bab90, 0x880b8388, 0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, - 0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db, 0xe0db3be0, 0x32645632, - 0x3a744e3a, 0x0a141e0a, 0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c, - 0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, 0x9139a891, 0x9531a495, - 0xe4d337e4, 0x79f28b79, 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, - 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, 0x6cd8b46c, 0x56acfa56, - 0xf4f307f4, 0xeacf25ea, 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808, - 0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, 0x1c38241c, 0xa657f1a6, - 0xb473c7b4, 0xc69751c6, 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, - 0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, 0x70e09070, 0x3e7c423e, - 0xb571c4b5, 0x66ccaa66, 0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e, - 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, 0x86179186, 0xc19958c1, - 0x1d3a271d, 0x9e27b99e, 0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, - 0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, 0x9b2db69b, 0x1e3c221e, - 0x87159287, 0xe9c920e9, 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, - 0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, 0xbf65dabf, 0xe6d731e6, - 0x4284c642, 0x68d0b868, 0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f, - 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16, + 0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, 0xf2ff0df2, 0x6bd6bd6b, + 0x6fdeb16f, 0xc59154c5, 0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b, + 0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, 0xca8f45ca, 0x821f9d82, + 0xc98940c9, 0x7dfa877d, 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, + 0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, 0x9c23bf9c, 0xa453f7a4, + 0x72e49672, 0xc09b5bc0, 0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, + 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, 0x34685c34, 0xa551f4a5, + 0xe5d134e5, 0xf1f908f1, 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, + 0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, 0x18302818, 0x9637a196, + 0x050a0f05, 0x9a2fb59a, 0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, + 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, 0x09121b09, 0x831d9e83, + 0x2c58742c, 0x1a342e1a, 0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, + 0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, 0x29527b29, 0xe3dd3ee3, + 0x2f5e712f, 0x84139784, 0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced, + 0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, 0x6ad4be6a, 0xcb8d46cb, + 0xbe67d9be, 0x39724b39, 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, + 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, 0x4386c543, 0x4d9ad74d, + 0x33665533, 0x85119485, 0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f, + 0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, 0x51a2f351, 0xa35dfea3, + 0x4080c040, 0x8f058a8f, 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, + 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, 0x10203010, 0xffe51aff, + 0xf3fd0ef3, 0xd2bf6dd2, 0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec, + 0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, 0xc49357c4, 0xa755f2a7, + 0x7efc827e, 0x3d7a473d, 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, + 0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, 0x22446622, 0x2a547e2a, + 0x903bab90, 0x880b8388, 0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, + 0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db, 0xe0db3be0, 0x32645632, + 0x3a744e3a, 0x0a141e0a, 0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c, + 0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, 0x9139a891, 0x9531a495, + 0xe4d337e4, 0x79f28b79, 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, + 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, 0x6cd8b46c, 0x56acfa56, + 0xf4f307f4, 0xeacf25ea, 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808, + 0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, 0x1c38241c, 0xa657f1a6, + 0xb473c7b4, 0xc69751c6, 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, + 0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, 0x70e09070, 0x3e7c423e, + 0xb571c4b5, 0x66ccaa66, 0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e, + 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, 0x86179186, 0xc19958c1, + 0x1d3a271d, 0x9e27b99e, 0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, + 0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, 0x9b2db69b, 0x1e3c221e, + 0x87159287, 0xe9c920e9, 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, + 0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, 0xbf65dabf, 0xe6d731e6, + 0x4284c642, 0x68d0b868, 0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f, + 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16, }; constexpr uint32_t te3[256] = { - 0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, 0xff0df2f2, 0xd6bd6b6b, - 0xdeb16f6f, 0x9154c5c5, 0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b, - 0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, 0x8f45caca, 0x1f9d8282, - 0x8940c9c9, 0xfa877d7d, 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, - 0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, 0x23bf9c9c, 0x53f7a4a4, - 0xe4967272, 0x9b5bc0c0, 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, - 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, 0x685c3434, 0x51f4a5a5, - 0xd134e5e5, 0xf908f1f1, 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, - 0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, 0x30281818, 0x37a19696, - 0x0a0f0505, 0x2fb59a9a, 0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, - 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, 0x121b0909, 0x1d9e8383, - 0x58742c2c, 0x342e1a1a, 0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, - 0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, 0x527b2929, 0xdd3ee3e3, - 0x5e712f2f, 0x13978484, 0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded, - 0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, 0xd4be6a6a, 0x8d46cbcb, - 0x67d9bebe, 0x724b3939, 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, - 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, 0x86c54343, 0x9ad74d4d, - 0x66553333, 0x11948585, 0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f, - 0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, 0xa2f35151, 0x5dfea3a3, - 0x80c04040, 0x058a8f8f, 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, - 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, 0x20301010, 0xe51affff, - 0xfd0ef3f3, 0xbf6dd2d2, 0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, - 0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, 0x9357c4c4, 0x55f2a7a7, - 0xfc827e7e, 0x7a473d3d, 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, - 0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, 0x44662222, 0x547e2a2a, - 0x3bab9090, 0x0b838888, 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, - 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, 0xdb3be0e0, 0x64563232, - 0x744e3a3a, 0x141e0a0a, 0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c, - 0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, 0x39a89191, 0x31a49595, - 0xd337e4e4, 0xf28b7979, 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, - 0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, 0xd8b46c6c, 0xacfa5656, - 0xf307f4f4, 0xcf25eaea, 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, - 0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, 0x38241c1c, 0x57f1a6a6, - 0x73c7b4b4, 0x9751c6c6, 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, - 0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a, 0xe0907070, 0x7c423e3e, - 0x71c4b5b5, 0xccaa6666, 0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e, - 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, 0x17918686, 0x9958c1c1, - 0x3a271d1d, 0x27b99e9e, 0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, - 0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494, 0x2db69b9b, 0x3c221e1e, - 0x15928787, 0xc920e9e9, 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, - 0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, 0x65dabfbf, 0xd731e6e6, - 0x84c64242, 0xd0b86868, 0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, - 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616, + 0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, 0xff0df2f2, 0xd6bd6b6b, + 0xdeb16f6f, 0x9154c5c5, 0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b, + 0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, 0x8f45caca, 0x1f9d8282, + 0x8940c9c9, 0xfa877d7d, 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, + 0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, 0x23bf9c9c, 0x53f7a4a4, + 0xe4967272, 0x9b5bc0c0, 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, + 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, 0x685c3434, 0x51f4a5a5, + 0xd134e5e5, 0xf908f1f1, 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, + 0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, 0x30281818, 0x37a19696, + 0x0a0f0505, 0x2fb59a9a, 0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, + 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, 0x121b0909, 0x1d9e8383, + 0x58742c2c, 0x342e1a1a, 0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, + 0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, 0x527b2929, 0xdd3ee3e3, + 0x5e712f2f, 0x13978484, 0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded, + 0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, 0xd4be6a6a, 0x8d46cbcb, + 0x67d9bebe, 0x724b3939, 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, + 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, 0x86c54343, 0x9ad74d4d, + 0x66553333, 0x11948585, 0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f, + 0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, 0xa2f35151, 0x5dfea3a3, + 0x80c04040, 0x058a8f8f, 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, + 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, 0x20301010, 0xe51affff, + 0xfd0ef3f3, 0xbf6dd2d2, 0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, + 0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, 0x9357c4c4, 0x55f2a7a7, + 0xfc827e7e, 0x7a473d3d, 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, + 0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, 0x44662222, 0x547e2a2a, + 0x3bab9090, 0x0b838888, 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, + 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, 0xdb3be0e0, 0x64563232, + 0x744e3a3a, 0x141e0a0a, 0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c, + 0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, 0x39a89191, 0x31a49595, + 0xd337e4e4, 0xf28b7979, 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, + 0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, 0xd8b46c6c, 0xacfa5656, + 0xf307f4f4, 0xcf25eaea, 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, + 0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, 0x38241c1c, 0x57f1a6a6, + 0x73c7b4b4, 0x9751c6c6, 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, + 0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a, 0xe0907070, 0x7c423e3e, + 0x71c4b5b5, 0xccaa6666, 0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e, + 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, 0x17918686, 0x9958c1c1, + 0x3a271d1d, 0x27b99e9e, 0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, + 0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494, 0x2db69b9b, 0x3c221e1e, + 0x15928787, 0xc920e9e9, 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, + 0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, 0x65dabfbf, 0xd731e6e6, + 0x84c64242, 0xd0b86868, 0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, + 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616, }; // Software implementation of the Vector128 class, using uint32_t @@ -238,13 +238,13 @@ struct alignas(16) Vector128 { inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128 Vector128Load(const void* from) { Vector128 result; - std::memcpy(result.s, from, sizeof(Vector128)); + std::memcpy(result.s, from, sizeof(Vector128)); return result; } inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void Vector128Store( const Vector128& v, void* to) { - std::memcpy(to, v.s, sizeof(Vector128)); + std::memcpy(to, v.s, sizeof(Vector128)); } // One round of AES. "round_key" is a public constant for breaking the @@ -252,49 +252,49 @@ inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void Vector128Store( inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128 AesRound(const Vector128& state, const Vector128& round_key) { Vector128 result; -#ifdef ABSL_IS_LITTLE_ENDIAN +#ifdef ABSL_IS_LITTLE_ENDIAN result.s[0] = round_key.s[0] ^ // - te0[uint8_t(state.s[0])] ^ // - te1[uint8_t(state.s[1] >> 8)] ^ // - te2[uint8_t(state.s[2] >> 16)] ^ // - te3[uint8_t(state.s[3] >> 24)]; + te0[uint8_t(state.s[0])] ^ // + te1[uint8_t(state.s[1] >> 8)] ^ // + te2[uint8_t(state.s[2] >> 16)] ^ // + te3[uint8_t(state.s[3] >> 24)]; result.s[1] = round_key.s[1] ^ // - te0[uint8_t(state.s[1])] ^ // - te1[uint8_t(state.s[2] >> 8)] ^ // - te2[uint8_t(state.s[3] >> 16)] ^ // - te3[uint8_t(state.s[0] >> 24)]; + te0[uint8_t(state.s[1])] ^ // + te1[uint8_t(state.s[2] >> 8)] ^ // + te2[uint8_t(state.s[3] >> 16)] ^ // + te3[uint8_t(state.s[0] >> 24)]; result.s[2] = round_key.s[2] ^ // - te0[uint8_t(state.s[2])] ^ // - te1[uint8_t(state.s[3] >> 8)] ^ // - te2[uint8_t(state.s[0] >> 16)] ^ // - te3[uint8_t(state.s[1] >> 24)]; + te0[uint8_t(state.s[2])] ^ // + te1[uint8_t(state.s[3] >> 8)] ^ // + te2[uint8_t(state.s[0] >> 16)] ^ // + te3[uint8_t(state.s[1] >> 24)]; result.s[3] = round_key.s[3] ^ // - te0[uint8_t(state.s[3])] ^ // - te1[uint8_t(state.s[0] >> 8)] ^ // - te2[uint8_t(state.s[1] >> 16)] ^ // - te3[uint8_t(state.s[2] >> 24)]; -#else - result.s[0] = round_key.s[0] ^ // - te0[uint8_t(state.s[0])] ^ // - te1[uint8_t(state.s[3] >> 8)] ^ // - te2[uint8_t(state.s[2] >> 16)] ^ // - te3[uint8_t(state.s[1] >> 24)]; - result.s[1] = round_key.s[1] ^ // - te0[uint8_t(state.s[1])] ^ // - te1[uint8_t(state.s[0] >> 8)] ^ // - te2[uint8_t(state.s[3] >> 16)] ^ // - te3[uint8_t(state.s[2] >> 24)]; - result.s[2] = round_key.s[2] ^ // - te0[uint8_t(state.s[2])] ^ // - te1[uint8_t(state.s[1] >> 8)] ^ // - te2[uint8_t(state.s[0] >> 16)] ^ // - te3[uint8_t(state.s[3] >> 24)]; - result.s[3] = round_key.s[3] ^ // - te0[uint8_t(state.s[3])] ^ // - te1[uint8_t(state.s[2] >> 8)] ^ // - te2[uint8_t(state.s[1] >> 16)] ^ // - te3[uint8_t(state.s[0] >> 24)]; -#endif + te0[uint8_t(state.s[3])] ^ // + te1[uint8_t(state.s[0] >> 8)] ^ // + te2[uint8_t(state.s[1] >> 16)] ^ // + te3[uint8_t(state.s[2] >> 24)]; +#else + result.s[0] = round_key.s[0] ^ // + te0[uint8_t(state.s[0])] ^ // + te1[uint8_t(state.s[3] >> 8)] ^ // + te2[uint8_t(state.s[2] >> 16)] ^ // + te3[uint8_t(state.s[1] >> 24)]; + result.s[1] = round_key.s[1] ^ // + te0[uint8_t(state.s[1])] ^ // + te1[uint8_t(state.s[0] >> 8)] ^ // + te2[uint8_t(state.s[3] >> 16)] ^ // + te3[uint8_t(state.s[2] >> 24)]; + result.s[2] = round_key.s[2] ^ // + te0[uint8_t(state.s[2])] ^ // + te1[uint8_t(state.s[1] >> 8)] ^ // + te2[uint8_t(state.s[0] >> 16)] ^ // + te3[uint8_t(state.s[3] >> 24)]; + result.s[3] = round_key.s[3] ^ // + te0[uint8_t(state.s[3])] ^ // + te1[uint8_t(state.s[2] >> 8)] ^ // + te2[uint8_t(state.s[1] >> 16)] ^ // + te3[uint8_t(state.s[0] >> 24)]; +#endif return result; } @@ -302,7 +302,7 @@ using ::absl::random_internal::RandenTraits; // The improved Feistel block shuffle function for 16 blocks. inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void BlockShuffle( - absl::uint128* state) { + absl::uint128* state) { static_assert(RandenTraits::kFeistelBlocks == 16, "Feistel block shuffle only works for 16 blocks."); @@ -312,31 +312,31 @@ inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void BlockShuffle( // The fully unrolled loop without the memcpy improves the speed by about // 30% over the equivalent: #if 0 - absl::uint128 source[RandenTraits::kFeistelBlocks]; + absl::uint128 source[RandenTraits::kFeistelBlocks]; std::memcpy(source, state, sizeof(source)); for (size_t i = 0; i < RandenTraits::kFeistelBlocks; i++) { - const absl::uint128 v0 = source[shuffle[i]]; + const absl::uint128 v0 = source[shuffle[i]]; state[i] = v0; } return; #endif - const absl::uint128 v0 = state[shuffle[0]]; - const absl::uint128 v1 = state[shuffle[1]]; - const absl::uint128 v2 = state[shuffle[2]]; - const absl::uint128 v3 = state[shuffle[3]]; - const absl::uint128 v4 = state[shuffle[4]]; - const absl::uint128 v5 = state[shuffle[5]]; - const absl::uint128 v6 = state[shuffle[6]]; - const absl::uint128 v7 = state[shuffle[7]]; - const absl::uint128 w0 = state[shuffle[8]]; - const absl::uint128 w1 = state[shuffle[9]]; - const absl::uint128 w2 = state[shuffle[10]]; - const absl::uint128 w3 = state[shuffle[11]]; - const absl::uint128 w4 = state[shuffle[12]]; - const absl::uint128 w5 = state[shuffle[13]]; - const absl::uint128 w6 = state[shuffle[14]]; - const absl::uint128 w7 = state[shuffle[15]]; + const absl::uint128 v0 = state[shuffle[0]]; + const absl::uint128 v1 = state[shuffle[1]]; + const absl::uint128 v2 = state[shuffle[2]]; + const absl::uint128 v3 = state[shuffle[3]]; + const absl::uint128 v4 = state[shuffle[4]]; + const absl::uint128 v5 = state[shuffle[5]]; + const absl::uint128 v6 = state[shuffle[6]]; + const absl::uint128 v7 = state[shuffle[7]]; + const absl::uint128 w0 = state[shuffle[8]]; + const absl::uint128 w1 = state[shuffle[9]]; + const absl::uint128 w2 = state[shuffle[10]]; + const absl::uint128 w3 = state[shuffle[11]]; + const absl::uint128 w4 = state[shuffle[12]]; + const absl::uint128 w5 = state[shuffle[13]]; + const absl::uint128 w6 = state[shuffle[14]]; + const absl::uint128 w7 = state[shuffle[15]]; state[0] = v0; state[1] = v1; state[2] = v2; @@ -360,9 +360,9 @@ inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void BlockShuffle( // per 16 bytes (vs. 10 for AES-CTR). Computing eight round functions in // parallel hides the 7-cycle AESNI latency on HSW. Note that the Feistel // XORs are 'free' (included in the second AES instruction). -inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE const absl::uint128* -FeistelRound(absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT state, - const absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT keys) { +inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE const absl::uint128* +FeistelRound(absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT state, + const absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT keys) { for (size_t branch = 0; branch < RandenTraits::kFeistelBlocks; branch += 4) { const Vector128 s0 = Vector128Load(state + branch); const Vector128 s1 = Vector128Load(state + branch + 1); @@ -387,31 +387,31 @@ FeistelRound(absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT state, // 2^64 queries if the round function is a PRF. This is similar to the b=8 case // of Simpira v2, but more efficient than its generic construction for b=16. inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void Permute( - absl::uint128* state, - const absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT keys) { + absl::uint128* state, + const absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT keys) { for (size_t round = 0; round < RandenTraits::kFeistelRounds; ++round) { keys = FeistelRound(state, keys); BlockShuffle(state); } } -// Enables native loads in the round loop by pre-swapping. -inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void SwapEndian( - absl::uint128* state) { -#ifdef ABSL_IS_BIG_ENDIAN - for (uint32_t block = 0; block < RandenTraits::kFeistelBlocks; ++block) { - uint64_t new_lo = absl::little_endian::ToHost64( - static_cast<uint64_t>(state[block] >> 64)); - uint64_t new_hi = absl::little_endian::ToHost64( - static_cast<uint64_t>((state[block] << 64) >> 64)); - state[block] = (static_cast<absl::uint128>(new_hi) << 64) | new_lo; - } -#else - // Avoid warning about unused variable. - (void)state; -#endif -} - +// Enables native loads in the round loop by pre-swapping. +inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void SwapEndian( + absl::uint128* state) { +#ifdef ABSL_IS_BIG_ENDIAN + for (uint32_t block = 0; block < RandenTraits::kFeistelBlocks; ++block) { + uint64_t new_lo = absl::little_endian::ToHost64( + static_cast<uint64_t>(state[block] >> 64)); + uint64_t new_hi = absl::little_endian::ToHost64( + static_cast<uint64_t>((state[block] << 64) >> 64)); + state[block] = (static_cast<absl::uint128>(new_hi) << 64) | new_lo; + } +#else + // Avoid warning about unused variable. + (void)state; +#endif +} + } // namespace namespace absl { @@ -421,11 +421,11 @@ namespace random_internal { const void* RandenSlow::GetKeys() { // Round keys for one AES per Feistel round and branch. // The canonical implementation uses first digits of Pi. -#ifdef ABSL_IS_LITTLE_ENDIAN +#ifdef ABSL_IS_LITTLE_ENDIAN return kRandenRoundKeys; -#else - return kRandenRoundKeysBE; -#endif +#else + return kRandenRoundKeysBE; +#endif } void RandenSlow::Absorb(const void* seed_void, void* state_void) { @@ -448,22 +448,22 @@ void RandenSlow::Absorb(const void* seed_void, void* state_void) { } void RandenSlow::Generate(const void* keys_void, void* state_void) { - static_assert(RandenTraits::kCapacityBytes == sizeof(absl::uint128), + static_assert(RandenTraits::kCapacityBytes == sizeof(absl::uint128), "Capacity mismatch"); - auto* state = reinterpret_cast<absl::uint128*>(state_void); - const auto* keys = reinterpret_cast<const absl::uint128*>(keys_void); - - const absl::uint128 prev_inner = state[0]; + auto* state = reinterpret_cast<absl::uint128*>(state_void); + const auto* keys = reinterpret_cast<const absl::uint128*>(keys_void); - SwapEndian(state); + const absl::uint128 prev_inner = state[0]; + SwapEndian(state); + Permute(state, keys); - SwapEndian(state); - + SwapEndian(state); + // Ensure backtracking resistance. - *state ^= prev_inner; + *state ^= prev_inner; } } // namespace random_internal diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/seed_material.cc b/contrib/restricted/abseil-cpp/absl/random/internal/seed_material.cc index c03cad8502..9f8dfecd5e 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/seed_material.cc +++ b/contrib/restricted/abseil-cpp/absl/random/internal/seed_material.cc @@ -28,7 +28,7 @@ #include <cstdlib> #include <cstring> -#include "absl/base/dynamic_annotations.h" +#include "absl/base/dynamic_annotations.h" #include "absl/base/internal/raw_logging.h" #include "absl/strings/ascii.h" #include "absl/strings/escaping.h" @@ -51,18 +51,18 @@ #endif -#if defined(__GLIBC__) && \ - (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25)) -// glibc >= 2.25 has getentropy() -#define ABSL_RANDOM_USE_GET_ENTROPY 1 -#endif - -#if defined(__EMSCRIPTEN__) -#include <sys/random.h> -// Emscripten has getentropy, but it resides in a different header. -#define ABSL_RANDOM_USE_GET_ENTROPY 1 -#endif - +#if defined(__GLIBC__) && \ + (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25)) +// glibc >= 2.25 has getentropy() +#define ABSL_RANDOM_USE_GET_ENTROPY 1 +#endif + +#if defined(__EMSCRIPTEN__) +#include <sys/random.h> +// Emscripten has getentropy, but it resides in a different header. +#define ABSL_RANDOM_USE_GET_ENTROPY 1 +#endif + #if defined(ABSL_RANDOM_USE_BCRYPT) #include <bcrypt.h> @@ -135,32 +135,32 @@ bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) { #else -#if defined(ABSL_RANDOM_USE_GET_ENTROPY) -// On *nix, use getentropy() if supported. Note that libc may support -// getentropy(), but the kernel may not, in which case this function will return -// false. -bool ReadSeedMaterialFromGetEntropy(absl::Span<uint32_t> values) { - auto buffer = reinterpret_cast<uint8_t*>(values.data()); - size_t buffer_size = sizeof(uint32_t) * values.size(); - while (buffer_size > 0) { - // getentropy() has a maximum permitted length of 256. - size_t to_read = std::min<size_t>(buffer_size, 256); - int result = getentropy(buffer, to_read); - if (result < 0) { - return false; - } - // https://github.com/google/sanitizers/issues/1173 - // MemorySanitizer can't see through getentropy(). - ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(buffer, to_read); - buffer += to_read; - buffer_size -= to_read; - } - return true; -} -#endif // defined(ABSL_RANDOM_GETENTROPY) - +#if defined(ABSL_RANDOM_USE_GET_ENTROPY) +// On *nix, use getentropy() if supported. Note that libc may support +// getentropy(), but the kernel may not, in which case this function will return +// false. +bool ReadSeedMaterialFromGetEntropy(absl::Span<uint32_t> values) { + auto buffer = reinterpret_cast<uint8_t*>(values.data()); + size_t buffer_size = sizeof(uint32_t) * values.size(); + while (buffer_size > 0) { + // getentropy() has a maximum permitted length of 256. + size_t to_read = std::min<size_t>(buffer_size, 256); + int result = getentropy(buffer, to_read); + if (result < 0) { + return false; + } + // https://github.com/google/sanitizers/issues/1173 + // MemorySanitizer can't see through getentropy(). + ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(buffer, to_read); + buffer += to_read; + buffer_size -= to_read; + } + return true; +} +#endif // defined(ABSL_RANDOM_GETENTROPY) + // On *nix, read entropy from /dev/urandom. -bool ReadSeedMaterialFromDevURandom(absl::Span<uint32_t> values) { +bool ReadSeedMaterialFromDevURandom(absl::Span<uint32_t> values) { const char kEntropyFile[] = "/dev/urandom"; auto buffer = reinterpret_cast<uint8_t*>(values.data()); @@ -187,19 +187,19 @@ bool ReadSeedMaterialFromDevURandom(absl::Span<uint32_t> values) { return success; } -bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) { -#if defined(ABSL_RANDOM_USE_GET_ENTROPY) - if (ReadSeedMaterialFromGetEntropy(values)) { - return true; - } -#endif - // Libc may support getentropy, but the kernel may not, so we still have - // to fallback to ReadSeedMaterialFromDevURandom(). - return ReadSeedMaterialFromDevURandom(values); -} - +bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) { +#if defined(ABSL_RANDOM_USE_GET_ENTROPY) + if (ReadSeedMaterialFromGetEntropy(values)) { + return true; + } #endif + // Libc may support getentropy, but the kernel may not, so we still have + // to fallback to ReadSeedMaterialFromDevURandom(). + return ReadSeedMaterialFromDevURandom(values); +} +#endif + } // namespace bool ReadSeedMaterialFromOSEntropy(absl::Span<uint32_t> values) { diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/seed_material/ya.make b/contrib/restricted/abseil-cpp/absl/random/internal/seed_material/ya.make index 65618b087d..4d848c00f6 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/seed_material/ya.make +++ b/contrib/restricted/abseil-cpp/absl/random/internal/seed_material/ya.make @@ -2,8 +2,8 @@ LIBRARY() -WITHOUT_LICENSE_TEXTS() - +WITHOUT_LICENSE_TEXTS() + OWNER(g:cpp-contrib) LICENSE(Apache-2.0) @@ -15,9 +15,9 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity contrib/restricted/abseil-cpp/absl/numeric - contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp/absl/types/bad_optional_access + contrib/restricted/abseil-cpp/absl/strings + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/types/bad_optional_access ) ADDINCL( @@ -32,10 +32,10 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal) - +SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal) + SRCS( - seed_material.cc + seed_material.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/random/seed_sequences/ya.make b/contrib/restricted/abseil-cpp/absl/random/seed_sequences/ya.make index 49cb3ff19c..937af3e490 100644 --- a/contrib/restricted/abseil-cpp/absl/random/seed_sequences/ya.make +++ b/contrib/restricted/abseil-cpp/absl/random/seed_sequences/ya.make @@ -24,7 +24,7 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/random/internal/seed_material contrib/restricted/abseil-cpp/absl/random/seed_gen_exception contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal contrib/restricted/abseil-cpp/absl/types/bad_optional_access ) diff --git a/contrib/restricted/abseil-cpp/absl/status/internal/status_internal.h b/contrib/restricted/abseil-cpp/absl/status/internal/status_internal.h index ac12940a6d..fa72612dbe 100644 --- a/contrib/restricted/abseil-cpp/absl/status/internal/status_internal.h +++ b/contrib/restricted/abseil-cpp/absl/status/internal/status_internal.h @@ -47,12 +47,12 @@ using Payloads = absl::InlinedVector<Payload, 1>; // Reference-counted representation of Status data. struct StatusRep { - StatusRep(absl::StatusCode code_arg, absl::string_view message_arg, - std::unique_ptr<status_internal::Payloads> payloads_arg) + StatusRep(absl::StatusCode code_arg, absl::string_view message_arg, + std::unique_ptr<status_internal::Payloads> payloads_arg) : ref(int32_t{1}), - code(code_arg), - message(message_arg), - payloads(std::move(payloads_arg)) {} + code(code_arg), + message(message_arg), + payloads(std::move(payloads_arg)) {} std::atomic<int32_t> ref; absl::StatusCode code; diff --git a/contrib/restricted/abseil-cpp/absl/status/status.cc b/contrib/restricted/abseil-cpp/absl/status/status.cc index bcf3413e5f..e97175a1d7 100644 --- a/contrib/restricted/abseil-cpp/absl/status/status.cc +++ b/contrib/restricted/abseil-cpp/absl/status/status.cc @@ -161,7 +161,7 @@ bool Status::ErasePayload(absl::string_view type_url) { } void Status::ForEachPayload( - absl::FunctionRef<void(absl::string_view, const absl::Cord&)> visitor) + absl::FunctionRef<void(absl::string_view, const absl::Cord&)> visitor) const { if (auto* payloads = GetPayloads()) { bool in_reverse = @@ -210,7 +210,7 @@ void Status::UnrefNonInlined(uintptr_t rep) { Status::Status(absl::StatusCode code, absl::string_view msg) : rep_(CodeToInlinedRep(code)) { if (code != absl::StatusCode::kOk && !msg.empty()) { - rep_ = PointerToRep(new status_internal::StatusRep(code, msg, nullptr)); + rep_ = PointerToRep(new status_internal::StatusRep(code, msg, nullptr)); } } @@ -229,9 +229,9 @@ absl::StatusCode Status::code() const { void Status::PrepareToModify() { ABSL_RAW_CHECK(!ok(), "PrepareToModify shouldn't be called on OK status."); if (IsInlined(rep_)) { - rep_ = PointerToRep(new status_internal::StatusRep( - static_cast<absl::StatusCode>(raw_code()), absl::string_view(), - nullptr)); + rep_ = PointerToRep(new status_internal::StatusRep( + static_cast<absl::StatusCode>(raw_code()), absl::string_view(), + nullptr)); return; } @@ -242,9 +242,9 @@ void Status::PrepareToModify() { if (rep->payloads) { payloads = absl::make_unique<status_internal::Payloads>(*rep->payloads); } - status_internal::StatusRep* const new_rep = new status_internal::StatusRep( - rep->code, message(), std::move(payloads)); - rep_ = PointerToRep(new_rep); + status_internal::StatusRep* const new_rep = new status_internal::StatusRep( + rep->code, message(), std::move(payloads)); + rep_ = PointerToRep(new_rep); UnrefNonInlined(rep_i); } } @@ -308,7 +308,7 @@ std::string Status::ToStringSlow(StatusToStringMode mode) const { } std::ostream& operator<<(std::ostream& os, const Status& x) { - os << x.ToString(StatusToStringMode::kWithEverything); + os << x.ToString(StatusToStringMode::kWithEverything); return os; } diff --git a/contrib/restricted/abseil-cpp/absl/status/status.h b/contrib/restricted/abseil-cpp/absl/status/status.h index 39071e5f4a..9d6f0fda8a 100644 --- a/contrib/restricted/abseil-cpp/absl/status/status.h +++ b/contrib/restricted/abseil-cpp/absl/status/status.h @@ -55,7 +55,7 @@ #include <string> #include "absl/container/inlined_vector.h" -#include "absl/functional/function_ref.h" +#include "absl/functional/function_ref.h" #include "absl/status/internal/status_internal.h" #include "absl/strings/cord.h" #include "absl/strings/string_view.h" @@ -81,7 +81,7 @@ ABSL_NAMESPACE_BEGIN // `kFailedPrecondition` if both codes apply. Similarly prefer `kNotFound` or // `kAlreadyExists` over `kFailedPrecondition`. // -// Because these errors may cross RPC boundaries, these codes are tied to the +// Because these errors may cross RPC boundaries, these codes are tied to the // `google.rpc.Code` definitions within // https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto // The string value of these RPC codes is denoted within each enum below. @@ -115,10 +115,10 @@ enum class StatusCode : int { // StatusCode::kInvalidArgument // // kInvalidArgument (gRPC code "INVALID_ARGUMENT") indicates the caller - // specified an invalid argument, such as a malformed filename. Note that use - // of such errors should be narrowly limited to indicate the invalid nature of - // the arguments themselves. Errors with validly formed arguments that may - // cause errors with the state of the receiving system should be denoted with + // specified an invalid argument, such as a malformed filename. Note that use + // of such errors should be narrowly limited to indicate the invalid nature of + // the arguments themselves. Errors with validly formed arguments that may + // cause errors with the state of the receiving system should be denoted with // `kFailedPrecondition` instead. kInvalidArgument = 3, @@ -138,15 +138,15 @@ enum class StatusCode : int { // // `kNotFound` is useful if a request should be denied for an entire class of // users, such as during a gradual feature rollout or undocumented allow list. - // If a request should be denied for specific sets of users, such as through - // user-based access control, use `kPermissionDenied` instead. + // If a request should be denied for specific sets of users, such as through + // user-based access control, use `kPermissionDenied` instead. kNotFound = 5, // StatusCode::kAlreadyExists // - // kAlreadyExists (gRPC code "ALREADY_EXISTS") indicates that the entity a - // caller attempted to create (such as a file or directory) is already - // present. + // kAlreadyExists (gRPC code "ALREADY_EXISTS") indicates that the entity a + // caller attempted to create (such as a file or directory) is already + // present. kAlreadyExists = 6, // StatusCode::kPermissionDenied @@ -185,7 +185,7 @@ enum class StatusCode : int { // level (such as when a client-specified test-and-set fails, indicating // the client should restart a read-modify-write sequence). // (c) Use `kFailedPrecondition` if the client should not retry until - // the system state has been explicitly fixed. For example, if a "rmdir" + // the system state has been explicitly fixed. For example, if a "rmdir" // fails because the directory is non-empty, `kFailedPrecondition` // should be returned since the client should not retry unless // the files are deleted from the directory. @@ -285,7 +285,7 @@ std::ostream& operator<<(std::ostream& os, StatusCode code); // absl::StatusToStringMode // // An `absl::StatusToStringMode` is an enumerated type indicating how -// `absl::Status::ToString()` should construct the output string for a non-ok +// `absl::Status::ToString()` should construct the output string for a non-ok // status. enum class StatusToStringMode : int { // ToString will not contain any extra data (such as payloads). It will only @@ -295,8 +295,8 @@ enum class StatusToStringMode : int { kWithPayload = 1 << 0, // ToString will include all the extra data this Status has. kWithEverything = ~kWithNoExtraData, - // Default mode used by ToString. Its exact value might change in the future. - kDefault = kWithPayload, + // Default mode used by ToString. Its exact value might change in the future. + kDefault = kWithPayload, }; // absl::StatusToStringMode is specified as a bitmask type, which means the @@ -347,7 +347,7 @@ inline StatusToStringMode& operator^=(StatusToStringMode& lhs, // API developers should construct their functions to return `absl::OkStatus()` // upon success, or an `absl::StatusCode` upon another type of error (e.g // an `absl::StatusCode::kInvalidArgument` error). The API provides convenience -// functions to construct each status code. +// functions to construct each status code. // // Example: // @@ -495,7 +495,7 @@ class Status final { // Returns the error message associated with this error code, if available. // Note that this message rarely describes the error code. It is not unusual // for the error message to be the empty string. As a result, prefer - // `operator<<` or `Status::ToString()` for debug logging. + // `operator<<` or `Status::ToString()` for debug logging. absl::string_view message() const; friend bool operator==(const Status&, const Status&); @@ -513,7 +513,7 @@ class Status final { // result, and the payloads to be printed use the status payload printer // mechanism (which is internal). std::string ToString( - StatusToStringMode mode = StatusToStringMode::kDefault) const; + StatusToStringMode mode = StatusToStringMode::kDefault) const; // Status::IgnoreError() // @@ -591,7 +591,7 @@ class Status final { // NOTE: Any mutation on the same 'absl::Status' object during visitation is // forbidden and could result in undefined behavior. void ForEachPayload( - absl::FunctionRef<void(absl::string_view, const absl::Cord&)> visitor) + absl::FunctionRef<void(absl::string_view, const absl::Cord&)> visitor) const; private: diff --git a/contrib/restricted/abseil-cpp/absl/status/statusor.cc b/contrib/restricted/abseil-cpp/absl/status/statusor.cc index 96642b340f..1bb22b9db8 100644 --- a/contrib/restricted/abseil-cpp/absl/status/statusor.cc +++ b/contrib/restricted/abseil-cpp/absl/status/statusor.cc @@ -16,7 +16,7 @@ #include <cstdlib> #include <utility> -#include "absl/base/call_once.h" +#include "absl/base/call_once.h" #include "absl/base/internal/raw_logging.h" #include "absl/status/status.h" #include "absl/strings/str_cat.h" @@ -27,44 +27,44 @@ ABSL_NAMESPACE_BEGIN BadStatusOrAccess::BadStatusOrAccess(absl::Status status) : status_(std::move(status)) {} -BadStatusOrAccess::BadStatusOrAccess(const BadStatusOrAccess& other) - : status_(other.status_) {} - -BadStatusOrAccess& BadStatusOrAccess::operator=( - const BadStatusOrAccess& other) { - // Ensure assignment is correct regardless of whether this->InitWhat() has - // already been called. - other.InitWhat(); - status_ = other.status_; - what_ = other.what_; - return *this; -} - -BadStatusOrAccess& BadStatusOrAccess::operator=(BadStatusOrAccess&& other) { - // Ensure assignment is correct regardless of whether this->InitWhat() has - // already been called. - other.InitWhat(); - status_ = std::move(other.status_); - what_ = std::move(other.what_); - return *this; -} - -BadStatusOrAccess::BadStatusOrAccess(BadStatusOrAccess&& other) - : status_(std::move(other.status_)) {} - +BadStatusOrAccess::BadStatusOrAccess(const BadStatusOrAccess& other) + : status_(other.status_) {} + +BadStatusOrAccess& BadStatusOrAccess::operator=( + const BadStatusOrAccess& other) { + // Ensure assignment is correct regardless of whether this->InitWhat() has + // already been called. + other.InitWhat(); + status_ = other.status_; + what_ = other.what_; + return *this; +} + +BadStatusOrAccess& BadStatusOrAccess::operator=(BadStatusOrAccess&& other) { + // Ensure assignment is correct regardless of whether this->InitWhat() has + // already been called. + other.InitWhat(); + status_ = std::move(other.status_); + what_ = std::move(other.what_); + return *this; +} + +BadStatusOrAccess::BadStatusOrAccess(BadStatusOrAccess&& other) + : status_(std::move(other.status_)) {} + const char* BadStatusOrAccess::what() const noexcept { - InitWhat(); - return what_.c_str(); + InitWhat(); + return what_.c_str(); } const absl::Status& BadStatusOrAccess::status() const { return status_; } -void BadStatusOrAccess::InitWhat() const { - absl::call_once(init_what_, [this] { - what_ = absl::StrCat("Bad StatusOr access: ", status_.ToString()); - }); -} - +void BadStatusOrAccess::InitWhat() const { + absl::call_once(init_what_, [this] { + what_ = absl::StrCat("Bad StatusOr access: ", status_.ToString()); + }); +} + namespace internal_statusor { void Helper::HandleInvalidStatusCtorArg(absl::Status* status) { diff --git a/contrib/restricted/abseil-cpp/absl/status/statusor.h b/contrib/restricted/abseil-cpp/absl/status/statusor.h index c051fbb3aa..3985888960 100644 --- a/contrib/restricted/abseil-cpp/absl/status/statusor.h +++ b/contrib/restricted/abseil-cpp/absl/status/statusor.h @@ -44,7 +44,7 @@ #include <utility> #include "absl/base/attributes.h" -#include "absl/base/call_once.h" +#include "absl/base/call_once.h" #include "absl/meta/type_traits.h" #include "absl/status/internal/statusor_internal.h" #include "absl/status/status.h" @@ -73,18 +73,18 @@ ABSL_NAMESPACE_BEGIN class BadStatusOrAccess : public std::exception { public: explicit BadStatusOrAccess(absl::Status status); - ~BadStatusOrAccess() override = default; - - BadStatusOrAccess(const BadStatusOrAccess& other); - BadStatusOrAccess& operator=(const BadStatusOrAccess& other); - BadStatusOrAccess(BadStatusOrAccess&& other); - BadStatusOrAccess& operator=(BadStatusOrAccess&& other); + ~BadStatusOrAccess() override = default; + BadStatusOrAccess(const BadStatusOrAccess& other); + BadStatusOrAccess& operator=(const BadStatusOrAccess& other); + BadStatusOrAccess(BadStatusOrAccess&& other); + BadStatusOrAccess& operator=(BadStatusOrAccess&& other); + // BadStatusOrAccess::what() // // Returns the associated explanatory string of the `absl::StatusOr<T>` - // object's error code. This function contains information about the failing - // status, but its exact formatting may change and should not be depended on. + // object's error code. This function contains information about the failing + // status, but its exact formatting may change and should not be depended on. // // The pointer of this string is guaranteed to be valid until any non-const // function is invoked on the exception object. @@ -97,11 +97,11 @@ class BadStatusOrAccess : public std::exception { const absl::Status& status() const; private: - void InitWhat() const; - + void InitWhat() const; + absl::Status status_; - mutable absl::once_flag init_what_; - mutable std::string what_; + mutable absl::once_flag init_what_; + mutable std::string what_; }; // Returned StatusOr objects may not be ignored. @@ -429,8 +429,8 @@ class StatusOr : private internal_statusor::StatusOrData<T>, // if `T` can be constructed from a `U`. Can accept move or copy constructors. // // This constructor is explicit if `U` is not convertible to `T`. To avoid - // ambiguity, this constructor is disabled if `U` is a `StatusOr<J>`, where - // `J` is convertible to `T`. + // ambiguity, this constructor is disabled if `U` is a `StatusOr<J>`, where + // `J` is convertible to `T`. template < typename U = T, absl::enable_if_t< @@ -447,7 +447,7 @@ class StatusOr : private internal_statusor::StatusOrData<T>, T, U&&>>>>>::value, int> = 0> StatusOr(U&& u) // NOLINT - : StatusOr(absl::in_place, std::forward<U>(u)) {} + : StatusOr(absl::in_place, std::forward<U>(u)) {} template < typename U = T, @@ -466,7 +466,7 @@ class StatusOr : private internal_statusor::StatusOrData<T>, absl::negation<std::is_convertible<U&&, T>>>::value, int> = 0> explicit StatusOr(U&& u) // NOLINT - : StatusOr(absl::in_place, std::forward<U>(u)) {} + : StatusOr(absl::in_place, std::forward<U>(u)) {} // StatusOr<T>::ok() // @@ -489,7 +489,7 @@ class StatusOr : private internal_statusor::StatusOrData<T>, // Returns a reference to the current `absl::Status` contained within the // `absl::StatusOr<T>`. If `absl::StatusOr<T>` contains a `T`, then this // function returns `absl::OkStatus()`. - const Status& status() const&; + const Status& status() const&; Status status() &&; // StatusOr<T>::value() @@ -518,10 +518,10 @@ class StatusOr : private internal_statusor::StatusOrData<T>, // // The `std::move` on statusor instead of on the whole expression enables // warnings about possible uses of the statusor object after the move. - const T& value() const& ABSL_ATTRIBUTE_LIFETIME_BOUND; - T& value() & ABSL_ATTRIBUTE_LIFETIME_BOUND; - const T&& value() const&& ABSL_ATTRIBUTE_LIFETIME_BOUND; - T&& value() && ABSL_ATTRIBUTE_LIFETIME_BOUND; + const T& value() const& ABSL_ATTRIBUTE_LIFETIME_BOUND; + T& value() & ABSL_ATTRIBUTE_LIFETIME_BOUND; + const T&& value() const&& ABSL_ATTRIBUTE_LIFETIME_BOUND; + T&& value() && ABSL_ATTRIBUTE_LIFETIME_BOUND; // StatusOr<T>:: operator*() // @@ -533,10 +533,10 @@ class StatusOr : private internal_statusor::StatusOrData<T>, // `absl::StatusOr<T>`. Alternatively, see the `value()` member function for a // similar API that guarantees crashing or throwing an exception if there is // no current value. - const T& operator*() const& ABSL_ATTRIBUTE_LIFETIME_BOUND; - T& operator*() & ABSL_ATTRIBUTE_LIFETIME_BOUND; - const T&& operator*() const&& ABSL_ATTRIBUTE_LIFETIME_BOUND; - T&& operator*() && ABSL_ATTRIBUTE_LIFETIME_BOUND; + const T& operator*() const& ABSL_ATTRIBUTE_LIFETIME_BOUND; + T& operator*() & ABSL_ATTRIBUTE_LIFETIME_BOUND; + const T&& operator*() const&& ABSL_ATTRIBUTE_LIFETIME_BOUND; + T&& operator*() && ABSL_ATTRIBUTE_LIFETIME_BOUND; // StatusOr<T>::operator->() // @@ -545,8 +545,8 @@ class StatusOr : private internal_statusor::StatusOrData<T>, // REQUIRES: `this->ok() == true`, otherwise the behavior is undefined. // // Use `this->ok()` to verify that there is a current value. - const T* operator->() const ABSL_ATTRIBUTE_LIFETIME_BOUND; - T* operator->() ABSL_ATTRIBUTE_LIFETIME_BOUND; + const T* operator->() const ABSL_ATTRIBUTE_LIFETIME_BOUND; + T* operator->() ABSL_ATTRIBUTE_LIFETIME_BOUND; // StatusOr<T>::value_or() // @@ -669,9 +669,9 @@ StatusOr<T>::StatusOr(absl::in_place_t, std::initializer_list<U> ilist, : Base(absl::in_place, ilist, std::forward<Args>(args)...) {} template <typename T> -const Status& StatusOr<T>::status() const& { - return this->status_; -} +const Status& StatusOr<T>::status() const& { + return this->status_; +} template <typename T> Status StatusOr<T>::status() && { return ok() ? OkStatus() : std::move(this->status_); diff --git a/contrib/restricted/abseil-cpp/absl/status/statusor/ya.make b/contrib/restricted/abseil-cpp/absl/status/statusor/ya.make index 9628fcdffb..936e0fe20b 100644 --- a/contrib/restricted/abseil-cpp/absl/status/statusor/ya.make +++ b/contrib/restricted/abseil-cpp/absl/status/statusor/ya.make @@ -10,33 +10,33 @@ LICENSE(Apache-2.0) PEERDIR( contrib/restricted/abseil-cpp/absl/base - contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc contrib/restricted/abseil-cpp/absl/base/internal/raw_logging contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/debugging - contrib/restricted/abseil-cpp/absl/debugging/stacktrace - contrib/restricted/abseil-cpp/absl/debugging/symbolize - contrib/restricted/abseil-cpp/absl/demangle + contrib/restricted/abseil-cpp/absl/debugging + contrib/restricted/abseil-cpp/absl/debugging/stacktrace + contrib/restricted/abseil-cpp/absl/debugging/symbolize + contrib/restricted/abseil-cpp/absl/demangle contrib/restricted/abseil-cpp/absl/numeric - contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased - contrib/restricted/abseil-cpp/absl/status + contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp/absl/status contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/cord - contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info - contrib/restricted/abseil-cpp/absl/strings/internal/str_format - contrib/restricted/abseil-cpp/absl/synchronization - contrib/restricted/abseil-cpp/absl/synchronization/internal - contrib/restricted/abseil-cpp/absl/time - contrib/restricted/abseil-cpp/absl/time/civil_time - contrib/restricted/abseil-cpp/absl/time/time_zone + contrib/restricted/abseil-cpp/absl/strings/cord + contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info + contrib/restricted/abseil-cpp/absl/strings/internal/str_format + contrib/restricted/abseil-cpp/absl/synchronization + contrib/restricted/abseil-cpp/absl/synchronization/internal + contrib/restricted/abseil-cpp/absl/time + contrib/restricted/abseil-cpp/absl/time/civil_time + contrib/restricted/abseil-cpp/absl/time/time_zone contrib/restricted/abseil-cpp/absl/types/bad_optional_access - contrib/restricted/abseil-cpp/absl/types/bad_variant_access + contrib/restricted/abseil-cpp/absl/types/bad_variant_access ) ADDINCL( @@ -51,10 +51,10 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/status) +SRCDIR(contrib/restricted/abseil-cpp/absl/status) SRCS( - statusor.cc + statusor.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/status/ya.make b/contrib/restricted/abseil-cpp/absl/status/ya.make index 54a88b1ab1..6bb6c38857 100644 --- a/contrib/restricted/abseil-cpp/absl/status/ya.make +++ b/contrib/restricted/abseil-cpp/absl/status/ya.make @@ -20,20 +20,20 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/debugging/symbolize contrib/restricted/abseil-cpp/absl/demangle contrib/restricted/abseil-cpp/absl/numeric - contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/cord - contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info + contrib/restricted/abseil-cpp/absl/strings/cord + contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info contrib/restricted/abseil-cpp/absl/strings/internal/str_format - contrib/restricted/abseil-cpp/absl/synchronization - contrib/restricted/abseil-cpp/absl/synchronization/internal - contrib/restricted/abseil-cpp/absl/time - contrib/restricted/abseil-cpp/absl/time/civil_time - contrib/restricted/abseil-cpp/absl/time/time_zone + contrib/restricted/abseil-cpp/absl/synchronization + contrib/restricted/abseil-cpp/absl/synchronization/internal + contrib/restricted/abseil-cpp/absl/time + contrib/restricted/abseil-cpp/absl/time/civil_time + contrib/restricted/abseil-cpp/absl/time/time_zone contrib/restricted/abseil-cpp/absl/types/bad_optional_access ) diff --git a/contrib/restricted/abseil-cpp/absl/strings/.yandex_meta/licenses.list.txt b/contrib/restricted/abseil-cpp/absl/strings/.yandex_meta/licenses.list.txt index 9d8552c68c..dd78f940d1 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/.yandex_meta/licenses.list.txt +++ b/contrib/restricted/abseil-cpp/absl/strings/.yandex_meta/licenses.list.txt @@ -35,10 +35,10 @@ ====================COPYRIGHT==================== -// Copyright 2019 The Abseil Authors. - - -====================COPYRIGHT==================== +// Copyright 2019 The Abseil Authors. + + +====================COPYRIGHT==================== // Copyright 2020 The Abseil Authors. diff --git a/contrib/restricted/abseil-cpp/absl/strings/charconv.cc b/contrib/restricted/abseil-cpp/absl/strings/charconv.cc index fefcfc90a5..24b2d3d1fc 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/charconv.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/charconv.cc @@ -111,7 +111,7 @@ struct FloatTraits<double> { return sign ? -ldexp(mantissa, exponent) : ldexp(mantissa, exponent); #else constexpr uint64_t kMantissaMask = - (uint64_t{1} << (kTargetMantissaBits - 1)) - 1; + (uint64_t{1} << (kTargetMantissaBits - 1)) - 1; uint64_t dbl = static_cast<uint64_t>(sign) << 63; if (mantissa > kMantissaMask) { // Normal value. @@ -151,7 +151,7 @@ struct FloatTraits<float> { return sign ? -ldexpf(mantissa, exponent) : ldexpf(mantissa, exponent); #else constexpr uint32_t kMantissaMask = - (uint32_t{1} << (kTargetMantissaBits - 1)) - 1; + (uint32_t{1} << (kTargetMantissaBits - 1)) - 1; uint32_t flt = static_cast<uint32_t>(sign) << 31; if (mantissa > kMantissaMask) { // Normal value. @@ -499,7 +499,7 @@ bool MustRoundUp(uint64_t guess_mantissa, int guess_exponent, template <typename FloatType> CalculatedFloat CalculatedFloatFromRawValues(uint64_t mantissa, int exponent) { CalculatedFloat result; - if (mantissa == uint64_t{1} << FloatTraits<FloatType>::kTargetMantissaBits) { + if (mantissa == uint64_t{1} << FloatTraits<FloatType>::kTargetMantissaBits) { mantissa >>= 1; exponent += 1; } diff --git a/contrib/restricted/abseil-cpp/absl/strings/charconv.h b/contrib/restricted/abseil-cpp/absl/strings/charconv.h index 7c50981245..a1ae788bfb 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/charconv.h +++ b/contrib/restricted/abseil-cpp/absl/strings/charconv.h @@ -64,9 +64,9 @@ struct from_chars_result { // the result in `value`. // // The matching pattern format is almost the same as that of strtod(), except -// that (1) C locale is not respected, (2) an initial '+' character in the -// input range will never be matched, and (3) leading whitespaces are not -// ignored. +// that (1) C locale is not respected, (2) an initial '+' character in the +// input range will never be matched, and (3) leading whitespaces are not +// ignored. // // If `fmt` is set, it must be one of the enumerator values of the chars_format. // (This is despite the fact that chars_format is a bitmask type.) If set to diff --git a/contrib/restricted/abseil-cpp/absl/strings/cord.cc b/contrib/restricted/abseil-cpp/absl/strings/cord.cc index 854047ca98..434fe55724 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/cord.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/cord.cc @@ -36,11 +36,11 @@ #include "absl/container/inlined_vector.h" #include "absl/strings/escaping.h" #include "absl/strings/internal/cord_internal.h" -#include "absl/strings/internal/cord_rep_btree.h" +#include "absl/strings/internal/cord_rep_btree.h" #include "absl/strings/internal/cord_rep_flat.h" -#include "absl/strings/internal/cordz_statistics.h" -#include "absl/strings/internal/cordz_update_scope.h" -#include "absl/strings/internal/cordz_update_tracker.h" +#include "absl/strings/internal/cordz_statistics.h" +#include "absl/strings/internal/cordz_update_scope.h" +#include "absl/strings/internal/cordz_update_tracker.h" #include "absl/strings/internal/resize_uninitialized.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" @@ -51,14 +51,14 @@ namespace absl { ABSL_NAMESPACE_BEGIN using ::absl::cord_internal::CordRep; -using ::absl::cord_internal::CordRepBtree; +using ::absl::cord_internal::CordRepBtree; using ::absl::cord_internal::CordRepConcat; using ::absl::cord_internal::CordRepExternal; using ::absl::cord_internal::CordRepFlat; using ::absl::cord_internal::CordRepSubstring; -using ::absl::cord_internal::CordzUpdateTracker; -using ::absl::cord_internal::InlineData; -using ::absl::cord_internal::kMaxFlatLength; +using ::absl::cord_internal::CordzUpdateTracker; +using ::absl::cord_internal::InlineData; +using ::absl::cord_internal::kMaxFlatLength; using ::absl::cord_internal::kMinFlatLength; using ::absl::cord_internal::kInlinedVectorSize; @@ -94,13 +94,13 @@ static constexpr uint64_t min_length[] = { static const int kMinLengthSize = ABSL_ARRAYSIZE(min_length); -static inline bool btree_enabled() { - return cord_internal::cord_btree_enabled.load( +static inline bool btree_enabled() { + return cord_internal::cord_btree_enabled.load( std::memory_order_relaxed); } static inline bool IsRootBalanced(CordRep* node) { - if (!node->IsConcat()) { + if (!node->IsConcat()) { return true; } else if (node->concat()->depth() <= 15) { return true; @@ -137,7 +137,7 @@ static inline CordRep* VerifyTree(CordRep* node) { // Return the depth of a node static int Depth(const CordRep* rep) { - if (rep->IsConcat()) { + if (rep->IsConcat()) { return rep->concat()->depth(); } else { return 0; @@ -170,7 +170,7 @@ static CordRep* RawConcat(CordRep* left, CordRep* right) { } CordRepConcat* rep = new CordRepConcat(); - rep->tag = cord_internal::CONCAT; + rep->tag = cord_internal::CONCAT; SetConcatChildren(rep, left, right); return rep; @@ -205,32 +205,32 @@ static CordRep* MakeBalancedTree(CordRep** reps, size_t n) { } static CordRepFlat* CreateFlat(const char* data, size_t length, - size_t alloc_hint) { + size_t alloc_hint) { CordRepFlat* flat = CordRepFlat::New(length + alloc_hint); flat->length = length; memcpy(flat->Data(), data, length); return flat; } -// Creates a new flat or Btree out of the specified array. +// Creates a new flat or Btree out of the specified array. // The returned node has a refcount of 1. -static CordRep* NewBtree(const char* data, size_t length, size_t alloc_hint) { +static CordRep* NewBtree(const char* data, size_t length, size_t alloc_hint) { if (length <= kMaxFlatLength) { return CreateFlat(data, length, alloc_hint); } CordRepFlat* flat = CreateFlat(data, kMaxFlatLength, 0); data += kMaxFlatLength; length -= kMaxFlatLength; - auto* root = CordRepBtree::Create(flat); - return CordRepBtree::Append(root, {data, length}, alloc_hint); + auto* root = CordRepBtree::Create(flat); + return CordRepBtree::Append(root, {data, length}, alloc_hint); } // Create a new tree out of the specified array. // The returned node has a refcount of 1. -static CordRep* NewTree(const char* data, size_t length, size_t alloc_hint) { +static CordRep* NewTree(const char* data, size_t length, size_t alloc_hint) { if (length == 0) return nullptr; - if (btree_enabled()) { - return NewBtree(data, length, alloc_hint); + if (btree_enabled()) { + return NewBtree(data, length, alloc_hint); } absl::FixedArray<CordRep*> reps((length - 1) / kMaxFlatLength + 1); size_t n = 0; @@ -267,42 +267,42 @@ static CordRep* NewSubstring(CordRep* child, size_t offset, size_t length) { CordRepSubstring* rep = new CordRepSubstring(); assert((offset + length) <= child->length); rep->length = length; - rep->tag = cord_internal::SUBSTRING; + rep->tag = cord_internal::SUBSTRING; rep->start = offset; rep->child = child; return VerifyTree(rep); } } -// Creates a CordRep from the provided string. If the string is large enough, -// and not wasteful, we move the string into an external cord rep, preserving -// the already allocated string contents. -// Requires the provided string length to be larger than `kMaxInline`. -static CordRep* CordRepFromString(std::string&& src) { - assert(src.length() > cord_internal::kMaxInline); - if ( - // String is short: copy data to avoid external block overhead. - src.size() <= kMaxBytesToCopy || - // String is wasteful: copy data to avoid pinning too much unused memory. - src.size() < src.capacity() / 2 - ) { - return NewTree(src.data(), src.size(), 0); - } - - struct StringReleaser { - void operator()(absl::string_view /* data */) {} - std::string data; - }; - const absl::string_view original_data = src; - auto* rep = - static_cast<::absl::cord_internal::CordRepExternalImpl<StringReleaser>*>( - absl::cord_internal::NewExternalRep(original_data, - StringReleaser{std::move(src)})); - // Moving src may have invalidated its data pointer, so adjust it. - rep->base = rep->template get<0>().data.data(); - return rep; -} - +// Creates a CordRep from the provided string. If the string is large enough, +// and not wasteful, we move the string into an external cord rep, preserving +// the already allocated string contents. +// Requires the provided string length to be larger than `kMaxInline`. +static CordRep* CordRepFromString(std::string&& src) { + assert(src.length() > cord_internal::kMaxInline); + if ( + // String is short: copy data to avoid external block overhead. + src.size() <= kMaxBytesToCopy || + // String is wasteful: copy data to avoid pinning too much unused memory. + src.size() < src.capacity() / 2 + ) { + return NewTree(src.data(), src.size(), 0); + } + + struct StringReleaser { + void operator()(absl::string_view /* data */) {} + std::string data; + }; + const absl::string_view original_data = src; + auto* rep = + static_cast<::absl::cord_internal::CordRepExternalImpl<StringReleaser>*>( + absl::cord_internal::NewExternalRep(original_data, + StringReleaser{std::move(src)})); + // Moving src may have invalidated its data pointer, so adjust it. + rep->base = rep->template get<0>().data.data(); + return rep; +} + // -------------------------------------------------------------------- // Cord::InlineRep functions @@ -338,78 +338,78 @@ inline void Cord::InlineRep::remove_prefix(size_t n) { reduce_size(n); } -// Returns `rep` converted into a CordRepBtree. -// Directly returns `rep` if `rep` is already a CordRepBtree. -static CordRepBtree* ForceBtree(CordRep* rep) { - return rep->IsBtree() ? rep->btree() : CordRepBtree::Create(rep); -} - -void Cord::InlineRep::AppendTreeToInlined(CordRep* tree, - MethodIdentifier method) { - assert(!is_tree()); - if (!data_.is_empty()) { - CordRepFlat* flat = MakeFlatWithExtraCapacity(0); - if (btree_enabled()) { - tree = CordRepBtree::Append(CordRepBtree::Create(flat), tree); - } else { - tree = Concat(flat, tree); - } - } - EmplaceTree(tree, method); -} - -void Cord::InlineRep::AppendTreeToTree(CordRep* tree, MethodIdentifier method) { - assert(is_tree()); - const CordzUpdateScope scope(data_.cordz_info(), method); - if (btree_enabled()) { - tree = CordRepBtree::Append(ForceBtree(data_.as_tree()), tree); - } else { - tree = Concat(data_.as_tree(), tree); - } - SetTree(tree, scope); -} - -void Cord::InlineRep::AppendTree(CordRep* tree, MethodIdentifier method) { +// Returns `rep` converted into a CordRepBtree. +// Directly returns `rep` if `rep` is already a CordRepBtree. +static CordRepBtree* ForceBtree(CordRep* rep) { + return rep->IsBtree() ? rep->btree() : CordRepBtree::Create(rep); +} + +void Cord::InlineRep::AppendTreeToInlined(CordRep* tree, + MethodIdentifier method) { + assert(!is_tree()); + if (!data_.is_empty()) { + CordRepFlat* flat = MakeFlatWithExtraCapacity(0); + if (btree_enabled()) { + tree = CordRepBtree::Append(CordRepBtree::Create(flat), tree); + } else { + tree = Concat(flat, tree); + } + } + EmplaceTree(tree, method); +} + +void Cord::InlineRep::AppendTreeToTree(CordRep* tree, MethodIdentifier method) { + assert(is_tree()); + const CordzUpdateScope scope(data_.cordz_info(), method); + if (btree_enabled()) { + tree = CordRepBtree::Append(ForceBtree(data_.as_tree()), tree); + } else { + tree = Concat(data_.as_tree(), tree); + } + SetTree(tree, scope); +} + +void Cord::InlineRep::AppendTree(CordRep* tree, MethodIdentifier method) { if (tree == nullptr) return; - if (data_.is_tree()) { - AppendTreeToTree(tree, method); - } else { - AppendTreeToInlined(tree, method); - } -} - -void Cord::InlineRep::PrependTreeToInlined(CordRep* tree, - MethodIdentifier method) { - assert(!is_tree()); - if (!data_.is_empty()) { - CordRepFlat* flat = MakeFlatWithExtraCapacity(0); - if (btree_enabled()) { - tree = CordRepBtree::Prepend(CordRepBtree::Create(flat), tree); - } else { - tree = Concat(tree, flat); - } - } - EmplaceTree(tree, method); -} - -void Cord::InlineRep::PrependTreeToTree(CordRep* tree, - MethodIdentifier method) { - assert(is_tree()); - const CordzUpdateScope scope(data_.cordz_info(), method); - if (btree_enabled()) { - tree = CordRepBtree::Prepend(ForceBtree(data_.as_tree()), tree); + if (data_.is_tree()) { + AppendTreeToTree(tree, method); } else { - tree = Concat(tree, data_.as_tree()); - } - SetTree(tree, scope); -} - -void Cord::InlineRep::PrependTree(CordRep* tree, MethodIdentifier method) { + AppendTreeToInlined(tree, method); + } +} + +void Cord::InlineRep::PrependTreeToInlined(CordRep* tree, + MethodIdentifier method) { + assert(!is_tree()); + if (!data_.is_empty()) { + CordRepFlat* flat = MakeFlatWithExtraCapacity(0); + if (btree_enabled()) { + tree = CordRepBtree::Prepend(CordRepBtree::Create(flat), tree); + } else { + tree = Concat(tree, flat); + } + } + EmplaceTree(tree, method); +} + +void Cord::InlineRep::PrependTreeToTree(CordRep* tree, + MethodIdentifier method) { + assert(is_tree()); + const CordzUpdateScope scope(data_.cordz_info(), method); + if (btree_enabled()) { + tree = CordRepBtree::Prepend(ForceBtree(data_.as_tree()), tree); + } else { + tree = Concat(tree, data_.as_tree()); + } + SetTree(tree, scope); +} + +void Cord::InlineRep::PrependTree(CordRep* tree, MethodIdentifier method) { assert(tree != nullptr); - if (data_.is_tree()) { - PrependTreeToTree(tree, method); + if (data_.is_tree()) { + PrependTreeToTree(tree, method); } else { - PrependTreeToInlined(tree, method); + PrependTreeToInlined(tree, method); } } @@ -419,8 +419,8 @@ void Cord::InlineRep::PrependTree(CordRep* tree, MethodIdentifier method) { // written to region and the actual size increase will be written to size. static inline bool PrepareAppendRegion(CordRep* root, char** region, size_t* size, size_t max_length) { - if (root->IsBtree() && root->refcount.IsMutable()) { - Span<char> span = root->btree()->GetAppendBuffer(max_length); + if (root->IsBtree() && root->refcount.IsMutable()) { + Span<char> span = root->btree()->GetAppendBuffer(max_length); if (!span.empty()) { *region = span.data(); *size = span.size(); @@ -430,11 +430,11 @@ static inline bool PrepareAppendRegion(CordRep* root, char** region, // Search down the right-hand path for a non-full FLAT node. CordRep* dst = root; - while (dst->IsConcat() && dst->refcount.IsMutable()) { + while (dst->IsConcat() && dst->refcount.IsMutable()) { dst = dst->concat()->right; } - if (!dst->IsFlat() || !dst->refcount.IsMutable()) { + if (!dst->IsFlat() || !dst->refcount.IsMutable()) { *region = nullptr; *size = 0; return false; @@ -461,115 +461,115 @@ static inline bool PrepareAppendRegion(CordRep* root, char** region, return true; } -template <bool has_length> +template <bool has_length> void Cord::InlineRep::GetAppendRegion(char** region, size_t* size, - size_t length) { - auto constexpr method = CordzUpdateTracker::kGetAppendRegion; - - CordRep* root = tree(); - size_t sz = root ? root->length : inline_size(); - if (root == nullptr) { - size_t available = kMaxInline - sz; - if (available >= (has_length ? length : 1)) { - *region = data_.as_chars() + sz; - *size = has_length ? length : available; - set_inline_size(has_length ? sz + length : kMaxInline); + size_t length) { + auto constexpr method = CordzUpdateTracker::kGetAppendRegion; + + CordRep* root = tree(); + size_t sz = root ? root->length : inline_size(); + if (root == nullptr) { + size_t available = kMaxInline - sz; + if (available >= (has_length ? length : 1)) { + *region = data_.as_chars() + sz; + *size = has_length ? length : available; + set_inline_size(has_length ? sz + length : kMaxInline); return; } } - size_t extra = has_length ? length : (std::max)(sz, kMinFlatLength); - CordRep* rep = root ? root : MakeFlatWithExtraCapacity(extra); - CordzUpdateScope scope(root ? data_.cordz_info() : nullptr, method); - if (PrepareAppendRegion(rep, region, size, length)) { - CommitTree(root, rep, scope, method); + size_t extra = has_length ? length : (std::max)(sz, kMinFlatLength); + CordRep* rep = root ? root : MakeFlatWithExtraCapacity(extra); + CordzUpdateScope scope(root ? data_.cordz_info() : nullptr, method); + if (PrepareAppendRegion(rep, region, size, length)) { + CommitTree(root, rep, scope, method); return; } // Allocate new node. - CordRepFlat* new_node = CordRepFlat::New(extra); - new_node->length = std::min(new_node->Capacity(), length); + CordRepFlat* new_node = CordRepFlat::New(extra); + new_node->length = std::min(new_node->Capacity(), length); *region = new_node->Data(); *size = new_node->length; - if (btree_enabled()) { - rep = CordRepBtree::Append(ForceBtree(rep), new_node); - } else { - rep = Concat(rep, new_node); + if (btree_enabled()) { + rep = CordRepBtree::Append(ForceBtree(rep), new_node); + } else { + rep = Concat(rep, new_node); } - CommitTree(root, rep, scope, method); + CommitTree(root, rep, scope, method); } -// Computes the memory side of the provided edge which must be a valid data edge -// for a btrtee, i.e., a FLAT, EXTERNAL or SUBSTRING of a FLAT or EXTERNAL node. -static bool RepMemoryUsageDataEdge(const CordRep* rep, - size_t* total_mem_usage) { - size_t maybe_sub_size = 0; - if (ABSL_PREDICT_FALSE(rep->IsSubstring())) { - maybe_sub_size = sizeof(cord_internal::CordRepSubstring); - rep = rep->substring()->child; +// Computes the memory side of the provided edge which must be a valid data edge +// for a btrtee, i.e., a FLAT, EXTERNAL or SUBSTRING of a FLAT or EXTERNAL node. +static bool RepMemoryUsageDataEdge(const CordRep* rep, + size_t* total_mem_usage) { + size_t maybe_sub_size = 0; + if (ABSL_PREDICT_FALSE(rep->IsSubstring())) { + maybe_sub_size = sizeof(cord_internal::CordRepSubstring); + rep = rep->substring()->child; } - if (rep->IsFlat()) { - *total_mem_usage += maybe_sub_size + rep->flat()->AllocatedSize(); - return true; + if (rep->IsFlat()) { + *total_mem_usage += maybe_sub_size + rep->flat()->AllocatedSize(); + return true; } - if (rep->IsExternal()) { - // We don't know anything about the embedded / bound data, but we can safely - // assume it is 'at least' a word / pointer to data. In the future we may - // choose to use the 'data' byte as a tag to identify the types of some - // well-known externals, such as a std::string instance. - *total_mem_usage += maybe_sub_size + - sizeof(cord_internal::CordRepExternalImpl<intptr_t>) + - rep->length; - return true; + if (rep->IsExternal()) { + // We don't know anything about the embedded / bound data, but we can safely + // assume it is 'at least' a word / pointer to data. In the future we may + // choose to use the 'data' byte as a tag to identify the types of some + // well-known externals, such as a std::string instance. + *total_mem_usage += maybe_sub_size + + sizeof(cord_internal::CordRepExternalImpl<intptr_t>) + + rep->length; + return true; } - return false; + return false; } // If the rep is a leaf, this will increment the value at total_mem_usage and // will return true. static bool RepMemoryUsageLeaf(const CordRep* rep, size_t* total_mem_usage) { - if (rep->IsFlat()) { + if (rep->IsFlat()) { *total_mem_usage += rep->flat()->AllocatedSize(); return true; } - if (rep->IsExternal()) { - // We don't know anything about the embedded / bound data, but we can safely - // assume it is 'at least' a word / pointer to data. In the future we may - // choose to use the 'data' byte as a tag to identify the types of some - // well-known externals, such as a std::string instance. - *total_mem_usage += - sizeof(cord_internal::CordRepExternalImpl<intptr_t>) + rep->length; + if (rep->IsExternal()) { + // We don't know anything about the embedded / bound data, but we can safely + // assume it is 'at least' a word / pointer to data. In the future we may + // choose to use the 'data' byte as a tag to identify the types of some + // well-known externals, such as a std::string instance. + *total_mem_usage += + sizeof(cord_internal::CordRepExternalImpl<intptr_t>) + rep->length; return true; } return false; } void Cord::InlineRep::AssignSlow(const Cord::InlineRep& src) { - assert(&src != this); - assert(is_tree() || src.is_tree()); - auto constexpr method = CordzUpdateTracker::kAssignCord; - if (ABSL_PREDICT_TRUE(!is_tree())) { - EmplaceTree(CordRep::Ref(src.as_tree()), src.data_, method); - return; - } - - CordRep* tree = as_tree(); - if (CordRep* src_tree = src.tree()) { - // Leave any existing `cordz_info` in place, and let MaybeTrackCord() - // decide if this cord should be (or remains to be) sampled or not. - data_.set_tree(CordRep::Ref(src_tree)); - CordzInfo::MaybeTrackCord(data_, src.data_, method); - } else { - CordzInfo::MaybeUntrackCord(data_.cordz_info()); - data_ = src.data_; - } - CordRep::Unref(tree); -} - -void Cord::InlineRep::UnrefTree() { + assert(&src != this); + assert(is_tree() || src.is_tree()); + auto constexpr method = CordzUpdateTracker::kAssignCord; + if (ABSL_PREDICT_TRUE(!is_tree())) { + EmplaceTree(CordRep::Ref(src.as_tree()), src.data_, method); + return; + } + + CordRep* tree = as_tree(); + if (CordRep* src_tree = src.tree()) { + // Leave any existing `cordz_info` in place, and let MaybeTrackCord() + // decide if this cord should be (or remains to be) sampled or not. + data_.set_tree(CordRep::Ref(src_tree)); + CordzInfo::MaybeTrackCord(data_, src.data_, method); + } else { + CordzInfo::MaybeUntrackCord(data_.cordz_info()); + data_ = src.data_; + } + CordRep::Unref(tree); +} + +void Cord::InlineRep::UnrefTree() { if (is_tree()) { - CordzInfo::MaybeUntrackCord(data_.cordz_info()); + CordzInfo::MaybeUntrackCord(data_.cordz_info()); CordRep::Unref(tree()); } } @@ -577,24 +577,24 @@ void Cord::InlineRep::UnrefTree() { // -------------------------------------------------------------------- // Constructors and destructors -Cord::Cord(absl::string_view src, MethodIdentifier method) - : contents_(InlineData::kDefaultInit) { +Cord::Cord(absl::string_view src, MethodIdentifier method) + : contents_(InlineData::kDefaultInit) { const size_t n = src.size(); if (n <= InlineRep::kMaxInline) { - contents_.set_data(src.data(), n, true); + contents_.set_data(src.data(), n, true); } else { - CordRep* rep = NewTree(src.data(), n, 0); - contents_.EmplaceTree(rep, method); + CordRep* rep = NewTree(src.data(), n, 0); + contents_.EmplaceTree(rep, method); } } template <typename T, Cord::EnableIfString<T>> -Cord::Cord(T&& src) : contents_(InlineData::kDefaultInit) { - if (src.size() <= InlineRep::kMaxInline) { - contents_.set_data(src.data(), src.size(), true); +Cord::Cord(T&& src) : contents_(InlineData::kDefaultInit) { + if (src.size() <= InlineRep::kMaxInline) { + contents_.set_data(src.data(), src.size(), true); } else { - CordRep* rep = CordRepFromString(std::forward<T>(src)); - contents_.EmplaceTree(rep, CordzUpdateTracker::kConstructorString); + CordRep* rep = CordRepFromString(std::forward<T>(src)); + contents_.EmplaceTree(rep, CordzUpdateTracker::kConstructorString); } } @@ -603,9 +603,9 @@ template Cord::Cord(std::string&& src); // The destruction code is separate so that the compiler can determine // that it does not need to call the destructor on a moved-from Cord. void Cord::DestroyCordSlow() { - assert(contents_.is_tree()); - CordzInfo::MaybeUntrackCord(contents_.cordz_info()); - CordRep::Unref(VerifyTree(contents_.as_tree())); + assert(contents_.is_tree()); + CordzInfo::MaybeUntrackCord(contents_.cordz_info()); + CordRep::Unref(VerifyTree(contents_.as_tree())); } // -------------------------------------------------------------------- @@ -617,116 +617,116 @@ void Cord::Clear() { } } -Cord& Cord::AssignLargeString(std::string&& src) { - auto constexpr method = CordzUpdateTracker::kAssignString; - assert(src.size() > kMaxBytesToCopy); - CordRep* rep = CordRepFromString(std::move(src)); - if (CordRep* tree = contents_.tree()) { - CordzUpdateScope scope(contents_.cordz_info(), method); - contents_.SetTree(rep, scope); - CordRep::Unref(tree); - } else { - contents_.EmplaceTree(rep, method); - } - return *this; -} - +Cord& Cord::AssignLargeString(std::string&& src) { + auto constexpr method = CordzUpdateTracker::kAssignString; + assert(src.size() > kMaxBytesToCopy); + CordRep* rep = CordRepFromString(std::move(src)); + if (CordRep* tree = contents_.tree()) { + CordzUpdateScope scope(contents_.cordz_info(), method); + contents_.SetTree(rep, scope); + CordRep::Unref(tree); + } else { + contents_.EmplaceTree(rep, method); + } + return *this; +} + Cord& Cord::operator=(absl::string_view src) { - auto constexpr method = CordzUpdateTracker::kAssignString; + auto constexpr method = CordzUpdateTracker::kAssignString; const char* data = src.data(); size_t length = src.size(); CordRep* tree = contents_.tree(); if (length <= InlineRep::kMaxInline) { - // Embed into this->contents_, which is somewhat subtle: - // - MaybeUntrackCord must be called before Unref(tree). - // - MaybeUntrackCord must be called before set_data() clobbers cordz_info. - // - set_data() must be called before Unref(tree) as it may reference tree. - if (tree != nullptr) CordzInfo::MaybeUntrackCord(contents_.cordz_info()); + // Embed into this->contents_, which is somewhat subtle: + // - MaybeUntrackCord must be called before Unref(tree). + // - MaybeUntrackCord must be called before set_data() clobbers cordz_info. + // - set_data() must be called before Unref(tree) as it may reference tree. + if (tree != nullptr) CordzInfo::MaybeUntrackCord(contents_.cordz_info()); contents_.set_data(data, length, true); - if (tree != nullptr) CordRep::Unref(tree); + if (tree != nullptr) CordRep::Unref(tree); return *this; } - if (tree != nullptr) { - CordzUpdateScope scope(contents_.cordz_info(), method); - if (tree->IsFlat() && tree->flat()->Capacity() >= length && - tree->refcount.IsMutable()) { - // Copy in place if the existing FLAT node is reusable. - memmove(tree->flat()->Data(), data, length); - tree->length = length; - VerifyTree(tree); - return *this; - } - contents_.SetTree(NewTree(data, length, 0), scope); - CordRep::Unref(tree); + if (tree != nullptr) { + CordzUpdateScope scope(contents_.cordz_info(), method); + if (tree->IsFlat() && tree->flat()->Capacity() >= length && + tree->refcount.IsMutable()) { + // Copy in place if the existing FLAT node is reusable. + memmove(tree->flat()->Data(), data, length); + tree->length = length; + VerifyTree(tree); + return *this; + } + contents_.SetTree(NewTree(data, length, 0), scope); + CordRep::Unref(tree); } else { - contents_.EmplaceTree(NewTree(data, length, 0), method); + contents_.EmplaceTree(NewTree(data, length, 0), method); } return *this; } // TODO(sanjay): Move to Cord::InlineRep section of file. For now, // we keep it here to make diffs easier. -void Cord::InlineRep::AppendArray(absl::string_view src, - MethodIdentifier method) { - if (src.empty()) return; // memcpy(_, nullptr, 0) is undefined. +void Cord::InlineRep::AppendArray(absl::string_view src, + MethodIdentifier method) { + if (src.empty()) return; // memcpy(_, nullptr, 0) is undefined. size_t appended = 0; - CordRep* rep = tree(); - const CordRep* const root = rep; - CordzUpdateScope scope(root ? cordz_info() : nullptr, method); - if (root != nullptr) { + CordRep* rep = tree(); + const CordRep* const root = rep; + CordzUpdateScope scope(root ? cordz_info() : nullptr, method); + if (root != nullptr) { char* region; - if (PrepareAppendRegion(rep, ®ion, &appended, src.size())) { - memcpy(region, src.data(), appended); + if (PrepareAppendRegion(rep, ®ion, &appended, src.size())) { + memcpy(region, src.data(), appended); } } else { // Try to fit in the inline buffer if possible. size_t inline_length = inline_size(); - if (src.size() <= kMaxInline - inline_length) { + if (src.size() <= kMaxInline - inline_length) { // Append new data to embedded array - memcpy(data_.as_chars() + inline_length, src.data(), src.size()); - set_inline_size(inline_length + src.size()); + memcpy(data_.as_chars() + inline_length, src.data(), src.size()); + set_inline_size(inline_length + src.size()); return; } - // Allocate flat to be a perfect fit on first append exceeding inlined size. - // Subsequent growth will use amortized growth until we reach maximum flat - // size. - rep = CordRepFlat::New(inline_length + src.size()); - appended = std::min(src.size(), rep->flat()->Capacity() - inline_length); - memcpy(rep->flat()->Data(), data_.as_chars(), inline_length); - memcpy(rep->flat()->Data() + inline_length, src.data(), appended); - rep->length = inline_length + appended; + // Allocate flat to be a perfect fit on first append exceeding inlined size. + // Subsequent growth will use amortized growth until we reach maximum flat + // size. + rep = CordRepFlat::New(inline_length + src.size()); + appended = std::min(src.size(), rep->flat()->Capacity() - inline_length); + memcpy(rep->flat()->Data(), data_.as_chars(), inline_length); + memcpy(rep->flat()->Data() + inline_length, src.data(), appended); + rep->length = inline_length + appended; } - src.remove_prefix(appended); - if (src.empty()) { - CommitTree(root, rep, scope, method); + src.remove_prefix(appended); + if (src.empty()) { + CommitTree(root, rep, scope, method); return; } - if (btree_enabled()) { - // TODO(b/192061034): keep legacy 10% growth rate: consider other rates. - rep = ForceBtree(rep); - const size_t min_growth = std::max<size_t>(rep->length / 10, src.size()); - rep = CordRepBtree::Append(rep->btree(), src, min_growth - src.size()); - } else { - // Use new block(s) for any remaining bytes that were not handled above. - // Alloc extra memory only if the right child of the root of the new tree - // is going to be a FLAT node, which will permit further inplace appends. - size_t length = src.size(); - if (src.size() < kMaxFlatLength) { - // The new length is either - // - old size + 10% - // - old_size + src.size() - // This will cause a reasonable conservative step-up in size that is - // still large enough to avoid excessive amounts of small fragments - // being added. - length = std::max<size_t>(rep->length / 10, src.size()); - } - rep = Concat(rep, NewTree(src.data(), src.size(), length - src.size())); - } - CommitTree(root, rep, scope, method); + if (btree_enabled()) { + // TODO(b/192061034): keep legacy 10% growth rate: consider other rates. + rep = ForceBtree(rep); + const size_t min_growth = std::max<size_t>(rep->length / 10, src.size()); + rep = CordRepBtree::Append(rep->btree(), src, min_growth - src.size()); + } else { + // Use new block(s) for any remaining bytes that were not handled above. + // Alloc extra memory only if the right child of the root of the new tree + // is going to be a FLAT node, which will permit further inplace appends. + size_t length = src.size(); + if (src.size() < kMaxFlatLength) { + // The new length is either + // - old size + 10% + // - old_size + src.size() + // This will cause a reasonable conservative step-up in size that is + // still large enough to avoid excessive amounts of small fragments + // being added. + length = std::max<size_t>(rep->length / 10, src.size()); + } + rep = Concat(rep, NewTree(src.data(), src.size(), length - src.size())); + } + CommitTree(root, rep, scope, method); } inline CordRep* Cord::TakeRep() const& { @@ -741,17 +741,17 @@ inline CordRep* Cord::TakeRep() && { template <typename C> inline void Cord::AppendImpl(C&& src) { - auto constexpr method = CordzUpdateTracker::kAppendCord; + auto constexpr method = CordzUpdateTracker::kAppendCord; if (empty()) { - // Since destination is empty, we can avoid allocating a node, - if (src.contents_.is_tree()) { - // by taking the tree directly - CordRep* rep = std::forward<C>(src).TakeRep(); - contents_.EmplaceTree(rep, method); - } else { - // or copying over inline data - contents_.data_ = src.contents_.data_; - } + // Since destination is empty, we can avoid allocating a node, + if (src.contents_.is_tree()) { + // by taking the tree directly + CordRep* rep = std::forward<C>(src).TakeRep(); + contents_.EmplaceTree(rep, method); + } else { + // or copying over inline data + contents_.data_ = src.contents_.data_; + } return; } @@ -761,12 +761,12 @@ inline void Cord::AppendImpl(C&& src) { CordRep* src_tree = src.contents_.tree(); if (src_tree == nullptr) { // src has embedded data. - contents_.AppendArray({src.contents_.data(), src_size}, method); + contents_.AppendArray({src.contents_.data(), src_size}, method); return; } - if (src_tree->IsFlat()) { + if (src_tree->IsFlat()) { // src tree just has one flat node. - contents_.AppendArray({src_tree->flat()->Data(), src_size}, method); + contents_.AppendArray({src_tree->flat()->Data(), src_size}, method); return; } if (&src == this) { @@ -782,25 +782,25 @@ inline void Cord::AppendImpl(C&& src) { } // Guaranteed to be a tree (kMaxBytesToCopy > kInlinedSize) - CordRep* rep = std::forward<C>(src).TakeRep(); - contents_.AppendTree(rep, CordzUpdateTracker::kAppendCord); + CordRep* rep = std::forward<C>(src).TakeRep(); + contents_.AppendTree(rep, CordzUpdateTracker::kAppendCord); } -void Cord::Append(const Cord& src) { - AppendImpl(src); -} +void Cord::Append(const Cord& src) { + AppendImpl(src); +} -void Cord::Append(Cord&& src) { - AppendImpl(std::move(src)); -} +void Cord::Append(Cord&& src) { + AppendImpl(std::move(src)); +} template <typename T, Cord::EnableIfString<T>> void Cord::Append(T&& src) { if (src.size() <= kMaxBytesToCopy) { Append(absl::string_view(src)); } else { - CordRep* rep = CordRepFromString(std::forward<T>(src)); - contents_.AppendTree(rep, CordzUpdateTracker::kAppendString); + CordRep* rep = CordRepFromString(std::forward<T>(src)); + contents_.AppendTree(rep, CordzUpdateTracker::kAppendString); } } @@ -810,7 +810,7 @@ void Cord::Prepend(const Cord& src) { CordRep* src_tree = src.contents_.tree(); if (src_tree != nullptr) { CordRep::Ref(src_tree); - contents_.PrependTree(src_tree, CordzUpdateTracker::kPrependCord); + contents_.PrependTree(src_tree, CordzUpdateTracker::kPrependCord); return; } @@ -819,7 +819,7 @@ void Cord::Prepend(const Cord& src) { return Prepend(src_contents); } -void Cord::PrependArray(absl::string_view src, MethodIdentifier method) { +void Cord::PrependArray(absl::string_view src, MethodIdentifier method) { if (src.empty()) return; // memcpy(_, nullptr, 0) is undefined. if (!contents_.is_tree()) { size_t cur_size = contents_.inline_size(); @@ -833,8 +833,8 @@ void Cord::PrependArray(absl::string_view src, MethodIdentifier method) { return; } } - CordRep* rep = NewTree(src.data(), src.size(), 0); - contents_.PrependTree(rep, method); + CordRep* rep = NewTree(src.data(), src.size(), 0); + contents_.PrependTree(rep, method); } template <typename T, Cord::EnableIfString<T>> @@ -842,8 +842,8 @@ inline void Cord::Prepend(T&& src) { if (src.size() <= kMaxBytesToCopy) { Prepend(absl::string_view(src)); } else { - CordRep* rep = CordRepFromString(std::forward<T>(src)); - contents_.PrependTree(rep, CordzUpdateTracker::kPrependString); + CordRep* rep = CordRepFromString(std::forward<T>(src)); + contents_.PrependTree(rep, CordzUpdateTracker::kPrependString); } } @@ -854,7 +854,7 @@ static CordRep* RemovePrefixFrom(CordRep* node, size_t n) { if (n == 0) return CordRep::Ref(node); absl::InlinedVector<CordRep*, kInlinedVectorSize> rhs_stack; - while (node->IsConcat()) { + while (node->IsConcat()) { assert(n <= node->length); if (n < node->concat()->left->length) { // Push right to stack, descend left. @@ -873,7 +873,7 @@ static CordRep* RemovePrefixFrom(CordRep* node, size_t n) { } else { size_t start = n; size_t len = node->length - n; - if (node->IsSubstring()) { + if (node->IsSubstring()) { // Consider in-place update of node, similar to in RemoveSuffixFrom(). start += node->substring()->start; node = node->substring()->child; @@ -894,9 +894,9 @@ static CordRep* RemoveSuffixFrom(CordRep* node, size_t n) { if (n >= node->length) return nullptr; if (n == 0) return CordRep::Ref(node); absl::InlinedVector<CordRep*, kInlinedVectorSize> lhs_stack; - bool inplace_ok = node->refcount.IsMutable(); + bool inplace_ok = node->refcount.IsMutable(); - while (node->IsConcat()) { + while (node->IsConcat()) { assert(n <= node->length); if (n < node->concat()->right->length) { // Push left to stack, descend right. @@ -907,13 +907,13 @@ static CordRep* RemoveSuffixFrom(CordRep* node, size_t n) { n -= node->concat()->right->length; node = node->concat()->left; } - inplace_ok = inplace_ok && node->refcount.IsMutable(); + inplace_ok = inplace_ok && node->refcount.IsMutable(); } assert(n <= node->length); if (n == 0) { CordRep::Ref(node); - } else if (inplace_ok && !node->IsExternal()) { + } else if (inplace_ok && !node->IsExternal()) { // Consider making a new buffer if the current node capacity is much // larger than the new length. CordRep::Ref(node); @@ -921,7 +921,7 @@ static CordRep* RemoveSuffixFrom(CordRep* node, size_t n) { } else { size_t start = 0; size_t len = node->length - n; - if (node->IsSubstring()) { + if (node->IsSubstring()) { start = node->substring()->start; node = node->substring()->child; } @@ -942,18 +942,18 @@ void Cord::RemovePrefix(size_t n) { if (tree == nullptr) { contents_.remove_prefix(n); } else { - auto constexpr method = CordzUpdateTracker::kRemovePrefix; - CordzUpdateScope scope(contents_.cordz_info(), method); - if (tree->IsBtree()) { - CordRep* old = tree; - tree = tree->btree()->SubTree(n, tree->length - n); - CordRep::Unref(old); - } else { - CordRep* newrep = RemovePrefixFrom(tree, n); - CordRep::Unref(tree); - tree = VerifyTree(newrep); - } - contents_.SetTreeOrEmpty(tree, scope); + auto constexpr method = CordzUpdateTracker::kRemovePrefix; + CordzUpdateScope scope(contents_.cordz_info(), method); + if (tree->IsBtree()) { + CordRep* old = tree; + tree = tree->btree()->SubTree(n, tree->length - n); + CordRep::Unref(old); + } else { + CordRep* newrep = RemovePrefixFrom(tree, n); + CordRep::Unref(tree); + tree = VerifyTree(newrep); + } + contents_.SetTreeOrEmpty(tree, scope); } } @@ -965,16 +965,16 @@ void Cord::RemoveSuffix(size_t n) { if (tree == nullptr) { contents_.reduce_size(n); } else { - auto constexpr method = CordzUpdateTracker::kRemoveSuffix; - CordzUpdateScope scope(contents_.cordz_info(), method); - if (tree->IsBtree()) { - tree = CordRepBtree::RemoveSuffix(tree->btree(), n); - } else { - CordRep* newrep = RemoveSuffixFrom(tree, n); - CordRep::Unref(tree); - tree = VerifyTree(newrep); - } - contents_.SetTreeOrEmpty(tree, scope); + auto constexpr method = CordzUpdateTracker::kRemoveSuffix; + CordzUpdateScope scope(contents_.cordz_info(), method); + if (tree->IsBtree()) { + tree = CordRepBtree::RemoveSuffix(tree->btree(), n); + } else { + CordRep* newrep = RemoveSuffixFrom(tree, n); + CordRep::Unref(tree); + tree = VerifyTree(newrep); + } + contents_.SetTreeOrEmpty(tree, scope); } } @@ -1007,8 +1007,8 @@ static CordRep* NewSubRange(CordRep* node, size_t pos, size_t n) { results.push_back(Concat(left, right)); } else if (pos == 0 && n == node->length) { results.push_back(CordRep::Ref(node)); - } else if (!node->IsConcat()) { - if (node->IsSubstring()) { + } else if (!node->IsConcat()) { + if (node->IsSubstring()) { pos += node->substring()->start; node = node->substring()->child; } @@ -1034,18 +1034,18 @@ Cord Cord::Subcord(size_t pos, size_t new_size) const { size_t length = size(); if (pos > length) pos = length; if (new_size > length - pos) new_size = length - pos; - if (new_size == 0) return sub_cord; - + if (new_size == 0) return sub_cord; + CordRep* tree = contents_.tree(); if (tree == nullptr) { // sub_cord is newly constructed, no need to re-zero-out the tail of // contents_ memory. sub_cord.contents_.set_data(contents_.data() + pos, new_size, false); - return sub_cord; - } - - if (new_size <= InlineRep::kMaxInline) { - char* dest = sub_cord.contents_.data_.as_chars(); + return sub_cord; + } + + if (new_size <= InlineRep::kMaxInline) { + char* dest = sub_cord.contents_.data_.as_chars(); Cord::ChunkIterator it = chunk_begin(); it.AdvanceBytes(pos); size_t remaining_size = new_size; @@ -1057,16 +1057,16 @@ Cord Cord::Subcord(size_t pos, size_t new_size) const { } cord_internal::SmallMemmove(dest, it->data(), remaining_size); sub_cord.contents_.set_inline_size(new_size); - return sub_cord; - } - - if (tree->IsBtree()) { - tree = tree->btree()->SubTree(pos, new_size); + return sub_cord; + } + + if (tree->IsBtree()) { + tree = tree->btree()->SubTree(pos, new_size); } else { - tree = NewSubRange(tree, pos, new_size); + tree = NewSubRange(tree, pos, new_size); } - sub_cord.contents_.EmplaceTree(tree, contents_.data_, - CordzUpdateTracker::kSubCord); + sub_cord.contents_.EmplaceTree(tree, contents_.data_, + CordzUpdateTracker::kSubCord); return sub_cord; } @@ -1085,7 +1085,7 @@ class CordForest { CordRep* node = pending.back(); pending.pop_back(); CheckNode(node); - if (ABSL_PREDICT_FALSE(!node->IsConcat())) { + if (ABSL_PREDICT_FALSE(!node->IsConcat())) { AddNode(node); continue; } @@ -1179,7 +1179,7 @@ class CordForest { static void CheckNode(CordRep* node) { ABSL_INTERNAL_CHECK(node->length != 0u, ""); - if (node->IsConcat()) { + if (node->IsConcat()) { ABSL_INTERNAL_CHECK(node->concat()->left != nullptr, ""); ABSL_INTERNAL_CHECK(node->concat()->right != nullptr, ""); ABSL_INTERNAL_CHECK(node->length == (node->concat()->left->length + @@ -1199,7 +1199,7 @@ class CordForest { static CordRep* Rebalance(CordRep* node) { VerifyTree(node); - assert(node->IsConcat()); + assert(node->IsConcat()); if (node->length == 0) { return nullptr; @@ -1249,33 +1249,33 @@ bool ComputeCompareResult<bool>(int memcmp_res) { } // namespace -// Helper routine. Locates the first flat or external chunk of the Cord without -// initializing the iterator, and returns a string_view referencing the data. +// Helper routine. Locates the first flat or external chunk of the Cord without +// initializing the iterator, and returns a string_view referencing the data. inline absl::string_view Cord::InlineRep::FindFlatStartPiece() const { if (!is_tree()) { return absl::string_view(data_.as_chars(), data_.inline_size()); } CordRep* node = tree(); - if (node->IsFlat()) { + if (node->IsFlat()) { return absl::string_view(node->flat()->Data(), node->length); } - if (node->IsExternal()) { + if (node->IsExternal()) { return absl::string_view(node->external()->base, node->length); } - if (node->IsBtree()) { - CordRepBtree* tree = node->btree(); - int height = tree->height(); - while (--height >= 0) { - tree = tree->Edge(CordRepBtree::kFront)->btree(); - } - return tree->Data(tree->begin()); + if (node->IsBtree()) { + CordRepBtree* tree = node->btree(); + int height = tree->height(); + while (--height >= 0) { + tree = tree->Edge(CordRepBtree::kFront)->btree(); + } + return tree->Data(tree->begin()); } // Walk down the left branches until we hit a non-CONCAT node. - while (node->IsConcat()) { + while (node->IsConcat()) { node = node->concat()->left; } @@ -1284,16 +1284,16 @@ inline absl::string_view Cord::InlineRep::FindFlatStartPiece() const { size_t length = node->length; assert(length != 0); - if (node->IsSubstring()) { + if (node->IsSubstring()) { offset = node->substring()->start; node = node->substring()->child; } - if (node->IsFlat()) { + if (node->IsFlat()) { return absl::string_view(node->flat()->Data() + offset, length); } - assert(node->IsExternal() && "Expect FLAT or EXTERNAL node here"); + assert(node->IsExternal() && "Expect FLAT or EXTERNAL node here"); return absl::string_view(node->external()->base + offset, length); } @@ -1487,7 +1487,7 @@ Cord::ChunkIterator& Cord::ChunkIterator::AdvanceStack() { // Walk down the left branches until we hit a non-CONCAT node. Save the // right children to the stack for subsequent traversal. - while (node->IsConcat()) { + while (node->IsConcat()) { stack_of_right_children.push_back(node->concat()->right); node = node->concat()->left; } @@ -1495,15 +1495,15 @@ Cord::ChunkIterator& Cord::ChunkIterator::AdvanceStack() { // Get the child node if we encounter a SUBSTRING. size_t offset = 0; size_t length = node->length; - if (node->IsSubstring()) { + if (node->IsSubstring()) { offset = node->substring()->start; node = node->substring()->child; } - assert(node->IsExternal() || node->IsFlat()); + assert(node->IsExternal() || node->IsFlat()); assert(length != 0); const char* data = - node->IsExternal() ? node->external()->base : node->flat()->Data(); + node->IsExternal() ? node->external()->base : node->flat()->Data(); current_chunk_ = absl::string_view(data + offset, length); current_leaf_ = node; return *this; @@ -1513,7 +1513,7 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) { ABSL_HARDENING_ASSERT(bytes_remaining_ >= n && "Attempted to iterate past `end()`"); Cord subcord; - auto constexpr method = CordzUpdateTracker::kCordReader; + auto constexpr method = CordzUpdateTracker::kCordReader; if (n <= InlineRep::kMaxInline) { // Range to read fits in inline data. Flatten it. @@ -1533,21 +1533,21 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) { return subcord; } - if (btree_reader_) { + if (btree_reader_) { size_t chunk_size = current_chunk_.size(); if (n <= chunk_size && n <= kMaxBytesToCopy) { - subcord = Cord(current_chunk_.substr(0, n), method); - if (n < chunk_size) { - current_chunk_.remove_prefix(n); - } else { - current_chunk_ = btree_reader_.Next(); - } + subcord = Cord(current_chunk_.substr(0, n), method); + if (n < chunk_size) { + current_chunk_.remove_prefix(n); + } else { + current_chunk_ = btree_reader_.Next(); + } } else { - CordRep* rep; - current_chunk_ = btree_reader_.Read(n, chunk_size, rep); - subcord.contents_.EmplaceTree(rep, method); + CordRep* rep; + current_chunk_ = btree_reader_.Read(n, chunk_size, rep); + subcord.contents_.EmplaceTree(rep, method); } - bytes_remaining_ -= n; + bytes_remaining_ -= n; return subcord; } @@ -1556,10 +1556,10 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) { // Range to read is a proper subrange of the current chunk. assert(current_leaf_ != nullptr); CordRep* subnode = CordRep::Ref(current_leaf_); - const char* data = subnode->IsExternal() ? subnode->external()->base - : subnode->flat()->Data(); + const char* data = subnode->IsExternal() ? subnode->external()->base + : subnode->flat()->Data(); subnode = NewSubstring(subnode, current_chunk_.data() - data, n); - subcord.contents_.EmplaceTree(VerifyTree(subnode), method); + subcord.contents_.EmplaceTree(VerifyTree(subnode), method); RemoveChunkPrefix(n); return subcord; } @@ -1569,8 +1569,8 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) { assert(current_leaf_ != nullptr); CordRep* subnode = CordRep::Ref(current_leaf_); if (current_chunk_.size() < subnode->length) { - const char* data = subnode->IsExternal() ? subnode->external()->base - : subnode->flat()->Data(); + const char* data = subnode->IsExternal() ? subnode->external()->base + : subnode->flat()->Data(); subnode = NewSubstring(subnode, current_chunk_.data() - data, current_chunk_.size()); } @@ -1602,13 +1602,13 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) { if (node == nullptr) { // We have reached the end of the Cord. assert(bytes_remaining_ == 0); - subcord.contents_.EmplaceTree(VerifyTree(subnode), method); + subcord.contents_.EmplaceTree(VerifyTree(subnode), method); return subcord; } // Walk down the appropriate branches until we hit a non-CONCAT node. Save the // right children to the stack for subsequent traversal. - while (node->IsConcat()) { + while (node->IsConcat()) { if (node->concat()->left->length > n) { // Push right, descend left. stack_of_right_children.push_back(node->concat()->right); @@ -1625,24 +1625,24 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) { // Get the child node if we encounter a SUBSTRING. size_t offset = 0; size_t length = node->length; - if (node->IsSubstring()) { + if (node->IsSubstring()) { offset = node->substring()->start; node = node->substring()->child; } // Range to read ends with a proper (possibly empty) subrange of the current // chunk. - assert(node->IsExternal() || node->IsFlat()); + assert(node->IsExternal() || node->IsFlat()); assert(length > n); if (n > 0) { subnode = Concat(subnode, NewSubstring(CordRep::Ref(node), offset, n)); } const char* data = - node->IsExternal() ? node->external()->base : node->flat()->Data(); + node->IsExternal() ? node->external()->base : node->flat()->Data(); current_chunk_ = absl::string_view(data + offset + n, length - n); current_leaf_ = node; bytes_remaining_ -= n; - subcord.contents_.EmplaceTree(VerifyTree(subnode), method); + subcord.contents_.EmplaceTree(VerifyTree(subnode), method); return subcord; } @@ -1681,7 +1681,7 @@ void Cord::ChunkIterator::AdvanceBytesSlowPath(size_t n) { // Walk down the appropriate branches until we hit a non-CONCAT node. Save the // right children to the stack for subsequent traversal. - while (node->IsConcat()) { + while (node->IsConcat()) { if (node->concat()->left->length > n) { // Push right, descend left. stack_of_right_children.push_back(node->concat()->right); @@ -1697,15 +1697,15 @@ void Cord::ChunkIterator::AdvanceBytesSlowPath(size_t n) { // Get the child node if we encounter a SUBSTRING. size_t offset = 0; size_t length = node->length; - if (node->IsSubstring()) { + if (node->IsSubstring()) { offset = node->substring()->start; node = node->substring()->child; } - assert(node->IsExternal() || node->IsFlat()); + assert(node->IsExternal() || node->IsFlat()); assert(length > n); const char* data = - node->IsExternal() ? node->external()->base : node->flat()->Data(); + node->IsExternal() ? node->external()->base : node->flat()->Data(); current_chunk_ = absl::string_view(data + offset + n, length - n); current_leaf_ = node; bytes_remaining_ -= n; @@ -1721,15 +1721,15 @@ char Cord::operator[](size_t i) const { while (true) { assert(rep != nullptr); assert(offset < rep->length); - if (rep->IsFlat()) { + if (rep->IsFlat()) { // Get the "i"th character directly from the flat array. return rep->flat()->Data()[offset]; - } else if (rep->IsBtree()) { - return rep->btree()->GetCharacter(offset); - } else if (rep->IsExternal()) { + } else if (rep->IsBtree()) { + return rep->btree()->GetCharacter(offset); + } else if (rep->IsExternal()) { // Get the "i"th character from the external array. return rep->external()->base[offset]; - } else if (rep->IsConcat()) { + } else if (rep->IsConcat()) { // Recursively branch to the side of the concatenation that the "i"th // character is on. size_t left_length = rep->concat()->left->length; @@ -1741,7 +1741,7 @@ char Cord::operator[](size_t i) const { } } else { // This must be a substring a node, so bypass it to get to the child. - assert(rep->IsSubstring()); + assert(rep->IsSubstring()); offset += rep->substring()->start; rep = rep->substring()->child; } @@ -1749,7 +1749,7 @@ char Cord::operator[](size_t i) const { } absl::string_view Cord::FlattenSlowPath() { - assert(contents_.is_tree()); + assert(contents_.is_tree()); size_t total_size = size(); CordRep* new_rep; char* new_buffer; @@ -1770,35 +1770,35 @@ absl::string_view Cord::FlattenSlowPath() { s.size()); }); } - CordzUpdateScope scope(contents_.cordz_info(), CordzUpdateTracker::kFlatten); - CordRep::Unref(contents_.as_tree()); - contents_.SetTree(new_rep, scope); + CordzUpdateScope scope(contents_.cordz_info(), CordzUpdateTracker::kFlatten); + CordRep::Unref(contents_.as_tree()); + contents_.SetTree(new_rep, scope); return absl::string_view(new_buffer, total_size); } /* static */ bool Cord::GetFlatAux(CordRep* rep, absl::string_view* fragment) { assert(rep != nullptr); - if (rep->IsFlat()) { + if (rep->IsFlat()) { *fragment = absl::string_view(rep->flat()->Data(), rep->length); return true; - } else if (rep->IsExternal()) { + } else if (rep->IsExternal()) { *fragment = absl::string_view(rep->external()->base, rep->length); return true; - } else if (rep->IsBtree()) { - return rep->btree()->IsFlat(fragment); - } else if (rep->IsSubstring()) { + } else if (rep->IsBtree()) { + return rep->btree()->IsFlat(fragment); + } else if (rep->IsSubstring()) { CordRep* child = rep->substring()->child; - if (child->IsFlat()) { + if (child->IsFlat()) { *fragment = absl::string_view( child->flat()->Data() + rep->substring()->start, rep->length); return true; - } else if (child->IsExternal()) { + } else if (child->IsExternal()) { *fragment = absl::string_view( child->external()->base + rep->substring()->start, rep->length); return true; - } else if (child->IsBtree()) { - return child->btree()->IsFlat(rep->substring()->start, rep->length, - fragment); + } else if (child->IsBtree()) { + return child->btree()->IsFlat(rep->substring()->start, rep->length, + fragment); } } return false; @@ -1807,7 +1807,7 @@ absl::string_view Cord::FlattenSlowPath() { /* static */ void Cord::ForEachChunkAux( absl::cord_internal::CordRep* rep, absl::FunctionRef<void(absl::string_view)> callback) { - if (rep->IsBtree()) { + if (rep->IsBtree()) { ChunkIterator it(rep), end; while (it != end) { callback(*it); @@ -1823,7 +1823,7 @@ absl::string_view Cord::FlattenSlowPath() { absl::cord_internal::CordRep* stack[stack_max]; absl::cord_internal::CordRep* current_node = rep; while (true) { - if (current_node->IsConcat()) { + if (current_node->IsConcat()) { if (stack_pos == stack_max) { // There's no more room on our stack array to add another right branch, // and the idea is to avoid allocations, so call this function @@ -1870,29 +1870,29 @@ static void DumpNode(CordRep* rep, bool include_data, std::ostream* os, *os << "]"; *os << " " << (IsRootBalanced(rep) ? 'b' : 'u'); *os << " " << std::setw(indent) << ""; - if (rep->IsConcat()) { + if (rep->IsConcat()) { *os << "CONCAT depth=" << Depth(rep) << "\n"; indent += kIndentStep; indents.push_back(indent); stack.push_back(rep->concat()->right); rep = rep->concat()->left; - } else if (rep->IsSubstring()) { + } else if (rep->IsSubstring()) { *os << "SUBSTRING @ " << rep->substring()->start << "\n"; indent += kIndentStep; rep = rep->substring()->child; } else { // Leaf or ring - if (rep->IsExternal()) { + if (rep->IsExternal()) { *os << "EXTERNAL ["; if (include_data) *os << absl::CEscape(std::string(rep->external()->base, rep->length)); *os << "]\n"; - } else if (rep->IsFlat()) { - *os << "FLAT cap=" << rep->flat()->Capacity() << " ["; + } else if (rep->IsFlat()) { + *os << "FLAT cap=" << rep->flat()->Capacity() << " ["; if (include_data) *os << absl::CEscape(std::string(rep->flat()->Data(), rep->length)); *os << "]\n"; } else { - CordRepBtree::Dump(rep, /*label=*/ "", include_data, *os); + CordRepBtree::Dump(rep, /*label=*/ "", include_data, *os); } if (stack.empty()) break; rep = stack.back(); @@ -1924,7 +1924,7 @@ static bool VerifyNode(CordRep* root, CordRep* start_node, ABSL_INTERNAL_CHECK(node->length != 0, ReportError(root, node)); } - if (node->IsConcat()) { + if (node->IsConcat()) { ABSL_INTERNAL_CHECK(node->concat()->left != nullptr, ReportError(root, node)); ABSL_INTERNAL_CHECK(node->concat()->right != nullptr, @@ -1936,13 +1936,13 @@ static bool VerifyNode(CordRep* root, CordRep* start_node, worklist.push_back(node->concat()->right); worklist.push_back(node->concat()->left); } - } else if (node->IsFlat()) { - ABSL_INTERNAL_CHECK(node->length <= node->flat()->Capacity(), - ReportError(root, node)); - } else if (node->IsExternal()) { + } else if (node->IsFlat()) { + ABSL_INTERNAL_CHECK(node->length <= node->flat()->Capacity(), + ReportError(root, node)); + } else if (node->IsExternal()) { ABSL_INTERNAL_CHECK(node->external()->base != nullptr, ReportError(root, node)); - } else if (node->IsSubstring()) { + } else if (node->IsSubstring()) { ABSL_INTERNAL_CHECK( node->substring()->start < node->substring()->child->length, ReportError(root, node)); @@ -1971,7 +1971,7 @@ static bool VerifyNode(CordRep* root, CordRep* start_node, while (true) { const CordRep* next_node = nullptr; - if (cur_node->IsConcat()) { + if (cur_node->IsConcat()) { total_mem_usage += sizeof(CordRepConcat); const CordRep* left = cur_node->concat()->left; if (!RepMemoryUsageLeaf(left, &total_mem_usage)) { @@ -1985,21 +1985,21 @@ static bool VerifyNode(CordRep* root, CordRep* start_node, } next_node = right; } - } else if (cur_node->IsBtree()) { - total_mem_usage += sizeof(CordRepBtree); - const CordRepBtree* node = cur_node->btree(); - if (node->height() == 0) { - for (const CordRep* edge : node->Edges()) { - RepMemoryUsageDataEdge(edge, &total_mem_usage); - } - } else { - for (const CordRep* edge : node->Edges()) { - tree_stack.push_back(edge); - } - } + } else if (cur_node->IsBtree()) { + total_mem_usage += sizeof(CordRepBtree); + const CordRepBtree* node = cur_node->btree(); + if (node->height() == 0) { + for (const CordRep* edge : node->Edges()) { + RepMemoryUsageDataEdge(edge, &total_mem_usage); + } + } else { + for (const CordRep* edge : node->Edges()) { + tree_stack.push_back(edge); + } + } } else { // Since cur_node is not a leaf or a concat node it must be a substring. - assert(cur_node->IsSubstring()); + assert(cur_node->IsSubstring()); total_mem_usage += sizeof(CordRepSubstring); next_node = cur_node->substring()->child; if (RepMemoryUsageLeaf(next_node, &total_mem_usage)) { diff --git a/contrib/restricted/abseil-cpp/absl/strings/cord.h b/contrib/restricted/abseil-cpp/absl/strings/cord.h index f0a1991471..fafe72d8f9 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/cord.h +++ b/contrib/restricted/abseil-cpp/absl/strings/cord.h @@ -70,7 +70,7 @@ #include <string> #include <type_traits> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/base/internal/endian.h" #include "absl/base/internal/per_thread_tls.h" #include "absl/base/macros.h" @@ -79,14 +79,14 @@ #include "absl/functional/function_ref.h" #include "absl/meta/type_traits.h" #include "absl/strings/internal/cord_internal.h" -#include "absl/strings/internal/cord_rep_btree.h" -#include "absl/strings/internal/cord_rep_btree_reader.h" +#include "absl/strings/internal/cord_rep_btree.h" +#include "absl/strings/internal/cord_rep_btree_reader.h" #include "absl/strings/internal/cord_rep_ring.h" -#include "absl/strings/internal/cordz_functions.h" -#include "absl/strings/internal/cordz_info.h" -#include "absl/strings/internal/cordz_statistics.h" -#include "absl/strings/internal/cordz_update_scope.h" -#include "absl/strings/internal/cordz_update_tracker.h" +#include "absl/strings/internal/cordz_functions.h" +#include "absl/strings/internal/cordz_info.h" +#include "absl/strings/internal/cordz_statistics.h" +#include "absl/strings/internal/cordz_update_scope.h" +#include "absl/strings/internal/cordz_update_tracker.h" #include "absl/strings/internal/resize_uninitialized.h" #include "absl/strings/internal/string_constant.h" #include "absl/strings/string_view.h" @@ -256,7 +256,7 @@ class Cord { // swap() // // Swaps the contents of two Cords. - friend void swap(Cord& x, Cord& y) noexcept { x.swap(y); } + friend void swap(Cord& x, Cord& y) noexcept { x.swap(y); } // Cord::size() // @@ -369,8 +369,8 @@ class Cord { private: using CordRep = absl::cord_internal::CordRep; - using CordRepBtree = absl::cord_internal::CordRepBtree; - using CordRepBtreeReader = absl::cord_internal::CordRepBtreeReader; + using CordRepBtree = absl::cord_internal::CordRepBtree; + using CordRepBtreeReader = absl::cord_internal::CordRepBtreeReader; // Stack of right children of concat nodes that we have to visit. // Keep this at the end of the structure to avoid cache-thrashing. @@ -396,9 +396,9 @@ class Cord { // Stack specific operator++ ChunkIterator& AdvanceStack(); - // Btree specific operator++ - ChunkIterator& AdvanceBtree(); - void AdvanceBytesBtree(size_t n); + // Btree specific operator++ + ChunkIterator& AdvanceBtree(); + void AdvanceBytesBtree(size_t n); // Iterates `n` bytes, where `n` is expected to be greater than or equal to // `current_chunk_.size()`. @@ -414,8 +414,8 @@ class Cord { // The number of bytes left in the `Cord` over which we are iterating. size_t bytes_remaining_ = 0; - // Cord reader for cord btrees. Empty if not traversing a btree. - CordRepBtreeReader btree_reader_; + // Cord reader for cord btrees. Empty if not traversing a btree. + CordRepBtreeReader btree_reader_; // See 'Stack' alias definition. Stack stack_of_right_children_; @@ -460,16 +460,16 @@ class Cord { // `Cord::chunk_begin()` and `Cord::chunk_end()`. class ChunkRange { public: - // Fulfill minimum c++ container requirements [container.requirements] - // Theses (partial) container type definitions allow ChunkRange to be used - // in various utilities expecting a subset of [container.requirements]. - // For example, the below enables using `::testing::ElementsAre(...)` - using value_type = absl::string_view; - using reference = value_type&; - using const_reference = const value_type&; - using iterator = ChunkIterator; - using const_iterator = ChunkIterator; - + // Fulfill minimum c++ container requirements [container.requirements] + // Theses (partial) container type definitions allow ChunkRange to be used + // in various utilities expecting a subset of [container.requirements]. + // For example, the below enables using `::testing::ElementsAre(...)` + using value_type = absl::string_view; + using reference = value_type&; + using const_reference = const value_type&; + using iterator = ChunkIterator; + using const_iterator = ChunkIterator; + explicit ChunkRange(const Cord* cord) : cord_(cord) {} ChunkIterator begin() const; @@ -601,16 +601,16 @@ class Cord { // `Cord::char_begin()` and `Cord::char_end()`. class CharRange { public: - // Fulfill minimum c++ container requirements [container.requirements] - // Theses (partial) container type definitions allow CharRange to be used - // in various utilities expecting a subset of [container.requirements]. - // For example, the below enables using `::testing::ElementsAre(...)` - using value_type = char; - using reference = value_type&; - using const_reference = const value_type&; - using iterator = CharIterator; - using const_iterator = CharIterator; - + // Fulfill minimum c++ container requirements [container.requirements] + // Theses (partial) container type definitions allow CharRange to be used + // in various utilities expecting a subset of [container.requirements]. + // For example, the below enables using `::testing::ElementsAre(...)` + using value_type = char; + using reference = value_type&; + using const_reference = const value_type&; + using iterator = CharIterator; + using const_iterator = CharIterator; + explicit CharRange(const Cord* cord) : cord_(cord) {} CharIterator begin() const; @@ -689,24 +689,24 @@ class Cord { explicit constexpr Cord(strings_internal::StringConstant<T>); private: - using CordRep = absl::cord_internal::CordRep; - using CordRepFlat = absl::cord_internal::CordRepFlat; - using CordzInfo = cord_internal::CordzInfo; - using CordzUpdateScope = cord_internal::CordzUpdateScope; - using CordzUpdateTracker = cord_internal::CordzUpdateTracker; - using InlineData = cord_internal::InlineData; - using MethodIdentifier = CordzUpdateTracker::MethodIdentifier; - - // Creates a cord instance with `method` representing the originating - // public API call causing the cord to be created. - explicit Cord(absl::string_view src, MethodIdentifier method); - + using CordRep = absl::cord_internal::CordRep; + using CordRepFlat = absl::cord_internal::CordRepFlat; + using CordzInfo = cord_internal::CordzInfo; + using CordzUpdateScope = cord_internal::CordzUpdateScope; + using CordzUpdateTracker = cord_internal::CordzUpdateTracker; + using InlineData = cord_internal::InlineData; + using MethodIdentifier = CordzUpdateTracker::MethodIdentifier; + + // Creates a cord instance with `method` representing the originating + // public API call causing the cord to be created. + explicit Cord(absl::string_view src, MethodIdentifier method); + friend class CordTestPeer; friend bool operator==(const Cord& lhs, const Cord& rhs); friend bool operator==(const Cord& lhs, absl::string_view rhs); - friend const CordzInfo* GetCordzInfoForTesting(const Cord& cord); - + friend const CordzInfo* GetCordzInfoForTesting(const Cord& cord); + // Calls the provided function once for each cord chunk, in order. Unlike // Chunks(), this API will not allocate memory. void ForEachChunk(absl::FunctionRef<void(absl::string_view)>) const; @@ -726,7 +726,7 @@ class Cord { static_assert(kMaxInline >= sizeof(absl::cord_internal::CordRep*), ""); constexpr InlineRep() : data_() {} - explicit InlineRep(InlineData::DefaultInitType init) : data_(init) {} + explicit InlineRep(InlineData::DefaultInitType init) : data_(init) {} InlineRep(const InlineRep& src); InlineRep(InlineRep&& src); InlineRep& operator=(const InlineRep& src); @@ -740,60 +740,60 @@ class Cord { const char* data() const; // Returns nullptr if holding pointer void set_data(const char* data, size_t n, bool nullify_tail); // Discards pointer, if any - char* set_data(size_t n); // Write data to the result + char* set_data(size_t n); // Write data to the result // Returns nullptr if holding bytes absl::cord_internal::CordRep* tree() const; absl::cord_internal::CordRep* as_tree() const; // Returns non-null iff was holding a pointer absl::cord_internal::CordRep* clear(); // Converts to pointer if necessary. - void reduce_size(size_t n); // REQUIRES: holding data + void reduce_size(size_t n); // REQUIRES: holding data void remove_prefix(size_t n); // REQUIRES: holding data - void AppendArray(absl::string_view src, MethodIdentifier method); + void AppendArray(absl::string_view src, MethodIdentifier method); absl::string_view FindFlatStartPiece() const; - - // Creates a CordRepFlat instance from the current inlined data with `extra' - // bytes of desired additional capacity. - CordRepFlat* MakeFlatWithExtraCapacity(size_t extra); - - // Sets the tree value for this instance. `rep` must not be null. - // Requires the current instance to hold a tree, and a lock to be held on - // any CordzInfo referenced by this instance. The latter is enforced through - // the CordzUpdateScope argument. If the current instance is sampled, then - // the CordzInfo instance is updated to reference the new `rep` value. - void SetTree(CordRep* rep, const CordzUpdateScope& scope); - - // Identical to SetTree(), except that `rep` is allowed to be null, in - // which case the current instance is reset to an empty value. - void SetTreeOrEmpty(CordRep* rep, const CordzUpdateScope& scope); - - // Sets the tree value for this instance, and randomly samples this cord. - // This function disregards existing contents in `data_`, and should be - // called when a Cord is 'promoted' from an 'uninitialized' or 'inlined' - // value to a non-inlined (tree / ring) value. - void EmplaceTree(CordRep* rep, MethodIdentifier method); - - // Identical to EmplaceTree, except that it copies the parent stack from - // the provided `parent` data if the parent is sampled. - void EmplaceTree(CordRep* rep, const InlineData& parent, - MethodIdentifier method); - - // Commits the change of a newly created, or updated `rep` root value into - // this cord. `old_rep` indicates the old (inlined or tree) value of the - // cord, and determines if the commit invokes SetTree() or EmplaceTree(). - void CommitTree(const CordRep* old_rep, CordRep* rep, - const CordzUpdateScope& scope, MethodIdentifier method); - - void AppendTreeToInlined(CordRep* tree, MethodIdentifier method); - void AppendTreeToTree(CordRep* tree, MethodIdentifier method); - void AppendTree(CordRep* tree, MethodIdentifier method); - void PrependTreeToInlined(CordRep* tree, MethodIdentifier method); - void PrependTreeToTree(CordRep* tree, MethodIdentifier method); - void PrependTree(CordRep* tree, MethodIdentifier method); - - template <bool has_length> - void GetAppendRegion(char** region, size_t* size, size_t length); - + + // Creates a CordRepFlat instance from the current inlined data with `extra' + // bytes of desired additional capacity. + CordRepFlat* MakeFlatWithExtraCapacity(size_t extra); + + // Sets the tree value for this instance. `rep` must not be null. + // Requires the current instance to hold a tree, and a lock to be held on + // any CordzInfo referenced by this instance. The latter is enforced through + // the CordzUpdateScope argument. If the current instance is sampled, then + // the CordzInfo instance is updated to reference the new `rep` value. + void SetTree(CordRep* rep, const CordzUpdateScope& scope); + + // Identical to SetTree(), except that `rep` is allowed to be null, in + // which case the current instance is reset to an empty value. + void SetTreeOrEmpty(CordRep* rep, const CordzUpdateScope& scope); + + // Sets the tree value for this instance, and randomly samples this cord. + // This function disregards existing contents in `data_`, and should be + // called when a Cord is 'promoted' from an 'uninitialized' or 'inlined' + // value to a non-inlined (tree / ring) value. + void EmplaceTree(CordRep* rep, MethodIdentifier method); + + // Identical to EmplaceTree, except that it copies the parent stack from + // the provided `parent` data if the parent is sampled. + void EmplaceTree(CordRep* rep, const InlineData& parent, + MethodIdentifier method); + + // Commits the change of a newly created, or updated `rep` root value into + // this cord. `old_rep` indicates the old (inlined or tree) value of the + // cord, and determines if the commit invokes SetTree() or EmplaceTree(). + void CommitTree(const CordRep* old_rep, CordRep* rep, + const CordzUpdateScope& scope, MethodIdentifier method); + + void AppendTreeToInlined(CordRep* tree, MethodIdentifier method); + void AppendTreeToTree(CordRep* tree, MethodIdentifier method); + void AppendTree(CordRep* tree, MethodIdentifier method); + void PrependTreeToInlined(CordRep* tree, MethodIdentifier method); + void PrependTreeToTree(CordRep* tree, MethodIdentifier method); + void PrependTree(CordRep* tree, MethodIdentifier method); + + template <bool has_length> + void GetAppendRegion(char** region, size_t* size, size_t length); + bool IsSame(const InlineRep& other) const { return memcmp(&data_, &other.data_, sizeof(data_)) == 0; } @@ -849,8 +849,8 @@ class Cord { friend class Cord; void AssignSlow(const InlineRep& src); - // Unrefs the tree and stops profiling. - void UnrefTree(); + // Unrefs the tree and stops profiling. + void UnrefTree(); void ResetToEmpty() { data_ = {}; } @@ -901,14 +901,14 @@ class Cord { template <typename C> void AppendImpl(C&& src); - // Prepends the provided data to this instance. `method` contains the public - // API method for this action which is tracked for Cordz sampling purposes. - void PrependArray(absl::string_view src, MethodIdentifier method); - - // Assigns the value in 'src' to this instance, 'stealing' its contents. - // Requires src.length() > kMaxBytesToCopy. - Cord& AssignLargeString(std::string&& src); - + // Prepends the provided data to this instance. `method` contains the public + // API method for this action which is tracked for Cordz sampling purposes. + void PrependArray(absl::string_view src, MethodIdentifier method); + + // Assigns the value in 'src' to this instance, 'stealing' its contents. + // Requires src.length() > kMaxBytesToCopy. + Cord& AssignLargeString(std::string&& src); + // Helper for AbslHashValue(). template <typename H> H HashFragmented(H hash_state) const { @@ -1011,11 +1011,11 @@ inline CordRep* NewExternalRep(absl::string_view data, template <typename Releaser> Cord MakeCordFromExternal(absl::string_view data, Releaser&& releaser) { Cord cord; - if (auto* rep = ::absl::cord_internal::NewExternalRep( - data, std::forward<Releaser>(releaser))) { - cord.contents_.EmplaceTree(rep, - Cord::MethodIdentifier::kMakeCordFromExternal); - } + if (auto* rep = ::absl::cord_internal::NewExternalRep( + data, std::forward<Releaser>(releaser))) { + cord.contents_.EmplaceTree(rep, + Cord::MethodIdentifier::kMakeCordFromExternal); + } return cord; } @@ -1023,16 +1023,16 @@ constexpr Cord::InlineRep::InlineRep(cord_internal::InlineData data) : data_(data) {} inline Cord::InlineRep::InlineRep(const Cord::InlineRep& src) - : data_(InlineData::kDefaultInit) { - if (CordRep* tree = src.tree()) { - EmplaceTree(CordRep::Ref(tree), src.data_, - CordzUpdateTracker::kConstructorCord); - } else { - data_ = src.data_; + : data_(InlineData::kDefaultInit) { + if (CordRep* tree = src.tree()) { + EmplaceTree(CordRep::Ref(tree), src.data_, + CordzUpdateTracker::kConstructorCord); + } else { + data_ = src.data_; } } -inline Cord::InlineRep::InlineRep(Cord::InlineRep&& src) : data_(src.data_) { +inline Cord::InlineRep::InlineRep(Cord::InlineRep&& src) : data_(src.data_) { src.ResetToEmpty(); } @@ -1051,7 +1051,7 @@ inline Cord::InlineRep& Cord::InlineRep::operator=(const Cord::InlineRep& src) { inline Cord::InlineRep& Cord::InlineRep::operator=( Cord::InlineRep&& src) noexcept { if (is_tree()) { - UnrefTree(); + UnrefTree(); } data_ = src.data_; src.ResetToEmpty(); @@ -1088,62 +1088,62 @@ inline size_t Cord::InlineRep::size() const { return is_tree() ? as_tree()->length : inline_size(); } -inline cord_internal::CordRepFlat* Cord::InlineRep::MakeFlatWithExtraCapacity( - size_t extra) { - static_assert(cord_internal::kMinFlatLength >= sizeof(data_), ""); - size_t len = data_.inline_size(); - auto* result = CordRepFlat::New(len + extra); - result->length = len; - memcpy(result->Data(), data_.as_chars(), sizeof(data_)); - return result; -} - -inline void Cord::InlineRep::EmplaceTree(CordRep* rep, - MethodIdentifier method) { - assert(rep); - data_.make_tree(rep); - CordzInfo::MaybeTrackCord(data_, method); -} - -inline void Cord::InlineRep::EmplaceTree(CordRep* rep, const InlineData& parent, - MethodIdentifier method) { - data_.make_tree(rep); - CordzInfo::MaybeTrackCord(data_, parent, method); -} - -inline void Cord::InlineRep::SetTree(CordRep* rep, - const CordzUpdateScope& scope) { - assert(rep); - assert(data_.is_tree()); - data_.set_tree(rep); - scope.SetCordRep(rep); -} - -inline void Cord::InlineRep::SetTreeOrEmpty(CordRep* rep, - const CordzUpdateScope& scope) { - assert(data_.is_tree()); - if (rep) { - data_.set_tree(rep); +inline cord_internal::CordRepFlat* Cord::InlineRep::MakeFlatWithExtraCapacity( + size_t extra) { + static_assert(cord_internal::kMinFlatLength >= sizeof(data_), ""); + size_t len = data_.inline_size(); + auto* result = CordRepFlat::New(len + extra); + result->length = len; + memcpy(result->Data(), data_.as_chars(), sizeof(data_)); + return result; +} + +inline void Cord::InlineRep::EmplaceTree(CordRep* rep, + MethodIdentifier method) { + assert(rep); + data_.make_tree(rep); + CordzInfo::MaybeTrackCord(data_, method); +} + +inline void Cord::InlineRep::EmplaceTree(CordRep* rep, const InlineData& parent, + MethodIdentifier method) { + data_.make_tree(rep); + CordzInfo::MaybeTrackCord(data_, parent, method); +} + +inline void Cord::InlineRep::SetTree(CordRep* rep, + const CordzUpdateScope& scope) { + assert(rep); + assert(data_.is_tree()); + data_.set_tree(rep); + scope.SetCordRep(rep); +} + +inline void Cord::InlineRep::SetTreeOrEmpty(CordRep* rep, + const CordzUpdateScope& scope) { + assert(data_.is_tree()); + if (rep) { + data_.set_tree(rep); } else { - data_ = {}; + data_ = {}; } - scope.SetCordRep(rep); + scope.SetCordRep(rep); } -inline void Cord::InlineRep::CommitTree(const CordRep* old_rep, CordRep* rep, - const CordzUpdateScope& scope, - MethodIdentifier method) { - if (old_rep) { - SetTree(rep, scope); - } else { - EmplaceTree(rep, method); +inline void Cord::InlineRep::CommitTree(const CordRep* old_rep, CordRep* rep, + const CordzUpdateScope& scope, + MethodIdentifier method) { + if (old_rep) { + SetTree(rep, scope); + } else { + EmplaceTree(rep, method); } } inline absl::cord_internal::CordRep* Cord::InlineRep::clear() { - if (is_tree()) { - CordzInfo::MaybeUntrackCord(cordz_info()); - } + if (is_tree()) { + CordzInfo::MaybeUntrackCord(cordz_info()); + } absl::cord_internal::CordRep* result = tree(); ResetToEmpty(); return result; @@ -1158,9 +1158,9 @@ inline void Cord::InlineRep::CopyToArray(char* dst) const { constexpr inline Cord::Cord() noexcept {} -inline Cord::Cord(absl::string_view src) - : Cord(src, CordzUpdateTracker::kConstructorString) {} - +inline Cord::Cord(absl::string_view src) + : Cord(src, CordzUpdateTracker::kConstructorString) {} + template <typename T> constexpr Cord::Cord(strings_internal::StringConstant<T>) : contents_(strings_internal::StringConstant<T>::value.size() <= @@ -1176,15 +1176,15 @@ inline Cord& Cord::operator=(const Cord& x) { return *this; } -template <typename T, Cord::EnableIfString<T>> -Cord& Cord::operator=(T&& src) { - if (src.size() <= cord_internal::kMaxBytesToCopy) { - return operator=(absl::string_view(src)); - } else { - return AssignLargeString(std::forward<T>(src)); - } -} - +template <typename T, Cord::EnableIfString<T>> +Cord& Cord::operator=(T&& src) { + if (src.size() <= cord_internal::kMaxBytesToCopy) { + return operator=(absl::string_view(src)); + } else { + return AssignLargeString(std::forward<T>(src)); + } +} + inline Cord::Cord(const Cord& src) : contents_(src.contents_) {} inline Cord::Cord(Cord&& src) noexcept : contents_(std::move(src.contents_)) {} @@ -1241,13 +1241,13 @@ inline absl::string_view Cord::Flatten() { } inline void Cord::Append(absl::string_view src) { - contents_.AppendArray(src, CordzUpdateTracker::kAppendString); -} - -inline void Cord::Prepend(absl::string_view src) { - PrependArray(src, CordzUpdateTracker::kPrependString); + contents_.AppendArray(src, CordzUpdateTracker::kAppendString); } +inline void Cord::Prepend(absl::string_view src) { + PrependArray(src, CordzUpdateTracker::kPrependString); +} + extern template void Cord::Append(std::string&& src); extern template void Cord::Prepend(std::string&& src); @@ -1274,8 +1274,8 @@ inline bool Cord::StartsWith(absl::string_view rhs) const { } inline void Cord::ChunkIterator::InitTree(cord_internal::CordRep* tree) { - if (tree->tag == cord_internal::BTREE) { - current_chunk_ = btree_reader_.Init(tree->btree()); + if (tree->tag == cord_internal::BTREE) { + current_chunk_ = btree_reader_.Init(tree->btree()); return; } @@ -1298,20 +1298,20 @@ inline Cord::ChunkIterator::ChunkIterator(const Cord* cord) } } -inline Cord::ChunkIterator& Cord::ChunkIterator::AdvanceBtree() { - current_chunk_ = btree_reader_.Next(); +inline Cord::ChunkIterator& Cord::ChunkIterator::AdvanceBtree() { + current_chunk_ = btree_reader_.Next(); return *this; } -inline void Cord::ChunkIterator::AdvanceBytesBtree(size_t n) { +inline void Cord::ChunkIterator::AdvanceBytesBtree(size_t n) { assert(n >= current_chunk_.size()); bytes_remaining_ -= n; if (bytes_remaining_) { if (n == current_chunk_.size()) { - current_chunk_ = btree_reader_.Next(); + current_chunk_ = btree_reader_.Next(); } else { - size_t offset = btree_reader_.length() - bytes_remaining_; - current_chunk_ = btree_reader_.Seek(offset); + size_t offset = btree_reader_.length() - bytes_remaining_; + current_chunk_ = btree_reader_.Seek(offset); } } else { current_chunk_ = {}; @@ -1324,7 +1324,7 @@ inline Cord::ChunkIterator& Cord::ChunkIterator::operator++() { assert(bytes_remaining_ >= current_chunk_.size()); bytes_remaining_ -= current_chunk_.size(); if (bytes_remaining_ > 0) { - return btree_reader_ ? AdvanceBtree() : AdvanceStack(); + return btree_reader_ ? AdvanceBtree() : AdvanceStack(); } else { current_chunk_ = {}; } @@ -1366,7 +1366,7 @@ inline void Cord::ChunkIterator::AdvanceBytes(size_t n) { if (ABSL_PREDICT_TRUE(n < current_chunk_.size())) { RemoveChunkPrefix(n); } else if (n != 0) { - btree_reader_ ? AdvanceBytesBtree(n) : AdvanceBytesSlowPath(n); + btree_reader_ ? AdvanceBytesBtree(n) : AdvanceBytesSlowPath(n); } } @@ -1466,8 +1466,8 @@ inline bool operator==(const Cord& lhs, const Cord& rhs) { } inline bool operator!=(const Cord& x, const Cord& y) { return !(x == y); } -inline bool operator<(const Cord& x, const Cord& y) { return x.Compare(y) < 0; } -inline bool operator>(const Cord& x, const Cord& y) { return x.Compare(y) > 0; } +inline bool operator<(const Cord& x, const Cord& y) { return x.Compare(y) < 0; } +inline bool operator>(const Cord& x, const Cord& y) { return x.Compare(y) > 0; } inline bool operator<=(const Cord& x, const Cord& y) { return x.Compare(y) <= 0; } diff --git a/contrib/restricted/abseil-cpp/absl/strings/cord/ya.make b/contrib/restricted/abseil-cpp/absl/strings/cord/ya.make index b3654c86d0..cfa0a1cdc4 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/cord/ya.make +++ b/contrib/restricted/abseil-cpp/absl/strings/cord/ya.make @@ -11,30 +11,30 @@ LICENSE(Apache-2.0) PEERDIR( contrib/restricted/abseil-cpp/absl/algorithm contrib/restricted/abseil-cpp/absl/base - contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc contrib/restricted/abseil-cpp/absl/base/internal/raw_logging contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity contrib/restricted/abseil-cpp/absl/container - contrib/restricted/abseil-cpp/absl/debugging - contrib/restricted/abseil-cpp/absl/debugging/stacktrace - contrib/restricted/abseil-cpp/absl/debugging/symbolize - contrib/restricted/abseil-cpp/absl/demangle + contrib/restricted/abseil-cpp/absl/debugging + contrib/restricted/abseil-cpp/absl/debugging/stacktrace + contrib/restricted/abseil-cpp/absl/debugging/symbolize + contrib/restricted/abseil-cpp/absl/demangle contrib/restricted/abseil-cpp/absl/functional contrib/restricted/abseil-cpp/absl/numeric - contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info - contrib/restricted/abseil-cpp/absl/synchronization - contrib/restricted/abseil-cpp/absl/synchronization/internal - contrib/restricted/abseil-cpp/absl/time - contrib/restricted/abseil-cpp/absl/time/civil_time - contrib/restricted/abseil-cpp/absl/time/time_zone + contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info + contrib/restricted/abseil-cpp/absl/synchronization + contrib/restricted/abseil-cpp/absl/synchronization/internal + contrib/restricted/abseil-cpp/absl/time + contrib/restricted/abseil-cpp/absl/time/civil_time + contrib/restricted/abseil-cpp/absl/time/time_zone contrib/restricted/abseil-cpp/absl/types contrib/restricted/abseil-cpp/absl/types/bad_optional_access contrib/restricted/abseil-cpp/absl/utility diff --git a/contrib/restricted/abseil-cpp/absl/strings/cord_test_helpers.h b/contrib/restricted/abseil-cpp/absl/strings/cord_test_helpers.h index 31a1dc8980..485f1f1d0e 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/cord_test_helpers.h +++ b/contrib/restricted/abseil-cpp/absl/strings/cord_test_helpers.h @@ -17,73 +17,73 @@ #ifndef ABSL_STRINGS_CORD_TEST_HELPERS_H_ #define ABSL_STRINGS_CORD_TEST_HELPERS_H_ -#include <cstdint> -#include <iostream> -#include <string> - -#include "absl/base/config.h" +#include <cstdint> +#include <iostream> +#include <string> + +#include "absl/base/config.h" #include "absl/strings/cord.h" -#include "absl/strings/internal/cord_internal.h" -#include "absl/strings/string_view.h" +#include "absl/strings/internal/cord_internal.h" +#include "absl/strings/string_view.h" namespace absl { ABSL_NAMESPACE_BEGIN -// Cord sizes relevant for testing -enum class TestCordSize { - // An empty value - kEmpty = 0, - - // An inlined string value - kInlined = cord_internal::kMaxInline / 2 + 1, - - // 'Well known' SSO lengths (excluding terminating zero). - // libstdcxx has a maximum SSO of 15, libc++ has a maximum SSO of 22. - kStringSso1 = 15, - kStringSso2 = 22, - - // A string value which is too large to fit in inlined data, but small enough - // such that Cord prefers copying the value if possible, i.e.: not stealing - // std::string inputs, or referencing existing CordReps on Append, etc. - kSmall = cord_internal::kMaxBytesToCopy / 2 + 1, - - // A string value large enough that Cord prefers to reference or steal from - // existing inputs rather than copying contents of the input. - kMedium = cord_internal::kMaxFlatLength / 2 + 1, - - // A string value large enough to cause it to be stored in mutliple flats. - kLarge = cord_internal::kMaxFlatLength * 4 -}; - -// To string helper -inline absl::string_view ToString(TestCordSize size) { - switch (size) { - case TestCordSize::kEmpty: - return "Empty"; - case TestCordSize::kInlined: - return "Inlined"; - case TestCordSize::kSmall: - return "Small"; - case TestCordSize::kStringSso1: - return "StringSso1"; - case TestCordSize::kStringSso2: - return "StringSso2"; - case TestCordSize::kMedium: - return "Medium"; - case TestCordSize::kLarge: - return "Large"; - } - return "???"; -} - -// Returns the length matching the specified size -inline size_t Length(TestCordSize size) { return static_cast<size_t>(size); } - -// Stream output helper -inline std::ostream& operator<<(std::ostream& stream, TestCordSize size) { - return stream << ToString(size); -} - +// Cord sizes relevant for testing +enum class TestCordSize { + // An empty value + kEmpty = 0, + + // An inlined string value + kInlined = cord_internal::kMaxInline / 2 + 1, + + // 'Well known' SSO lengths (excluding terminating zero). + // libstdcxx has a maximum SSO of 15, libc++ has a maximum SSO of 22. + kStringSso1 = 15, + kStringSso2 = 22, + + // A string value which is too large to fit in inlined data, but small enough + // such that Cord prefers copying the value if possible, i.e.: not stealing + // std::string inputs, or referencing existing CordReps on Append, etc. + kSmall = cord_internal::kMaxBytesToCopy / 2 + 1, + + // A string value large enough that Cord prefers to reference or steal from + // existing inputs rather than copying contents of the input. + kMedium = cord_internal::kMaxFlatLength / 2 + 1, + + // A string value large enough to cause it to be stored in mutliple flats. + kLarge = cord_internal::kMaxFlatLength * 4 +}; + +// To string helper +inline absl::string_view ToString(TestCordSize size) { + switch (size) { + case TestCordSize::kEmpty: + return "Empty"; + case TestCordSize::kInlined: + return "Inlined"; + case TestCordSize::kSmall: + return "Small"; + case TestCordSize::kStringSso1: + return "StringSso1"; + case TestCordSize::kStringSso2: + return "StringSso2"; + case TestCordSize::kMedium: + return "Medium"; + case TestCordSize::kLarge: + return "Large"; + } + return "???"; +} + +// Returns the length matching the specified size +inline size_t Length(TestCordSize size) { return static_cast<size_t>(size); } + +// Stream output helper +inline std::ostream& operator<<(std::ostream& stream, TestCordSize size) { + return stream << ToString(size); +} + // Creates a multi-segment Cord from an iterable container of strings. The // resulting Cord is guaranteed to have one segment for every string in the // container. This allows code to be unit tested with multi-segment Cord diff --git a/contrib/restricted/abseil-cpp/absl/strings/cordz_test_helpers.h b/contrib/restricted/abseil-cpp/absl/strings/cordz_test_helpers.h index e410eecf7f..e6b7b77b25 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/cordz_test_helpers.h +++ b/contrib/restricted/abseil-cpp/absl/strings/cordz_test_helpers.h @@ -1,151 +1,151 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_CORDZ_TEST_HELPERS_H_ -#define ABSL_STRINGS_CORDZ_TEST_HELPERS_H_ - -#include <utility> - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/base/config.h" -#include "absl/base/macros.h" -#include "absl/strings/cord.h" -#include "absl/strings/internal/cord_internal.h" -#include "absl/strings/internal/cordz_info.h" -#include "absl/strings/internal/cordz_sample_token.h" -#include "absl/strings/internal/cordz_statistics.h" -#include "absl/strings/internal/cordz_update_tracker.h" -#include "absl/strings/str_cat.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -// Returns the CordzInfo for the cord, or nullptr if the cord is not sampled. -inline const cord_internal::CordzInfo* GetCordzInfoForTesting( - const Cord& cord) { - if (!cord.contents_.is_tree()) return nullptr; - return cord.contents_.cordz_info(); -} - -// Returns true if the provided cordz_info is in the list of sampled cords. -inline bool CordzInfoIsListed(const cord_internal::CordzInfo* cordz_info, - cord_internal::CordzSampleToken token = {}) { - for (const cord_internal::CordzInfo& info : token) { - if (cordz_info == &info) return true; - } - return false; -} - -// Matcher on Cord that verifies all of: -// - the cord is sampled -// - the CordzInfo of the cord is listed / discoverable. -// - the reported CordzStatistics match the cord's actual properties -// - the cord has an (initial) UpdateTracker count of 1 for `method` -MATCHER_P(HasValidCordzInfoOf, method, "CordzInfo matches cord") { - const cord_internal::CordzInfo* cord_info = GetCordzInfoForTesting(arg); - if (cord_info == nullptr) { - *result_listener << "cord is not sampled"; - return false; - } - if (!CordzInfoIsListed(cord_info)) { - *result_listener << "cord is sampled, but not listed"; - return false; - } - cord_internal::CordzStatistics stat = cord_info->GetCordzStatistics(); - if (stat.size != arg.size()) { - *result_listener << "cordz size " << stat.size - << " does not match cord size " << arg.size(); - return false; - } - if (stat.update_tracker.Value(method) != 1) { - *result_listener << "Expected method count 1 for " << method << ", found " - << stat.update_tracker.Value(method); - return false; - } - return true; -} - -// Matcher on Cord that verifies that the cord is sampled and that the CordzInfo -// update tracker has 'method' with a call count of 'n' -MATCHER_P2(CordzMethodCountEq, method, n, - absl::StrCat("CordzInfo method count equals ", n)) { - const cord_internal::CordzInfo* cord_info = GetCordzInfoForTesting(arg); - if (cord_info == nullptr) { - *result_listener << "cord is not sampled"; - return false; - } - cord_internal::CordzStatistics stat = cord_info->GetCordzStatistics(); - if (stat.update_tracker.Value(method) != n) { - *result_listener << "Expected method count " << n << " for " << method - << ", found " << stat.update_tracker.Value(method); - return false; - } - return true; -} - -// Cordz will only update with a new rate once the previously scheduled event -// has fired. When we disable Cordz, a long delay takes place where we won't -// consider profiling new Cords. CordzSampleIntervalHelper will burn through -// that interval and allow for testing that assumes that the average sampling -// interval is a particular value. -class CordzSamplingIntervalHelper { - public: - explicit CordzSamplingIntervalHelper(int32_t interval) - : orig_mean_interval_(absl::cord_internal::get_cordz_mean_interval()) { - absl::cord_internal::set_cordz_mean_interval(interval); - absl::cord_internal::cordz_set_next_sample_for_testing(interval); - } - - ~CordzSamplingIntervalHelper() { - absl::cord_internal::set_cordz_mean_interval(orig_mean_interval_); - absl::cord_internal::cordz_set_next_sample_for_testing(orig_mean_interval_); - } - - private: - int32_t orig_mean_interval_; -}; - -// Wrapper struct managing a small CordRep `rep` -struct TestCordRep { - cord_internal::CordRepFlat* rep; - - TestCordRep() { - rep = cord_internal::CordRepFlat::New(100); - rep->length = 100; - memset(rep->Data(), 1, 100); - } - ~TestCordRep() { cord_internal::CordRep::Unref(rep); } -}; - -// Wrapper struct managing a small CordRep `rep`, and -// an InlineData `data` initialized with that CordRep. -struct TestCordData { - TestCordRep rep; - cord_internal::InlineData data{rep.rep}; -}; - -// Creates a Cord that is not sampled -template <typename... Args> -Cord UnsampledCord(Args... args) { - CordzSamplingIntervalHelper never(9999); - Cord cord(std::forward<Args>(args)...); - ABSL_ASSERT(GetCordzInfoForTesting(cord) == nullptr); - return cord; -} - -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STRINGS_CORDZ_TEST_HELPERS_H_ +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_CORDZ_TEST_HELPERS_H_ +#define ABSL_STRINGS_CORDZ_TEST_HELPERS_H_ + +#include <utility> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/base/config.h" +#include "absl/base/macros.h" +#include "absl/strings/cord.h" +#include "absl/strings/internal/cord_internal.h" +#include "absl/strings/internal/cordz_info.h" +#include "absl/strings/internal/cordz_sample_token.h" +#include "absl/strings/internal/cordz_statistics.h" +#include "absl/strings/internal/cordz_update_tracker.h" +#include "absl/strings/str_cat.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +// Returns the CordzInfo for the cord, or nullptr if the cord is not sampled. +inline const cord_internal::CordzInfo* GetCordzInfoForTesting( + const Cord& cord) { + if (!cord.contents_.is_tree()) return nullptr; + return cord.contents_.cordz_info(); +} + +// Returns true if the provided cordz_info is in the list of sampled cords. +inline bool CordzInfoIsListed(const cord_internal::CordzInfo* cordz_info, + cord_internal::CordzSampleToken token = {}) { + for (const cord_internal::CordzInfo& info : token) { + if (cordz_info == &info) return true; + } + return false; +} + +// Matcher on Cord that verifies all of: +// - the cord is sampled +// - the CordzInfo of the cord is listed / discoverable. +// - the reported CordzStatistics match the cord's actual properties +// - the cord has an (initial) UpdateTracker count of 1 for `method` +MATCHER_P(HasValidCordzInfoOf, method, "CordzInfo matches cord") { + const cord_internal::CordzInfo* cord_info = GetCordzInfoForTesting(arg); + if (cord_info == nullptr) { + *result_listener << "cord is not sampled"; + return false; + } + if (!CordzInfoIsListed(cord_info)) { + *result_listener << "cord is sampled, but not listed"; + return false; + } + cord_internal::CordzStatistics stat = cord_info->GetCordzStatistics(); + if (stat.size != arg.size()) { + *result_listener << "cordz size " << stat.size + << " does not match cord size " << arg.size(); + return false; + } + if (stat.update_tracker.Value(method) != 1) { + *result_listener << "Expected method count 1 for " << method << ", found " + << stat.update_tracker.Value(method); + return false; + } + return true; +} + +// Matcher on Cord that verifies that the cord is sampled and that the CordzInfo +// update tracker has 'method' with a call count of 'n' +MATCHER_P2(CordzMethodCountEq, method, n, + absl::StrCat("CordzInfo method count equals ", n)) { + const cord_internal::CordzInfo* cord_info = GetCordzInfoForTesting(arg); + if (cord_info == nullptr) { + *result_listener << "cord is not sampled"; + return false; + } + cord_internal::CordzStatistics stat = cord_info->GetCordzStatistics(); + if (stat.update_tracker.Value(method) != n) { + *result_listener << "Expected method count " << n << " for " << method + << ", found " << stat.update_tracker.Value(method); + return false; + } + return true; +} + +// Cordz will only update with a new rate once the previously scheduled event +// has fired. When we disable Cordz, a long delay takes place where we won't +// consider profiling new Cords. CordzSampleIntervalHelper will burn through +// that interval and allow for testing that assumes that the average sampling +// interval is a particular value. +class CordzSamplingIntervalHelper { + public: + explicit CordzSamplingIntervalHelper(int32_t interval) + : orig_mean_interval_(absl::cord_internal::get_cordz_mean_interval()) { + absl::cord_internal::set_cordz_mean_interval(interval); + absl::cord_internal::cordz_set_next_sample_for_testing(interval); + } + + ~CordzSamplingIntervalHelper() { + absl::cord_internal::set_cordz_mean_interval(orig_mean_interval_); + absl::cord_internal::cordz_set_next_sample_for_testing(orig_mean_interval_); + } + + private: + int32_t orig_mean_interval_; +}; + +// Wrapper struct managing a small CordRep `rep` +struct TestCordRep { + cord_internal::CordRepFlat* rep; + + TestCordRep() { + rep = cord_internal::CordRepFlat::New(100); + rep->length = 100; + memset(rep->Data(), 1, 100); + } + ~TestCordRep() { cord_internal::CordRep::Unref(rep); } +}; + +// Wrapper struct managing a small CordRep `rep`, and +// an InlineData `data` initialized with that CordRep. +struct TestCordData { + TestCordRep rep; + cord_internal::InlineData data{rep.rep}; +}; + +// Creates a Cord that is not sampled +template <typename... Args> +Cord UnsampledCord(Args... args) { + CordzSamplingIntervalHelper never(9999); + Cord cord(std::forward<Args>(args)...); + ABSL_ASSERT(GetCordzInfoForTesting(cord) == nullptr); + return cord; +} + +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STRINGS_CORDZ_TEST_HELPERS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal/ya.make b/contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal/ya.make index 2471f46c15..30ff4ca457 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal/ya.make +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal/ya.make @@ -1,45 +1,45 @@ -# Generated by devtools/yamaker. - -LIBRARY() - -WITHOUT_LICENSE_TEXTS() - -OWNER(g:cpp-contrib) - -LICENSE(Apache-2.0) - -PEERDIR( - contrib/restricted/abseil-cpp/absl/base - contrib/restricted/abseil-cpp/absl/base/internal/raw_logging - contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait - contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate - contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/numeric - contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal -) - -ADDINCL( - GLOBAL contrib/restricted/abseil-cpp -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DNOMINMAX -) - -SRCDIR(contrib/restricted/abseil-cpp/absl/strings/internal) - -SRCS( - cord_internal.cc - cord_rep_btree.cc - cord_rep_btree_navigator.cc - cord_rep_btree_reader.cc - cord_rep_consume.cc - cord_rep_ring.cc -) - -END() +# Generated by devtools/yamaker. + +LIBRARY() + +WITHOUT_LICENSE_TEXTS() + +OWNER(g:cpp-contrib) + +LICENSE(Apache-2.0) + +PEERDIR( + contrib/restricted/abseil-cpp/absl/base + contrib/restricted/abseil-cpp/absl/base/internal/raw_logging + contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait + contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate + contrib/restricted/abseil-cpp/absl/base/log_severity + contrib/restricted/abseil-cpp/absl/numeric + contrib/restricted/abseil-cpp/absl/strings + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal +) + +ADDINCL( + GLOBAL contrib/restricted/abseil-cpp +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DNOMINMAX +) + +SRCDIR(contrib/restricted/abseil-cpp/absl/strings/internal) + +SRCS( + cord_internal.cc + cord_rep_btree.cc + cord_rep_btree_navigator.cc + cord_rep_btree_reader.cc + cord_rep_consume.cc + cord_rep_ring.cc +) + +END() diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal/ya.make b/contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal/ya.make index 2c62f6421a..aa732b64fb 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal/ya.make +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal/ya.make @@ -2,8 +2,8 @@ LIBRARY() -WITHOUT_LICENSE_TEXTS() - +WITHOUT_LICENSE_TEXTS() + OWNER(g:cpp-contrib) LICENSE(Apache-2.0) @@ -27,8 +27,8 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/strings/internal) - +SRCDIR(contrib/restricted/abseil-cpp/absl/strings/internal) + SRCS( escaping.cc ostringstream.cc diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_parse.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_parse.cc index d29acaf462..6f0b6fe704 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_parse.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_parse.cc @@ -52,7 +52,7 @@ static_assert(std::numeric_limits<double>::digits == 53, "IEEE double fact"); // The lowest valued 19-digit decimal mantissa we can read still contains // sufficient information to reconstruct a binary mantissa. -static_assert(1000000000000000000u > (uint64_t{1} << (53 + 3)), "(b) above"); +static_assert(1000000000000000000u > (uint64_t{1} << (53 + 3)), "(b) above"); // ParseFloat<16> will read the first 15 significant digits of the mantissa. // diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.cc index 1767e6fcc5..9f4c1a0b9e 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.cc @@ -18,7 +18,7 @@ #include <memory> #include "absl/container/inlined_vector.h" -#include "absl/strings/internal/cord_rep_btree.h" +#include "absl/strings/internal/cord_rep_btree.h" #include "absl/strings/internal/cord_rep_flat.h" #include "absl/strings/internal/cord_rep_ring.h" @@ -26,12 +26,12 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace cord_internal { -ABSL_CONST_INIT std::atomic<bool> cord_btree_enabled(kCordEnableBtreeDefault); +ABSL_CONST_INIT std::atomic<bool> cord_btree_enabled(kCordEnableBtreeDefault); ABSL_CONST_INIT std::atomic<bool> cord_ring_buffer_enabled( kCordEnableRingBufferDefault); ABSL_CONST_INIT std::atomic<bool> shallow_subcords_enabled( kCordShallowSubcordsDefault); -ABSL_CONST_INIT std::atomic<bool> cord_btree_exhaustive_validation(false); +ABSL_CONST_INIT std::atomic<bool> cord_btree_exhaustive_validation(false); void CordRep::Destroy(CordRep* rep) { assert(rep != nullptr); @@ -52,9 +52,9 @@ void CordRep::Destroy(CordRep* rep) { rep = left; continue; } - } else if (rep->tag == BTREE) { - CordRepBtree::Destroy(rep->btree()); - rep = nullptr; + } else if (rep->tag == BTREE) { + CordRepBtree::Destroy(rep->btree()); + rep = nullptr; } else if (rep->tag == RING) { CordRepRing::Destroy(rep->ring()); rep = nullptr; diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.h b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.h index bfe5564e46..6fca77d83a 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.h @@ -37,25 +37,25 @@ class CordzInfo; // Default feature enable states for cord ring buffers enum CordFeatureDefaults { - kCordEnableBtreeDefault = true, + kCordEnableBtreeDefault = true, kCordEnableRingBufferDefault = false, kCordShallowSubcordsDefault = false }; -extern std::atomic<bool> cord_btree_enabled; +extern std::atomic<bool> cord_btree_enabled; extern std::atomic<bool> cord_ring_buffer_enabled; extern std::atomic<bool> shallow_subcords_enabled; -// `cord_btree_exhaustive_validation` can be set to force exhaustive validation -// in debug assertions, and code that calls `IsValid()` explicitly. By default, -// assertions should be relatively cheap and AssertValid() can easily lead to -// O(n^2) complexity as recursive / full tree validation is O(n). -extern std::atomic<bool> cord_btree_exhaustive_validation; - -inline void enable_cord_btree(bool enable) { - cord_btree_enabled.store(enable, std::memory_order_relaxed); -} - +// `cord_btree_exhaustive_validation` can be set to force exhaustive validation +// in debug assertions, and code that calls `IsValid()` explicitly. By default, +// assertions should be relatively cheap and AssertValid() can easily lead to +// O(n^2) complexity as recursive / full tree validation is O(n). +extern std::atomic<bool> cord_btree_exhaustive_validation; + +inline void enable_cord_btree(bool enable) { + cord_btree_enabled.store(enable, std::memory_order_relaxed); +} + inline void enable_cord_ring_buffer(bool enable) { cord_ring_buffer_enabled.store(enable, std::memory_order_relaxed); } @@ -80,16 +80,16 @@ enum Constants { kMaxBytesToCopy = 511 }; -// Compact class for tracking the reference count and state flags for CordRep -// instances. Data is stored in an atomic int32_t for compactness and speed. -class RefcountAndFlags { +// Compact class for tracking the reference count and state flags for CordRep +// instances. Data is stored in an atomic int32_t for compactness and speed. +class RefcountAndFlags { public: - constexpr RefcountAndFlags() : count_{kRefIncrement} {} + constexpr RefcountAndFlags() : count_{kRefIncrement} {} struct Immortal {}; - explicit constexpr RefcountAndFlags(Immortal) : count_(kImmortalFlag) {} - struct WithCrc {}; - explicit constexpr RefcountAndFlags(WithCrc) - : count_(kCrcFlag | kRefIncrement) {} + explicit constexpr RefcountAndFlags(Immortal) : count_(kImmortalFlag) {} + struct WithCrc {}; + explicit constexpr RefcountAndFlags(WithCrc) + : count_(kCrcFlag | kRefIncrement) {} // Increments the reference count. Imposes no memory ordering. inline void Increment() { @@ -102,82 +102,82 @@ class RefcountAndFlags { // Returns false if there are no references outstanding; true otherwise. // Inserts barriers to ensure that state written before this method returns // false will be visible to a thread that just observed this method returning - // false. Always returns false when the immortal bit is set. + // false. Always returns false when the immortal bit is set. inline bool Decrement() { - int32_t refcount = count_.load(std::memory_order_acquire) & kRefcountMask; - assert(refcount > 0 || refcount & kImmortalFlag); + int32_t refcount = count_.load(std::memory_order_acquire) & kRefcountMask; + assert(refcount > 0 || refcount & kImmortalFlag); return refcount != kRefIncrement && - (count_.fetch_sub(kRefIncrement, std::memory_order_acq_rel) & - kRefcountMask) != kRefIncrement; + (count_.fetch_sub(kRefIncrement, std::memory_order_acq_rel) & + kRefcountMask) != kRefIncrement; } // Same as Decrement but expect that refcount is greater than 1. inline bool DecrementExpectHighRefcount() { int32_t refcount = - count_.fetch_sub(kRefIncrement, std::memory_order_acq_rel) & - kRefcountMask; - assert(refcount > 0 || refcount & kImmortalFlag); + count_.fetch_sub(kRefIncrement, std::memory_order_acq_rel) & + kRefcountMask; + assert(refcount > 0 || refcount & kImmortalFlag); return refcount != kRefIncrement; } // Returns the current reference count using acquire semantics. inline int32_t Get() const { - return count_.load(std::memory_order_acquire) >> kNumFlags; - } - - // Returns true if the referenced object carries a CRC value. - bool HasCrc() const { - return (count_.load(std::memory_order_relaxed) & kCrcFlag) != 0; - } - - // Returns true iff the atomic integer is 1 and this node does not store - // a CRC. When both these conditions are met, the current thread owns - // the reference and no other thread shares it, so its contents may be - // safely mutated. - // - // If the referenced item is shared, carries a CRC, or is immortal, - // it should not be modified in-place, and this function returns false. - // - // This call performs the memory barrier needed for the owning thread - // to act on the object, so that if it returns true, it may safely - // assume exclusive access to the object. - inline bool IsMutable() { - return (count_.load(std::memory_order_acquire)) == kRefIncrement; + return count_.load(std::memory_order_acquire) >> kNumFlags; } - // Returns whether the atomic integer is 1. Similar to IsMutable(), - // but does not check for a stored CRC. (An unshared node with a CRC is not - // mutable, because changing its data would invalidate the CRC.) - // - // When this returns true, there are no other references, and data sinks - // may safely adopt the children of the CordRep. + // Returns true if the referenced object carries a CRC value. + bool HasCrc() const { + return (count_.load(std::memory_order_relaxed) & kCrcFlag) != 0; + } + + // Returns true iff the atomic integer is 1 and this node does not store + // a CRC. When both these conditions are met, the current thread owns + // the reference and no other thread shares it, so its contents may be + // safely mutated. + // + // If the referenced item is shared, carries a CRC, or is immortal, + // it should not be modified in-place, and this function returns false. + // + // This call performs the memory barrier needed for the owning thread + // to act on the object, so that if it returns true, it may safely + // assume exclusive access to the object. + inline bool IsMutable() { + return (count_.load(std::memory_order_acquire)) == kRefIncrement; + } + + // Returns whether the atomic integer is 1. Similar to IsMutable(), + // but does not check for a stored CRC. (An unshared node with a CRC is not + // mutable, because changing its data would invalidate the CRC.) + // + // When this returns true, there are no other references, and data sinks + // may safely adopt the children of the CordRep. inline bool IsOne() { - return (count_.load(std::memory_order_acquire) & kRefcountMask) == - kRefIncrement; + return (count_.load(std::memory_order_acquire) & kRefcountMask) == + kRefIncrement; } bool IsImmortal() const { - return (count_.load(std::memory_order_relaxed) & kImmortalFlag) != 0; + return (count_.load(std::memory_order_relaxed) & kImmortalFlag) != 0; } private: - // We reserve the bottom bits for flags. - // kImmortalBit indicates that this entity should never be collected; it is - // used for the StringConstant constructor to avoid collecting immutable - // constant cords. - // kReservedFlag is reserved for future use. + // We reserve the bottom bits for flags. + // kImmortalBit indicates that this entity should never be collected; it is + // used for the StringConstant constructor to avoid collecting immutable + // constant cords. + // kReservedFlag is reserved for future use. enum { - kNumFlags = 2, - - kImmortalFlag = 0x1, - kCrcFlag = 0x2, - kRefIncrement = (1 << kNumFlags), - - // Bitmask to use when checking refcount by equality. This masks out - // all flags except kImmortalFlag, which is part of the refcount for - // purposes of equality. (A refcount of 0 or 1 does not count as 0 or 1 - // if the immortal bit is set.) - kRefcountMask = ~kCrcFlag, + kNumFlags = 2, + + kImmortalFlag = 0x1, + kCrcFlag = 0x2, + kRefIncrement = (1 << kNumFlags), + + // Bitmask to use when checking refcount by equality. This masks out + // all flags except kImmortalFlag, which is part of the refcount for + // purposes of equality. (A refcount of 0 or 1 does not count as 0 or 1 + // if the immortal bit is set.) + kRefcountMask = ~kCrcFlag, }; std::atomic<int32_t> count_; @@ -193,68 +193,68 @@ struct CordRepExternal; struct CordRepFlat; struct CordRepSubstring; class CordRepRing; -class CordRepBtree; +class CordRepBtree; // Various representations that we allow enum CordRepKind { CONCAT = 0, - SUBSTRING = 1, - BTREE = 2, + SUBSTRING = 1, + BTREE = 2, RING = 3, - EXTERNAL = 4, + EXTERNAL = 4, // We have different tags for different sized flat arrays, - // starting with FLAT, and limited to MAX_FLAT_TAG. The 225 value is based on + // starting with FLAT, and limited to MAX_FLAT_TAG. The 225 value is based on // the current 'size to tag' encoding of 8 / 32 bytes. If a new tag is needed // in the future, then 'FLAT' and 'MAX_FLAT_TAG' should be adjusted as well // as the Tag <---> Size logic so that FLAT stil represents the minimum flat // allocation size. (32 bytes as of now). - FLAT = 5, - MAX_FLAT_TAG = 225 + FLAT = 5, + MAX_FLAT_TAG = 225 }; -// There are various locations where we want to check if some rep is a 'plain' -// data edge, i.e. an external or flat rep. By having FLAT == EXTERNAL + 1, we -// can perform this check in a single branch as 'tag >= EXTERNAL' -// Likewise, we have some locations where we check for 'ring or external/flat', -// so likewise align RING to EXTERNAL. -// Note that we can leave this optimization to the compiler. The compiler will -// DTRT when it sees a condition like `tag == EXTERNAL || tag >= FLAT`. -static_assert(RING == BTREE + 1, "BTREE and RING not consecutive"); -static_assert(EXTERNAL == RING + 1, "BTREE and EXTERNAL not consecutive"); -static_assert(FLAT == EXTERNAL + 1, "EXTERNAL and FLAT not consecutive"); - +// There are various locations where we want to check if some rep is a 'plain' +// data edge, i.e. an external or flat rep. By having FLAT == EXTERNAL + 1, we +// can perform this check in a single branch as 'tag >= EXTERNAL' +// Likewise, we have some locations where we check for 'ring or external/flat', +// so likewise align RING to EXTERNAL. +// Note that we can leave this optimization to the compiler. The compiler will +// DTRT when it sees a condition like `tag == EXTERNAL || tag >= FLAT`. +static_assert(RING == BTREE + 1, "BTREE and RING not consecutive"); +static_assert(EXTERNAL == RING + 1, "BTREE and EXTERNAL not consecutive"); +static_assert(FLAT == EXTERNAL + 1, "EXTERNAL and FLAT not consecutive"); + struct CordRep { CordRep() = default; - constexpr CordRep(RefcountAndFlags::Immortal immortal, size_t l) + constexpr CordRep(RefcountAndFlags::Immortal immortal, size_t l) : length(l), refcount(immortal), tag(EXTERNAL), storage{} {} // The following three fields have to be less than 32 bytes since // that is the smallest supported flat node size. size_t length; - RefcountAndFlags refcount; + RefcountAndFlags refcount; // If tag < FLAT, it represents CordRepKind and indicates the type of node. // Otherwise, the node type is CordRepFlat and the tag is the encoded size. uint8_t tag; - // `storage` provides two main purposes: - // - the starting point for FlatCordRep.Data() [flexible-array-member] - // - 3 bytes of additional storage for use by derived classes. - // The latter is used by CordrepConcat and CordRepBtree. CordRepConcat stores - // a 'depth' value in storage[0], and the (future) CordRepBtree class stores - // `height`, `begin` and `end` in the 3 entries. Otherwise we would need to - // allocate room for these in the derived class, as not all compilers reuse - // padding space from the base class (clang and gcc do, MSVC does not, etc) - uint8_t storage[3]; - - // Returns true if this instance's tag matches the requested type. - constexpr bool IsRing() const { return tag == RING; } - constexpr bool IsConcat() const { return tag == CONCAT; } - constexpr bool IsSubstring() const { return tag == SUBSTRING; } - constexpr bool IsExternal() const { return tag == EXTERNAL; } - constexpr bool IsFlat() const { return tag >= FLAT; } - constexpr bool IsBtree() const { return tag == BTREE; } - + // `storage` provides two main purposes: + // - the starting point for FlatCordRep.Data() [flexible-array-member] + // - 3 bytes of additional storage for use by derived classes. + // The latter is used by CordrepConcat and CordRepBtree. CordRepConcat stores + // a 'depth' value in storage[0], and the (future) CordRepBtree class stores + // `height`, `begin` and `end` in the 3 entries. Otherwise we would need to + // allocate room for these in the derived class, as not all compilers reuse + // padding space from the base class (clang and gcc do, MSVC does not, etc) + uint8_t storage[3]; + + // Returns true if this instance's tag matches the requested type. + constexpr bool IsRing() const { return tag == RING; } + constexpr bool IsConcat() const { return tag == CONCAT; } + constexpr bool IsSubstring() const { return tag == SUBSTRING; } + constexpr bool IsExternal() const { return tag == EXTERNAL; } + constexpr bool IsFlat() const { return tag >= FLAT; } + constexpr bool IsBtree() const { return tag == BTREE; } + inline CordRepRing* ring(); inline const CordRepRing* ring() const; inline CordRepConcat* concat(); @@ -265,8 +265,8 @@ struct CordRep { inline const CordRepExternal* external() const; inline CordRepFlat* flat(); inline const CordRepFlat* flat() const; - inline CordRepBtree* btree(); - inline const CordRepBtree* btree() const; + inline CordRepBtree* btree(); + inline const CordRepBtree* btree() const; // -------------------------------------------------------------------- // Memory management @@ -287,8 +287,8 @@ struct CordRepConcat : public CordRep { CordRep* left; CordRep* right; - uint8_t depth() const { return storage[0]; } - void set_depth(uint8_t depth) { storage[0] = depth; } + uint8_t depth() const { return storage[0]; } + void set_depth(uint8_t depth) { storage[0] = depth; } }; struct CordRepSubstring : public CordRep { @@ -306,7 +306,7 @@ using ExternalReleaserInvoker = void (*)(CordRepExternal*); struct CordRepExternal : public CordRep { CordRepExternal() = default; explicit constexpr CordRepExternal(absl::string_view str) - : CordRep(RefcountAndFlags::Immortal{}, str.size()), + : CordRep(RefcountAndFlags::Immortal{}, str.size()), base(str.data()), releaser_invoker(nullptr) {} @@ -315,7 +315,7 @@ struct CordRepExternal : public CordRep { ExternalReleaserInvoker releaser_invoker; // Deletes (releases) the external rep. - // Requires rep != nullptr and rep->IsExternal() + // Requires rep != nullptr and rep->IsExternal() static void Delete(CordRep* rep); }; @@ -358,7 +358,7 @@ struct CordRepExternalImpl }; inline void CordRepExternal::Delete(CordRep* rep) { - assert(rep != nullptr && rep->IsExternal()); + assert(rep != nullptr && rep->IsExternal()); auto* rep_external = static_cast<CordRepExternal*>(rep); assert(rep_external->releaser_invoker != nullptr); rep_external->releaser_invoker(rep_external); @@ -404,9 +404,9 @@ static constexpr cordz_info_t BigEndianByte(unsigned char value) { class InlineData { public: - // DefaultInitType forces the use of the default initialization constructor. - enum DefaultInitType { kDefaultInit }; - + // DefaultInitType forces the use of the default initialization constructor. + enum DefaultInitType { kDefaultInit }; + // kNullCordzInfo holds the big endian representation of intptr_t(1) // This is the 'null' / initial value of 'cordz_info'. The null value // is specifically big endian 1 as with 64-bit pointers, the last @@ -414,7 +414,7 @@ class InlineData { static constexpr cordz_info_t kNullCordzInfo = BigEndianByte(1); constexpr InlineData() : as_chars_{0} {} - explicit InlineData(DefaultInitType) {} + explicit InlineData(DefaultInitType) {} explicit constexpr InlineData(CordRep* rep) : as_tree_(rep) {} explicit constexpr InlineData(absl::string_view chars) : as_chars_{ @@ -441,16 +441,16 @@ class InlineData { return as_tree_.cordz_info != kNullCordzInfo; } - // Returns true if either of the provided instances hold a cordz_info value. - // This method is more efficient than the equivalent `data1.is_profiled() || - // data2.is_profiled()`. Requires both arguments to hold a tree. - static bool is_either_profiled(const InlineData& data1, - const InlineData& data2) { - assert(data1.is_tree() && data2.is_tree()); - return (data1.as_tree_.cordz_info | data2.as_tree_.cordz_info) != - kNullCordzInfo; - } - + // Returns true if either of the provided instances hold a cordz_info value. + // This method is more efficient than the equivalent `data1.is_profiled() || + // data2.is_profiled()`. Requires both arguments to hold a tree. + static bool is_either_profiled(const InlineData& data1, + const InlineData& data2) { + assert(data1.is_tree() && data2.is_tree()); + return (data1.as_tree_.cordz_info | data2.as_tree_.cordz_info) != + kNullCordzInfo; + } + // Returns the cordz_info sampling instance for this instance, or nullptr // if the current instance is not sampled and does not have CordzInfo data. // Requires the current instance to hold a tree value. @@ -560,7 +560,7 @@ class InlineData { // store the size in the last char of `as_chars_` shifted left + 1. // Else we store it in a tree and store a pointer to that tree in // `as_tree_.rep` and store a tag in `tagged_size`. - union { + union { char as_chars_[kMaxInline + 1]; AsTree as_tree_; }; @@ -569,32 +569,32 @@ class InlineData { static_assert(sizeof(InlineData) == kMaxInline + 1, ""); inline CordRepConcat* CordRep::concat() { - assert(IsConcat()); + assert(IsConcat()); return static_cast<CordRepConcat*>(this); } inline const CordRepConcat* CordRep::concat() const { - assert(IsConcat()); + assert(IsConcat()); return static_cast<const CordRepConcat*>(this); } inline CordRepSubstring* CordRep::substring() { - assert(IsSubstring()); + assert(IsSubstring()); return static_cast<CordRepSubstring*>(this); } inline const CordRepSubstring* CordRep::substring() const { - assert(IsSubstring()); + assert(IsSubstring()); return static_cast<const CordRepSubstring*>(this); } inline CordRepExternal* CordRep::external() { - assert(IsExternal()); + assert(IsExternal()); return static_cast<CordRepExternal*>(this); } inline const CordRepExternal* CordRep::external() const { - assert(IsExternal()); + assert(IsExternal()); return static_cast<const CordRepExternal*>(this); } diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree.cc index 4404f33a12..0543e121d8 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree.cc @@ -1,1128 +1,1128 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/strings/internal/cord_rep_btree.h" - -#include <cassert> -#include <cstdint> -#include <iostream> -#include <string> - -#include "absl/base/attributes.h" -#include "absl/base/config.h" -#include "absl/base/internal/raw_logging.h" -#include "absl/strings/internal/cord_internal.h" -#include "absl/strings/internal/cord_rep_consume.h" -#include "absl/strings/internal/cord_rep_flat.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -constexpr size_t CordRepBtree::kMaxCapacity; // NOLINT: needed for c++ < c++17 - -namespace { - -using NodeStack = CordRepBtree * [CordRepBtree::kMaxDepth]; -using EdgeType = CordRepBtree::EdgeType; -using OpResult = CordRepBtree::OpResult; -using CopyResult = CordRepBtree::CopyResult; - -constexpr auto kFront = CordRepBtree::kFront; -constexpr auto kBack = CordRepBtree::kBack; - -inline bool exhaustive_validation() { - return cord_btree_exhaustive_validation.load(std::memory_order_relaxed); -} - -// Implementation of the various 'Dump' functions. -// Prints the entire tree structure or 'rep'. External callers should -// not specify 'depth' and leave it to its default (0) value. -// Rep may be a CordRepBtree tree, or a SUBSTRING / EXTERNAL / FLAT node. -void DumpAll(const CordRep* rep, bool include_contents, std::ostream& stream, - int depth = 0) { - // Allow for full height trees + substring -> flat / external nodes. - assert(depth <= CordRepBtree::kMaxDepth + 2); - std::string sharing = const_cast<CordRep*>(rep)->refcount.IsOne() - ? std::string("Private") - : absl::StrCat("Shared(", rep->refcount.Get(), ")"); - std::string sptr = absl::StrCat("0x", absl::Hex(rep)); - - // Dumps the data contents of `rep` if `include_contents` is true. - // Always emits a new line character. - auto maybe_dump_data = [&stream, include_contents](const CordRep* r) { - if (include_contents) { - // Allow for up to 60 wide display of content data, which with some - // indentation and prefix / labels keeps us within roughly 80-100 wide. - constexpr size_t kMaxDataLength = 60; - stream << ", data = \"" - << CordRepBtree::EdgeData(r).substr(0, kMaxDataLength) - << (r->length > kMaxDataLength ? "\"..." : "\""); - } - stream << '\n'; - }; - - // For each level, we print the 'shared/private' state and the rep pointer, - // indented by two spaces per recursive depth. - stream << std::string(depth * 2, ' ') << sharing << " (" << sptr << ") "; - - if (rep->IsBtree()) { - const CordRepBtree* node = rep->btree(); - std::string label = - node->height() ? absl::StrCat("Node(", node->height(), ")") : "Leaf"; - stream << label << ", len = " << node->length - << ", begin = " << node->begin() << ", end = " << node->end() - << "\n"; - for (CordRep* edge : node->Edges()) { - DumpAll(edge, include_contents, stream, depth + 1); - } - } else if (rep->tag == SUBSTRING) { - const CordRepSubstring* substring = rep->substring(); - stream << "Substring, len = " << rep->length - << ", start = " << substring->start; - maybe_dump_data(rep); - DumpAll(substring->child, include_contents, stream, depth + 1); - } else if (rep->tag >= FLAT) { - stream << "Flat, len = " << rep->length - << ", cap = " << rep->flat()->Capacity(); - maybe_dump_data(rep); - } else if (rep->tag == EXTERNAL) { - stream << "Extn, len = " << rep->length; - maybe_dump_data(rep); - } -} - -// TODO(b/192061034): add 'bytes to copy' logic to avoid large slop on substring -// small data out of large reps, and general efficiency of 'always copy small -// data'. Consider making this a cord rep internal library function. -CordRepSubstring* CreateSubstring(CordRep* rep, size_t offset, size_t n) { - assert(n != 0); - assert(offset + n <= rep->length); - assert(offset != 0 || n != rep->length); - - if (rep->tag == SUBSTRING) { - CordRepSubstring* substring = rep->substring(); - offset += substring->start; - rep = CordRep::Ref(substring->child); - CordRep::Unref(substring); - } - CordRepSubstring* substring = new CordRepSubstring(); - substring->length = n; - substring->tag = SUBSTRING; - substring->start = offset; - substring->child = rep; - return substring; -} - -// TODO(b/192061034): consider making this a cord rep library function. -inline CordRep* MakeSubstring(CordRep* rep, size_t offset, size_t n) { - if (n == rep->length) return rep; - if (n == 0) return CordRep::Unref(rep), nullptr; - return CreateSubstring(rep, offset, n); -} - -// TODO(b/192061034): consider making this a cord rep library function. -inline CordRep* MakeSubstring(CordRep* rep, size_t offset) { - if (offset == 0) return rep; - return CreateSubstring(rep, offset, rep->length - offset); -} - -// Resizes `edge` to the provided `length`. Adopts a reference on `edge`. -// This method directly returns `edge` if `length` equals `edge->length`. -// If `is_mutable` is set to true, this function may return `edge` with -// `edge->length` set to the new length depending on the type and size of -// `edge`. Otherwise, this function returns a new CordRepSubstring value. -// Requires `length > 0 && length <= edge->length`. -CordRep* ResizeEdge(CordRep* edge, size_t length, bool is_mutable) { - assert(length > 0); - assert(length <= edge->length); - assert(CordRepBtree::IsDataEdge(edge)); - if (length >= edge->length) return edge; - - if (is_mutable && (edge->tag >= FLAT || edge->tag == SUBSTRING)) { - edge->length = length; - return edge; - } - - return CreateSubstring(edge, 0, length); -} - -template <EdgeType edge_type> -inline absl::string_view Consume(absl::string_view s, size_t n) { - return edge_type == kBack ? s.substr(n) : s.substr(0, s.size() - n); -} - -template <EdgeType edge_type> -inline absl::string_view Consume(char* dst, absl::string_view s, size_t n) { - if (edge_type == kBack) { - memcpy(dst, s.data(), n); - return s.substr(n); - } else { - const size_t offset = s.size() - n; - memcpy(dst, s.data() + offset, n); - return s.substr(0, offset); - } -} - -// Known issue / optimization weirdness: the store associated with the -// decrement introduces traffic between cpus (even if the result of that -// traffic does nothing), making this faster than a single call to -// refcount.Decrement() checking the zero refcount condition. -template <typename R, typename Fn> -inline void FastUnref(R* r, Fn&& fn) { - if (r->refcount.IsOne()) { - fn(r); - } else if (!r->refcount.DecrementExpectHighRefcount()) { - fn(r); - } -} - -// Deletes a leaf node data edge. Requires `rep` to be an EXTERNAL or FLAT -// node, or a SUBSTRING of an EXTERNAL or FLAT node. -void DeleteLeafEdge(CordRep* rep) { - for (;;) { - if (rep->tag >= FLAT) { - CordRepFlat::Delete(rep->flat()); - return; - } - if (rep->tag == EXTERNAL) { - CordRepExternal::Delete(rep->external()); - return; - } - assert(rep->tag == SUBSTRING); - CordRepSubstring* substring = rep->substring(); - rep = substring->child; - assert(rep->tag == EXTERNAL || rep->tag >= FLAT); - delete substring; - if (rep->refcount.Decrement()) return; - } -} - -// StackOperations contains the logic to build a left-most or right-most stack -// (leg) down to the leaf level of a btree, and 'unwind' / 'Finalize' methods to -// propagate node changes up the stack. -template <EdgeType edge_type> -struct StackOperations { - // Returns true if the node at 'depth' is mutable, i.e. has a refcount - // of one, carries no CRC, and all of its parent nodes have a refcount of one. - inline bool owned(int depth) const { return depth < share_depth; } - - // Returns the node at 'depth'. - inline CordRepBtree* node(int depth) const { return stack[depth]; } - - // Builds a `depth` levels deep stack starting at `tree` recording which nodes - // are private in the form of the 'share depth' where nodes are shared. - inline CordRepBtree* BuildStack(CordRepBtree* tree, int depth) { - assert(depth <= tree->height()); - int current_depth = 0; - while (current_depth < depth && tree->refcount.IsMutable()) { - stack[current_depth++] = tree; - tree = tree->Edge(edge_type)->btree(); - } - share_depth = current_depth + (tree->refcount.IsMutable() ? 1 : 0); - while (current_depth < depth) { - stack[current_depth++] = tree; - tree = tree->Edge(edge_type)->btree(); - } - return tree; - } - - // Builds a stack with the invariant that all nodes are private owned / not - // shared and carry no CRC data. This is used in iterative updates where a - // previous propagation guaranteed all nodes have this property. - inline void BuildOwnedStack(CordRepBtree* tree, int height) { - assert(height <= CordRepBtree::kMaxHeight); - int depth = 0; - while (depth < height) { - assert(tree->refcount.IsMutable()); - stack[depth++] = tree; - tree = tree->Edge(edge_type)->btree(); - } - assert(tree->refcount.IsMutable()); - share_depth = depth + 1; - } - - // Processes the final 'top level' result action for the tree. - // See the 'Action' enum for the various action implications. - static inline CordRepBtree* Finalize(CordRepBtree* tree, OpResult result) { - switch (result.action) { - case CordRepBtree::kPopped: - tree = edge_type == kBack ? CordRepBtree::New(tree, result.tree) - : CordRepBtree::New(result.tree, tree); - if (ABSL_PREDICT_FALSE(tree->height() > CordRepBtree::kMaxHeight)) { - tree = CordRepBtree::Rebuild(tree); - ABSL_RAW_CHECK(tree->height() <= CordRepBtree::kMaxHeight, - "Max height exceeded"); - } - return tree; - case CordRepBtree::kCopied: - CordRep::Unref(tree); - ABSL_FALLTHROUGH_INTENDED; - case CordRepBtree::kSelf: - return result.tree; - } - ABSL_INTERNAL_UNREACHABLE; - return result.tree; - } - - // Propagate the action result in 'result' up into all nodes of the stack - // starting at depth 'depth'. 'length' contains the extra length of data that - // was added at the lowest level, and is updated into all nodes of the stack. - // See the 'Action' enum for the various action implications. - // If 'propagate' is true, then any copied node values are updated into the - // stack, which is used for iterative processing on the same stack. - template <bool propagate = false> - inline CordRepBtree* Unwind(CordRepBtree* tree, int depth, size_t length, - OpResult result) { - // TODO(mvels): revisit the below code to check if 3 loops with 3 - // (incremental) conditions is faster than 1 loop with a switch. - // Benchmarking and perf recordings indicate the loop with switch is - // fastest, likely because of indirect jumps on the tight case values and - // dense branches. But it's worth considering 3 loops, as the `action` - // transitions are mono directional. E.g.: - // while (action == kPopped) { - // ... - // } - // while (action == kCopied) { - // ... - // } - // ... - // We also found that an "if () do {}" loop here seems faster, possibly - // because it allows the branch predictor more granular heuristics on - // 'single leaf' (`depth` == 0) and 'single depth' (`depth` == 1) cases - // which appear to be the most common use cases. - if (depth != 0) { - do { - CordRepBtree* node = stack[--depth]; - const bool owned = depth < share_depth; - switch (result.action) { - case CordRepBtree::kPopped: - assert(!propagate); - result = node->AddEdge<edge_type>(owned, result.tree, length); - break; - case CordRepBtree::kCopied: - result = node->SetEdge<edge_type>(owned, result.tree, length); - if (propagate) stack[depth] = result.tree; - break; - case CordRepBtree::kSelf: - node->length += length; - while (depth > 0) { - node = stack[--depth]; - node->length += length; - } - return node; - } - } while (depth > 0); - } - return Finalize(tree, result); - } - - // Invokes `Unwind` with `propagate=true` to update the stack node values. - inline CordRepBtree* Propagate(CordRepBtree* tree, int depth, size_t length, - OpResult result) { - return Unwind</*propagate=*/true>(tree, depth, length, result); - } - - // `share_depth` contains the depth at which the nodes in the stack cannot - // be mutated. I.e., if the top most level is shared (i.e.: - // `!refcount.IsMutable()`), then `share_depth` is 0. If the 2nd node - // is shared (and implicitly all nodes below that) then `share_depth` is 1, - // etc. A `share_depth` greater than the depth of the stack indicates that - // none of the nodes in the stack are shared. - int share_depth; - - NodeStack stack; -}; - -} // namespace - -void CordRepBtree::Dump(const CordRep* rep, absl::string_view label, - bool include_contents, std::ostream& stream) { - stream << "===================================\n"; - if (!label.empty()) { - stream << label << '\n'; - stream << "-----------------------------------\n"; - } - if (rep) { - DumpAll(rep, include_contents, stream); - } else { - stream << "NULL\n"; - } -} - -void CordRepBtree::Dump(const CordRep* rep, absl::string_view label, - std::ostream& stream) { - Dump(rep, label, false, stream); -} - -void CordRepBtree::Dump(const CordRep* rep, std::ostream& stream) { - Dump(rep, absl::string_view(), false, stream); -} - -void CordRepBtree::DestroyLeaf(CordRepBtree* tree, size_t begin, size_t end) { - for (CordRep* edge : tree->Edges(begin, end)) { - FastUnref(edge, DeleteLeafEdge); - } - Delete(tree); -} - -void CordRepBtree::DestroyNonLeaf(CordRepBtree* tree, size_t begin, - size_t end) { - for (CordRep* edge : tree->Edges(begin, end)) { - FastUnref(edge->btree(), Destroy); - } - Delete(tree); -} - -bool CordRepBtree::IsValid(const CordRepBtree* tree, bool shallow) { -#define NODE_CHECK_VALID(x) \ - if (!(x)) { \ - ABSL_RAW_LOG(ERROR, "CordRepBtree::CheckValid() FAILED: %s", #x); \ - return false; \ - } -#define NODE_CHECK_EQ(x, y) \ - if ((x) != (y)) { \ - ABSL_RAW_LOG(ERROR, \ - "CordRepBtree::CheckValid() FAILED: %s != %s (%s vs %s)", #x, \ - #y, absl::StrCat(x).c_str(), absl::StrCat(y).c_str()); \ - return false; \ - } - - NODE_CHECK_VALID(tree != nullptr); - NODE_CHECK_VALID(tree->IsBtree()); - NODE_CHECK_VALID(tree->height() <= kMaxHeight); - NODE_CHECK_VALID(tree->begin() < tree->capacity()); - NODE_CHECK_VALID(tree->end() <= tree->capacity()); - NODE_CHECK_VALID(tree->begin() <= tree->end()); - size_t child_length = 0; - for (CordRep* edge : tree->Edges()) { - NODE_CHECK_VALID(edge != nullptr); - if (tree->height() > 0) { - NODE_CHECK_VALID(edge->IsBtree()); - NODE_CHECK_VALID(edge->btree()->height() == tree->height() - 1); - } else { - NODE_CHECK_VALID(IsDataEdge(edge)); - } - child_length += edge->length; - } - NODE_CHECK_EQ(child_length, tree->length); - if ((!shallow || exhaustive_validation()) && tree->height() > 0) { - for (CordRep* edge : tree->Edges()) { - if (!IsValid(edge->btree(), shallow)) return false; - } - } - return true; - -#undef NODE_CHECK_VALID -#undef NODE_CHECK_EQ -} - -#ifndef NDEBUG - -CordRepBtree* CordRepBtree::AssertValid(CordRepBtree* tree, bool shallow) { - if (!IsValid(tree, shallow)) { - Dump(tree, "CordRepBtree validation failed:", false, std::cout); - ABSL_RAW_LOG(FATAL, "CordRepBtree::CheckValid() FAILED"); - } - return tree; -} - -const CordRepBtree* CordRepBtree::AssertValid(const CordRepBtree* tree, - bool shallow) { - if (!IsValid(tree, shallow)) { - Dump(tree, "CordRepBtree validation failed:", false, std::cout); - ABSL_RAW_LOG(FATAL, "CordRepBtree::CheckValid() FAILED"); - } - return tree; -} - -#endif // NDEBUG - -template <EdgeType edge_type> -inline OpResult CordRepBtree::AddEdge(bool owned, CordRep* edge, size_t delta) { - if (size() >= kMaxCapacity) return {New(edge), kPopped}; - OpResult result = ToOpResult(owned); - result.tree->Add<edge_type>(edge); - result.tree->length += delta; - return result; -} - -template <EdgeType edge_type> -OpResult CordRepBtree::SetEdge(bool owned, CordRep* edge, size_t delta) { - OpResult result; - const size_t idx = index(edge_type); - if (owned) { - result = {this, kSelf}; - CordRep::Unref(edges_[idx]); - } else { - // Create a copy containing all unchanged edges. Unchanged edges are the - // open interval [begin, back) or [begin + 1, end) depending on `edge_type`. - // We conveniently cover both case using a constexpr `shift` being 0 or 1 - // as `end :== back + 1`. - result = {CopyRaw(), kCopied}; - constexpr int shift = edge_type == kFront ? 1 : 0; - for (CordRep* r : Edges(begin() + shift, back() + shift)) { - CordRep::Ref(r); - } - } - result.tree->edges_[idx] = edge; - result.tree->length += delta; - return result; -} - -template <EdgeType edge_type> -CordRepBtree* CordRepBtree::AddCordRep(CordRepBtree* tree, CordRep* rep) { - const int depth = tree->height(); - const size_t length = rep->length; - StackOperations<edge_type> ops; - CordRepBtree* leaf = ops.BuildStack(tree, depth); - const OpResult result = - leaf->AddEdge<edge_type>(ops.owned(depth), rep, length); - return ops.Unwind(tree, depth, length, result); -} - -template <> -CordRepBtree* CordRepBtree::NewLeaf<kBack>(absl::string_view data, - size_t extra) { - CordRepBtree* leaf = CordRepBtree::New(0); - size_t length = 0; - size_t end = 0; - const size_t cap = leaf->capacity(); - while (!data.empty() && end != cap) { - auto* flat = CordRepFlat::New(data.length() + extra); - flat->length = (std::min)(data.length(), flat->Capacity()); - length += flat->length; - leaf->edges_[end++] = flat; - data = Consume<kBack>(flat->Data(), data, flat->length); - } - leaf->length = length; - leaf->set_end(end); - return leaf; -} - -template <> -CordRepBtree* CordRepBtree::NewLeaf<kFront>(absl::string_view data, - size_t extra) { - CordRepBtree* leaf = CordRepBtree::New(0); - size_t length = 0; - size_t begin = leaf->capacity(); - leaf->set_end(leaf->capacity()); - while (!data.empty() && begin != 0) { - auto* flat = CordRepFlat::New(data.length() + extra); - flat->length = (std::min)(data.length(), flat->Capacity()); - length += flat->length; - leaf->edges_[--begin] = flat; - data = Consume<kFront>(flat->Data(), data, flat->length); - } - leaf->length = length; - leaf->set_begin(begin); - return leaf; -} - -template <> -absl::string_view CordRepBtree::AddData<kBack>(absl::string_view data, - size_t extra) { - assert(!data.empty()); - assert(size() < capacity()); - AlignBegin(); - const size_t cap = capacity(); - do { - CordRepFlat* flat = CordRepFlat::New(data.length() + extra); - const size_t n = (std::min)(data.length(), flat->Capacity()); - flat->length = n; - edges_[fetch_add_end(1)] = flat; - data = Consume<kBack>(flat->Data(), data, n); - } while (!data.empty() && end() != cap); - return data; -} - -template <> -absl::string_view CordRepBtree::AddData<kFront>(absl::string_view data, - size_t extra) { - assert(!data.empty()); - assert(size() < capacity()); - AlignEnd(); - do { - CordRepFlat* flat = CordRepFlat::New(data.length() + extra); - const size_t n = (std::min)(data.length(), flat->Capacity()); - flat->length = n; - edges_[sub_fetch_begin(1)] = flat; - data = Consume<kFront>(flat->Data(), data, n); - } while (!data.empty() && begin() != 0); - return data; -} - -template <EdgeType edge_type> -CordRepBtree* CordRepBtree::AddData(CordRepBtree* tree, absl::string_view data, - size_t extra) { - if (ABSL_PREDICT_FALSE(data.empty())) return tree; - - const size_t original_data_size = data.size(); - int depth = tree->height(); - StackOperations<edge_type> ops; - CordRepBtree* leaf = ops.BuildStack(tree, depth); - - // If there is capacity in the last edge, append as much data - // as possible into this last edge. - if (leaf->size() < leaf->capacity()) { - OpResult result = leaf->ToOpResult(ops.owned(depth)); - data = result.tree->AddData<edge_type>(data, extra); - if (data.empty()) { - result.tree->length += original_data_size; - return ops.Unwind(tree, depth, original_data_size, result); - } - - // We added some data into this leaf, but not all. Propagate the added - // length to the top most node, and rebuild the stack with any newly copied - // or updated nodes. From this point on, the path (leg) from the top most - // node to the right-most node towards the leaf node is privately owned. - size_t delta = original_data_size - data.size(); - assert(delta > 0); - result.tree->length += delta; - tree = ops.Propagate(tree, depth, delta, result); - ops.share_depth = depth + 1; - } - - // We were unable to append all data into the existing right-most leaf node. - // This means all remaining data must be put into (a) new leaf node(s) which - // we append to the tree. To make this efficient, we iteratively build full - // leaf nodes from `data` until the created leaf contains all remaining data. - // We utilize the `Unwind` method to merge the created leaf into the first - // level towards root that has capacity. On each iteration with remaining - // data, we rebuild the stack in the knowledge that right-most nodes are - // privately owned after the first `Unwind` completes. - for (;;) { - OpResult result = {CordRepBtree::NewLeaf<edge_type>(data, extra), kPopped}; - if (result.tree->length == data.size()) { - return ops.Unwind(tree, depth, result.tree->length, result); - } - data = Consume<edge_type>(data, result.tree->length); - tree = ops.Unwind(tree, depth, result.tree->length, result); - depth = tree->height(); - ops.BuildOwnedStack(tree, depth); - } -} - -template <EdgeType edge_type> -CordRepBtree* CordRepBtree::Merge(CordRepBtree* dst, CordRepBtree* src) { - assert(dst->height() >= src->height()); - - // Capture source length as we may consume / destroy `src`. - const size_t length = src->length; - - // We attempt to merge `src` at its corresponding height in `dst`. - const int depth = dst->height() - src->height(); - StackOperations<edge_type> ops; - CordRepBtree* merge_node = ops.BuildStack(dst, depth); - - // If there is enough space in `merge_node` for all edges from `src`, add all - // edges to this node, making a fresh copy as needed if not privately owned. - // If `merge_node` does not have capacity for `src`, we rely on `Unwind` and - // `Finalize` to merge `src` into the first level towards `root` where there - // is capacity for another edge, or create a new top level node. - OpResult result; - if (merge_node->size() + src->size() <= kMaxCapacity) { - result = merge_node->ToOpResult(ops.owned(depth)); - result.tree->Add<edge_type>(src->Edges()); - result.tree->length += src->length; - if (src->refcount.IsOne()) { - Delete(src); - } else { - for (CordRep* edge : src->Edges()) CordRep::Ref(edge); - CordRepBtree::Unref(src); - } - } else { - result = {src, kPopped}; - } - - // Unless we merged at the top level (i.e.: src and dst are equal height), - // unwind the result towards the top level, and finalize the result. - if (depth) { - return ops.Unwind(dst, depth, length, result); - } - return ops.Finalize(dst, result); -} - -CopyResult CordRepBtree::CopySuffix(size_t offset) { - assert(offset < this->length); - - // As long as `offset` starts inside the last edge, we can 'drop' the current - // depth. For the most extreme example: if offset references the last data - // edge in the tree, there is only a single edge / path from the top of the - // tree to that last edge, so we can drop all the nodes except that edge. - // The fast path check for this is `back->length >= length - offset`. - int height = this->height(); - CordRepBtree* node = this; - size_t len = node->length - offset; - CordRep* back = node->Edge(kBack); - while (back->length >= len) { - offset = back->length - len; - if (--height < 0) { - return {MakeSubstring(CordRep::Ref(back), offset), height}; - } - node = back->btree(); - back = node->Edge(kBack); - } - if (offset == 0) return {CordRep::Ref(node), height}; - - // Offset does not point into the last edge, so we span at least two edges. - // Find the index of offset with `IndexBeyond` which provides us the edge - // 'beyond' the offset if offset is not a clean starting point of an edge. - Position pos = node->IndexBeyond(offset); - CordRepBtree* sub = node->CopyToEndFrom(pos.index, len); - const CopyResult result = {sub, height}; - - // `pos.n` contains a non zero value if the offset is not an exact starting - // point of an edge. In this case, `pos.n` contains the 'trailing' amount of - // bytes of the edge preceding that in `pos.index`. We need to iteratively - // adjust the preceding edge with the 'broken' offset until we have a perfect - // start of the edge. - while (pos.n != 0) { - assert(pos.index >= 1); - const size_t begin = pos.index - 1; - sub->set_begin(begin); - CordRep* const edge = node->Edge(begin); - - len = pos.n; - offset = edge->length - len; - - if (--height < 0) { - sub->edges_[begin] = MakeSubstring(CordRep::Ref(edge), offset, len); - return result; - } - - node = edge->btree(); - pos = node->IndexBeyond(offset); - - CordRepBtree* nsub = node->CopyToEndFrom(pos.index, len); - sub->edges_[begin] = nsub; - sub = nsub; - } - sub->set_begin(pos.index); - return result; -} - -CopyResult CordRepBtree::CopyPrefix(size_t n, bool allow_folding) { - assert(n > 0); - assert(n <= this->length); - - // As long as `n` does not exceed the length of the first edge, we can 'drop' - // the current depth. For the most extreme example: if we'd copy a 1 byte - // prefix from a tree, there is only a single edge / path from the top of the - // tree to the single data edge containing this byte, so we can drop all the - // nodes except the data node. - int height = this->height(); - CordRepBtree* node = this; - CordRep* front = node->Edge(kFront); - if (allow_folding) { - while (front->length >= n) { - if (--height < 0) return {MakeSubstring(CordRep::Ref(front), 0, n), -1}; - node = front->btree(); - front = node->Edge(kFront); - } - } - if (node->length == n) return {CordRep::Ref(node), height}; - - // `n` spans at least two nodes, find the end point of the span. - Position pos = node->IndexOf(n); - - // Create a partial copy of the node up to `pos.index`, with a defined length - // of `n`. Any 'partial last edge' is added further below as needed. - CordRepBtree* sub = node->CopyBeginTo(pos.index, n); - const CopyResult result = {sub, height}; - - // `pos.n` contains the 'offset inside the edge for IndexOf(n)'. As long as - // this is not zero, we don't have a 'clean cut', so we need to make a - // (partial) copy of that last edge, and repeat this until pos.n is zero. - while (pos.n != 0) { - size_t end = pos.index; - n = pos.n; - - CordRep* edge = node->Edge(pos.index); - if (--height < 0) { - sub->edges_[end++] = MakeSubstring(CordRep::Ref(edge), 0, n); - sub->set_end(end); - AssertValid(result.edge->btree()); - return result; - } - - node = edge->btree(); - pos = node->IndexOf(n); - CordRepBtree* nsub = node->CopyBeginTo(pos.index, n); - sub->edges_[end++] = nsub; - sub->set_end(end); - sub = nsub; - } - sub->set_end(pos.index); - AssertValid(result.edge->btree()); - return result; -} - -CordRep* CordRepBtree::ExtractFront(CordRepBtree* tree) { - CordRep* front = tree->Edge(tree->begin()); - if (tree->refcount.IsMutable()) { - Unref(tree->Edges(tree->begin() + 1, tree->end())); - CordRepBtree::Delete(tree); - } else { - CordRep::Ref(front); - CordRep::Unref(tree); - } - return front; -} - -CordRepBtree* CordRepBtree::ConsumeBeginTo(CordRepBtree* tree, size_t end, - size_t new_length) { - assert(end <= tree->end()); - if (tree->refcount.IsMutable()) { - Unref(tree->Edges(end, tree->end())); - tree->set_end(end); - tree->length = new_length; - } else { - CordRepBtree* old = tree; - tree = tree->CopyBeginTo(end, new_length); - CordRep::Unref(old); - } - return tree; -} - -CordRep* CordRepBtree::RemoveSuffix(CordRepBtree* tree, size_t n) { - // Check input and deal with trivial cases 'Remove all/none' - assert(tree != nullptr); - assert(n <= tree->length); - const size_t len = tree->length; - if (ABSL_PREDICT_FALSE(n == 0)) { - return tree; - } - if (ABSL_PREDICT_FALSE(n >= len)) { - CordRepBtree::Unref(tree); - return nullptr; - } - - size_t length = len - n; - int height = tree->height(); - bool is_mutable = tree->refcount.IsMutable(); - - // Extract all top nodes which are reduced to size = 1 - Position pos = tree->IndexOfLength(length); - while (pos.index == tree->begin()) { - CordRep* edge = ExtractFront(tree); - is_mutable &= edge->refcount.IsMutable(); - if (height-- == 0) return ResizeEdge(edge, length, is_mutable); - tree = edge->btree(); - pos = tree->IndexOfLength(length); - } - - // Repeat the following sequence traversing down the tree: - // - Crop the top node to the 'last remaining edge' adjusting length. - // - Set the length for down edges to the partial length in that last edge. - // - Repeat this until the last edge is 'included in full' - // - If we hit the data edge level, resize and return the last data edge - CordRepBtree* top = tree = ConsumeBeginTo(tree, pos.index + 1, length); - CordRep* edge = tree->Edge(pos.index); - length = pos.n; - while (length != edge->length) { - // ConsumeBeginTo guarantees `tree` is a clean, privately owned copy. - assert(tree->refcount.IsMutable()); - const bool edge_is_mutable = edge->refcount.IsMutable(); - - if (height-- == 0) { - tree->edges_[pos.index] = ResizeEdge(edge, length, edge_is_mutable); - return AssertValid(top); - } - - if (!edge_is_mutable) { - // We can't 'in place' remove any suffixes down this edge. - // Replace this edge with a prefix copy instead. - tree->edges_[pos.index] = edge->btree()->CopyPrefix(length, false).edge; - CordRep::Unref(edge); - return AssertValid(top); - } - - // Move down one level, rinse repeat. - tree = edge->btree(); - pos = tree->IndexOfLength(length); - tree = ConsumeBeginTo(edge->btree(), pos.index + 1, length); - edge = tree->Edge(pos.index); - length = pos.n; - } - - return AssertValid(top); -} - -CordRep* CordRepBtree::SubTree(size_t offset, size_t n) { - assert(n <= this->length); - assert(offset <= this->length - n); - if (ABSL_PREDICT_FALSE(n == 0)) return nullptr; - - CordRepBtree* node = this; - int height = node->height(); - Position front = node->IndexOf(offset); - CordRep* left = node->edges_[front.index]; - while (front.n + n <= left->length) { - if (--height < 0) return MakeSubstring(CordRep::Ref(left), front.n, n); - node = left->btree(); - front = node->IndexOf(front.n); - left = node->edges_[front.index]; - } - - const Position back = node->IndexBefore(front, n); - CordRep* const right = node->edges_[back.index]; - assert(back.index > front.index); - - // Get partial suffix and prefix entries. - CopyResult prefix; - CopyResult suffix; - if (height > 0) { - // Copy prefix and suffix of the boundary nodes. - prefix = left->btree()->CopySuffix(front.n); - suffix = right->btree()->CopyPrefix(back.n); - - // If there is an edge between the prefix and suffix edges, then the tree - // must remain at its previous (full) height. If we have no edges between - // prefix and suffix edges, then the tree must be as high as either the - // suffix or prefix edges (which are collapsed to their minimum heights). - if (front.index + 1 == back.index) { - height = (std::max)(prefix.height, suffix.height) + 1; - } - - // Raise prefix and suffixes to the new tree height. - for (int h = prefix.height + 1; h < height; ++h) { - prefix.edge = CordRepBtree::New(prefix.edge); - } - for (int h = suffix.height + 1; h < height; ++h) { - suffix.edge = CordRepBtree::New(suffix.edge); - } - } else { - // Leaf node, simply take substrings for prefix and suffix. - prefix = CopyResult{MakeSubstring(CordRep::Ref(left), front.n), -1}; - suffix = CopyResult{MakeSubstring(CordRep::Ref(right), 0, back.n), -1}; - } - - // Compose resulting tree. - CordRepBtree* sub = CordRepBtree::New(height); - size_t end = 0; - sub->edges_[end++] = prefix.edge; - for (CordRep* r : node->Edges(front.index + 1, back.index)) { - sub->edges_[end++] = CordRep::Ref(r); - } - sub->edges_[end++] = suffix.edge; - sub->set_end(end); - sub->length = n; - return AssertValid(sub); -} - -CordRepBtree* CordRepBtree::MergeTrees(CordRepBtree* left, - CordRepBtree* right) { - return left->height() >= right->height() ? Merge<kBack>(left, right) - : Merge<kFront>(right, left); -} - -bool CordRepBtree::IsFlat(absl::string_view* fragment) const { - if (height() == 0 && size() == 1) { - if (fragment) *fragment = Data(begin()); - return true; - } - return false; -} - -bool CordRepBtree::IsFlat(size_t offset, const size_t n, - absl::string_view* fragment) const { - assert(n <= this->length); - assert(offset <= this->length - n); - if (ABSL_PREDICT_FALSE(n == 0)) return false; - int height = this->height(); - const CordRepBtree* node = this; - for (;;) { - const Position front = node->IndexOf(offset); - const CordRep* edge = node->Edge(front.index); - if (edge->length < front.n + n) return false; - if (--height < 0) { - if (fragment) *fragment = EdgeData(edge).substr(front.n, n); - return true; - } - offset = front.n; - node = node->Edge(front.index)->btree(); - } -} - -char CordRepBtree::GetCharacter(size_t offset) const { - assert(offset < length); - const CordRepBtree* node = this; - int height = node->height(); - for (;;) { - Position front = node->IndexOf(offset); - if (--height < 0) return node->Data(front.index)[front.n]; - offset = front.n; - node = node->Edge(front.index)->btree(); - } -} - -Span<char> CordRepBtree::GetAppendBufferSlow(size_t size) { - // The inlined version in `GetAppendBuffer()` deals with all heights <= 3. - assert(height() >= 4); - assert(refcount.IsMutable()); - - // Build a stack of nodes we may potentially need to update if we find a - // non-shared FLAT with capacity at the leaf level. - const int depth = height(); - CordRepBtree* node = this; - CordRepBtree* stack[kMaxDepth]; - for (int i = 0; i < depth; ++i) { - node = node->Edge(kBack)->btree(); - if (!node->refcount.IsMutable()) return {}; - stack[i] = node; - } - - // Must be a privately owned, mutable flat. - CordRep* const edge = node->Edge(kBack); - if (!edge->refcount.IsMutable() || edge->tag < FLAT) return {}; - - // Must have capacity. - const size_t avail = edge->flat()->Capacity() - edge->length; - if (avail == 0) return {}; - - // Build span on remaining capacity. - size_t delta = (std::min)(size, avail); - Span<char> span = {edge->flat()->Data() + edge->length, delta}; - edge->length += delta; - this->length += delta; - for (int i = 0; i < depth; ++i) { - stack[i]->length += delta; - } - return span; -} - -CordRepBtree* CordRepBtree::CreateSlow(CordRep* rep) { - if (rep->IsBtree()) return rep->btree(); - - CordRepBtree* node = nullptr; - auto consume = [&node](CordRep* r, size_t offset, size_t length) { - r = MakeSubstring(r, offset, length); - if (node == nullptr) { - node = New(r); - } else { - node = CordRepBtree::AddCordRep<kBack>(node, r); - } - }; - Consume(rep, consume); - return node; -} - -CordRepBtree* CordRepBtree::AppendSlow(CordRepBtree* tree, CordRep* rep) { - if (ABSL_PREDICT_TRUE(rep->IsBtree())) { - return MergeTrees(tree, rep->btree()); - } - auto consume = [&tree](CordRep* r, size_t offset, size_t length) { - r = MakeSubstring(r, offset, length); - tree = CordRepBtree::AddCordRep<kBack>(tree, r); - }; - Consume(rep, consume); - return tree; -} - -CordRepBtree* CordRepBtree::PrependSlow(CordRepBtree* tree, CordRep* rep) { - if (ABSL_PREDICT_TRUE(rep->IsBtree())) { - return MergeTrees(rep->btree(), tree); - } - auto consume = [&tree](CordRep* r, size_t offset, size_t length) { - r = MakeSubstring(r, offset, length); - tree = CordRepBtree::AddCordRep<kFront>(tree, r); - }; - ReverseConsume(rep, consume); - return tree; -} - -CordRepBtree* CordRepBtree::Append(CordRepBtree* tree, absl::string_view data, - size_t extra) { - return CordRepBtree::AddData<kBack>(tree, data, extra); -} - -CordRepBtree* CordRepBtree::Prepend(CordRepBtree* tree, absl::string_view data, - size_t extra) { - return CordRepBtree::AddData<kFront>(tree, data, extra); -} - -template CordRepBtree* CordRepBtree::AddCordRep<kFront>(CordRepBtree* tree, - CordRep* rep); -template CordRepBtree* CordRepBtree::AddCordRep<kBack>(CordRepBtree* tree, - CordRep* rep); -template CordRepBtree* CordRepBtree::AddData<kFront>(CordRepBtree* tree, - absl::string_view data, - size_t extra); -template CordRepBtree* CordRepBtree::AddData<kBack>(CordRepBtree* tree, - absl::string_view data, - size_t extra); - -void CordRepBtree::Rebuild(CordRepBtree** stack, CordRepBtree* tree, - bool consume) { - bool owned = consume && tree->refcount.IsOne(); - if (tree->height() == 0) { - for (CordRep* edge : tree->Edges()) { - if (!owned) edge = CordRep::Ref(edge); - size_t height = 0; - size_t length = edge->length; - CordRepBtree* node = stack[0]; - OpResult result = node->AddEdge<kBack>(true, edge, length); - while (result.action == CordRepBtree::kPopped) { - stack[height] = result.tree; - if (stack[++height] == nullptr) { - result.action = CordRepBtree::kSelf; - stack[height] = CordRepBtree::New(node, result.tree); - } else { - node = stack[height]; - result = node->AddEdge<kBack>(true, result.tree, length); - } - } - while (stack[++height] != nullptr) { - stack[height]->length += length; - } - } - } else { - for (CordRep* rep : tree->Edges()) { - Rebuild(stack, rep->btree(), owned); - } - } - if (consume) { - if (owned) { - CordRepBtree::Delete(tree); - } else { - CordRepBtree::Unref(tree); - } - } -} - -CordRepBtree* CordRepBtree::Rebuild(CordRepBtree* tree) { - // Set up initial stack with empty leaf node. - CordRepBtree* node = CordRepBtree::New(); - CordRepBtree* stack[CordRepBtree::kMaxDepth + 1] = {node}; - - // Recursively build the tree, consuming the input tree. - Rebuild(stack, tree, /* consume reference */ true); - - // Return top most node - for (CordRepBtree* parent : stack) { - if (parent == nullptr) return node; - node = parent; - } - - // Unreachable - assert(false); - return nullptr; -} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace absl +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/strings/internal/cord_rep_btree.h" + +#include <cassert> +#include <cstdint> +#include <iostream> +#include <string> + +#include "absl/base/attributes.h" +#include "absl/base/config.h" +#include "absl/base/internal/raw_logging.h" +#include "absl/strings/internal/cord_internal.h" +#include "absl/strings/internal/cord_rep_consume.h" +#include "absl/strings/internal/cord_rep_flat.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +constexpr size_t CordRepBtree::kMaxCapacity; // NOLINT: needed for c++ < c++17 + +namespace { + +using NodeStack = CordRepBtree * [CordRepBtree::kMaxDepth]; +using EdgeType = CordRepBtree::EdgeType; +using OpResult = CordRepBtree::OpResult; +using CopyResult = CordRepBtree::CopyResult; + +constexpr auto kFront = CordRepBtree::kFront; +constexpr auto kBack = CordRepBtree::kBack; + +inline bool exhaustive_validation() { + return cord_btree_exhaustive_validation.load(std::memory_order_relaxed); +} + +// Implementation of the various 'Dump' functions. +// Prints the entire tree structure or 'rep'. External callers should +// not specify 'depth' and leave it to its default (0) value. +// Rep may be a CordRepBtree tree, or a SUBSTRING / EXTERNAL / FLAT node. +void DumpAll(const CordRep* rep, bool include_contents, std::ostream& stream, + int depth = 0) { + // Allow for full height trees + substring -> flat / external nodes. + assert(depth <= CordRepBtree::kMaxDepth + 2); + std::string sharing = const_cast<CordRep*>(rep)->refcount.IsOne() + ? std::string("Private") + : absl::StrCat("Shared(", rep->refcount.Get(), ")"); + std::string sptr = absl::StrCat("0x", absl::Hex(rep)); + + // Dumps the data contents of `rep` if `include_contents` is true. + // Always emits a new line character. + auto maybe_dump_data = [&stream, include_contents](const CordRep* r) { + if (include_contents) { + // Allow for up to 60 wide display of content data, which with some + // indentation and prefix / labels keeps us within roughly 80-100 wide. + constexpr size_t kMaxDataLength = 60; + stream << ", data = \"" + << CordRepBtree::EdgeData(r).substr(0, kMaxDataLength) + << (r->length > kMaxDataLength ? "\"..." : "\""); + } + stream << '\n'; + }; + + // For each level, we print the 'shared/private' state and the rep pointer, + // indented by two spaces per recursive depth. + stream << std::string(depth * 2, ' ') << sharing << " (" << sptr << ") "; + + if (rep->IsBtree()) { + const CordRepBtree* node = rep->btree(); + std::string label = + node->height() ? absl::StrCat("Node(", node->height(), ")") : "Leaf"; + stream << label << ", len = " << node->length + << ", begin = " << node->begin() << ", end = " << node->end() + << "\n"; + for (CordRep* edge : node->Edges()) { + DumpAll(edge, include_contents, stream, depth + 1); + } + } else if (rep->tag == SUBSTRING) { + const CordRepSubstring* substring = rep->substring(); + stream << "Substring, len = " << rep->length + << ", start = " << substring->start; + maybe_dump_data(rep); + DumpAll(substring->child, include_contents, stream, depth + 1); + } else if (rep->tag >= FLAT) { + stream << "Flat, len = " << rep->length + << ", cap = " << rep->flat()->Capacity(); + maybe_dump_data(rep); + } else if (rep->tag == EXTERNAL) { + stream << "Extn, len = " << rep->length; + maybe_dump_data(rep); + } +} + +// TODO(b/192061034): add 'bytes to copy' logic to avoid large slop on substring +// small data out of large reps, and general efficiency of 'always copy small +// data'. Consider making this a cord rep internal library function. +CordRepSubstring* CreateSubstring(CordRep* rep, size_t offset, size_t n) { + assert(n != 0); + assert(offset + n <= rep->length); + assert(offset != 0 || n != rep->length); + + if (rep->tag == SUBSTRING) { + CordRepSubstring* substring = rep->substring(); + offset += substring->start; + rep = CordRep::Ref(substring->child); + CordRep::Unref(substring); + } + CordRepSubstring* substring = new CordRepSubstring(); + substring->length = n; + substring->tag = SUBSTRING; + substring->start = offset; + substring->child = rep; + return substring; +} + +// TODO(b/192061034): consider making this a cord rep library function. +inline CordRep* MakeSubstring(CordRep* rep, size_t offset, size_t n) { + if (n == rep->length) return rep; + if (n == 0) return CordRep::Unref(rep), nullptr; + return CreateSubstring(rep, offset, n); +} + +// TODO(b/192061034): consider making this a cord rep library function. +inline CordRep* MakeSubstring(CordRep* rep, size_t offset) { + if (offset == 0) return rep; + return CreateSubstring(rep, offset, rep->length - offset); +} + +// Resizes `edge` to the provided `length`. Adopts a reference on `edge`. +// This method directly returns `edge` if `length` equals `edge->length`. +// If `is_mutable` is set to true, this function may return `edge` with +// `edge->length` set to the new length depending on the type and size of +// `edge`. Otherwise, this function returns a new CordRepSubstring value. +// Requires `length > 0 && length <= edge->length`. +CordRep* ResizeEdge(CordRep* edge, size_t length, bool is_mutable) { + assert(length > 0); + assert(length <= edge->length); + assert(CordRepBtree::IsDataEdge(edge)); + if (length >= edge->length) return edge; + + if (is_mutable && (edge->tag >= FLAT || edge->tag == SUBSTRING)) { + edge->length = length; + return edge; + } + + return CreateSubstring(edge, 0, length); +} + +template <EdgeType edge_type> +inline absl::string_view Consume(absl::string_view s, size_t n) { + return edge_type == kBack ? s.substr(n) : s.substr(0, s.size() - n); +} + +template <EdgeType edge_type> +inline absl::string_view Consume(char* dst, absl::string_view s, size_t n) { + if (edge_type == kBack) { + memcpy(dst, s.data(), n); + return s.substr(n); + } else { + const size_t offset = s.size() - n; + memcpy(dst, s.data() + offset, n); + return s.substr(0, offset); + } +} + +// Known issue / optimization weirdness: the store associated with the +// decrement introduces traffic between cpus (even if the result of that +// traffic does nothing), making this faster than a single call to +// refcount.Decrement() checking the zero refcount condition. +template <typename R, typename Fn> +inline void FastUnref(R* r, Fn&& fn) { + if (r->refcount.IsOne()) { + fn(r); + } else if (!r->refcount.DecrementExpectHighRefcount()) { + fn(r); + } +} + +// Deletes a leaf node data edge. Requires `rep` to be an EXTERNAL or FLAT +// node, or a SUBSTRING of an EXTERNAL or FLAT node. +void DeleteLeafEdge(CordRep* rep) { + for (;;) { + if (rep->tag >= FLAT) { + CordRepFlat::Delete(rep->flat()); + return; + } + if (rep->tag == EXTERNAL) { + CordRepExternal::Delete(rep->external()); + return; + } + assert(rep->tag == SUBSTRING); + CordRepSubstring* substring = rep->substring(); + rep = substring->child; + assert(rep->tag == EXTERNAL || rep->tag >= FLAT); + delete substring; + if (rep->refcount.Decrement()) return; + } +} + +// StackOperations contains the logic to build a left-most or right-most stack +// (leg) down to the leaf level of a btree, and 'unwind' / 'Finalize' methods to +// propagate node changes up the stack. +template <EdgeType edge_type> +struct StackOperations { + // Returns true if the node at 'depth' is mutable, i.e. has a refcount + // of one, carries no CRC, and all of its parent nodes have a refcount of one. + inline bool owned(int depth) const { return depth < share_depth; } + + // Returns the node at 'depth'. + inline CordRepBtree* node(int depth) const { return stack[depth]; } + + // Builds a `depth` levels deep stack starting at `tree` recording which nodes + // are private in the form of the 'share depth' where nodes are shared. + inline CordRepBtree* BuildStack(CordRepBtree* tree, int depth) { + assert(depth <= tree->height()); + int current_depth = 0; + while (current_depth < depth && tree->refcount.IsMutable()) { + stack[current_depth++] = tree; + tree = tree->Edge(edge_type)->btree(); + } + share_depth = current_depth + (tree->refcount.IsMutable() ? 1 : 0); + while (current_depth < depth) { + stack[current_depth++] = tree; + tree = tree->Edge(edge_type)->btree(); + } + return tree; + } + + // Builds a stack with the invariant that all nodes are private owned / not + // shared and carry no CRC data. This is used in iterative updates where a + // previous propagation guaranteed all nodes have this property. + inline void BuildOwnedStack(CordRepBtree* tree, int height) { + assert(height <= CordRepBtree::kMaxHeight); + int depth = 0; + while (depth < height) { + assert(tree->refcount.IsMutable()); + stack[depth++] = tree; + tree = tree->Edge(edge_type)->btree(); + } + assert(tree->refcount.IsMutable()); + share_depth = depth + 1; + } + + // Processes the final 'top level' result action for the tree. + // See the 'Action' enum for the various action implications. + static inline CordRepBtree* Finalize(CordRepBtree* tree, OpResult result) { + switch (result.action) { + case CordRepBtree::kPopped: + tree = edge_type == kBack ? CordRepBtree::New(tree, result.tree) + : CordRepBtree::New(result.tree, tree); + if (ABSL_PREDICT_FALSE(tree->height() > CordRepBtree::kMaxHeight)) { + tree = CordRepBtree::Rebuild(tree); + ABSL_RAW_CHECK(tree->height() <= CordRepBtree::kMaxHeight, + "Max height exceeded"); + } + return tree; + case CordRepBtree::kCopied: + CordRep::Unref(tree); + ABSL_FALLTHROUGH_INTENDED; + case CordRepBtree::kSelf: + return result.tree; + } + ABSL_INTERNAL_UNREACHABLE; + return result.tree; + } + + // Propagate the action result in 'result' up into all nodes of the stack + // starting at depth 'depth'. 'length' contains the extra length of data that + // was added at the lowest level, and is updated into all nodes of the stack. + // See the 'Action' enum for the various action implications. + // If 'propagate' is true, then any copied node values are updated into the + // stack, which is used for iterative processing on the same stack. + template <bool propagate = false> + inline CordRepBtree* Unwind(CordRepBtree* tree, int depth, size_t length, + OpResult result) { + // TODO(mvels): revisit the below code to check if 3 loops with 3 + // (incremental) conditions is faster than 1 loop with a switch. + // Benchmarking and perf recordings indicate the loop with switch is + // fastest, likely because of indirect jumps on the tight case values and + // dense branches. But it's worth considering 3 loops, as the `action` + // transitions are mono directional. E.g.: + // while (action == kPopped) { + // ... + // } + // while (action == kCopied) { + // ... + // } + // ... + // We also found that an "if () do {}" loop here seems faster, possibly + // because it allows the branch predictor more granular heuristics on + // 'single leaf' (`depth` == 0) and 'single depth' (`depth` == 1) cases + // which appear to be the most common use cases. + if (depth != 0) { + do { + CordRepBtree* node = stack[--depth]; + const bool owned = depth < share_depth; + switch (result.action) { + case CordRepBtree::kPopped: + assert(!propagate); + result = node->AddEdge<edge_type>(owned, result.tree, length); + break; + case CordRepBtree::kCopied: + result = node->SetEdge<edge_type>(owned, result.tree, length); + if (propagate) stack[depth] = result.tree; + break; + case CordRepBtree::kSelf: + node->length += length; + while (depth > 0) { + node = stack[--depth]; + node->length += length; + } + return node; + } + } while (depth > 0); + } + return Finalize(tree, result); + } + + // Invokes `Unwind` with `propagate=true` to update the stack node values. + inline CordRepBtree* Propagate(CordRepBtree* tree, int depth, size_t length, + OpResult result) { + return Unwind</*propagate=*/true>(tree, depth, length, result); + } + + // `share_depth` contains the depth at which the nodes in the stack cannot + // be mutated. I.e., if the top most level is shared (i.e.: + // `!refcount.IsMutable()`), then `share_depth` is 0. If the 2nd node + // is shared (and implicitly all nodes below that) then `share_depth` is 1, + // etc. A `share_depth` greater than the depth of the stack indicates that + // none of the nodes in the stack are shared. + int share_depth; + + NodeStack stack; +}; + +} // namespace + +void CordRepBtree::Dump(const CordRep* rep, absl::string_view label, + bool include_contents, std::ostream& stream) { + stream << "===================================\n"; + if (!label.empty()) { + stream << label << '\n'; + stream << "-----------------------------------\n"; + } + if (rep) { + DumpAll(rep, include_contents, stream); + } else { + stream << "NULL\n"; + } +} + +void CordRepBtree::Dump(const CordRep* rep, absl::string_view label, + std::ostream& stream) { + Dump(rep, label, false, stream); +} + +void CordRepBtree::Dump(const CordRep* rep, std::ostream& stream) { + Dump(rep, absl::string_view(), false, stream); +} + +void CordRepBtree::DestroyLeaf(CordRepBtree* tree, size_t begin, size_t end) { + for (CordRep* edge : tree->Edges(begin, end)) { + FastUnref(edge, DeleteLeafEdge); + } + Delete(tree); +} + +void CordRepBtree::DestroyNonLeaf(CordRepBtree* tree, size_t begin, + size_t end) { + for (CordRep* edge : tree->Edges(begin, end)) { + FastUnref(edge->btree(), Destroy); + } + Delete(tree); +} + +bool CordRepBtree::IsValid(const CordRepBtree* tree, bool shallow) { +#define NODE_CHECK_VALID(x) \ + if (!(x)) { \ + ABSL_RAW_LOG(ERROR, "CordRepBtree::CheckValid() FAILED: %s", #x); \ + return false; \ + } +#define NODE_CHECK_EQ(x, y) \ + if ((x) != (y)) { \ + ABSL_RAW_LOG(ERROR, \ + "CordRepBtree::CheckValid() FAILED: %s != %s (%s vs %s)", #x, \ + #y, absl::StrCat(x).c_str(), absl::StrCat(y).c_str()); \ + return false; \ + } + + NODE_CHECK_VALID(tree != nullptr); + NODE_CHECK_VALID(tree->IsBtree()); + NODE_CHECK_VALID(tree->height() <= kMaxHeight); + NODE_CHECK_VALID(tree->begin() < tree->capacity()); + NODE_CHECK_VALID(tree->end() <= tree->capacity()); + NODE_CHECK_VALID(tree->begin() <= tree->end()); + size_t child_length = 0; + for (CordRep* edge : tree->Edges()) { + NODE_CHECK_VALID(edge != nullptr); + if (tree->height() > 0) { + NODE_CHECK_VALID(edge->IsBtree()); + NODE_CHECK_VALID(edge->btree()->height() == tree->height() - 1); + } else { + NODE_CHECK_VALID(IsDataEdge(edge)); + } + child_length += edge->length; + } + NODE_CHECK_EQ(child_length, tree->length); + if ((!shallow || exhaustive_validation()) && tree->height() > 0) { + for (CordRep* edge : tree->Edges()) { + if (!IsValid(edge->btree(), shallow)) return false; + } + } + return true; + +#undef NODE_CHECK_VALID +#undef NODE_CHECK_EQ +} + +#ifndef NDEBUG + +CordRepBtree* CordRepBtree::AssertValid(CordRepBtree* tree, bool shallow) { + if (!IsValid(tree, shallow)) { + Dump(tree, "CordRepBtree validation failed:", false, std::cout); + ABSL_RAW_LOG(FATAL, "CordRepBtree::CheckValid() FAILED"); + } + return tree; +} + +const CordRepBtree* CordRepBtree::AssertValid(const CordRepBtree* tree, + bool shallow) { + if (!IsValid(tree, shallow)) { + Dump(tree, "CordRepBtree validation failed:", false, std::cout); + ABSL_RAW_LOG(FATAL, "CordRepBtree::CheckValid() FAILED"); + } + return tree; +} + +#endif // NDEBUG + +template <EdgeType edge_type> +inline OpResult CordRepBtree::AddEdge(bool owned, CordRep* edge, size_t delta) { + if (size() >= kMaxCapacity) return {New(edge), kPopped}; + OpResult result = ToOpResult(owned); + result.tree->Add<edge_type>(edge); + result.tree->length += delta; + return result; +} + +template <EdgeType edge_type> +OpResult CordRepBtree::SetEdge(bool owned, CordRep* edge, size_t delta) { + OpResult result; + const size_t idx = index(edge_type); + if (owned) { + result = {this, kSelf}; + CordRep::Unref(edges_[idx]); + } else { + // Create a copy containing all unchanged edges. Unchanged edges are the + // open interval [begin, back) or [begin + 1, end) depending on `edge_type`. + // We conveniently cover both case using a constexpr `shift` being 0 or 1 + // as `end :== back + 1`. + result = {CopyRaw(), kCopied}; + constexpr int shift = edge_type == kFront ? 1 : 0; + for (CordRep* r : Edges(begin() + shift, back() + shift)) { + CordRep::Ref(r); + } + } + result.tree->edges_[idx] = edge; + result.tree->length += delta; + return result; +} + +template <EdgeType edge_type> +CordRepBtree* CordRepBtree::AddCordRep(CordRepBtree* tree, CordRep* rep) { + const int depth = tree->height(); + const size_t length = rep->length; + StackOperations<edge_type> ops; + CordRepBtree* leaf = ops.BuildStack(tree, depth); + const OpResult result = + leaf->AddEdge<edge_type>(ops.owned(depth), rep, length); + return ops.Unwind(tree, depth, length, result); +} + +template <> +CordRepBtree* CordRepBtree::NewLeaf<kBack>(absl::string_view data, + size_t extra) { + CordRepBtree* leaf = CordRepBtree::New(0); + size_t length = 0; + size_t end = 0; + const size_t cap = leaf->capacity(); + while (!data.empty() && end != cap) { + auto* flat = CordRepFlat::New(data.length() + extra); + flat->length = (std::min)(data.length(), flat->Capacity()); + length += flat->length; + leaf->edges_[end++] = flat; + data = Consume<kBack>(flat->Data(), data, flat->length); + } + leaf->length = length; + leaf->set_end(end); + return leaf; +} + +template <> +CordRepBtree* CordRepBtree::NewLeaf<kFront>(absl::string_view data, + size_t extra) { + CordRepBtree* leaf = CordRepBtree::New(0); + size_t length = 0; + size_t begin = leaf->capacity(); + leaf->set_end(leaf->capacity()); + while (!data.empty() && begin != 0) { + auto* flat = CordRepFlat::New(data.length() + extra); + flat->length = (std::min)(data.length(), flat->Capacity()); + length += flat->length; + leaf->edges_[--begin] = flat; + data = Consume<kFront>(flat->Data(), data, flat->length); + } + leaf->length = length; + leaf->set_begin(begin); + return leaf; +} + +template <> +absl::string_view CordRepBtree::AddData<kBack>(absl::string_view data, + size_t extra) { + assert(!data.empty()); + assert(size() < capacity()); + AlignBegin(); + const size_t cap = capacity(); + do { + CordRepFlat* flat = CordRepFlat::New(data.length() + extra); + const size_t n = (std::min)(data.length(), flat->Capacity()); + flat->length = n; + edges_[fetch_add_end(1)] = flat; + data = Consume<kBack>(flat->Data(), data, n); + } while (!data.empty() && end() != cap); + return data; +} + +template <> +absl::string_view CordRepBtree::AddData<kFront>(absl::string_view data, + size_t extra) { + assert(!data.empty()); + assert(size() < capacity()); + AlignEnd(); + do { + CordRepFlat* flat = CordRepFlat::New(data.length() + extra); + const size_t n = (std::min)(data.length(), flat->Capacity()); + flat->length = n; + edges_[sub_fetch_begin(1)] = flat; + data = Consume<kFront>(flat->Data(), data, n); + } while (!data.empty() && begin() != 0); + return data; +} + +template <EdgeType edge_type> +CordRepBtree* CordRepBtree::AddData(CordRepBtree* tree, absl::string_view data, + size_t extra) { + if (ABSL_PREDICT_FALSE(data.empty())) return tree; + + const size_t original_data_size = data.size(); + int depth = tree->height(); + StackOperations<edge_type> ops; + CordRepBtree* leaf = ops.BuildStack(tree, depth); + + // If there is capacity in the last edge, append as much data + // as possible into this last edge. + if (leaf->size() < leaf->capacity()) { + OpResult result = leaf->ToOpResult(ops.owned(depth)); + data = result.tree->AddData<edge_type>(data, extra); + if (data.empty()) { + result.tree->length += original_data_size; + return ops.Unwind(tree, depth, original_data_size, result); + } + + // We added some data into this leaf, but not all. Propagate the added + // length to the top most node, and rebuild the stack with any newly copied + // or updated nodes. From this point on, the path (leg) from the top most + // node to the right-most node towards the leaf node is privately owned. + size_t delta = original_data_size - data.size(); + assert(delta > 0); + result.tree->length += delta; + tree = ops.Propagate(tree, depth, delta, result); + ops.share_depth = depth + 1; + } + + // We were unable to append all data into the existing right-most leaf node. + // This means all remaining data must be put into (a) new leaf node(s) which + // we append to the tree. To make this efficient, we iteratively build full + // leaf nodes from `data` until the created leaf contains all remaining data. + // We utilize the `Unwind` method to merge the created leaf into the first + // level towards root that has capacity. On each iteration with remaining + // data, we rebuild the stack in the knowledge that right-most nodes are + // privately owned after the first `Unwind` completes. + for (;;) { + OpResult result = {CordRepBtree::NewLeaf<edge_type>(data, extra), kPopped}; + if (result.tree->length == data.size()) { + return ops.Unwind(tree, depth, result.tree->length, result); + } + data = Consume<edge_type>(data, result.tree->length); + tree = ops.Unwind(tree, depth, result.tree->length, result); + depth = tree->height(); + ops.BuildOwnedStack(tree, depth); + } +} + +template <EdgeType edge_type> +CordRepBtree* CordRepBtree::Merge(CordRepBtree* dst, CordRepBtree* src) { + assert(dst->height() >= src->height()); + + // Capture source length as we may consume / destroy `src`. + const size_t length = src->length; + + // We attempt to merge `src` at its corresponding height in `dst`. + const int depth = dst->height() - src->height(); + StackOperations<edge_type> ops; + CordRepBtree* merge_node = ops.BuildStack(dst, depth); + + // If there is enough space in `merge_node` for all edges from `src`, add all + // edges to this node, making a fresh copy as needed if not privately owned. + // If `merge_node` does not have capacity for `src`, we rely on `Unwind` and + // `Finalize` to merge `src` into the first level towards `root` where there + // is capacity for another edge, or create a new top level node. + OpResult result; + if (merge_node->size() + src->size() <= kMaxCapacity) { + result = merge_node->ToOpResult(ops.owned(depth)); + result.tree->Add<edge_type>(src->Edges()); + result.tree->length += src->length; + if (src->refcount.IsOne()) { + Delete(src); + } else { + for (CordRep* edge : src->Edges()) CordRep::Ref(edge); + CordRepBtree::Unref(src); + } + } else { + result = {src, kPopped}; + } + + // Unless we merged at the top level (i.e.: src and dst are equal height), + // unwind the result towards the top level, and finalize the result. + if (depth) { + return ops.Unwind(dst, depth, length, result); + } + return ops.Finalize(dst, result); +} + +CopyResult CordRepBtree::CopySuffix(size_t offset) { + assert(offset < this->length); + + // As long as `offset` starts inside the last edge, we can 'drop' the current + // depth. For the most extreme example: if offset references the last data + // edge in the tree, there is only a single edge / path from the top of the + // tree to that last edge, so we can drop all the nodes except that edge. + // The fast path check for this is `back->length >= length - offset`. + int height = this->height(); + CordRepBtree* node = this; + size_t len = node->length - offset; + CordRep* back = node->Edge(kBack); + while (back->length >= len) { + offset = back->length - len; + if (--height < 0) { + return {MakeSubstring(CordRep::Ref(back), offset), height}; + } + node = back->btree(); + back = node->Edge(kBack); + } + if (offset == 0) return {CordRep::Ref(node), height}; + + // Offset does not point into the last edge, so we span at least two edges. + // Find the index of offset with `IndexBeyond` which provides us the edge + // 'beyond' the offset if offset is not a clean starting point of an edge. + Position pos = node->IndexBeyond(offset); + CordRepBtree* sub = node->CopyToEndFrom(pos.index, len); + const CopyResult result = {sub, height}; + + // `pos.n` contains a non zero value if the offset is not an exact starting + // point of an edge. In this case, `pos.n` contains the 'trailing' amount of + // bytes of the edge preceding that in `pos.index`. We need to iteratively + // adjust the preceding edge with the 'broken' offset until we have a perfect + // start of the edge. + while (pos.n != 0) { + assert(pos.index >= 1); + const size_t begin = pos.index - 1; + sub->set_begin(begin); + CordRep* const edge = node->Edge(begin); + + len = pos.n; + offset = edge->length - len; + + if (--height < 0) { + sub->edges_[begin] = MakeSubstring(CordRep::Ref(edge), offset, len); + return result; + } + + node = edge->btree(); + pos = node->IndexBeyond(offset); + + CordRepBtree* nsub = node->CopyToEndFrom(pos.index, len); + sub->edges_[begin] = nsub; + sub = nsub; + } + sub->set_begin(pos.index); + return result; +} + +CopyResult CordRepBtree::CopyPrefix(size_t n, bool allow_folding) { + assert(n > 0); + assert(n <= this->length); + + // As long as `n` does not exceed the length of the first edge, we can 'drop' + // the current depth. For the most extreme example: if we'd copy a 1 byte + // prefix from a tree, there is only a single edge / path from the top of the + // tree to the single data edge containing this byte, so we can drop all the + // nodes except the data node. + int height = this->height(); + CordRepBtree* node = this; + CordRep* front = node->Edge(kFront); + if (allow_folding) { + while (front->length >= n) { + if (--height < 0) return {MakeSubstring(CordRep::Ref(front), 0, n), -1}; + node = front->btree(); + front = node->Edge(kFront); + } + } + if (node->length == n) return {CordRep::Ref(node), height}; + + // `n` spans at least two nodes, find the end point of the span. + Position pos = node->IndexOf(n); + + // Create a partial copy of the node up to `pos.index`, with a defined length + // of `n`. Any 'partial last edge' is added further below as needed. + CordRepBtree* sub = node->CopyBeginTo(pos.index, n); + const CopyResult result = {sub, height}; + + // `pos.n` contains the 'offset inside the edge for IndexOf(n)'. As long as + // this is not zero, we don't have a 'clean cut', so we need to make a + // (partial) copy of that last edge, and repeat this until pos.n is zero. + while (pos.n != 0) { + size_t end = pos.index; + n = pos.n; + + CordRep* edge = node->Edge(pos.index); + if (--height < 0) { + sub->edges_[end++] = MakeSubstring(CordRep::Ref(edge), 0, n); + sub->set_end(end); + AssertValid(result.edge->btree()); + return result; + } + + node = edge->btree(); + pos = node->IndexOf(n); + CordRepBtree* nsub = node->CopyBeginTo(pos.index, n); + sub->edges_[end++] = nsub; + sub->set_end(end); + sub = nsub; + } + sub->set_end(pos.index); + AssertValid(result.edge->btree()); + return result; +} + +CordRep* CordRepBtree::ExtractFront(CordRepBtree* tree) { + CordRep* front = tree->Edge(tree->begin()); + if (tree->refcount.IsMutable()) { + Unref(tree->Edges(tree->begin() + 1, tree->end())); + CordRepBtree::Delete(tree); + } else { + CordRep::Ref(front); + CordRep::Unref(tree); + } + return front; +} + +CordRepBtree* CordRepBtree::ConsumeBeginTo(CordRepBtree* tree, size_t end, + size_t new_length) { + assert(end <= tree->end()); + if (tree->refcount.IsMutable()) { + Unref(tree->Edges(end, tree->end())); + tree->set_end(end); + tree->length = new_length; + } else { + CordRepBtree* old = tree; + tree = tree->CopyBeginTo(end, new_length); + CordRep::Unref(old); + } + return tree; +} + +CordRep* CordRepBtree::RemoveSuffix(CordRepBtree* tree, size_t n) { + // Check input and deal with trivial cases 'Remove all/none' + assert(tree != nullptr); + assert(n <= tree->length); + const size_t len = tree->length; + if (ABSL_PREDICT_FALSE(n == 0)) { + return tree; + } + if (ABSL_PREDICT_FALSE(n >= len)) { + CordRepBtree::Unref(tree); + return nullptr; + } + + size_t length = len - n; + int height = tree->height(); + bool is_mutable = tree->refcount.IsMutable(); + + // Extract all top nodes which are reduced to size = 1 + Position pos = tree->IndexOfLength(length); + while (pos.index == tree->begin()) { + CordRep* edge = ExtractFront(tree); + is_mutable &= edge->refcount.IsMutable(); + if (height-- == 0) return ResizeEdge(edge, length, is_mutable); + tree = edge->btree(); + pos = tree->IndexOfLength(length); + } + + // Repeat the following sequence traversing down the tree: + // - Crop the top node to the 'last remaining edge' adjusting length. + // - Set the length for down edges to the partial length in that last edge. + // - Repeat this until the last edge is 'included in full' + // - If we hit the data edge level, resize and return the last data edge + CordRepBtree* top = tree = ConsumeBeginTo(tree, pos.index + 1, length); + CordRep* edge = tree->Edge(pos.index); + length = pos.n; + while (length != edge->length) { + // ConsumeBeginTo guarantees `tree` is a clean, privately owned copy. + assert(tree->refcount.IsMutable()); + const bool edge_is_mutable = edge->refcount.IsMutable(); + + if (height-- == 0) { + tree->edges_[pos.index] = ResizeEdge(edge, length, edge_is_mutable); + return AssertValid(top); + } + + if (!edge_is_mutable) { + // We can't 'in place' remove any suffixes down this edge. + // Replace this edge with a prefix copy instead. + tree->edges_[pos.index] = edge->btree()->CopyPrefix(length, false).edge; + CordRep::Unref(edge); + return AssertValid(top); + } + + // Move down one level, rinse repeat. + tree = edge->btree(); + pos = tree->IndexOfLength(length); + tree = ConsumeBeginTo(edge->btree(), pos.index + 1, length); + edge = tree->Edge(pos.index); + length = pos.n; + } + + return AssertValid(top); +} + +CordRep* CordRepBtree::SubTree(size_t offset, size_t n) { + assert(n <= this->length); + assert(offset <= this->length - n); + if (ABSL_PREDICT_FALSE(n == 0)) return nullptr; + + CordRepBtree* node = this; + int height = node->height(); + Position front = node->IndexOf(offset); + CordRep* left = node->edges_[front.index]; + while (front.n + n <= left->length) { + if (--height < 0) return MakeSubstring(CordRep::Ref(left), front.n, n); + node = left->btree(); + front = node->IndexOf(front.n); + left = node->edges_[front.index]; + } + + const Position back = node->IndexBefore(front, n); + CordRep* const right = node->edges_[back.index]; + assert(back.index > front.index); + + // Get partial suffix and prefix entries. + CopyResult prefix; + CopyResult suffix; + if (height > 0) { + // Copy prefix and suffix of the boundary nodes. + prefix = left->btree()->CopySuffix(front.n); + suffix = right->btree()->CopyPrefix(back.n); + + // If there is an edge between the prefix and suffix edges, then the tree + // must remain at its previous (full) height. If we have no edges between + // prefix and suffix edges, then the tree must be as high as either the + // suffix or prefix edges (which are collapsed to their minimum heights). + if (front.index + 1 == back.index) { + height = (std::max)(prefix.height, suffix.height) + 1; + } + + // Raise prefix and suffixes to the new tree height. + for (int h = prefix.height + 1; h < height; ++h) { + prefix.edge = CordRepBtree::New(prefix.edge); + } + for (int h = suffix.height + 1; h < height; ++h) { + suffix.edge = CordRepBtree::New(suffix.edge); + } + } else { + // Leaf node, simply take substrings for prefix and suffix. + prefix = CopyResult{MakeSubstring(CordRep::Ref(left), front.n), -1}; + suffix = CopyResult{MakeSubstring(CordRep::Ref(right), 0, back.n), -1}; + } + + // Compose resulting tree. + CordRepBtree* sub = CordRepBtree::New(height); + size_t end = 0; + sub->edges_[end++] = prefix.edge; + for (CordRep* r : node->Edges(front.index + 1, back.index)) { + sub->edges_[end++] = CordRep::Ref(r); + } + sub->edges_[end++] = suffix.edge; + sub->set_end(end); + sub->length = n; + return AssertValid(sub); +} + +CordRepBtree* CordRepBtree::MergeTrees(CordRepBtree* left, + CordRepBtree* right) { + return left->height() >= right->height() ? Merge<kBack>(left, right) + : Merge<kFront>(right, left); +} + +bool CordRepBtree::IsFlat(absl::string_view* fragment) const { + if (height() == 0 && size() == 1) { + if (fragment) *fragment = Data(begin()); + return true; + } + return false; +} + +bool CordRepBtree::IsFlat(size_t offset, const size_t n, + absl::string_view* fragment) const { + assert(n <= this->length); + assert(offset <= this->length - n); + if (ABSL_PREDICT_FALSE(n == 0)) return false; + int height = this->height(); + const CordRepBtree* node = this; + for (;;) { + const Position front = node->IndexOf(offset); + const CordRep* edge = node->Edge(front.index); + if (edge->length < front.n + n) return false; + if (--height < 0) { + if (fragment) *fragment = EdgeData(edge).substr(front.n, n); + return true; + } + offset = front.n; + node = node->Edge(front.index)->btree(); + } +} + +char CordRepBtree::GetCharacter(size_t offset) const { + assert(offset < length); + const CordRepBtree* node = this; + int height = node->height(); + for (;;) { + Position front = node->IndexOf(offset); + if (--height < 0) return node->Data(front.index)[front.n]; + offset = front.n; + node = node->Edge(front.index)->btree(); + } +} + +Span<char> CordRepBtree::GetAppendBufferSlow(size_t size) { + // The inlined version in `GetAppendBuffer()` deals with all heights <= 3. + assert(height() >= 4); + assert(refcount.IsMutable()); + + // Build a stack of nodes we may potentially need to update if we find a + // non-shared FLAT with capacity at the leaf level. + const int depth = height(); + CordRepBtree* node = this; + CordRepBtree* stack[kMaxDepth]; + for (int i = 0; i < depth; ++i) { + node = node->Edge(kBack)->btree(); + if (!node->refcount.IsMutable()) return {}; + stack[i] = node; + } + + // Must be a privately owned, mutable flat. + CordRep* const edge = node->Edge(kBack); + if (!edge->refcount.IsMutable() || edge->tag < FLAT) return {}; + + // Must have capacity. + const size_t avail = edge->flat()->Capacity() - edge->length; + if (avail == 0) return {}; + + // Build span on remaining capacity. + size_t delta = (std::min)(size, avail); + Span<char> span = {edge->flat()->Data() + edge->length, delta}; + edge->length += delta; + this->length += delta; + for (int i = 0; i < depth; ++i) { + stack[i]->length += delta; + } + return span; +} + +CordRepBtree* CordRepBtree::CreateSlow(CordRep* rep) { + if (rep->IsBtree()) return rep->btree(); + + CordRepBtree* node = nullptr; + auto consume = [&node](CordRep* r, size_t offset, size_t length) { + r = MakeSubstring(r, offset, length); + if (node == nullptr) { + node = New(r); + } else { + node = CordRepBtree::AddCordRep<kBack>(node, r); + } + }; + Consume(rep, consume); + return node; +} + +CordRepBtree* CordRepBtree::AppendSlow(CordRepBtree* tree, CordRep* rep) { + if (ABSL_PREDICT_TRUE(rep->IsBtree())) { + return MergeTrees(tree, rep->btree()); + } + auto consume = [&tree](CordRep* r, size_t offset, size_t length) { + r = MakeSubstring(r, offset, length); + tree = CordRepBtree::AddCordRep<kBack>(tree, r); + }; + Consume(rep, consume); + return tree; +} + +CordRepBtree* CordRepBtree::PrependSlow(CordRepBtree* tree, CordRep* rep) { + if (ABSL_PREDICT_TRUE(rep->IsBtree())) { + return MergeTrees(rep->btree(), tree); + } + auto consume = [&tree](CordRep* r, size_t offset, size_t length) { + r = MakeSubstring(r, offset, length); + tree = CordRepBtree::AddCordRep<kFront>(tree, r); + }; + ReverseConsume(rep, consume); + return tree; +} + +CordRepBtree* CordRepBtree::Append(CordRepBtree* tree, absl::string_view data, + size_t extra) { + return CordRepBtree::AddData<kBack>(tree, data, extra); +} + +CordRepBtree* CordRepBtree::Prepend(CordRepBtree* tree, absl::string_view data, + size_t extra) { + return CordRepBtree::AddData<kFront>(tree, data, extra); +} + +template CordRepBtree* CordRepBtree::AddCordRep<kFront>(CordRepBtree* tree, + CordRep* rep); +template CordRepBtree* CordRepBtree::AddCordRep<kBack>(CordRepBtree* tree, + CordRep* rep); +template CordRepBtree* CordRepBtree::AddData<kFront>(CordRepBtree* tree, + absl::string_view data, + size_t extra); +template CordRepBtree* CordRepBtree::AddData<kBack>(CordRepBtree* tree, + absl::string_view data, + size_t extra); + +void CordRepBtree::Rebuild(CordRepBtree** stack, CordRepBtree* tree, + bool consume) { + bool owned = consume && tree->refcount.IsOne(); + if (tree->height() == 0) { + for (CordRep* edge : tree->Edges()) { + if (!owned) edge = CordRep::Ref(edge); + size_t height = 0; + size_t length = edge->length; + CordRepBtree* node = stack[0]; + OpResult result = node->AddEdge<kBack>(true, edge, length); + while (result.action == CordRepBtree::kPopped) { + stack[height] = result.tree; + if (stack[++height] == nullptr) { + result.action = CordRepBtree::kSelf; + stack[height] = CordRepBtree::New(node, result.tree); + } else { + node = stack[height]; + result = node->AddEdge<kBack>(true, result.tree, length); + } + } + while (stack[++height] != nullptr) { + stack[height]->length += length; + } + } + } else { + for (CordRep* rep : tree->Edges()) { + Rebuild(stack, rep->btree(), owned); + } + } + if (consume) { + if (owned) { + CordRepBtree::Delete(tree); + } else { + CordRepBtree::Unref(tree); + } + } +} + +CordRepBtree* CordRepBtree::Rebuild(CordRepBtree* tree) { + // Set up initial stack with empty leaf node. + CordRepBtree* node = CordRepBtree::New(); + CordRepBtree* stack[CordRepBtree::kMaxDepth + 1] = {node}; + + // Recursively build the tree, consuming the input tree. + Rebuild(stack, tree, /* consume reference */ true); + + // Return top most node + for (CordRepBtree* parent : stack) { + if (parent == nullptr) return node; + node = parent; + } + + // Unreachable + assert(false); + return nullptr; +} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree.h b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree.h index bb38f0c3fe..6890ba1425 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree.h @@ -1,939 +1,939 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_H_ -#define ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_H_ - -#include <cassert> -#include <cstdint> -#include <iosfwd> - -#include "absl/base/config.h" -#include "absl/base/internal/raw_logging.h" -#include "absl/base/optimization.h" -#include "absl/strings/internal/cord_internal.h" -#include "absl/strings/internal/cord_rep_flat.h" -#include "absl/strings/string_view.h" -#include "absl/types/span.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -class CordRepBtreeNavigator; - -// CordRepBtree is as the name implies a btree implementation of a Cordrep tree. -// Data is stored at the leaf level only, non leaf nodes contain down pointers -// only. Allowed types of data edges are FLAT, EXTERNAL and SUBSTRINGs of FLAT -// or EXTERNAL nodes. The implementation allows for data to be added to either -// end of the tree only, it does not provide any 'insert' logic. This has the -// benefit that we can expect good fill ratios: all nodes except the outer -// 'legs' will have 100% fill ratios for trees built using Append/Prepend -// methods. Merged trees will typically have a fill ratio well above 50% as in a -// similar fashion, one side of the merged tree will typically have a 100% fill -// ratio, and the 'open' end will average 50%. All operations are O(log(n)) or -// better, and the tree never needs balancing. -// -// All methods accepting a CordRep* or CordRepBtree* adopt a reference on that -// input unless explicitly stated otherwise. All functions returning a CordRep* -// or CordRepBtree* instance transfer a reference back to the caller. -// Simplified, callers both 'donate' and 'consume' a reference count on each -// call, simplifying the API. An example of building a tree: -// -// CordRepBtree* tree = CordRepBtree::Create(MakeFlat("Hello")); -// tree = CordRepBtree::Append(tree, MakeFlat("world")); -// -// In the above example, all inputs are consumed, making each call affecting -// `tree` reference count neutral. The returned `tree` value can be different -// from the input if the input is shared with other threads, or if the tree -// grows in height, but callers typically never have to concern themselves with -// that and trust that all methods DTRT at all times. -class CordRepBtree : public CordRep { - public: - // EdgeType identifies `front` and `back` enum values. - // Various implementations in CordRepBtree such as `Add` and `Edge` are - // generic and templated on operating on either of the boundary edges. - // For more information on the possible edges contained in a CordRepBtree - // instance see the documentation for `edges_`. - enum class EdgeType { kFront, kBack }; - - // Convenience constants into `EdgeType` - static constexpr EdgeType kFront = EdgeType::kFront; - static constexpr EdgeType kBack = EdgeType::kBack; - - // Maximum number of edges: based on experiments and performance data, we can - // pick suitable values resulting in optimum cacheline aligned values. The - // preferred values are based on 64-bit systems where we aim to align this - // class onto 64 bytes, i.e.: 6 = 64 bytes, 14 = 128 bytes, etc. - // TODO(b/192061034): experiment with alternative sizes. - static constexpr size_t kMaxCapacity = 6; - - // Reasonable maximum height of the btree. We can expect a fill ratio of at - // least 50%: trees are always expanded at the front or back. Concatenating - // trees will then typically fold at the top most node, where the lower nodes - // are at least at capacity on one side of joined inputs. At a lower fill - // rate of 4 edges per node, we have capacity for ~16 million leaf nodes. - // We will fail / abort if an application ever exceeds this height, which - // should be extremely rare (near impossible) and be an indication of an - // application error: we do not assume it reasonable for any application to - // operate correctly with such monster trees. - // Another compelling reason for the number `12` is that any contextual stack - // required for navigation or insertion requires 12 words and 12 bytes, which - // fits inside 2 cache lines with some room to spare, and is reasonable as a - // local stack variable compared to Cord's current near 400 bytes stack use. - // The maximum `height` value of a node is then `kMaxDepth - 1` as node height - // values start with a value of 0 for leaf nodes. - static constexpr int kMaxDepth = 12; - static constexpr int kMaxHeight = kMaxDepth - 1; - - // `Action` defines the action for unwinding changes done at the btree's leaf - // level that need to be propagated up to the parent node(s). Each operation - // on a node has an effect / action defined as follows: - // - kSelf - // The operation (add / update, etc) was performed directly on the node as - // the node is private to the current thread (i.e.: not shared directly or - // indirectly through a refcount > 1). Changes can be propagated directly to - // all parent nodes as all parent nodes are also then private to the current - // thread. - // - kCopied - // The operation (add / update, etc) was performed on a copy of the original - // node, as the node is (potentially) directly or indirectly shared with - // other threads. Changes need to be propagated into the parent nodes where - // the old down pointer must be unreffed and replaced with this new copy. - // Such changes to parent nodes may themselves require a copy if the parent - // node is also shared. A kCopied action can propagate all the way to the - // top node where we then must unref the `tree` input provided by the - // caller, and return the new copy. - // - kPopped - // The operation (typically add) could not be satisfied due to insufficient - // capacity in the targeted node, and a new 'leg' was created that needs to - // be added into the parent node. For example, adding a FLAT inside a leaf - // node that is at capacity will create a new leaf node containing that - // FLAT, that needs to be 'popped' up the btree. Such 'pop' actions can - // cascade up the tree if parent nodes are also at capacity. A 'Popped' - // action propagating all the way to the top of the tree will result in - // the tree becoming one level higher than the current tree through a final - // `CordRepBtree::New(tree, popped)` call, resulting in a new top node - // referencing the old tree and the new (fully popped upwards) 'leg'. - enum Action { kSelf, kCopied, kPopped }; - - // Result of an operation on a node. See the `Action` enum for details. - struct OpResult { - CordRepBtree* tree; - Action action; - }; - - // Return value of the CopyPrefix and CopySuffix methods which can - // return a node or data edge at any height inside the tree. - // A height of 0 defines the lowest (leaf) node, a height of -1 identifies - // `edge` as being a plain data node: EXTERNAL / FLAT or SUBSTRING thereof. - struct CopyResult { - CordRep* edge; - int height; - }; - - // Logical position inside a node: - // - index: index of the edge. - // - n: size or offset value depending on context. - struct Position { - size_t index; - size_t n; - }; - - // Creates a btree from the given input. Adopts a ref of `rep`. - // If the input `rep` is itself a btree, i.e., `IsBtree()`, then this - // function immediately returns `rep->btree()`. If the input is a valid data - // edge (see IsDataEdge()), then a new leaf node is returned containing `rep` - // as the sole data edge. Else, the input is assumed to be a (legacy) concat - // tree, and the input is consumed and transformed into a btree(). - static CordRepBtree* Create(CordRep* rep); - - // Destroys the provided tree. Should only be called by cord internal API's, - // typically after a ref_count.Decrement() on the last reference count. - static void Destroy(CordRepBtree* tree); - - // Use CordRep::Unref() as we overload for absl::Span<CordRep* const>. - using CordRep::Unref; - - // Unrefs all edges in `edges` which are assumed to be 'likely one'. - static void Unref(absl::Span<CordRep* const> edges); - - // Appends / Prepends an existing CordRep instance to this tree. - // The below methods accept three types of input: - // 1) `rep` is a data node (See `IsDataNode` for valid data edges). - // `rep` is appended or prepended to this tree 'as is'. - // 2) `rep` is a BTREE. - // `rep` is merged into `tree` respecting the Append/Prepend order. - // 3) `rep` is some other (legacy) type. - // `rep` is converted in place and added to `tree` - // Requires `tree` and `rep` to be not null. - static CordRepBtree* Append(CordRepBtree* tree, CordRep* rep); - static CordRepBtree* Prepend(CordRepBtree* tree, CordRep* rep); - - // Append/Prepend the data in `data` to this tree. - // The `extra` parameter defines how much extra capacity should be allocated - // for any additional FLAT being allocated. This is an optimization hint from - // the caller. For example, a caller may need to add 2 string_views of data - // "abc" and "defghi" which are not consecutive. The caller can in this case - // invoke `AddData(tree, "abc", 6)`, and any newly added flat is allocated - // where possible with at least 6 bytes of extra capacity beyond `length`. - // This helps avoiding data getting fragmented over multiple flats. - // There is no limit on the size of `data`. If `data` can not be stored inside - // a single flat, then the function will iteratively add flats until all data - // has been consumed and appended or prepended to the tree. - static CordRepBtree* Append(CordRepBtree* tree, string_view data, - size_t extra = 0); - static CordRepBtree* Prepend(CordRepBtree* tree, string_view data, - size_t extra = 0); - - // Returns a new tree, containing `n` bytes of data from this instance - // starting at offset `offset`. Where possible, the returned tree shares - // (re-uses) data edges and nodes with this instance to minimize the - // combined memory footprint of both trees. - // Requires `offset + n <= length`. Returns `nullptr` if `n` is zero. - CordRep* SubTree(size_t offset, size_t n); - - // Removes `n` trailing bytes from `tree`, and returns the resulting tree - // or data edge. Returns `tree` if n is zero, and nullptr if n == length. - // This function is logically identical to: - // result = tree->SubTree(0, tree->length - n); - // Unref(tree); - // return result; - // However, the actual implementation will as much as possible perform 'in - // place' modifications on the tree on all nodes and edges that are mutable. - // For example, in a fully privately owned tree with the last edge being a - // flat of length 12, RemoveSuffix(1) will simply set the length of that data - // edge to 11, and reduce the length of all nodes on the edge path by 1. - static CordRep* RemoveSuffix(CordRepBtree* tree, size_t n); - - // Returns the character at the given offset. - char GetCharacter(size_t offset) const; - - // Returns true if this node holds a single data edge, and if so, sets - // `fragment` to reference the contained data. `fragment` is an optional - // output parameter and allowed to be null. - bool IsFlat(absl::string_view* fragment) const; - - // Returns true if the data of `n` bytes starting at offset `offset` - // is contained in a single data edge, and if so, sets fragment to reference - // the contained data. `fragment` is an optional output parameter and allowed - // to be null. - bool IsFlat(size_t offset, size_t n, absl::string_view* fragment) const; - - // Returns a span (mutable range of bytes) of up to `size` bytes into the - // last FLAT data edge inside this tree under the following conditions: - // - none of the nodes down into the FLAT node are shared. - // - the last data edge in this tree is a non-shared FLAT. - // - the referenced FLAT has additional capacity available. - // If all these conditions are met, a non-empty span is returned, and the - // length of the flat node and involved tree nodes have been increased by - // `span.length()`. The caller is responsible for immediately assigning values - // to all uninitialized data reference by the returned span. - // Requires `this->refcount.IsMutable()`: this function forces the - // caller to do this fast path check on the top level node, as this is the - // most commonly shared node of a cord tree. - Span<char> GetAppendBuffer(size_t size); - - // Returns the `height` of the tree. The height of a tree is limited to - // kMaxHeight. `height` is implemented as an `int` as in some places we - // use negative (-1) values for 'data edges'. - int height() const { return static_cast<int>(storage[0]); } - - // Properties: begin, back, end, front/back boundary indexes. - size_t begin() const { return static_cast<size_t>(storage[1]); } - size_t back() const { return static_cast<size_t>(storage[2]) - 1; } - size_t end() const { return static_cast<size_t>(storage[2]); } - size_t index(EdgeType edge) const { - return edge == kFront ? begin() : back(); - } - - // Properties: size and capacity. - // `capacity` contains the current capacity of this instance, where - // `kMaxCapacity` contains the maximum capacity of a btree node. - // For now, `capacity` and `kMaxCapacity` return the same value, but this may - // change in the future if we see benefit in dynamically sizing 'small' nodes - // to 'large' nodes for large data trees. - size_t size() const { return end() - begin(); } - size_t capacity() const { return kMaxCapacity; } - - // Edge access - inline CordRep* Edge(size_t index) const; - inline CordRep* Edge(EdgeType edge_type) const; - inline absl::Span<CordRep* const> Edges() const; - inline absl::Span<CordRep* const> Edges(size_t begin, size_t end) const; - - // Returns reference to the data edge at `index`. - // Requires this instance to be a leaf node, and `index` to be valid index. - inline absl::string_view Data(size_t index) const; - - static const char* EdgeDataPtr(const CordRep* r); - static absl::string_view EdgeData(const CordRep* r); - - // Returns true if the provided rep is a FLAT, EXTERNAL or a SUBSTRING node - // holding a FLAT or EXTERNAL child rep. - static bool IsDataEdge(const CordRep* rep); - - // Diagnostics: returns true if `tree` is valid and internally consistent. - // If `shallow` is false, then the provided top level node and all child nodes - // below it are recursively checked. If `shallow` is true, only the provided - // node in `tree` and the cumulative length, type and height of the direct - // child nodes of `tree` are checked. The value of `shallow` is ignored if the - // internal `cord_btree_exhaustive_validation` diagnostics variable is true, - // in which case the performed validations works as if `shallow` were false. - // This function is intended for debugging and testing purposes only. - static bool IsValid(const CordRepBtree* tree, bool shallow = false); - - // Diagnostics: asserts that the provided tree is valid. - // `AssertValid()` performs a shallow validation by default. `shallow` can be - // set to false in which case an exhaustive validation is performed. This - // function is implemented in terms of calling `IsValid()` and asserting the - // return value to be true. See `IsValid()` for more information. - // This function is intended for debugging and testing purposes only. - static CordRepBtree* AssertValid(CordRepBtree* tree, bool shallow = true); - static const CordRepBtree* AssertValid(const CordRepBtree* tree, - bool shallow = true); - - // Diagnostics: dump the contents of this tree to `stream`. - // This function is intended for debugging and testing purposes only. - static void Dump(const CordRep* rep, std::ostream& stream); - static void Dump(const CordRep* rep, absl::string_view label, - std::ostream& stream); - static void Dump(const CordRep* rep, absl::string_view label, - bool include_contents, std::ostream& stream); - - // Adds the edge `edge` to this node if possible. `owned` indicates if the - // current node is potentially shared or not with other threads. Returns: - // - {kSelf, <this>} - // The edge was directly added to this node. - // - {kCopied, <node>} - // The edge was added to a copy of this node. - // - {kPopped, New(edge, height())} - // A new leg with the edge was created as this node has no extra capacity. - template <EdgeType edge_type> - inline OpResult AddEdge(bool owned, CordRep* edge, size_t delta); - - // Replaces the front or back edge with the provided new edge. Returns: - // - {kSelf, <this>} - // The edge was directly set in this node. The old edge is unreffed. - // - {kCopied, <node>} - // A copy of this node was created with the new edge value. - // In both cases, the function adopts a reference on `edge`. - template <EdgeType edge_type> - OpResult SetEdge(bool owned, CordRep* edge, size_t delta); - - // Creates a new empty node at the specified height. - static CordRepBtree* New(int height = 0); - - // Creates a new node containing `rep`, with the height being computed - // automatically based on the type of `rep`. - static CordRepBtree* New(CordRep* rep); - - // Creates a new node containing both `front` and `back` at height - // `front.height() + 1`. Requires `back.height() == front.height()`. - static CordRepBtree* New(CordRepBtree* front, CordRepBtree* back); - - // Creates a fully balanced tree from the provided tree by rebuilding a new - // tree from all data edges in the input. This function is automatically - // invoked internally when the tree exceeds the maximum height. - static CordRepBtree* Rebuild(CordRepBtree* tree); - - private: - CordRepBtree() = default; - ~CordRepBtree() = default; - - // Initializes the main properties `tag`, `begin`, `end`, `height`. - inline void InitInstance(int height, size_t begin = 0, size_t end = 0); - - // Direct property access begin / end - void set_begin(size_t begin) { storage[1] = static_cast<uint8_t>(begin); } - void set_end(size_t end) { storage[2] = static_cast<uint8_t>(end); } - - // Decreases the value of `begin` by `n`, and returns the new value. Notice - // how this returns the new value unlike atomic::fetch_add which returns the - // old value. This is because this is used to prepend edges at 'begin - 1'. - size_t sub_fetch_begin(size_t n) { - storage[1] -= static_cast<uint8_t>(n); - return storage[1]; - } - - // Increases the value of `end` by `n`, and returns the previous value. This - // function is typically used to append edges at 'end'. - size_t fetch_add_end(size_t n) { - const uint8_t current = storage[2]; - storage[2] = static_cast<uint8_t>(current + n); - return current; - } - - // Returns the index of the last edge starting on, or before `offset`, with - // `n` containing the relative offset of `offset` inside that edge. - // Requires `offset` < length. - Position IndexOf(size_t offset) const; - - // Returns the index of the last edge starting before `offset`, with `n` - // containing the relative offset of `offset` inside that edge. - // This function is useful to find the edges for some span of bytes ending at - // `offset` (i.e., `n` bytes). For example: - // - // Position pos = IndexBefore(n) - // edges = Edges(begin(), pos.index) // All full edges (may be empty) - // last = Sub(Edge(pos.index), 0, pos.n) // Last partial edge (may be empty) - // - // Requires 0 < `offset` <= length. - Position IndexBefore(size_t offset) const; - - // Returns the index of the edge ending at (or on) length `length`, and the - // number of bytes inside that edge up to `length`. For example, if we have a - // Node with 2 edges, one of 10 and one of 20 long, then IndexOfLength(27) - // will return {1, 17}, and IndexOfLength(10) will return {0, 10}. - Position IndexOfLength(size_t n) const; - - // Identical to the above function except starting from the position `front`. - // This function is equivalent to `IndexBefore(front.n + offset)`, with - // the difference that this function is optimized to start at `front.index`. - Position IndexBefore(Position front, size_t offset) const; - - // Returns the index of the edge directly beyond the edge containing offset - // `offset`, with `n` containing the distance of that edge from `offset`. - // This function is useful for iteratively finding suffix nodes and remaining - // partial bytes in left-most suffix nodes as for example in CopySuffix. - // Requires `offset` < length. - Position IndexBeyond(size_t offset) const; - - // Destruction - static void DestroyLeaf(CordRepBtree* tree, size_t begin, size_t end); - static void DestroyNonLeaf(CordRepBtree* tree, size_t begin, size_t end); - static void DestroyTree(CordRepBtree* tree, size_t begin, size_t end); - static void Delete(CordRepBtree* tree) { delete tree; } - - // Creates a new leaf node containing as much data as possible from `data`. - // The data is added either forwards or reversed depending on `edge_type`. - // Callers must check the length of the returned node to determine if all data - // was copied or not. - // See the `Append/Prepend` function for the meaning and purpose of `extra`. - template <EdgeType edge_type> - static CordRepBtree* NewLeaf(absl::string_view data, size_t extra); - - // Creates a raw copy of this Btree node, copying all properties, but - // without adding any references to existing edges. - CordRepBtree* CopyRaw() const; - - // Creates a full copy of this Btree node, adding a reference on all edges. - CordRepBtree* Copy() const; - - // Creates a partial copy of this Btree node, copying all edges up to `end`, - // adding a reference on each copied edge, and sets the length of the newly - // created copy to `new_length`. - CordRepBtree* CopyBeginTo(size_t end, size_t new_length) const; - - // Returns a tree containing the edges [tree->begin(), end) and length - // of `new_length`. This method consumes a reference on the provided - // tree, and logically performs the following operation: - // result = tree->CopyBeginTo(end, new_length); - // CordRep::Unref(tree); - // return result; - static CordRepBtree* ConsumeBeginTo(CordRepBtree* tree, size_t end, - size_t new_length); - - // Creates a partial copy of this Btree node, copying all edges starting at - // `begin`, adding a reference on each copied edge, and sets the length of - // the newly created copy to `new_length`. - CordRepBtree* CopyToEndFrom(size_t begin, size_t new_length) const; - - // Extracts and returns the front edge from the provided tree. - // This method consumes a reference on the provided tree, and logically - // performs the following operation: - // edge = CordRep::Ref(tree->Edge(kFront)); - // CordRep::Unref(tree); - // return edge; - static CordRep* ExtractFront(CordRepBtree* tree); - - // Returns a tree containing the result of appending `right` to `left`. - static CordRepBtree* MergeTrees(CordRepBtree* left, CordRepBtree* right); - - // Fallback functions for `Create()`, `Append()` and `Prepend()` which - // deal with legacy / non conforming input, i.e.: CONCAT trees. - static CordRepBtree* CreateSlow(CordRep* rep); - static CordRepBtree* AppendSlow(CordRepBtree*, CordRep* rep); - static CordRepBtree* PrependSlow(CordRepBtree*, CordRep* rep); - - // Recursively rebuilds `tree` into `stack`. If 'consume` is set to true, the - // function will consume a reference on `tree`. `stack` is a null terminated - // array containing the new tree's state, with the current leaf node at - // stack[0], and parent nodes above that, or null for 'top of tree'. - static void Rebuild(CordRepBtree** stack, CordRepBtree* tree, bool consume); - - // Aligns existing edges to start at index 0, to allow for a new edge to be - // added to the back of the current edges. - inline void AlignBegin(); - - // Aligns existing edges to end at `capacity`, to allow for a new edge to be - // added in front of the current edges. - inline void AlignEnd(); - - // Adds the provided edge to this node. - // Requires this node to have capacity for the edge. Realigns / moves - // existing edges as needed to prepend or append the new edge. - template <EdgeType edge_type> - inline void Add(CordRep* rep); - - // Adds the provided edges to this node. - // Requires this node to have capacity for the edges. Realigns / moves - // existing edges as needed to prepend or append the new edges. - template <EdgeType edge_type> - inline void Add(absl::Span<CordRep* const>); - - // Adds data from `data` to this node until either all data has been consumed, - // or there is no more capacity for additional flat nodes inside this node. - // Requires the current node to be a leaf node, data to be non empty, and the - // current node to have capacity for at least one more data edge. - // Returns any remaining data from `data` that was not added, which is - // depending on the edge type (front / back) either the remaining prefix of - // suffix of the input. - // See the `Append/Prepend` function for the meaning and purpose of `extra`. - template <EdgeType edge_type> - absl::string_view AddData(absl::string_view data, size_t extra); - - // Replace the front or back edge with the provided value. - // Adopts a reference on `edge` and unrefs the old edge. - template <EdgeType edge_type> - inline void SetEdge(CordRep* edge); - - // Returns a partial copy of the current tree containing the first `n` bytes - // of data. `CopyResult` contains both the resulting edge and its height. The - // resulting tree may be less high than the current tree, or even be a single - // matching data edge if `allow_folding` is set to true. - // For example, if `n == 1`, then the result will be the single data edge, and - // height will be set to -1 (one below the owning leaf node). If n == 0, this - // function returns null. Requires `n <= length` - CopyResult CopyPrefix(size_t n, bool allow_folding = true); - - // Returns a partial copy of the current tree containing all data starting - // after `offset`. `CopyResult` contains both the resulting edge and its - // height. The resulting tree may be less high than the current tree, or even - // be a single matching data edge. For example, if `n == length - 1`, then the - // result will be a single data edge, and height will be set to -1 (one below - // the owning leaf node). - // Requires `offset < length` - CopyResult CopySuffix(size_t offset); - - // Returns a OpResult value of {this, kSelf} or {Copy(), kCopied} - // depending on the value of `owned`. - inline OpResult ToOpResult(bool owned); - - // Adds `rep` to the specified tree, returning the modified tree. - template <EdgeType edge_type> - static CordRepBtree* AddCordRep(CordRepBtree* tree, CordRep* rep); - - // Adds `data` to the specified tree, returning the modified tree. - // See the `Append/Prepend` function for the meaning and purpose of `extra`. - template <EdgeType edge_type> - static CordRepBtree* AddData(CordRepBtree* tree, absl::string_view data, - size_t extra = 0); - - // Merges `src` into `dst` with `src` being added either before (kFront) or - // after (kBack) `dst`. Requires the height of `dst` to be greater than or - // equal to the height of `src`. - template <EdgeType edge_type> - static CordRepBtree* Merge(CordRepBtree* dst, CordRepBtree* src); - - // Fallback version of GetAppendBuffer for large trees: GetAppendBuffer() - // implements an inlined version for trees of limited height (3 levels), - // GetAppendBufferSlow implements the logic for large trees. - Span<char> GetAppendBufferSlow(size_t size); - - // `edges_` contains all edges starting from this instance. - // These are explicitly `child` edges only, a cord btree (or any cord tree in - // that respect) does not store `parent` pointers anywhere: multiple trees / - // parents can reference the same shared child edge. The type of these edges - // depends on the height of the node. `Leaf nodes` (height == 0) contain `data - // edges` (external or flat nodes, or sub-strings thereof). All other nodes - // (height > 0) contain pointers to BTREE nodes with a height of `height - 1`. - CordRep* edges_[kMaxCapacity]; - - friend class CordRepBtreeTestPeer; - friend class CordRepBtreeNavigator; -}; - -inline CordRepBtree* CordRep::btree() { - assert(IsBtree()); - return static_cast<CordRepBtree*>(this); -} - -inline const CordRepBtree* CordRep::btree() const { - assert(IsBtree()); - return static_cast<const CordRepBtree*>(this); -} - -inline void CordRepBtree::InitInstance(int height, size_t begin, size_t end) { - tag = BTREE; - storage[0] = static_cast<uint8_t>(height); - storage[1] = static_cast<uint8_t>(begin); - storage[2] = static_cast<uint8_t>(end); -} - -inline CordRep* CordRepBtree::Edge(size_t index) const { - assert(index >= begin()); - assert(index < end()); - return edges_[index]; -} - -inline CordRep* CordRepBtree::Edge(EdgeType edge_type) const { - return edges_[edge_type == kFront ? begin() : back()]; -} - -inline absl::Span<CordRep* const> CordRepBtree::Edges() const { - return {edges_ + begin(), size()}; -} - -inline absl::Span<CordRep* const> CordRepBtree::Edges(size_t begin, - size_t end) const { - assert(begin <= end); - assert(begin >= this->begin()); - assert(end <= this->end()); - return {edges_ + begin, static_cast<size_t>(end - begin)}; -} - -inline const char* CordRepBtree::EdgeDataPtr(const CordRep* r) { - assert(IsDataEdge(r)); - size_t offset = 0; - if (r->tag == SUBSTRING) { - offset = r->substring()->start; - r = r->substring()->child; - } - return (r->tag >= FLAT ? r->flat()->Data() : r->external()->base) + offset; -} - -inline absl::string_view CordRepBtree::EdgeData(const CordRep* r) { - return absl::string_view(EdgeDataPtr(r), r->length); -} - -inline absl::string_view CordRepBtree::Data(size_t index) const { - assert(height() == 0); - return EdgeData(Edge(index)); -} - -inline bool CordRepBtree::IsDataEdge(const CordRep* rep) { - // The fast path is that `rep` is an EXTERNAL or FLAT node, making the below - // if a single, well predicted branch. We then repeat the FLAT or EXTERNAL - // check in the slow path the SUBSTRING check to optimize for the hot path. - if (rep->tag == EXTERNAL || rep->tag >= FLAT) return true; - if (rep->tag == SUBSTRING) rep = rep->substring()->child; - return rep->tag == EXTERNAL || rep->tag >= FLAT; -} - -inline CordRepBtree* CordRepBtree::New(int height) { - CordRepBtree* tree = new CordRepBtree; - tree->length = 0; - tree->InitInstance(height); - return tree; -} - -inline CordRepBtree* CordRepBtree::New(CordRep* rep) { - CordRepBtree* tree = new CordRepBtree; - int height = rep->IsBtree() ? rep->btree()->height() + 1 : 0; - tree->length = rep->length; - tree->InitInstance(height, /*begin=*/0, /*end=*/1); - tree->edges_[0] = rep; - return tree; -} - -inline CordRepBtree* CordRepBtree::New(CordRepBtree* front, - CordRepBtree* back) { - assert(front->height() == back->height()); - CordRepBtree* tree = new CordRepBtree; - tree->length = front->length + back->length; - tree->InitInstance(front->height() + 1, /*begin=*/0, /*end=*/2); - tree->edges_[0] = front; - tree->edges_[1] = back; - return tree; -} - -inline void CordRepBtree::DestroyTree(CordRepBtree* tree, size_t begin, - size_t end) { - if (tree->height() == 0) { - DestroyLeaf(tree, begin, end); - } else { - DestroyNonLeaf(tree, begin, end); - } -} - -inline void CordRepBtree::Destroy(CordRepBtree* tree) { - DestroyTree(tree, tree->begin(), tree->end()); -} - -inline void CordRepBtree::Unref(absl::Span<CordRep* const> edges) { - for (CordRep* edge : edges) { - if (ABSL_PREDICT_FALSE(!edge->refcount.Decrement())) { - CordRep::Destroy(edge); - } - } -} - -inline CordRepBtree* CordRepBtree::CopyRaw() const { - auto* tree = static_cast<CordRepBtree*>(::operator new(sizeof(CordRepBtree))); - memcpy(static_cast<void*>(tree), this, sizeof(CordRepBtree)); - new (&tree->refcount) RefcountAndFlags; - return tree; -} - -inline CordRepBtree* CordRepBtree::Copy() const { - CordRepBtree* tree = CopyRaw(); - for (CordRep* rep : Edges()) CordRep::Ref(rep); - return tree; -} - -inline CordRepBtree* CordRepBtree::CopyToEndFrom(size_t begin, - size_t new_length) const { - assert(begin >= this->begin()); - assert(begin <= this->end()); - CordRepBtree* tree = CopyRaw(); - tree->length = new_length; - tree->set_begin(begin); - for (CordRep* edge : tree->Edges()) CordRep::Ref(edge); - return tree; -} - -inline CordRepBtree* CordRepBtree::CopyBeginTo(size_t end, - size_t new_length) const { - assert(end <= capacity()); - assert(end >= this->begin()); - CordRepBtree* tree = CopyRaw(); - tree->length = new_length; - tree->set_end(end); - for (CordRep* edge : tree->Edges()) CordRep::Ref(edge); - return tree; -} - -inline void CordRepBtree::AlignBegin() { - // The below code itself does not need to be fast as typically we have - // mono-directional append/prepend calls, and `begin` / `end` are typically - // adjusted no more than once. But we want to avoid potential register clobber - // effects, making the compiler emit register save/store/spills, and minimize - // the size of code. - const size_t delta = begin(); - if (ABSL_PREDICT_FALSE(delta != 0)) { - const size_t new_end = end() - delta; - set_begin(0); - set_end(new_end); - // TODO(mvels): we can write this using 2 loads / 2 stores depending on - // total size for the kMaxCapacity = 6 case. I.e., we can branch (switch) on - // size, and then do overlapping load/store of up to 4 pointers (inlined as - // XMM, YMM or ZMM load/store) and up to 2 pointers (XMM / YMM), which is a) - // compact and b) not clobbering any registers. - ABSL_INTERNAL_ASSUME(new_end <= kMaxCapacity); -#ifdef __clang__ -#pragma unroll 1 -#endif - for (size_t i = 0; i < new_end; ++i) { - edges_[i] = edges_[i + delta]; - } - } -} - -inline void CordRepBtree::AlignEnd() { - // See comments in `AlignBegin` for motivation on the hand-rolled for loops. - const size_t delta = capacity() - end(); - if (delta != 0) { - const size_t new_begin = begin() + delta; - const size_t new_end = end() + delta; - set_begin(new_begin); - set_end(new_end); - ABSL_INTERNAL_ASSUME(new_end <= kMaxCapacity); -#ifdef __clang__ -#pragma unroll 1 -#endif - for (size_t i = new_end - 1; i >= new_begin; --i) { - edges_[i] = edges_[i - delta]; - } - } -} - -template <> -inline void CordRepBtree::Add<CordRepBtree::kBack>(CordRep* rep) { - AlignBegin(); - edges_[fetch_add_end(1)] = rep; -} - -template <> -inline void CordRepBtree::Add<CordRepBtree::kBack>( - absl::Span<CordRep* const> edges) { - AlignBegin(); - size_t new_end = end(); - for (CordRep* edge : edges) edges_[new_end++] = edge; - set_end(new_end); -} - -template <> -inline void CordRepBtree::Add<CordRepBtree::kFront>(CordRep* rep) { - AlignEnd(); - edges_[sub_fetch_begin(1)] = rep; -} - -template <> -inline void CordRepBtree::Add<CordRepBtree::kFront>( - absl::Span<CordRep* const> edges) { - AlignEnd(); - size_t new_begin = begin() - edges.size(); - set_begin(new_begin); - for (CordRep* edge : edges) edges_[new_begin++] = edge; -} - -template <CordRepBtree::EdgeType edge_type> -inline void CordRepBtree::SetEdge(CordRep* edge) { - const int idx = edge_type == kFront ? begin() : back(); - CordRep::Unref(edges_[idx]); - edges_[idx] = edge; -} - -inline CordRepBtree::OpResult CordRepBtree::ToOpResult(bool owned) { - return owned ? OpResult{this, kSelf} : OpResult{Copy(), kCopied}; -} - -inline CordRepBtree::Position CordRepBtree::IndexOf(size_t offset) const { - assert(offset < length); - size_t index = begin(); - while (offset >= edges_[index]->length) offset -= edges_[index++]->length; - return {index, offset}; -} - -inline CordRepBtree::Position CordRepBtree::IndexBefore(size_t offset) const { - assert(offset > 0); - assert(offset <= length); - size_t index = begin(); - while (offset > edges_[index]->length) offset -= edges_[index++]->length; - return {index, offset}; -} - -inline CordRepBtree::Position CordRepBtree::IndexBefore(Position front, - size_t offset) const { - size_t index = front.index; - offset = offset + front.n; - while (offset > edges_[index]->length) offset -= edges_[index++]->length; - return {index, offset}; -} - -inline CordRepBtree::Position CordRepBtree::IndexOfLength(size_t n) const { - assert(n <= length); - size_t index = back(); - size_t strip = length - n; - while (strip >= edges_[index]->length) strip -= edges_[index--]->length; - return {index, edges_[index]->length - strip}; -} - -inline CordRepBtree::Position CordRepBtree::IndexBeyond( - const size_t offset) const { - // We need to find the edge which `starting offset` is beyond (>=)`offset`. - // For this we can't use the `offset -= length` logic of IndexOf. Instead, we - // track the offset of the `current edge` in `off`, which we increase as we - // iterate over the edges until we find the matching edge. - size_t off = 0; - size_t index = begin(); - while (offset > off) off += edges_[index++]->length; - return {index, off - offset}; -} - -inline CordRepBtree* CordRepBtree::Create(CordRep* rep) { - if (IsDataEdge(rep)) return New(rep); - return CreateSlow(rep); -} - -inline Span<char> CordRepBtree::GetAppendBuffer(size_t size) { - assert(refcount.IsMutable()); - CordRepBtree* tree = this; - const int height = this->height(); - CordRepBtree* n1 = tree; - CordRepBtree* n2 = tree; - CordRepBtree* n3 = tree; - switch (height) { - case 3: - tree = tree->Edge(kBack)->btree(); - if (!tree->refcount.IsMutable()) return {}; - n2 = tree; - ABSL_FALLTHROUGH_INTENDED; - case 2: - tree = tree->Edge(kBack)->btree(); - if (!tree->refcount.IsMutable()) return {}; - n1 = tree; - ABSL_FALLTHROUGH_INTENDED; - case 1: - tree = tree->Edge(kBack)->btree(); - if (!tree->refcount.IsMutable()) return {}; - ABSL_FALLTHROUGH_INTENDED; - case 0: - CordRep* edge = tree->Edge(kBack); - if (!edge->refcount.IsMutable()) return {}; - if (edge->tag < FLAT) return {}; - size_t avail = edge->flat()->Capacity() - edge->length; - if (avail == 0) return {}; - size_t delta = (std::min)(size, avail); - Span<char> span = {edge->flat()->Data() + edge->length, delta}; - edge->length += delta; - switch (height) { - case 3: - n3->length += delta; - ABSL_FALLTHROUGH_INTENDED; - case 2: - n2->length += delta; - ABSL_FALLTHROUGH_INTENDED; - case 1: - n1->length += delta; - ABSL_FALLTHROUGH_INTENDED; - case 0: - tree->length += delta; - return span; - } - break; - } - return GetAppendBufferSlow(size); -} - -extern template CordRepBtree* CordRepBtree::AddCordRep<CordRepBtree::kBack>( - CordRepBtree* tree, CordRep* rep); - -extern template CordRepBtree* CordRepBtree::AddCordRep<CordRepBtree::kFront>( - CordRepBtree* tree, CordRep* rep); - -inline CordRepBtree* CordRepBtree::Append(CordRepBtree* tree, CordRep* rep) { - if (ABSL_PREDICT_TRUE(IsDataEdge(rep))) { - return CordRepBtree::AddCordRep<kBack>(tree, rep); - } - return AppendSlow(tree, rep); -} - -inline CordRepBtree* CordRepBtree::Prepend(CordRepBtree* tree, CordRep* rep) { - if (ABSL_PREDICT_TRUE(IsDataEdge(rep))) { - return CordRepBtree::AddCordRep<kFront>(tree, rep); - } - return PrependSlow(tree, rep); -} - -#ifdef NDEBUG - -inline CordRepBtree* CordRepBtree::AssertValid(CordRepBtree* tree, - bool /* shallow */) { - return tree; -} - -inline const CordRepBtree* CordRepBtree::AssertValid(const CordRepBtree* tree, - bool /* shallow */) { - return tree; -} - -#endif - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_H_ +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_H_ +#define ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_H_ + +#include <cassert> +#include <cstdint> +#include <iosfwd> + +#include "absl/base/config.h" +#include "absl/base/internal/raw_logging.h" +#include "absl/base/optimization.h" +#include "absl/strings/internal/cord_internal.h" +#include "absl/strings/internal/cord_rep_flat.h" +#include "absl/strings/string_view.h" +#include "absl/types/span.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +class CordRepBtreeNavigator; + +// CordRepBtree is as the name implies a btree implementation of a Cordrep tree. +// Data is stored at the leaf level only, non leaf nodes contain down pointers +// only. Allowed types of data edges are FLAT, EXTERNAL and SUBSTRINGs of FLAT +// or EXTERNAL nodes. The implementation allows for data to be added to either +// end of the tree only, it does not provide any 'insert' logic. This has the +// benefit that we can expect good fill ratios: all nodes except the outer +// 'legs' will have 100% fill ratios for trees built using Append/Prepend +// methods. Merged trees will typically have a fill ratio well above 50% as in a +// similar fashion, one side of the merged tree will typically have a 100% fill +// ratio, and the 'open' end will average 50%. All operations are O(log(n)) or +// better, and the tree never needs balancing. +// +// All methods accepting a CordRep* or CordRepBtree* adopt a reference on that +// input unless explicitly stated otherwise. All functions returning a CordRep* +// or CordRepBtree* instance transfer a reference back to the caller. +// Simplified, callers both 'donate' and 'consume' a reference count on each +// call, simplifying the API. An example of building a tree: +// +// CordRepBtree* tree = CordRepBtree::Create(MakeFlat("Hello")); +// tree = CordRepBtree::Append(tree, MakeFlat("world")); +// +// In the above example, all inputs are consumed, making each call affecting +// `tree` reference count neutral. The returned `tree` value can be different +// from the input if the input is shared with other threads, or if the tree +// grows in height, but callers typically never have to concern themselves with +// that and trust that all methods DTRT at all times. +class CordRepBtree : public CordRep { + public: + // EdgeType identifies `front` and `back` enum values. + // Various implementations in CordRepBtree such as `Add` and `Edge` are + // generic and templated on operating on either of the boundary edges. + // For more information on the possible edges contained in a CordRepBtree + // instance see the documentation for `edges_`. + enum class EdgeType { kFront, kBack }; + + // Convenience constants into `EdgeType` + static constexpr EdgeType kFront = EdgeType::kFront; + static constexpr EdgeType kBack = EdgeType::kBack; + + // Maximum number of edges: based on experiments and performance data, we can + // pick suitable values resulting in optimum cacheline aligned values. The + // preferred values are based on 64-bit systems where we aim to align this + // class onto 64 bytes, i.e.: 6 = 64 bytes, 14 = 128 bytes, etc. + // TODO(b/192061034): experiment with alternative sizes. + static constexpr size_t kMaxCapacity = 6; + + // Reasonable maximum height of the btree. We can expect a fill ratio of at + // least 50%: trees are always expanded at the front or back. Concatenating + // trees will then typically fold at the top most node, where the lower nodes + // are at least at capacity on one side of joined inputs. At a lower fill + // rate of 4 edges per node, we have capacity for ~16 million leaf nodes. + // We will fail / abort if an application ever exceeds this height, which + // should be extremely rare (near impossible) and be an indication of an + // application error: we do not assume it reasonable for any application to + // operate correctly with such monster trees. + // Another compelling reason for the number `12` is that any contextual stack + // required for navigation or insertion requires 12 words and 12 bytes, which + // fits inside 2 cache lines with some room to spare, and is reasonable as a + // local stack variable compared to Cord's current near 400 bytes stack use. + // The maximum `height` value of a node is then `kMaxDepth - 1` as node height + // values start with a value of 0 for leaf nodes. + static constexpr int kMaxDepth = 12; + static constexpr int kMaxHeight = kMaxDepth - 1; + + // `Action` defines the action for unwinding changes done at the btree's leaf + // level that need to be propagated up to the parent node(s). Each operation + // on a node has an effect / action defined as follows: + // - kSelf + // The operation (add / update, etc) was performed directly on the node as + // the node is private to the current thread (i.e.: not shared directly or + // indirectly through a refcount > 1). Changes can be propagated directly to + // all parent nodes as all parent nodes are also then private to the current + // thread. + // - kCopied + // The operation (add / update, etc) was performed on a copy of the original + // node, as the node is (potentially) directly or indirectly shared with + // other threads. Changes need to be propagated into the parent nodes where + // the old down pointer must be unreffed and replaced with this new copy. + // Such changes to parent nodes may themselves require a copy if the parent + // node is also shared. A kCopied action can propagate all the way to the + // top node where we then must unref the `tree` input provided by the + // caller, and return the new copy. + // - kPopped + // The operation (typically add) could not be satisfied due to insufficient + // capacity in the targeted node, and a new 'leg' was created that needs to + // be added into the parent node. For example, adding a FLAT inside a leaf + // node that is at capacity will create a new leaf node containing that + // FLAT, that needs to be 'popped' up the btree. Such 'pop' actions can + // cascade up the tree if parent nodes are also at capacity. A 'Popped' + // action propagating all the way to the top of the tree will result in + // the tree becoming one level higher than the current tree through a final + // `CordRepBtree::New(tree, popped)` call, resulting in a new top node + // referencing the old tree and the new (fully popped upwards) 'leg'. + enum Action { kSelf, kCopied, kPopped }; + + // Result of an operation on a node. See the `Action` enum for details. + struct OpResult { + CordRepBtree* tree; + Action action; + }; + + // Return value of the CopyPrefix and CopySuffix methods which can + // return a node or data edge at any height inside the tree. + // A height of 0 defines the lowest (leaf) node, a height of -1 identifies + // `edge` as being a plain data node: EXTERNAL / FLAT or SUBSTRING thereof. + struct CopyResult { + CordRep* edge; + int height; + }; + + // Logical position inside a node: + // - index: index of the edge. + // - n: size or offset value depending on context. + struct Position { + size_t index; + size_t n; + }; + + // Creates a btree from the given input. Adopts a ref of `rep`. + // If the input `rep` is itself a btree, i.e., `IsBtree()`, then this + // function immediately returns `rep->btree()`. If the input is a valid data + // edge (see IsDataEdge()), then a new leaf node is returned containing `rep` + // as the sole data edge. Else, the input is assumed to be a (legacy) concat + // tree, and the input is consumed and transformed into a btree(). + static CordRepBtree* Create(CordRep* rep); + + // Destroys the provided tree. Should only be called by cord internal API's, + // typically after a ref_count.Decrement() on the last reference count. + static void Destroy(CordRepBtree* tree); + + // Use CordRep::Unref() as we overload for absl::Span<CordRep* const>. + using CordRep::Unref; + + // Unrefs all edges in `edges` which are assumed to be 'likely one'. + static void Unref(absl::Span<CordRep* const> edges); + + // Appends / Prepends an existing CordRep instance to this tree. + // The below methods accept three types of input: + // 1) `rep` is a data node (See `IsDataNode` for valid data edges). + // `rep` is appended or prepended to this tree 'as is'. + // 2) `rep` is a BTREE. + // `rep` is merged into `tree` respecting the Append/Prepend order. + // 3) `rep` is some other (legacy) type. + // `rep` is converted in place and added to `tree` + // Requires `tree` and `rep` to be not null. + static CordRepBtree* Append(CordRepBtree* tree, CordRep* rep); + static CordRepBtree* Prepend(CordRepBtree* tree, CordRep* rep); + + // Append/Prepend the data in `data` to this tree. + // The `extra` parameter defines how much extra capacity should be allocated + // for any additional FLAT being allocated. This is an optimization hint from + // the caller. For example, a caller may need to add 2 string_views of data + // "abc" and "defghi" which are not consecutive. The caller can in this case + // invoke `AddData(tree, "abc", 6)`, and any newly added flat is allocated + // where possible with at least 6 bytes of extra capacity beyond `length`. + // This helps avoiding data getting fragmented over multiple flats. + // There is no limit on the size of `data`. If `data` can not be stored inside + // a single flat, then the function will iteratively add flats until all data + // has been consumed and appended or prepended to the tree. + static CordRepBtree* Append(CordRepBtree* tree, string_view data, + size_t extra = 0); + static CordRepBtree* Prepend(CordRepBtree* tree, string_view data, + size_t extra = 0); + + // Returns a new tree, containing `n` bytes of data from this instance + // starting at offset `offset`. Where possible, the returned tree shares + // (re-uses) data edges and nodes with this instance to minimize the + // combined memory footprint of both trees. + // Requires `offset + n <= length`. Returns `nullptr` if `n` is zero. + CordRep* SubTree(size_t offset, size_t n); + + // Removes `n` trailing bytes from `tree`, and returns the resulting tree + // or data edge. Returns `tree` if n is zero, and nullptr if n == length. + // This function is logically identical to: + // result = tree->SubTree(0, tree->length - n); + // Unref(tree); + // return result; + // However, the actual implementation will as much as possible perform 'in + // place' modifications on the tree on all nodes and edges that are mutable. + // For example, in a fully privately owned tree with the last edge being a + // flat of length 12, RemoveSuffix(1) will simply set the length of that data + // edge to 11, and reduce the length of all nodes on the edge path by 1. + static CordRep* RemoveSuffix(CordRepBtree* tree, size_t n); + + // Returns the character at the given offset. + char GetCharacter(size_t offset) const; + + // Returns true if this node holds a single data edge, and if so, sets + // `fragment` to reference the contained data. `fragment` is an optional + // output parameter and allowed to be null. + bool IsFlat(absl::string_view* fragment) const; + + // Returns true if the data of `n` bytes starting at offset `offset` + // is contained in a single data edge, and if so, sets fragment to reference + // the contained data. `fragment` is an optional output parameter and allowed + // to be null. + bool IsFlat(size_t offset, size_t n, absl::string_view* fragment) const; + + // Returns a span (mutable range of bytes) of up to `size` bytes into the + // last FLAT data edge inside this tree under the following conditions: + // - none of the nodes down into the FLAT node are shared. + // - the last data edge in this tree is a non-shared FLAT. + // - the referenced FLAT has additional capacity available. + // If all these conditions are met, a non-empty span is returned, and the + // length of the flat node and involved tree nodes have been increased by + // `span.length()`. The caller is responsible for immediately assigning values + // to all uninitialized data reference by the returned span. + // Requires `this->refcount.IsMutable()`: this function forces the + // caller to do this fast path check on the top level node, as this is the + // most commonly shared node of a cord tree. + Span<char> GetAppendBuffer(size_t size); + + // Returns the `height` of the tree. The height of a tree is limited to + // kMaxHeight. `height` is implemented as an `int` as in some places we + // use negative (-1) values for 'data edges'. + int height() const { return static_cast<int>(storage[0]); } + + // Properties: begin, back, end, front/back boundary indexes. + size_t begin() const { return static_cast<size_t>(storage[1]); } + size_t back() const { return static_cast<size_t>(storage[2]) - 1; } + size_t end() const { return static_cast<size_t>(storage[2]); } + size_t index(EdgeType edge) const { + return edge == kFront ? begin() : back(); + } + + // Properties: size and capacity. + // `capacity` contains the current capacity of this instance, where + // `kMaxCapacity` contains the maximum capacity of a btree node. + // For now, `capacity` and `kMaxCapacity` return the same value, but this may + // change in the future if we see benefit in dynamically sizing 'small' nodes + // to 'large' nodes for large data trees. + size_t size() const { return end() - begin(); } + size_t capacity() const { return kMaxCapacity; } + + // Edge access + inline CordRep* Edge(size_t index) const; + inline CordRep* Edge(EdgeType edge_type) const; + inline absl::Span<CordRep* const> Edges() const; + inline absl::Span<CordRep* const> Edges(size_t begin, size_t end) const; + + // Returns reference to the data edge at `index`. + // Requires this instance to be a leaf node, and `index` to be valid index. + inline absl::string_view Data(size_t index) const; + + static const char* EdgeDataPtr(const CordRep* r); + static absl::string_view EdgeData(const CordRep* r); + + // Returns true if the provided rep is a FLAT, EXTERNAL or a SUBSTRING node + // holding a FLAT or EXTERNAL child rep. + static bool IsDataEdge(const CordRep* rep); + + // Diagnostics: returns true if `tree` is valid and internally consistent. + // If `shallow` is false, then the provided top level node and all child nodes + // below it are recursively checked. If `shallow` is true, only the provided + // node in `tree` and the cumulative length, type and height of the direct + // child nodes of `tree` are checked. The value of `shallow` is ignored if the + // internal `cord_btree_exhaustive_validation` diagnostics variable is true, + // in which case the performed validations works as if `shallow` were false. + // This function is intended for debugging and testing purposes only. + static bool IsValid(const CordRepBtree* tree, bool shallow = false); + + // Diagnostics: asserts that the provided tree is valid. + // `AssertValid()` performs a shallow validation by default. `shallow` can be + // set to false in which case an exhaustive validation is performed. This + // function is implemented in terms of calling `IsValid()` and asserting the + // return value to be true. See `IsValid()` for more information. + // This function is intended for debugging and testing purposes only. + static CordRepBtree* AssertValid(CordRepBtree* tree, bool shallow = true); + static const CordRepBtree* AssertValid(const CordRepBtree* tree, + bool shallow = true); + + // Diagnostics: dump the contents of this tree to `stream`. + // This function is intended for debugging and testing purposes only. + static void Dump(const CordRep* rep, std::ostream& stream); + static void Dump(const CordRep* rep, absl::string_view label, + std::ostream& stream); + static void Dump(const CordRep* rep, absl::string_view label, + bool include_contents, std::ostream& stream); + + // Adds the edge `edge` to this node if possible. `owned` indicates if the + // current node is potentially shared or not with other threads. Returns: + // - {kSelf, <this>} + // The edge was directly added to this node. + // - {kCopied, <node>} + // The edge was added to a copy of this node. + // - {kPopped, New(edge, height())} + // A new leg with the edge was created as this node has no extra capacity. + template <EdgeType edge_type> + inline OpResult AddEdge(bool owned, CordRep* edge, size_t delta); + + // Replaces the front or back edge with the provided new edge. Returns: + // - {kSelf, <this>} + // The edge was directly set in this node. The old edge is unreffed. + // - {kCopied, <node>} + // A copy of this node was created with the new edge value. + // In both cases, the function adopts a reference on `edge`. + template <EdgeType edge_type> + OpResult SetEdge(bool owned, CordRep* edge, size_t delta); + + // Creates a new empty node at the specified height. + static CordRepBtree* New(int height = 0); + + // Creates a new node containing `rep`, with the height being computed + // automatically based on the type of `rep`. + static CordRepBtree* New(CordRep* rep); + + // Creates a new node containing both `front` and `back` at height + // `front.height() + 1`. Requires `back.height() == front.height()`. + static CordRepBtree* New(CordRepBtree* front, CordRepBtree* back); + + // Creates a fully balanced tree from the provided tree by rebuilding a new + // tree from all data edges in the input. This function is automatically + // invoked internally when the tree exceeds the maximum height. + static CordRepBtree* Rebuild(CordRepBtree* tree); + + private: + CordRepBtree() = default; + ~CordRepBtree() = default; + + // Initializes the main properties `tag`, `begin`, `end`, `height`. + inline void InitInstance(int height, size_t begin = 0, size_t end = 0); + + // Direct property access begin / end + void set_begin(size_t begin) { storage[1] = static_cast<uint8_t>(begin); } + void set_end(size_t end) { storage[2] = static_cast<uint8_t>(end); } + + // Decreases the value of `begin` by `n`, and returns the new value. Notice + // how this returns the new value unlike atomic::fetch_add which returns the + // old value. This is because this is used to prepend edges at 'begin - 1'. + size_t sub_fetch_begin(size_t n) { + storage[1] -= static_cast<uint8_t>(n); + return storage[1]; + } + + // Increases the value of `end` by `n`, and returns the previous value. This + // function is typically used to append edges at 'end'. + size_t fetch_add_end(size_t n) { + const uint8_t current = storage[2]; + storage[2] = static_cast<uint8_t>(current + n); + return current; + } + + // Returns the index of the last edge starting on, or before `offset`, with + // `n` containing the relative offset of `offset` inside that edge. + // Requires `offset` < length. + Position IndexOf(size_t offset) const; + + // Returns the index of the last edge starting before `offset`, with `n` + // containing the relative offset of `offset` inside that edge. + // This function is useful to find the edges for some span of bytes ending at + // `offset` (i.e., `n` bytes). For example: + // + // Position pos = IndexBefore(n) + // edges = Edges(begin(), pos.index) // All full edges (may be empty) + // last = Sub(Edge(pos.index), 0, pos.n) // Last partial edge (may be empty) + // + // Requires 0 < `offset` <= length. + Position IndexBefore(size_t offset) const; + + // Returns the index of the edge ending at (or on) length `length`, and the + // number of bytes inside that edge up to `length`. For example, if we have a + // Node with 2 edges, one of 10 and one of 20 long, then IndexOfLength(27) + // will return {1, 17}, and IndexOfLength(10) will return {0, 10}. + Position IndexOfLength(size_t n) const; + + // Identical to the above function except starting from the position `front`. + // This function is equivalent to `IndexBefore(front.n + offset)`, with + // the difference that this function is optimized to start at `front.index`. + Position IndexBefore(Position front, size_t offset) const; + + // Returns the index of the edge directly beyond the edge containing offset + // `offset`, with `n` containing the distance of that edge from `offset`. + // This function is useful for iteratively finding suffix nodes and remaining + // partial bytes in left-most suffix nodes as for example in CopySuffix. + // Requires `offset` < length. + Position IndexBeyond(size_t offset) const; + + // Destruction + static void DestroyLeaf(CordRepBtree* tree, size_t begin, size_t end); + static void DestroyNonLeaf(CordRepBtree* tree, size_t begin, size_t end); + static void DestroyTree(CordRepBtree* tree, size_t begin, size_t end); + static void Delete(CordRepBtree* tree) { delete tree; } + + // Creates a new leaf node containing as much data as possible from `data`. + // The data is added either forwards or reversed depending on `edge_type`. + // Callers must check the length of the returned node to determine if all data + // was copied or not. + // See the `Append/Prepend` function for the meaning and purpose of `extra`. + template <EdgeType edge_type> + static CordRepBtree* NewLeaf(absl::string_view data, size_t extra); + + // Creates a raw copy of this Btree node, copying all properties, but + // without adding any references to existing edges. + CordRepBtree* CopyRaw() const; + + // Creates a full copy of this Btree node, adding a reference on all edges. + CordRepBtree* Copy() const; + + // Creates a partial copy of this Btree node, copying all edges up to `end`, + // adding a reference on each copied edge, and sets the length of the newly + // created copy to `new_length`. + CordRepBtree* CopyBeginTo(size_t end, size_t new_length) const; + + // Returns a tree containing the edges [tree->begin(), end) and length + // of `new_length`. This method consumes a reference on the provided + // tree, and logically performs the following operation: + // result = tree->CopyBeginTo(end, new_length); + // CordRep::Unref(tree); + // return result; + static CordRepBtree* ConsumeBeginTo(CordRepBtree* tree, size_t end, + size_t new_length); + + // Creates a partial copy of this Btree node, copying all edges starting at + // `begin`, adding a reference on each copied edge, and sets the length of + // the newly created copy to `new_length`. + CordRepBtree* CopyToEndFrom(size_t begin, size_t new_length) const; + + // Extracts and returns the front edge from the provided tree. + // This method consumes a reference on the provided tree, and logically + // performs the following operation: + // edge = CordRep::Ref(tree->Edge(kFront)); + // CordRep::Unref(tree); + // return edge; + static CordRep* ExtractFront(CordRepBtree* tree); + + // Returns a tree containing the result of appending `right` to `left`. + static CordRepBtree* MergeTrees(CordRepBtree* left, CordRepBtree* right); + + // Fallback functions for `Create()`, `Append()` and `Prepend()` which + // deal with legacy / non conforming input, i.e.: CONCAT trees. + static CordRepBtree* CreateSlow(CordRep* rep); + static CordRepBtree* AppendSlow(CordRepBtree*, CordRep* rep); + static CordRepBtree* PrependSlow(CordRepBtree*, CordRep* rep); + + // Recursively rebuilds `tree` into `stack`. If 'consume` is set to true, the + // function will consume a reference on `tree`. `stack` is a null terminated + // array containing the new tree's state, with the current leaf node at + // stack[0], and parent nodes above that, or null for 'top of tree'. + static void Rebuild(CordRepBtree** stack, CordRepBtree* tree, bool consume); + + // Aligns existing edges to start at index 0, to allow for a new edge to be + // added to the back of the current edges. + inline void AlignBegin(); + + // Aligns existing edges to end at `capacity`, to allow for a new edge to be + // added in front of the current edges. + inline void AlignEnd(); + + // Adds the provided edge to this node. + // Requires this node to have capacity for the edge. Realigns / moves + // existing edges as needed to prepend or append the new edge. + template <EdgeType edge_type> + inline void Add(CordRep* rep); + + // Adds the provided edges to this node. + // Requires this node to have capacity for the edges. Realigns / moves + // existing edges as needed to prepend or append the new edges. + template <EdgeType edge_type> + inline void Add(absl::Span<CordRep* const>); + + // Adds data from `data` to this node until either all data has been consumed, + // or there is no more capacity for additional flat nodes inside this node. + // Requires the current node to be a leaf node, data to be non empty, and the + // current node to have capacity for at least one more data edge. + // Returns any remaining data from `data` that was not added, which is + // depending on the edge type (front / back) either the remaining prefix of + // suffix of the input. + // See the `Append/Prepend` function for the meaning and purpose of `extra`. + template <EdgeType edge_type> + absl::string_view AddData(absl::string_view data, size_t extra); + + // Replace the front or back edge with the provided value. + // Adopts a reference on `edge` and unrefs the old edge. + template <EdgeType edge_type> + inline void SetEdge(CordRep* edge); + + // Returns a partial copy of the current tree containing the first `n` bytes + // of data. `CopyResult` contains both the resulting edge and its height. The + // resulting tree may be less high than the current tree, or even be a single + // matching data edge if `allow_folding` is set to true. + // For example, if `n == 1`, then the result will be the single data edge, and + // height will be set to -1 (one below the owning leaf node). If n == 0, this + // function returns null. Requires `n <= length` + CopyResult CopyPrefix(size_t n, bool allow_folding = true); + + // Returns a partial copy of the current tree containing all data starting + // after `offset`. `CopyResult` contains both the resulting edge and its + // height. The resulting tree may be less high than the current tree, or even + // be a single matching data edge. For example, if `n == length - 1`, then the + // result will be a single data edge, and height will be set to -1 (one below + // the owning leaf node). + // Requires `offset < length` + CopyResult CopySuffix(size_t offset); + + // Returns a OpResult value of {this, kSelf} or {Copy(), kCopied} + // depending on the value of `owned`. + inline OpResult ToOpResult(bool owned); + + // Adds `rep` to the specified tree, returning the modified tree. + template <EdgeType edge_type> + static CordRepBtree* AddCordRep(CordRepBtree* tree, CordRep* rep); + + // Adds `data` to the specified tree, returning the modified tree. + // See the `Append/Prepend` function for the meaning and purpose of `extra`. + template <EdgeType edge_type> + static CordRepBtree* AddData(CordRepBtree* tree, absl::string_view data, + size_t extra = 0); + + // Merges `src` into `dst` with `src` being added either before (kFront) or + // after (kBack) `dst`. Requires the height of `dst` to be greater than or + // equal to the height of `src`. + template <EdgeType edge_type> + static CordRepBtree* Merge(CordRepBtree* dst, CordRepBtree* src); + + // Fallback version of GetAppendBuffer for large trees: GetAppendBuffer() + // implements an inlined version for trees of limited height (3 levels), + // GetAppendBufferSlow implements the logic for large trees. + Span<char> GetAppendBufferSlow(size_t size); + + // `edges_` contains all edges starting from this instance. + // These are explicitly `child` edges only, a cord btree (or any cord tree in + // that respect) does not store `parent` pointers anywhere: multiple trees / + // parents can reference the same shared child edge. The type of these edges + // depends on the height of the node. `Leaf nodes` (height == 0) contain `data + // edges` (external or flat nodes, or sub-strings thereof). All other nodes + // (height > 0) contain pointers to BTREE nodes with a height of `height - 1`. + CordRep* edges_[kMaxCapacity]; + + friend class CordRepBtreeTestPeer; + friend class CordRepBtreeNavigator; +}; + +inline CordRepBtree* CordRep::btree() { + assert(IsBtree()); + return static_cast<CordRepBtree*>(this); +} + +inline const CordRepBtree* CordRep::btree() const { + assert(IsBtree()); + return static_cast<const CordRepBtree*>(this); +} + +inline void CordRepBtree::InitInstance(int height, size_t begin, size_t end) { + tag = BTREE; + storage[0] = static_cast<uint8_t>(height); + storage[1] = static_cast<uint8_t>(begin); + storage[2] = static_cast<uint8_t>(end); +} + +inline CordRep* CordRepBtree::Edge(size_t index) const { + assert(index >= begin()); + assert(index < end()); + return edges_[index]; +} + +inline CordRep* CordRepBtree::Edge(EdgeType edge_type) const { + return edges_[edge_type == kFront ? begin() : back()]; +} + +inline absl::Span<CordRep* const> CordRepBtree::Edges() const { + return {edges_ + begin(), size()}; +} + +inline absl::Span<CordRep* const> CordRepBtree::Edges(size_t begin, + size_t end) const { + assert(begin <= end); + assert(begin >= this->begin()); + assert(end <= this->end()); + return {edges_ + begin, static_cast<size_t>(end - begin)}; +} + +inline const char* CordRepBtree::EdgeDataPtr(const CordRep* r) { + assert(IsDataEdge(r)); + size_t offset = 0; + if (r->tag == SUBSTRING) { + offset = r->substring()->start; + r = r->substring()->child; + } + return (r->tag >= FLAT ? r->flat()->Data() : r->external()->base) + offset; +} + +inline absl::string_view CordRepBtree::EdgeData(const CordRep* r) { + return absl::string_view(EdgeDataPtr(r), r->length); +} + +inline absl::string_view CordRepBtree::Data(size_t index) const { + assert(height() == 0); + return EdgeData(Edge(index)); +} + +inline bool CordRepBtree::IsDataEdge(const CordRep* rep) { + // The fast path is that `rep` is an EXTERNAL or FLAT node, making the below + // if a single, well predicted branch. We then repeat the FLAT or EXTERNAL + // check in the slow path the SUBSTRING check to optimize for the hot path. + if (rep->tag == EXTERNAL || rep->tag >= FLAT) return true; + if (rep->tag == SUBSTRING) rep = rep->substring()->child; + return rep->tag == EXTERNAL || rep->tag >= FLAT; +} + +inline CordRepBtree* CordRepBtree::New(int height) { + CordRepBtree* tree = new CordRepBtree; + tree->length = 0; + tree->InitInstance(height); + return tree; +} + +inline CordRepBtree* CordRepBtree::New(CordRep* rep) { + CordRepBtree* tree = new CordRepBtree; + int height = rep->IsBtree() ? rep->btree()->height() + 1 : 0; + tree->length = rep->length; + tree->InitInstance(height, /*begin=*/0, /*end=*/1); + tree->edges_[0] = rep; + return tree; +} + +inline CordRepBtree* CordRepBtree::New(CordRepBtree* front, + CordRepBtree* back) { + assert(front->height() == back->height()); + CordRepBtree* tree = new CordRepBtree; + tree->length = front->length + back->length; + tree->InitInstance(front->height() + 1, /*begin=*/0, /*end=*/2); + tree->edges_[0] = front; + tree->edges_[1] = back; + return tree; +} + +inline void CordRepBtree::DestroyTree(CordRepBtree* tree, size_t begin, + size_t end) { + if (tree->height() == 0) { + DestroyLeaf(tree, begin, end); + } else { + DestroyNonLeaf(tree, begin, end); + } +} + +inline void CordRepBtree::Destroy(CordRepBtree* tree) { + DestroyTree(tree, tree->begin(), tree->end()); +} + +inline void CordRepBtree::Unref(absl::Span<CordRep* const> edges) { + for (CordRep* edge : edges) { + if (ABSL_PREDICT_FALSE(!edge->refcount.Decrement())) { + CordRep::Destroy(edge); + } + } +} + +inline CordRepBtree* CordRepBtree::CopyRaw() const { + auto* tree = static_cast<CordRepBtree*>(::operator new(sizeof(CordRepBtree))); + memcpy(static_cast<void*>(tree), this, sizeof(CordRepBtree)); + new (&tree->refcount) RefcountAndFlags; + return tree; +} + +inline CordRepBtree* CordRepBtree::Copy() const { + CordRepBtree* tree = CopyRaw(); + for (CordRep* rep : Edges()) CordRep::Ref(rep); + return tree; +} + +inline CordRepBtree* CordRepBtree::CopyToEndFrom(size_t begin, + size_t new_length) const { + assert(begin >= this->begin()); + assert(begin <= this->end()); + CordRepBtree* tree = CopyRaw(); + tree->length = new_length; + tree->set_begin(begin); + for (CordRep* edge : tree->Edges()) CordRep::Ref(edge); + return tree; +} + +inline CordRepBtree* CordRepBtree::CopyBeginTo(size_t end, + size_t new_length) const { + assert(end <= capacity()); + assert(end >= this->begin()); + CordRepBtree* tree = CopyRaw(); + tree->length = new_length; + tree->set_end(end); + for (CordRep* edge : tree->Edges()) CordRep::Ref(edge); + return tree; +} + +inline void CordRepBtree::AlignBegin() { + // The below code itself does not need to be fast as typically we have + // mono-directional append/prepend calls, and `begin` / `end` are typically + // adjusted no more than once. But we want to avoid potential register clobber + // effects, making the compiler emit register save/store/spills, and minimize + // the size of code. + const size_t delta = begin(); + if (ABSL_PREDICT_FALSE(delta != 0)) { + const size_t new_end = end() - delta; + set_begin(0); + set_end(new_end); + // TODO(mvels): we can write this using 2 loads / 2 stores depending on + // total size for the kMaxCapacity = 6 case. I.e., we can branch (switch) on + // size, and then do overlapping load/store of up to 4 pointers (inlined as + // XMM, YMM or ZMM load/store) and up to 2 pointers (XMM / YMM), which is a) + // compact and b) not clobbering any registers. + ABSL_INTERNAL_ASSUME(new_end <= kMaxCapacity); +#ifdef __clang__ +#pragma unroll 1 +#endif + for (size_t i = 0; i < new_end; ++i) { + edges_[i] = edges_[i + delta]; + } + } +} + +inline void CordRepBtree::AlignEnd() { + // See comments in `AlignBegin` for motivation on the hand-rolled for loops. + const size_t delta = capacity() - end(); + if (delta != 0) { + const size_t new_begin = begin() + delta; + const size_t new_end = end() + delta; + set_begin(new_begin); + set_end(new_end); + ABSL_INTERNAL_ASSUME(new_end <= kMaxCapacity); +#ifdef __clang__ +#pragma unroll 1 +#endif + for (size_t i = new_end - 1; i >= new_begin; --i) { + edges_[i] = edges_[i - delta]; + } + } +} + +template <> +inline void CordRepBtree::Add<CordRepBtree::kBack>(CordRep* rep) { + AlignBegin(); + edges_[fetch_add_end(1)] = rep; +} + +template <> +inline void CordRepBtree::Add<CordRepBtree::kBack>( + absl::Span<CordRep* const> edges) { + AlignBegin(); + size_t new_end = end(); + for (CordRep* edge : edges) edges_[new_end++] = edge; + set_end(new_end); +} + +template <> +inline void CordRepBtree::Add<CordRepBtree::kFront>(CordRep* rep) { + AlignEnd(); + edges_[sub_fetch_begin(1)] = rep; +} + +template <> +inline void CordRepBtree::Add<CordRepBtree::kFront>( + absl::Span<CordRep* const> edges) { + AlignEnd(); + size_t new_begin = begin() - edges.size(); + set_begin(new_begin); + for (CordRep* edge : edges) edges_[new_begin++] = edge; +} + +template <CordRepBtree::EdgeType edge_type> +inline void CordRepBtree::SetEdge(CordRep* edge) { + const int idx = edge_type == kFront ? begin() : back(); + CordRep::Unref(edges_[idx]); + edges_[idx] = edge; +} + +inline CordRepBtree::OpResult CordRepBtree::ToOpResult(bool owned) { + return owned ? OpResult{this, kSelf} : OpResult{Copy(), kCopied}; +} + +inline CordRepBtree::Position CordRepBtree::IndexOf(size_t offset) const { + assert(offset < length); + size_t index = begin(); + while (offset >= edges_[index]->length) offset -= edges_[index++]->length; + return {index, offset}; +} + +inline CordRepBtree::Position CordRepBtree::IndexBefore(size_t offset) const { + assert(offset > 0); + assert(offset <= length); + size_t index = begin(); + while (offset > edges_[index]->length) offset -= edges_[index++]->length; + return {index, offset}; +} + +inline CordRepBtree::Position CordRepBtree::IndexBefore(Position front, + size_t offset) const { + size_t index = front.index; + offset = offset + front.n; + while (offset > edges_[index]->length) offset -= edges_[index++]->length; + return {index, offset}; +} + +inline CordRepBtree::Position CordRepBtree::IndexOfLength(size_t n) const { + assert(n <= length); + size_t index = back(); + size_t strip = length - n; + while (strip >= edges_[index]->length) strip -= edges_[index--]->length; + return {index, edges_[index]->length - strip}; +} + +inline CordRepBtree::Position CordRepBtree::IndexBeyond( + const size_t offset) const { + // We need to find the edge which `starting offset` is beyond (>=)`offset`. + // For this we can't use the `offset -= length` logic of IndexOf. Instead, we + // track the offset of the `current edge` in `off`, which we increase as we + // iterate over the edges until we find the matching edge. + size_t off = 0; + size_t index = begin(); + while (offset > off) off += edges_[index++]->length; + return {index, off - offset}; +} + +inline CordRepBtree* CordRepBtree::Create(CordRep* rep) { + if (IsDataEdge(rep)) return New(rep); + return CreateSlow(rep); +} + +inline Span<char> CordRepBtree::GetAppendBuffer(size_t size) { + assert(refcount.IsMutable()); + CordRepBtree* tree = this; + const int height = this->height(); + CordRepBtree* n1 = tree; + CordRepBtree* n2 = tree; + CordRepBtree* n3 = tree; + switch (height) { + case 3: + tree = tree->Edge(kBack)->btree(); + if (!tree->refcount.IsMutable()) return {}; + n2 = tree; + ABSL_FALLTHROUGH_INTENDED; + case 2: + tree = tree->Edge(kBack)->btree(); + if (!tree->refcount.IsMutable()) return {}; + n1 = tree; + ABSL_FALLTHROUGH_INTENDED; + case 1: + tree = tree->Edge(kBack)->btree(); + if (!tree->refcount.IsMutable()) return {}; + ABSL_FALLTHROUGH_INTENDED; + case 0: + CordRep* edge = tree->Edge(kBack); + if (!edge->refcount.IsMutable()) return {}; + if (edge->tag < FLAT) return {}; + size_t avail = edge->flat()->Capacity() - edge->length; + if (avail == 0) return {}; + size_t delta = (std::min)(size, avail); + Span<char> span = {edge->flat()->Data() + edge->length, delta}; + edge->length += delta; + switch (height) { + case 3: + n3->length += delta; + ABSL_FALLTHROUGH_INTENDED; + case 2: + n2->length += delta; + ABSL_FALLTHROUGH_INTENDED; + case 1: + n1->length += delta; + ABSL_FALLTHROUGH_INTENDED; + case 0: + tree->length += delta; + return span; + } + break; + } + return GetAppendBufferSlow(size); +} + +extern template CordRepBtree* CordRepBtree::AddCordRep<CordRepBtree::kBack>( + CordRepBtree* tree, CordRep* rep); + +extern template CordRepBtree* CordRepBtree::AddCordRep<CordRepBtree::kFront>( + CordRepBtree* tree, CordRep* rep); + +inline CordRepBtree* CordRepBtree::Append(CordRepBtree* tree, CordRep* rep) { + if (ABSL_PREDICT_TRUE(IsDataEdge(rep))) { + return CordRepBtree::AddCordRep<kBack>(tree, rep); + } + return AppendSlow(tree, rep); +} + +inline CordRepBtree* CordRepBtree::Prepend(CordRepBtree* tree, CordRep* rep) { + if (ABSL_PREDICT_TRUE(IsDataEdge(rep))) { + return CordRepBtree::AddCordRep<kFront>(tree, rep); + } + return PrependSlow(tree, rep); +} + +#ifdef NDEBUG + +inline CordRepBtree* CordRepBtree::AssertValid(CordRepBtree* tree, + bool /* shallow */) { + return tree; +} + +inline const CordRepBtree* CordRepBtree::AssertValid(const CordRepBtree* tree, + bool /* shallow */) { + return tree; +} + +#endif + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.cc index d1f9995d00..df94523db9 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.cc @@ -1,185 +1,185 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/strings/internal/cord_rep_btree_navigator.h" - -#include <cassert> - -#include "absl/strings/internal/cord_internal.h" -#include "absl/strings/internal/cord_rep_btree.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -using ReadResult = CordRepBtreeNavigator::ReadResult; - -namespace { - -// Returns a `CordRepSubstring` from `rep` starting at `offset` of size `n`. -// If `rep` is already a `CordRepSubstring` instance, an adjusted instance is -// created based on the old offset and new offset. -// Adopts a reference on `rep`. Rep must be a valid data edge. Returns -// nullptr if `n == 0`, `rep` if `n == rep->length`. -// Requires `offset < rep->length` and `offset + n <= rep->length`. -// TODO(192061034): move to utility library in internal and optimize for small -// substrings of larger reps. -inline CordRep* Substring(CordRep* rep, size_t offset, size_t n) { - assert(n <= rep->length); - assert(offset < rep->length); - assert(offset <= rep->length - n); - assert(CordRepBtree::IsDataEdge(rep)); - - if (n == 0) return nullptr; - if (n == rep->length) return CordRep::Ref(rep); - - if (rep->tag == SUBSTRING) { - offset += rep->substring()->start; - rep = rep->substring()->child; - } - - CordRepSubstring* substring = new CordRepSubstring(); - substring->length = n; - substring->tag = SUBSTRING; - substring->start = offset; - substring->child = CordRep::Ref(rep); - return substring; -} - -inline CordRep* Substring(CordRep* rep, size_t offset) { - return Substring(rep, offset, rep->length - offset); -} - -} // namespace - -CordRepBtreeNavigator::Position CordRepBtreeNavigator::Skip(size_t n) { - int height = 0; - size_t index = index_[0]; - CordRepBtree* node = node_[0]; - CordRep* edge = node->Edge(index); - - // Overall logic: Find an edge of at least the length we need to skip. - // We consume all edges which are smaller (i.e., must be 100% skipped). - // If we exhausted all edges on the current level, we move one level - // up the tree, and repeat until we either find the edge, or until we hit - // the top of the tree meaning the skip exceeds tree->length. - while (n >= edge->length) { - n -= edge->length; - while (++index == node->end()) { - if (++height > height_) return {nullptr, n}; - node = node_[height]; - index = index_[height]; - } - edge = node->Edge(index); - } - - // If we moved up the tree, descend down to the leaf level, consuming all - // edges that must be skipped. - while (height > 0) { - node = edge->btree(); - index_[height] = index; - node_[--height] = node; - index = node->begin(); - edge = node->Edge(index); - while (n >= edge->length) { - n -= edge->length; - ++index; - assert(index != node->end()); - edge = node->Edge(index); - } - } - index_[0] = index; - return {edge, n}; -} - -ReadResult CordRepBtreeNavigator::Read(size_t edge_offset, size_t n) { - int height = 0; - size_t length = edge_offset + n; - size_t index = index_[0]; - CordRepBtree* node = node_[0]; - CordRep* edge = node->Edge(index); - assert(edge_offset < edge->length); - - if (length < edge->length) { - return {Substring(edge, edge_offset, n), length}; - } - - // Similar to 'Skip', we consume all edges that are inside the 'length' of - // data that needs to be read. If we exhaust the current level, we move one - // level up the tree and repeat until we hit the final edge that must be - // (partially) read. We consume all edges into `subtree`. - CordRepBtree* subtree = CordRepBtree::New(Substring(edge, edge_offset)); - size_t subtree_end = 1; - do { - length -= edge->length; - while (++index == node->end()) { - index_[height] = index; - if (++height > height_) { - subtree->set_end(subtree_end); - if (length == 0) return {subtree, 0}; - CordRep::Unref(subtree); - return {nullptr, length}; - } - if (length != 0) { - subtree->set_end(subtree_end); - subtree = CordRepBtree::New(subtree); - subtree_end = 1; - } - node = node_[height]; - index = index_[height]; - } - edge = node->Edge(index); - if (length >= edge->length) { - subtree->length += edge->length; - subtree->edges_[subtree_end++] = CordRep::Ref(edge); - } - } while (length >= edge->length); - CordRepBtree* tree = subtree; - subtree->length += length; - - // If we moved up the tree, descend down to the leaf level, consuming all - // edges that must be read, adding 'down' nodes to `subtree`. - while (height > 0) { - node = edge->btree(); - index_[height] = index; - node_[--height] = node; - index = node->begin(); - edge = node->Edge(index); - - if (length != 0) { - CordRepBtree* right = CordRepBtree::New(height); - right->length = length; - subtree->edges_[subtree_end++] = right; - subtree->set_end(subtree_end); - subtree = right; - subtree_end = 0; - while (length >= edge->length) { - subtree->edges_[subtree_end++] = CordRep::Ref(edge); - length -= edge->length; - edge = node->Edge(++index); - } - } - } - // Add any (partial) edge still remaining at the leaf level. - if (length != 0) { - subtree->edges_[subtree_end++] = Substring(edge, 0, length); - } - subtree->set_end(subtree_end); - index_[0] = index; - return {tree, length}; -} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace absl +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/strings/internal/cord_rep_btree_navigator.h" + +#include <cassert> + +#include "absl/strings/internal/cord_internal.h" +#include "absl/strings/internal/cord_rep_btree.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +using ReadResult = CordRepBtreeNavigator::ReadResult; + +namespace { + +// Returns a `CordRepSubstring` from `rep` starting at `offset` of size `n`. +// If `rep` is already a `CordRepSubstring` instance, an adjusted instance is +// created based on the old offset and new offset. +// Adopts a reference on `rep`. Rep must be a valid data edge. Returns +// nullptr if `n == 0`, `rep` if `n == rep->length`. +// Requires `offset < rep->length` and `offset + n <= rep->length`. +// TODO(192061034): move to utility library in internal and optimize for small +// substrings of larger reps. +inline CordRep* Substring(CordRep* rep, size_t offset, size_t n) { + assert(n <= rep->length); + assert(offset < rep->length); + assert(offset <= rep->length - n); + assert(CordRepBtree::IsDataEdge(rep)); + + if (n == 0) return nullptr; + if (n == rep->length) return CordRep::Ref(rep); + + if (rep->tag == SUBSTRING) { + offset += rep->substring()->start; + rep = rep->substring()->child; + } + + CordRepSubstring* substring = new CordRepSubstring(); + substring->length = n; + substring->tag = SUBSTRING; + substring->start = offset; + substring->child = CordRep::Ref(rep); + return substring; +} + +inline CordRep* Substring(CordRep* rep, size_t offset) { + return Substring(rep, offset, rep->length - offset); +} + +} // namespace + +CordRepBtreeNavigator::Position CordRepBtreeNavigator::Skip(size_t n) { + int height = 0; + size_t index = index_[0]; + CordRepBtree* node = node_[0]; + CordRep* edge = node->Edge(index); + + // Overall logic: Find an edge of at least the length we need to skip. + // We consume all edges which are smaller (i.e., must be 100% skipped). + // If we exhausted all edges on the current level, we move one level + // up the tree, and repeat until we either find the edge, or until we hit + // the top of the tree meaning the skip exceeds tree->length. + while (n >= edge->length) { + n -= edge->length; + while (++index == node->end()) { + if (++height > height_) return {nullptr, n}; + node = node_[height]; + index = index_[height]; + } + edge = node->Edge(index); + } + + // If we moved up the tree, descend down to the leaf level, consuming all + // edges that must be skipped. + while (height > 0) { + node = edge->btree(); + index_[height] = index; + node_[--height] = node; + index = node->begin(); + edge = node->Edge(index); + while (n >= edge->length) { + n -= edge->length; + ++index; + assert(index != node->end()); + edge = node->Edge(index); + } + } + index_[0] = index; + return {edge, n}; +} + +ReadResult CordRepBtreeNavigator::Read(size_t edge_offset, size_t n) { + int height = 0; + size_t length = edge_offset + n; + size_t index = index_[0]; + CordRepBtree* node = node_[0]; + CordRep* edge = node->Edge(index); + assert(edge_offset < edge->length); + + if (length < edge->length) { + return {Substring(edge, edge_offset, n), length}; + } + + // Similar to 'Skip', we consume all edges that are inside the 'length' of + // data that needs to be read. If we exhaust the current level, we move one + // level up the tree and repeat until we hit the final edge that must be + // (partially) read. We consume all edges into `subtree`. + CordRepBtree* subtree = CordRepBtree::New(Substring(edge, edge_offset)); + size_t subtree_end = 1; + do { + length -= edge->length; + while (++index == node->end()) { + index_[height] = index; + if (++height > height_) { + subtree->set_end(subtree_end); + if (length == 0) return {subtree, 0}; + CordRep::Unref(subtree); + return {nullptr, length}; + } + if (length != 0) { + subtree->set_end(subtree_end); + subtree = CordRepBtree::New(subtree); + subtree_end = 1; + } + node = node_[height]; + index = index_[height]; + } + edge = node->Edge(index); + if (length >= edge->length) { + subtree->length += edge->length; + subtree->edges_[subtree_end++] = CordRep::Ref(edge); + } + } while (length >= edge->length); + CordRepBtree* tree = subtree; + subtree->length += length; + + // If we moved up the tree, descend down to the leaf level, consuming all + // edges that must be read, adding 'down' nodes to `subtree`. + while (height > 0) { + node = edge->btree(); + index_[height] = index; + node_[--height] = node; + index = node->begin(); + edge = node->Edge(index); + + if (length != 0) { + CordRepBtree* right = CordRepBtree::New(height); + right->length = length; + subtree->edges_[subtree_end++] = right; + subtree->set_end(subtree_end); + subtree = right; + subtree_end = 0; + while (length >= edge->length) { + subtree->edges_[subtree_end++] = CordRep::Ref(edge); + length -= edge->length; + edge = node->Edge(++index); + } + } + } + // Add any (partial) edge still remaining at the leaf level. + if (length != 0) { + subtree->edges_[subtree_end++] = Substring(edge, 0, length); + } + subtree->set_end(subtree_end); + index_[0] = index; + return {tree, length}; +} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.h b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.h index 971b92eda6..9fd3b1d333 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.h @@ -1,265 +1,265 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_NAVIGATOR_H_ -#define ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_NAVIGATOR_H_ - -#include <cassert> -#include <iostream> - -#include "absl/strings/internal/cord_internal.h" -#include "absl/strings/internal/cord_rep_btree.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -// CordRepBtreeNavigator is a bi-directional navigator allowing callers to -// navigate all the (leaf) data edges in a CordRepBtree instance. -// -// A CordRepBtreeNavigator instance is by default empty. Callers initialize a -// navigator instance by calling one of `InitFirst()`, `InitLast()` or -// `InitOffset()`, which establishes a current position. Callers can then -// navigate using the `Next`, `Previous`, `Skip` and `Seek` methods. -// -// The navigator instance does not take or adopt a reference on the provided -// `tree` on any of the initialization calls. Callers are responsible for -// guaranteeing the lifecycle of the provided tree. A navigator instance can -// be reset to the empty state by calling `Reset`. -// -// A navigator only keeps positional state on the 'current data edge', it does -// explicitly not keep any 'offset' state. The class does accept and return -// offsets in the `Read()`, `Skip()` and 'Seek()` methods as these would -// otherwise put a big burden on callers. Callers are expected to maintain -// (returned) offset info if they require such granular state. -class CordRepBtreeNavigator { - public: - // The logical position as returned by the Seek() and Skip() functions. - // Returns the current leaf edge for the desired seek or skip position and - // the offset of that position inside that edge. - struct Position { - CordRep* edge; - size_t offset; - }; - - // The read result as returned by the Read() function. - // `tree` contains the resulting tree which is identical to the result - // of calling CordRepBtree::SubTree(...) on the tree being navigated. - // `n` contains the number of bytes used from the last navigated to - // edge of the tree. - struct ReadResult { - CordRep* tree; - size_t n; - }; - - // Returns true if this instance is not empty. - explicit operator bool() const; - - // Returns the tree for this instance or nullptr if empty. - CordRepBtree* btree() const; - - // Returns the data edge of the current position. - // Requires this instance to not be empty. - CordRep* Current() const; - - // Resets this navigator to `tree`, returning the first data edge in the tree. - CordRep* InitFirst(CordRepBtree* tree); - - // Resets this navigator to `tree`, returning the last data edge in the tree. - CordRep* InitLast(CordRepBtree* tree); - - // Resets this navigator to `tree` returning the data edge at position - // `offset` and the relative offset of `offset` into that data edge. - // Returns `Position.edge = nullptr` if the provided offset is greater - // than or equal to the length of the tree, in which case the state of - // the navigator instance remains unchanged. - Position InitOffset(CordRepBtree* tree, size_t offset); - - // Navigates to the next data edge. - // Returns the next data edge or nullptr if there is no next data edge, in - // which case the current position remains unchanged. - CordRep* Next(); - - // Navigates to the previous data edge. - // Returns the previous data edge or nullptr if there is no previous data - // edge, in which case the current position remains unchanged. - CordRep* Previous(); - - // Navigates to the data edge at position `offset`. Returns the navigated to - // data edge in `Position.edge` and the relative offset of `offset` into that - // data edge in `Position.offset`. Returns `Position.edge = nullptr` if the - // provide offset is greater than or equal to the tree's length. - Position Seek(size_t offset); - - // Reads `n` bytes of data starting at offset `edge_offset` of the current - // data edge, and returns the result in `ReadResult.tree`. `ReadResult.n` - // contains the 'bytes used` from the last / current data edge in the tree. - // This allows users that mix regular navigation (using string views) and - // 'read into cord' navigation to keep track of the current state, and which - // bytes have been consumed from a navigator. - // This function returns `ReadResult.tree = nullptr` if the requested length - // exceeds the length of the tree starting at the current data edge. - ReadResult Read(size_t edge_offset, size_t n); - - // Skips `n` bytes forward from the current data edge, returning the navigated - // to data edge in `Position.edge` and `Position.offset` containing the offset - // inside that data edge. Note that the state of the navigator is left - // unchanged if `n` is smaller than the length of the current data edge. - Position Skip(size_t n); - - // Resets this instance to the default / empty state. - void Reset(); - - private: - // Slow path for Next() if Next() reached the end of a leaf node. Backtracks - // up the stack until it finds a node that has a 'next' position available, - // and then does a 'front dive' towards the next leaf node. - CordRep* NextUp(); - - // Slow path for Previous() if Previous() reached the beginning of a leaf - // node. Backtracks up the stack until it finds a node that has a 'previous' - // position available, and then does a 'back dive' towards the previous leaf - // node. - CordRep* PreviousUp(); - - // Generic implementation of InitFirst() and InitLast(). - template <CordRepBtree::EdgeType edge_type> - CordRep* Init(CordRepBtree* tree); - - // `height_` contains the height of the current tree, or -1 if empty. - int height_ = -1; - - // `index_` and `node_` contain the navigation state as the 'path' to the - // current data edge which is at `node_[0]->Edge(index_[0])`. The contents - // of these are undefined until the instance is initialized (`height_ >= 0`). - uint8_t index_[CordRepBtree::kMaxHeight]; - CordRepBtree* node_[CordRepBtree::kMaxHeight]; -}; - -// Returns true if this instance is not empty. -inline CordRepBtreeNavigator::operator bool() const { return height_ >= 0; } - -inline CordRepBtree* CordRepBtreeNavigator::btree() const { - return height_ >= 0 ? node_[height_] : nullptr; -} - -inline CordRep* CordRepBtreeNavigator::Current() const { - assert(height_ >= 0); - return node_[0]->Edge(index_[0]); -} - -inline void CordRepBtreeNavigator::Reset() { height_ = -1; } - -inline CordRep* CordRepBtreeNavigator::InitFirst(CordRepBtree* tree) { - return Init<CordRepBtree::kFront>(tree); -} - -inline CordRep* CordRepBtreeNavigator::InitLast(CordRepBtree* tree) { - return Init<CordRepBtree::kBack>(tree); -} - -template <CordRepBtree::EdgeType edge_type> -inline CordRep* CordRepBtreeNavigator::Init(CordRepBtree* tree) { - assert(tree != nullptr); - assert(tree->size() > 0); - int height = height_ = tree->height(); - size_t index = tree->index(edge_type); - node_[height] = tree; - index_[height] = static_cast<uint8_t>(index); - while (--height >= 0) { - tree = tree->Edge(index)->btree(); - node_[height] = tree; - index = tree->index(edge_type); - index_[height] = static_cast<uint8_t>(index); - } - return node_[0]->Edge(index); -} - -inline CordRepBtreeNavigator::Position CordRepBtreeNavigator::Seek( - size_t offset) { - assert(btree() != nullptr); - int height = height_; - CordRepBtree* edge = node_[height]; - if (ABSL_PREDICT_FALSE(offset >= edge->length)) return {nullptr, 0}; - CordRepBtree::Position index = edge->IndexOf(offset); - index_[height] = static_cast<uint8_t>(index.index); - while (--height >= 0) { - edge = edge->Edge(index.index)->btree(); - node_[height] = edge; - index = edge->IndexOf(index.n); - index_[height] = static_cast<uint8_t>(index.index); - } - return {edge->Edge(index.index), index.n}; -} - -inline CordRepBtreeNavigator::Position CordRepBtreeNavigator::InitOffset( - CordRepBtree* tree, size_t offset) { - assert(tree != nullptr); - if (ABSL_PREDICT_FALSE(offset >= tree->length)) return {nullptr, 0}; - height_ = tree->height(); - node_[height_] = tree; - return Seek(offset); -} - -inline CordRep* CordRepBtreeNavigator::Next() { - CordRepBtree* edge = node_[0]; - return index_[0] == edge->back() ? NextUp() : edge->Edge(++index_[0]); -} - -inline CordRep* CordRepBtreeNavigator::Previous() { - CordRepBtree* edge = node_[0]; - return index_[0] == edge->begin() ? PreviousUp() : edge->Edge(--index_[0]); -} - -inline CordRep* CordRepBtreeNavigator::NextUp() { - assert(index_[0] == node_[0]->back()); - CordRepBtree* edge; - size_t index; - int height = 0; - do { - if (++height > height_) return nullptr; - edge = node_[height]; - index = index_[height] + 1; - } while (index == edge->end()); - index_[height] = static_cast<uint8_t>(index); - do { - node_[--height] = edge = edge->Edge(index)->btree(); - index_[height] = static_cast<uint8_t>(index = edge->begin()); - } while (height > 0); - return edge->Edge(index); -} - -inline CordRep* CordRepBtreeNavigator::PreviousUp() { - assert(index_[0] == node_[0]->begin()); - CordRepBtree* edge; - size_t index; - int height = 0; - do { - if (++height > height_) return nullptr; - edge = node_[height]; - index = index_[height]; - } while (index == edge->begin()); - index_[height] = static_cast<uint8_t>(--index); - do { - node_[--height] = edge = edge->Edge(index)->btree(); - index_[height] = static_cast<uint8_t>(index = edge->back()); - } while (height > 0); - return edge->Edge(index); -} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_NAVIGATOR_H_ +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_NAVIGATOR_H_ +#define ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_NAVIGATOR_H_ + +#include <cassert> +#include <iostream> + +#include "absl/strings/internal/cord_internal.h" +#include "absl/strings/internal/cord_rep_btree.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +// CordRepBtreeNavigator is a bi-directional navigator allowing callers to +// navigate all the (leaf) data edges in a CordRepBtree instance. +// +// A CordRepBtreeNavigator instance is by default empty. Callers initialize a +// navigator instance by calling one of `InitFirst()`, `InitLast()` or +// `InitOffset()`, which establishes a current position. Callers can then +// navigate using the `Next`, `Previous`, `Skip` and `Seek` methods. +// +// The navigator instance does not take or adopt a reference on the provided +// `tree` on any of the initialization calls. Callers are responsible for +// guaranteeing the lifecycle of the provided tree. A navigator instance can +// be reset to the empty state by calling `Reset`. +// +// A navigator only keeps positional state on the 'current data edge', it does +// explicitly not keep any 'offset' state. The class does accept and return +// offsets in the `Read()`, `Skip()` and 'Seek()` methods as these would +// otherwise put a big burden on callers. Callers are expected to maintain +// (returned) offset info if they require such granular state. +class CordRepBtreeNavigator { + public: + // The logical position as returned by the Seek() and Skip() functions. + // Returns the current leaf edge for the desired seek or skip position and + // the offset of that position inside that edge. + struct Position { + CordRep* edge; + size_t offset; + }; + + // The read result as returned by the Read() function. + // `tree` contains the resulting tree which is identical to the result + // of calling CordRepBtree::SubTree(...) on the tree being navigated. + // `n` contains the number of bytes used from the last navigated to + // edge of the tree. + struct ReadResult { + CordRep* tree; + size_t n; + }; + + // Returns true if this instance is not empty. + explicit operator bool() const; + + // Returns the tree for this instance or nullptr if empty. + CordRepBtree* btree() const; + + // Returns the data edge of the current position. + // Requires this instance to not be empty. + CordRep* Current() const; + + // Resets this navigator to `tree`, returning the first data edge in the tree. + CordRep* InitFirst(CordRepBtree* tree); + + // Resets this navigator to `tree`, returning the last data edge in the tree. + CordRep* InitLast(CordRepBtree* tree); + + // Resets this navigator to `tree` returning the data edge at position + // `offset` and the relative offset of `offset` into that data edge. + // Returns `Position.edge = nullptr` if the provided offset is greater + // than or equal to the length of the tree, in which case the state of + // the navigator instance remains unchanged. + Position InitOffset(CordRepBtree* tree, size_t offset); + + // Navigates to the next data edge. + // Returns the next data edge or nullptr if there is no next data edge, in + // which case the current position remains unchanged. + CordRep* Next(); + + // Navigates to the previous data edge. + // Returns the previous data edge or nullptr if there is no previous data + // edge, in which case the current position remains unchanged. + CordRep* Previous(); + + // Navigates to the data edge at position `offset`. Returns the navigated to + // data edge in `Position.edge` and the relative offset of `offset` into that + // data edge in `Position.offset`. Returns `Position.edge = nullptr` if the + // provide offset is greater than or equal to the tree's length. + Position Seek(size_t offset); + + // Reads `n` bytes of data starting at offset `edge_offset` of the current + // data edge, and returns the result in `ReadResult.tree`. `ReadResult.n` + // contains the 'bytes used` from the last / current data edge in the tree. + // This allows users that mix regular navigation (using string views) and + // 'read into cord' navigation to keep track of the current state, and which + // bytes have been consumed from a navigator. + // This function returns `ReadResult.tree = nullptr` if the requested length + // exceeds the length of the tree starting at the current data edge. + ReadResult Read(size_t edge_offset, size_t n); + + // Skips `n` bytes forward from the current data edge, returning the navigated + // to data edge in `Position.edge` and `Position.offset` containing the offset + // inside that data edge. Note that the state of the navigator is left + // unchanged if `n` is smaller than the length of the current data edge. + Position Skip(size_t n); + + // Resets this instance to the default / empty state. + void Reset(); + + private: + // Slow path for Next() if Next() reached the end of a leaf node. Backtracks + // up the stack until it finds a node that has a 'next' position available, + // and then does a 'front dive' towards the next leaf node. + CordRep* NextUp(); + + // Slow path for Previous() if Previous() reached the beginning of a leaf + // node. Backtracks up the stack until it finds a node that has a 'previous' + // position available, and then does a 'back dive' towards the previous leaf + // node. + CordRep* PreviousUp(); + + // Generic implementation of InitFirst() and InitLast(). + template <CordRepBtree::EdgeType edge_type> + CordRep* Init(CordRepBtree* tree); + + // `height_` contains the height of the current tree, or -1 if empty. + int height_ = -1; + + // `index_` and `node_` contain the navigation state as the 'path' to the + // current data edge which is at `node_[0]->Edge(index_[0])`. The contents + // of these are undefined until the instance is initialized (`height_ >= 0`). + uint8_t index_[CordRepBtree::kMaxHeight]; + CordRepBtree* node_[CordRepBtree::kMaxHeight]; +}; + +// Returns true if this instance is not empty. +inline CordRepBtreeNavigator::operator bool() const { return height_ >= 0; } + +inline CordRepBtree* CordRepBtreeNavigator::btree() const { + return height_ >= 0 ? node_[height_] : nullptr; +} + +inline CordRep* CordRepBtreeNavigator::Current() const { + assert(height_ >= 0); + return node_[0]->Edge(index_[0]); +} + +inline void CordRepBtreeNavigator::Reset() { height_ = -1; } + +inline CordRep* CordRepBtreeNavigator::InitFirst(CordRepBtree* tree) { + return Init<CordRepBtree::kFront>(tree); +} + +inline CordRep* CordRepBtreeNavigator::InitLast(CordRepBtree* tree) { + return Init<CordRepBtree::kBack>(tree); +} + +template <CordRepBtree::EdgeType edge_type> +inline CordRep* CordRepBtreeNavigator::Init(CordRepBtree* tree) { + assert(tree != nullptr); + assert(tree->size() > 0); + int height = height_ = tree->height(); + size_t index = tree->index(edge_type); + node_[height] = tree; + index_[height] = static_cast<uint8_t>(index); + while (--height >= 0) { + tree = tree->Edge(index)->btree(); + node_[height] = tree; + index = tree->index(edge_type); + index_[height] = static_cast<uint8_t>(index); + } + return node_[0]->Edge(index); +} + +inline CordRepBtreeNavigator::Position CordRepBtreeNavigator::Seek( + size_t offset) { + assert(btree() != nullptr); + int height = height_; + CordRepBtree* edge = node_[height]; + if (ABSL_PREDICT_FALSE(offset >= edge->length)) return {nullptr, 0}; + CordRepBtree::Position index = edge->IndexOf(offset); + index_[height] = static_cast<uint8_t>(index.index); + while (--height >= 0) { + edge = edge->Edge(index.index)->btree(); + node_[height] = edge; + index = edge->IndexOf(index.n); + index_[height] = static_cast<uint8_t>(index.index); + } + return {edge->Edge(index.index), index.n}; +} + +inline CordRepBtreeNavigator::Position CordRepBtreeNavigator::InitOffset( + CordRepBtree* tree, size_t offset) { + assert(tree != nullptr); + if (ABSL_PREDICT_FALSE(offset >= tree->length)) return {nullptr, 0}; + height_ = tree->height(); + node_[height_] = tree; + return Seek(offset); +} + +inline CordRep* CordRepBtreeNavigator::Next() { + CordRepBtree* edge = node_[0]; + return index_[0] == edge->back() ? NextUp() : edge->Edge(++index_[0]); +} + +inline CordRep* CordRepBtreeNavigator::Previous() { + CordRepBtree* edge = node_[0]; + return index_[0] == edge->begin() ? PreviousUp() : edge->Edge(--index_[0]); +} + +inline CordRep* CordRepBtreeNavigator::NextUp() { + assert(index_[0] == node_[0]->back()); + CordRepBtree* edge; + size_t index; + int height = 0; + do { + if (++height > height_) return nullptr; + edge = node_[height]; + index = index_[height] + 1; + } while (index == edge->end()); + index_[height] = static_cast<uint8_t>(index); + do { + node_[--height] = edge = edge->Edge(index)->btree(); + index_[height] = static_cast<uint8_t>(index = edge->begin()); + } while (height > 0); + return edge->Edge(index); +} + +inline CordRep* CordRepBtreeNavigator::PreviousUp() { + assert(index_[0] == node_[0]->begin()); + CordRepBtree* edge; + size_t index; + int height = 0; + do { + if (++height > height_) return nullptr; + edge = node_[height]; + index = index_[height]; + } while (index == edge->begin()); + index_[height] = static_cast<uint8_t>(--index); + do { + node_[--height] = edge = edge->Edge(index)->btree(); + index_[height] = static_cast<uint8_t>(index = edge->back()); + } while (height > 0); + return edge->Edge(index); +} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_NAVIGATOR_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree_reader.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree_reader.cc index 5dc76966d2..a48ed77fdc 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree_reader.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree_reader.cc @@ -1,68 +1,68 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/strings/internal/cord_rep_btree_reader.h" - -#include <cassert> - -#include "absl/base/config.h" -#include "absl/strings/internal/cord_internal.h" -#include "absl/strings/internal/cord_rep_btree.h" -#include "absl/strings/internal/cord_rep_btree_navigator.h" -#include "absl/strings/internal/cord_rep_flat.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -absl::string_view CordRepBtreeReader::Read(size_t n, size_t chunk_size, - CordRep*& tree) { - assert(chunk_size <= navigator_.Current()->length); - - // If chunk_size is non-zero, we need to start inside last returned edge. - // Else we start reading at the next data edge of the tree. - CordRep* edge = chunk_size ? navigator_.Current() : navigator_.Next(); - const size_t offset = chunk_size ? edge->length - chunk_size : 0; - - // Read the sub tree and verify we got what we wanted. - ReadResult result = navigator_.Read(offset, n); - tree = result.tree; - - // If the data returned in `tree` was covered entirely by `chunk_size`, i.e., - // read from the 'previous' edge, we did not consume any additional data, and - // can directly return the substring into the current data edge as the next - // chunk. We can easily establish from the above code that `navigator_.Next()` - // has not been called as that requires `chunk_size` to be zero. - if (n < chunk_size) return CordRepBtree::EdgeData(edge).substr(result.n); - - // The amount of data taken from the last edge is `chunk_size` and `result.n` - // contains the offset into the current edge trailing the read data (which can - // be 0). As the call to `navigator_.Read()` could have consumed all remaining - // data, calling `navigator_.Current()` is not safe before checking if we - // already consumed all remaining data. - const size_t consumed_by_read = n - chunk_size - result.n; - if (consumed_by_read >= remaining_) { - remaining_ = 0; - return {}; - } - - // We did not read all data, return remaining data from current edge. - edge = navigator_.Current(); - remaining_ -= consumed_by_read + edge->length; - return CordRepBtree::EdgeData(edge).substr(result.n); -} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace absl +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/strings/internal/cord_rep_btree_reader.h" + +#include <cassert> + +#include "absl/base/config.h" +#include "absl/strings/internal/cord_internal.h" +#include "absl/strings/internal/cord_rep_btree.h" +#include "absl/strings/internal/cord_rep_btree_navigator.h" +#include "absl/strings/internal/cord_rep_flat.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +absl::string_view CordRepBtreeReader::Read(size_t n, size_t chunk_size, + CordRep*& tree) { + assert(chunk_size <= navigator_.Current()->length); + + // If chunk_size is non-zero, we need to start inside last returned edge. + // Else we start reading at the next data edge of the tree. + CordRep* edge = chunk_size ? navigator_.Current() : navigator_.Next(); + const size_t offset = chunk_size ? edge->length - chunk_size : 0; + + // Read the sub tree and verify we got what we wanted. + ReadResult result = navigator_.Read(offset, n); + tree = result.tree; + + // If the data returned in `tree` was covered entirely by `chunk_size`, i.e., + // read from the 'previous' edge, we did not consume any additional data, and + // can directly return the substring into the current data edge as the next + // chunk. We can easily establish from the above code that `navigator_.Next()` + // has not been called as that requires `chunk_size` to be zero. + if (n < chunk_size) return CordRepBtree::EdgeData(edge).substr(result.n); + + // The amount of data taken from the last edge is `chunk_size` and `result.n` + // contains the offset into the current edge trailing the read data (which can + // be 0). As the call to `navigator_.Read()` could have consumed all remaining + // data, calling `navigator_.Current()` is not safe before checking if we + // already consumed all remaining data. + const size_t consumed_by_read = n - chunk_size - result.n; + if (consumed_by_read >= remaining_) { + remaining_ = 0; + return {}; + } + + // We did not read all data, return remaining data from current edge. + edge = navigator_.Current(); + remaining_ -= consumed_by_read + edge->length; + return CordRepBtree::EdgeData(edge).substr(result.n); +} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree_reader.h b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree_reader.h index 7aa79dbf10..51f4ab48c4 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree_reader.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_btree_reader.h @@ -1,211 +1,211 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_READER_H_ -#define ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_READER_H_ - -#include <cassert> - -#include "absl/base/config.h" -#include "absl/strings/internal/cord_internal.h" -#include "absl/strings/internal/cord_rep_btree.h" -#include "absl/strings/internal/cord_rep_btree_navigator.h" -#include "absl/strings/internal/cord_rep_flat.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -// CordRepBtreeReader implements logic to iterate over cord btrees. -// References to the underlying data are returned as absl::string_view values. -// The most typical use case is a forward only iteration over tree data. -// The class also provides `Skip()`, `Seek()` and `Read()` methods similar to -// CordRepBtreeNavigator that allow more advanced navigation. -// -// Example: iterate over all data inside a cord btree: -// -// CordRepBtreeReader reader; -// for (string_view sv = reader.Init(tree); !sv.Empty(); sv = sv.Next()) { -// DoSomethingWithDataIn(sv); -// } -// -// All navigation methods always return the next 'chunk' of data. The class -// assumes that all data is directly 'consumed' by the caller. For example: -// invoking `Skip()` will skip the desired number of bytes, and directly -// read and return the next chunk of data directly after the skipped bytes. -// -// Example: iterate over all data inside a btree skipping the first 100 bytes: -// -// CordRepBtreeReader reader; -// absl::string_view sv = reader.Init(tree); -// if (sv.length() > 100) { -// sv.RemovePrefix(100); -// } else { -// sv = reader.Skip(100 - sv.length()); -// } -// while (!sv.empty()) { -// DoSomethingWithDataIn(sv); -// absl::string_view sv = reader.Next(); -// } -// -// It is important to notice that `remaining` is based on the end position of -// the last data edge returned to the caller, not the cumulative data returned -// to the caller which can be less in cases of skipping or seeking over data. -// -// For example, consider a cord btree with five data edges: "abc", "def", "ghi", -// "jkl" and "mno": -// -// absl::string_view sv; -// CordRepBtreeReader reader; -// -// sv = reader.Init(tree); // sv = "abc", remaining = 12 -// sv = reader.Skip(4); // sv = "hi", remaining = 6 -// sv = reader.Skip(2); // sv = "l", remaining = 3 -// sv = reader.Next(); // sv = "mno", remaining = 0 -// sv = reader.Seek(1); // sv = "bc", remaining = 12 -// -class CordRepBtreeReader { - public: - using ReadResult = CordRepBtreeNavigator::ReadResult; - using Position = CordRepBtreeNavigator::Position; - - // Returns true if this instance is not empty. - explicit operator bool() const { return navigator_.btree() != nullptr; } - - // Returns the tree referenced by this instance or nullptr if empty. - CordRepBtree* btree() const { return navigator_.btree(); } - - // Returns the current data edge inside the referenced btree. - // Requires that the current instance is not empty. - CordRep* node() const { return navigator_.Current(); } - - // Returns the length of the referenced tree. - // Requires that the current instance is not empty. - size_t length() const; - - // Returns the number of remaining bytes available for iteration, which is the - // number of bytes directly following the end of the last chunk returned. - // This value will be zero if we iterated over the last edge in the bound - // tree, in which case any call to Next() or Skip() will return an empty - // string_view reflecting the EOF state. - // Note that a call to `Seek()` resets `remaining` to a value based on the - // end position of the chunk returned by that call. - size_t remaining() const { return remaining_; } - - // Resets this instance to an empty value. - void Reset() { navigator_.Reset(); } - - // Initializes this instance with `tree`. `tree` must not be null. - // Returns a reference to the first data edge of the provided tree. - absl::string_view Init(CordRepBtree* tree); - - // Navigates to and returns the next data edge of the referenced tree. - // Returns an empty string_view if an attempt is made to read beyond the end - // of the tree, i.e.: if `remaining()` is zero indicating an EOF condition. - // Requires that the current instance is not empty. - absl::string_view Next(); - - // Skips the provided amount of bytes and returns a reference to the data - // directly following the skipped bytes. - absl::string_view Skip(size_t skip); - - // Reads `n` bytes into `tree`. - // If `chunk_size` is zero, starts reading at the next data edge. If - // `chunk_size` is non zero, the read starts at the last `chunk_size` bytes of - // the last returned data edge. Effectively, this means that the read starts - // at offset `consumed() - chunk_size`. - // Requires that `chunk_size` is less than or equal to the length of the - // last returned data edge. The purpose of `chunk_size` is to simplify code - // partially consuming a returned chunk and wanting to include the remaining - // bytes in the Read call. For example, the below code will read 1000 bytes of - // data into a cord tree if the first chunk starts with "big:": - // - // CordRepBtreeReader reader; - // absl::string_view sv = reader.Init(tree); - // if (absl::StartsWith(sv, "big:")) { - // CordRepBtree tree; - // sv = reader.Read(1000, sv.size() - 4 /* "big:" */, &tree); - // } - // - // This method will return an empty string view if all remaining data was - // read. If `n` exceeded the amount of remaining data this function will - // return an empty string view and `tree` will be set to nullptr. - // In both cases, `consumed` will be set to `length`. - absl::string_view Read(size_t n, size_t chunk_size, CordRep*& tree); - - // Navigates to the chunk at offset `offset`. - // Returns a reference into the navigated to chunk, adjusted for the relative - // position of `offset` into that chunk. For example, calling `Seek(13)` on a - // cord tree containing 2 chunks of 10 and 20 bytes respectively will return - // a string view into the second chunk starting at offset 3 with a size of 17. - // Returns an empty string view if `offset` is equal to or greater than the - // length of the referenced tree. - absl::string_view Seek(size_t offset); - - private: - size_t remaining_ = 0; - CordRepBtreeNavigator navigator_; -}; - -inline size_t CordRepBtreeReader::length() const { - assert(btree() != nullptr); - return btree()->length; -} - -inline absl::string_view CordRepBtreeReader::Init(CordRepBtree* tree) { - assert(tree != nullptr); - const CordRep* edge = navigator_.InitFirst(tree); - remaining_ = tree->length - edge->length; - return CordRepBtree::EdgeData(edge); -} - -inline absl::string_view CordRepBtreeReader::Next() { - if (remaining_ == 0) return {}; - const CordRep* edge = navigator_.Next(); - assert(edge != nullptr); - remaining_ -= edge->length; - return CordRepBtree::EdgeData(edge); -} - -inline absl::string_view CordRepBtreeReader::Skip(size_t skip) { - // As we are always positioned on the last 'consumed' edge, we - // need to skip the current edge as well as `skip`. - const size_t edge_length = navigator_.Current()->length; - CordRepBtreeNavigator::Position pos = navigator_.Skip(skip + edge_length); - if (ABSL_PREDICT_FALSE(pos.edge == nullptr)) { - remaining_ = 0; - return {}; - } - // The combined length of all edges skipped before `pos.edge` is `skip - - // pos.offset`, all of which are 'consumed', as well as the current edge. - remaining_ -= skip - pos.offset + pos.edge->length; - return CordRepBtree::EdgeData(pos.edge).substr(pos.offset); -} - -inline absl::string_view CordRepBtreeReader::Seek(size_t offset) { - const CordRepBtreeNavigator::Position pos = navigator_.Seek(offset); - if (ABSL_PREDICT_FALSE(pos.edge == nullptr)) { - remaining_ = 0; - return {}; - } - absl::string_view chunk = CordRepBtree::EdgeData(pos.edge).substr(pos.offset); - remaining_ = length() - offset - chunk.length(); - return chunk; -} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_READER_H_ +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_READER_H_ +#define ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_READER_H_ + +#include <cassert> + +#include "absl/base/config.h" +#include "absl/strings/internal/cord_internal.h" +#include "absl/strings/internal/cord_rep_btree.h" +#include "absl/strings/internal/cord_rep_btree_navigator.h" +#include "absl/strings/internal/cord_rep_flat.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +// CordRepBtreeReader implements logic to iterate over cord btrees. +// References to the underlying data are returned as absl::string_view values. +// The most typical use case is a forward only iteration over tree data. +// The class also provides `Skip()`, `Seek()` and `Read()` methods similar to +// CordRepBtreeNavigator that allow more advanced navigation. +// +// Example: iterate over all data inside a cord btree: +// +// CordRepBtreeReader reader; +// for (string_view sv = reader.Init(tree); !sv.Empty(); sv = sv.Next()) { +// DoSomethingWithDataIn(sv); +// } +// +// All navigation methods always return the next 'chunk' of data. The class +// assumes that all data is directly 'consumed' by the caller. For example: +// invoking `Skip()` will skip the desired number of bytes, and directly +// read and return the next chunk of data directly after the skipped bytes. +// +// Example: iterate over all data inside a btree skipping the first 100 bytes: +// +// CordRepBtreeReader reader; +// absl::string_view sv = reader.Init(tree); +// if (sv.length() > 100) { +// sv.RemovePrefix(100); +// } else { +// sv = reader.Skip(100 - sv.length()); +// } +// while (!sv.empty()) { +// DoSomethingWithDataIn(sv); +// absl::string_view sv = reader.Next(); +// } +// +// It is important to notice that `remaining` is based on the end position of +// the last data edge returned to the caller, not the cumulative data returned +// to the caller which can be less in cases of skipping or seeking over data. +// +// For example, consider a cord btree with five data edges: "abc", "def", "ghi", +// "jkl" and "mno": +// +// absl::string_view sv; +// CordRepBtreeReader reader; +// +// sv = reader.Init(tree); // sv = "abc", remaining = 12 +// sv = reader.Skip(4); // sv = "hi", remaining = 6 +// sv = reader.Skip(2); // sv = "l", remaining = 3 +// sv = reader.Next(); // sv = "mno", remaining = 0 +// sv = reader.Seek(1); // sv = "bc", remaining = 12 +// +class CordRepBtreeReader { + public: + using ReadResult = CordRepBtreeNavigator::ReadResult; + using Position = CordRepBtreeNavigator::Position; + + // Returns true if this instance is not empty. + explicit operator bool() const { return navigator_.btree() != nullptr; } + + // Returns the tree referenced by this instance or nullptr if empty. + CordRepBtree* btree() const { return navigator_.btree(); } + + // Returns the current data edge inside the referenced btree. + // Requires that the current instance is not empty. + CordRep* node() const { return navigator_.Current(); } + + // Returns the length of the referenced tree. + // Requires that the current instance is not empty. + size_t length() const; + + // Returns the number of remaining bytes available for iteration, which is the + // number of bytes directly following the end of the last chunk returned. + // This value will be zero if we iterated over the last edge in the bound + // tree, in which case any call to Next() or Skip() will return an empty + // string_view reflecting the EOF state. + // Note that a call to `Seek()` resets `remaining` to a value based on the + // end position of the chunk returned by that call. + size_t remaining() const { return remaining_; } + + // Resets this instance to an empty value. + void Reset() { navigator_.Reset(); } + + // Initializes this instance with `tree`. `tree` must not be null. + // Returns a reference to the first data edge of the provided tree. + absl::string_view Init(CordRepBtree* tree); + + // Navigates to and returns the next data edge of the referenced tree. + // Returns an empty string_view if an attempt is made to read beyond the end + // of the tree, i.e.: if `remaining()` is zero indicating an EOF condition. + // Requires that the current instance is not empty. + absl::string_view Next(); + + // Skips the provided amount of bytes and returns a reference to the data + // directly following the skipped bytes. + absl::string_view Skip(size_t skip); + + // Reads `n` bytes into `tree`. + // If `chunk_size` is zero, starts reading at the next data edge. If + // `chunk_size` is non zero, the read starts at the last `chunk_size` bytes of + // the last returned data edge. Effectively, this means that the read starts + // at offset `consumed() - chunk_size`. + // Requires that `chunk_size` is less than or equal to the length of the + // last returned data edge. The purpose of `chunk_size` is to simplify code + // partially consuming a returned chunk and wanting to include the remaining + // bytes in the Read call. For example, the below code will read 1000 bytes of + // data into a cord tree if the first chunk starts with "big:": + // + // CordRepBtreeReader reader; + // absl::string_view sv = reader.Init(tree); + // if (absl::StartsWith(sv, "big:")) { + // CordRepBtree tree; + // sv = reader.Read(1000, sv.size() - 4 /* "big:" */, &tree); + // } + // + // This method will return an empty string view if all remaining data was + // read. If `n` exceeded the amount of remaining data this function will + // return an empty string view and `tree` will be set to nullptr. + // In both cases, `consumed` will be set to `length`. + absl::string_view Read(size_t n, size_t chunk_size, CordRep*& tree); + + // Navigates to the chunk at offset `offset`. + // Returns a reference into the navigated to chunk, adjusted for the relative + // position of `offset` into that chunk. For example, calling `Seek(13)` on a + // cord tree containing 2 chunks of 10 and 20 bytes respectively will return + // a string view into the second chunk starting at offset 3 with a size of 17. + // Returns an empty string view if `offset` is equal to or greater than the + // length of the referenced tree. + absl::string_view Seek(size_t offset); + + private: + size_t remaining_ = 0; + CordRepBtreeNavigator navigator_; +}; + +inline size_t CordRepBtreeReader::length() const { + assert(btree() != nullptr); + return btree()->length; +} + +inline absl::string_view CordRepBtreeReader::Init(CordRepBtree* tree) { + assert(tree != nullptr); + const CordRep* edge = navigator_.InitFirst(tree); + remaining_ = tree->length - edge->length; + return CordRepBtree::EdgeData(edge); +} + +inline absl::string_view CordRepBtreeReader::Next() { + if (remaining_ == 0) return {}; + const CordRep* edge = navigator_.Next(); + assert(edge != nullptr); + remaining_ -= edge->length; + return CordRepBtree::EdgeData(edge); +} + +inline absl::string_view CordRepBtreeReader::Skip(size_t skip) { + // As we are always positioned on the last 'consumed' edge, we + // need to skip the current edge as well as `skip`. + const size_t edge_length = navigator_.Current()->length; + CordRepBtreeNavigator::Position pos = navigator_.Skip(skip + edge_length); + if (ABSL_PREDICT_FALSE(pos.edge == nullptr)) { + remaining_ = 0; + return {}; + } + // The combined length of all edges skipped before `pos.edge` is `skip - + // pos.offset`, all of which are 'consumed', as well as the current edge. + remaining_ -= skip - pos.offset + pos.edge->length; + return CordRepBtree::EdgeData(pos.edge).substr(pos.offset); +} + +inline absl::string_view CordRepBtreeReader::Seek(size_t offset) { + const CordRepBtreeNavigator::Position pos = navigator_.Seek(offset); + if (ABSL_PREDICT_FALSE(pos.edge == nullptr)) { + remaining_ = 0; + return {}; + } + absl::string_view chunk = CordRepBtree::EdgeData(pos.edge).substr(pos.offset); + remaining_ = length() - offset - chunk.length(); + return chunk; +} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_READER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_consume.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_consume.cc index 81514543db..a9d0ebd0ef 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_consume.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_consume.cc @@ -1,129 +1,129 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/strings/internal/cord_rep_consume.h" - -#include <array> -#include <utility> - -#include "absl/container/inlined_vector.h" -#include "absl/functional/function_ref.h" -#include "absl/strings/internal/cord_internal.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -namespace { - -// Unrefs the provided `substring`, and returns `substring->child` -// Adds or assumes a reference on `substring->child` -CordRep* ClipSubstring(CordRepSubstring* substring) { - CordRep* child = substring->child; - if (substring->refcount.IsOne()) { - delete substring; - } else { - CordRep::Ref(child); - CordRep::Unref(substring); - } - return child; -} - -// Unrefs the provided `concat`, and returns `{concat->left, concat->right}` -// Adds or assumes a reference on `concat->left` and `concat->right`. -// Returns an array of 2 elements containing the left and right nodes. -std::array<CordRep*, 2> ClipConcat(CordRepConcat* concat) { - std::array<CordRep*, 2> result{concat->left, concat->right}; - if (concat->refcount.IsOne()) { - delete concat; - } else { - CordRep::Ref(result[0]); - CordRep::Ref(result[1]); - CordRep::Unref(concat); - } - return result; -} - -void Consume(bool forward, CordRep* rep, ConsumeFn consume_fn) { - size_t offset = 0; - size_t length = rep->length; - struct Entry { - CordRep* rep; - size_t offset; - size_t length; - }; - absl::InlinedVector<Entry, 40> stack; - - for (;;) { - if (rep->tag == CONCAT) { - std::array<CordRep*, 2> res = ClipConcat(rep->concat()); - CordRep* left = res[0]; - CordRep* right = res[1]; - - if (left->length <= offset) { - // Don't need left node - offset -= left->length; - CordRep::Unref(left); - rep = right; - continue; - } - - size_t length_left = left->length - offset; - if (length_left >= length) { - // Don't need right node - CordRep::Unref(right); - rep = left; - continue; - } - - // Need both nodes - size_t length_right = length - length_left; - if (forward) { - stack.push_back({right, 0, length_right}); - rep = left; - length = length_left; - } else { - stack.push_back({left, offset, length_left}); - rep = right; - offset = 0; - length = length_right; - } - } else if (rep->tag == SUBSTRING) { - offset += rep->substring()->start; - rep = ClipSubstring(rep->substring()); - } else { - consume_fn(rep, offset, length); - if (stack.empty()) return; - - rep = stack.back().rep; - offset = stack.back().offset; - length = stack.back().length; - stack.pop_back(); - } - } -} - -} // namespace - -void Consume(CordRep* rep, ConsumeFn consume_fn) { - return Consume(true, rep, std::move(consume_fn)); -} - -void ReverseConsume(CordRep* rep, ConsumeFn consume_fn) { - return Consume(false, rep, std::move(consume_fn)); -} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace absl +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/strings/internal/cord_rep_consume.h" + +#include <array> +#include <utility> + +#include "absl/container/inlined_vector.h" +#include "absl/functional/function_ref.h" +#include "absl/strings/internal/cord_internal.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +namespace { + +// Unrefs the provided `substring`, and returns `substring->child` +// Adds or assumes a reference on `substring->child` +CordRep* ClipSubstring(CordRepSubstring* substring) { + CordRep* child = substring->child; + if (substring->refcount.IsOne()) { + delete substring; + } else { + CordRep::Ref(child); + CordRep::Unref(substring); + } + return child; +} + +// Unrefs the provided `concat`, and returns `{concat->left, concat->right}` +// Adds or assumes a reference on `concat->left` and `concat->right`. +// Returns an array of 2 elements containing the left and right nodes. +std::array<CordRep*, 2> ClipConcat(CordRepConcat* concat) { + std::array<CordRep*, 2> result{concat->left, concat->right}; + if (concat->refcount.IsOne()) { + delete concat; + } else { + CordRep::Ref(result[0]); + CordRep::Ref(result[1]); + CordRep::Unref(concat); + } + return result; +} + +void Consume(bool forward, CordRep* rep, ConsumeFn consume_fn) { + size_t offset = 0; + size_t length = rep->length; + struct Entry { + CordRep* rep; + size_t offset; + size_t length; + }; + absl::InlinedVector<Entry, 40> stack; + + for (;;) { + if (rep->tag == CONCAT) { + std::array<CordRep*, 2> res = ClipConcat(rep->concat()); + CordRep* left = res[0]; + CordRep* right = res[1]; + + if (left->length <= offset) { + // Don't need left node + offset -= left->length; + CordRep::Unref(left); + rep = right; + continue; + } + + size_t length_left = left->length - offset; + if (length_left >= length) { + // Don't need right node + CordRep::Unref(right); + rep = left; + continue; + } + + // Need both nodes + size_t length_right = length - length_left; + if (forward) { + stack.push_back({right, 0, length_right}); + rep = left; + length = length_left; + } else { + stack.push_back({left, offset, length_left}); + rep = right; + offset = 0; + length = length_right; + } + } else if (rep->tag == SUBSTRING) { + offset += rep->substring()->start; + rep = ClipSubstring(rep->substring()); + } else { + consume_fn(rep, offset, length); + if (stack.empty()) return; + + rep = stack.back().rep; + offset = stack.back().offset; + length = stack.back().length; + stack.pop_back(); + } + } +} + +} // namespace + +void Consume(CordRep* rep, ConsumeFn consume_fn) { + return Consume(true, rep, std::move(consume_fn)); +} + +void ReverseConsume(CordRep* rep, ConsumeFn consume_fn) { + return Consume(false, rep, std::move(consume_fn)); +} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_consume.h b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_consume.h index d46fca2b21..3d07203c81 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_consume.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_consume.h @@ -1,50 +1,50 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_CONSUME_H_ -#define ABSL_STRINGS_INTERNAL_CORD_REP_CONSUME_H_ - -#include <functional> - -#include "absl/functional/function_ref.h" -#include "absl/strings/internal/cord_internal.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -// Functor for the Consume() and ReverseConsume() functions: -// void ConsumeFunc(CordRep* rep, size_t offset, size_t length); -// See the Consume() and ReverseConsume() function comments for documentation. -using ConsumeFn = FunctionRef<void(CordRep*, size_t, size_t)>; - -// Consume() and ReverseConsume() consume CONCAT based trees and invoke the -// provided functor with the contained nodes in the proper forward or reverse -// order, which is used to convert CONCAT trees into other tree or cord data. -// All CONCAT and SUBSTRING nodes are processed internally. The 'offset` -// parameter of the functor is non-zero for any nodes below SUBSTRING nodes. -// It's up to the caller to form these back into SUBSTRING nodes or otherwise -// store offset / prefix information. These functions are intended to be used -// only for migration / transitional code where due to factors such as ODR -// violations, we can not 100% guarantee that all code respects 'new format' -// settings and flags, so we need to be able to parse old data on the fly until -// all old code is deprecated / no longer the default format. -void Consume(CordRep* rep, ConsumeFn consume_fn); -void ReverseConsume(CordRep* rep, ConsumeFn consume_fn); - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STRINGS_INTERNAL_CORD_REP_CONSUME_H_ +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_CONSUME_H_ +#define ABSL_STRINGS_INTERNAL_CORD_REP_CONSUME_H_ + +#include <functional> + +#include "absl/functional/function_ref.h" +#include "absl/strings/internal/cord_internal.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +// Functor for the Consume() and ReverseConsume() functions: +// void ConsumeFunc(CordRep* rep, size_t offset, size_t length); +// See the Consume() and ReverseConsume() function comments for documentation. +using ConsumeFn = FunctionRef<void(CordRep*, size_t, size_t)>; + +// Consume() and ReverseConsume() consume CONCAT based trees and invoke the +// provided functor with the contained nodes in the proper forward or reverse +// order, which is used to convert CONCAT trees into other tree or cord data. +// All CONCAT and SUBSTRING nodes are processed internally. The 'offset` +// parameter of the functor is non-zero for any nodes below SUBSTRING nodes. +// It's up to the caller to form these back into SUBSTRING nodes or otherwise +// store offset / prefix information. These functions are intended to be used +// only for migration / transitional code where due to factors such as ODR +// violations, we can not 100% guarantee that all code respects 'new format' +// settings and flags, so we need to be able to parse old data on the fly until +// all old code is deprecated / no longer the default format. +void Consume(CordRep* rep, ConsumeFn consume_fn); +void ReverseConsume(CordRep* rep, ConsumeFn consume_fn); + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STRINGS_INTERNAL_CORD_REP_CONSUME_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_flat.h b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_flat.h index 4d0f988697..bb8c9a28e3 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_flat.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_flat.h @@ -44,11 +44,11 @@ static constexpr size_t kMaxFlatLength = kMaxFlatSize - kFlatOverhead; static constexpr size_t kMinFlatLength = kMinFlatSize - kFlatOverhead; constexpr uint8_t AllocatedSizeToTagUnchecked(size_t size) { - return static_cast<uint8_t>((size <= 1024) ? size / 8 + 1 - : 129 + size / 32 - 1024 / 32); + return static_cast<uint8_t>((size <= 1024) ? size / 8 + 1 + : 129 + size / 32 - 1024 / 32); } -static_assert(kMinFlatSize / 8 + 1 >= FLAT, ""); +static_assert(kMinFlatSize / 8 + 1 >= FLAT, ""); static_assert(AllocatedSizeToTagUnchecked(kMaxFlatSize) <= MAX_FLAT_TAG, ""); // Helper functions for rounded div, and rounding to exact sizes. @@ -73,7 +73,7 @@ inline uint8_t AllocatedSizeToTag(size_t size) { // Converts the provided tag to the corresponding allocated size constexpr size_t TagToAllocatedSize(uint8_t tag) { - return (tag <= 129) ? ((tag - 1) * 8) : (1024 + (tag - 129) * 32); + return (tag <= 129) ? ((tag - 1) * 8) : (1024 + (tag - 129) * 32); } // Converts the provided tag to the corresponding available data length @@ -82,7 +82,7 @@ constexpr size_t TagToLength(uint8_t tag) { } // Enforce that kMaxFlatSize maps to a well-known exact tag value. -static_assert(TagToAllocatedSize(225) == kMaxFlatSize, "Bad tag logic"); +static_assert(TagToAllocatedSize(225) == kMaxFlatSize, "Bad tag logic"); struct CordRepFlat : public CordRep { // Creates a new flat node. @@ -118,8 +118,8 @@ struct CordRepFlat : public CordRep { } // Returns a pointer to the data inside this flat rep. - char* Data() { return reinterpret_cast<char*>(storage); } - const char* Data() const { return reinterpret_cast<const char*>(storage); } + char* Data() { return reinterpret_cast<char*>(storage); } + const char* Data() const { return reinterpret_cast<const char*>(storage); } // Returns the maximum capacity (payload size) of this instance. size_t Capacity() const { return TagToLength(tag); } diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_ring.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_ring.cc index 07c77eb3e5..b18a2049a1 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_ring.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_ring.cc @@ -26,7 +26,7 @@ #include "absl/base/macros.h" #include "absl/container/inlined_vector.h" #include "absl/strings/internal/cord_internal.h" -#include "absl/strings/internal/cord_rep_consume.h" +#include "absl/strings/internal/cord_rep_consume.h" #include "absl/strings/internal/cord_rep_flat.h" namespace absl { @@ -40,7 +40,7 @@ using index_type = CordRepRing::index_type; enum class Direction { kForward, kReversed }; inline bool IsFlatOrExternal(CordRep* rep) { - return rep->IsFlat() || rep->IsExternal(); + return rep->IsFlat() || rep->IsExternal(); } // Verifies that n + extra <= kMaxCapacity: throws std::length_error otherwise. @@ -178,7 +178,7 @@ bool CordRepRing::IsValid(std::ostream& output) const { if (offset >= child->length || entry_length > child->length - offset) { output << "entry[" << head << "] has offset " << offset << " and entry length " << entry_length - << " which are outside of the child's length of " << child->length; + << " which are outside of the child's length of " << child->length; return false; } @@ -229,7 +229,7 @@ void CordRepRing::SetCapacityForTesting(size_t capacity) { } void CordRepRing::Delete(CordRepRing* rep) { - assert(rep != nullptr && rep->IsRing()); + assert(rep != nullptr && rep->IsRing()); #if defined(__cpp_sized_deallocation) size_t size = AllocSize(rep->capacity_); rep->~CordRepRing(); @@ -277,11 +277,11 @@ CordRepRing* CordRepRing::Mutable(CordRepRing* rep, size_t extra) { // Get current number of entries, and check for max capacity. size_t entries = rep->entries(); - if (!rep->refcount.IsMutable()) { - return Copy(rep, rep->head(), rep->tail(), extra); + if (!rep->refcount.IsMutable()) { + return Copy(rep, rep->head(), rep->tail(), extra); } else if (entries + extra > rep->capacity()) { - const size_t min_grow = rep->capacity() + rep->capacity() / 2; - const size_t min_extra = (std::max)(extra, min_grow - entries); + const size_t min_grow = rep->capacity() + rep->capacity() / 2; + const size_t min_extra = (std::max)(extra, min_grow - entries); CordRepRing* newrep = CordRepRing::New(entries, min_extra); newrep->Fill<false>(rep, rep->head(), rep->tail()); CordRepRing::Delete(rep); @@ -292,10 +292,10 @@ CordRepRing* CordRepRing::Mutable(CordRepRing* rep, size_t extra) { } Span<char> CordRepRing::GetAppendBuffer(size_t size) { - assert(refcount.IsMutable()); + assert(refcount.IsMutable()); index_type back = retreat(tail_); CordRep* child = entry_child(back); - if (child->tag >= FLAT && child->refcount.IsMutable()) { + if (child->tag >= FLAT && child->refcount.IsMutable()) { size_t capacity = child->flat()->Capacity(); pos_type end_pos = entry_end_pos(back); size_t data_offset = entry_data_offset(back); @@ -312,10 +312,10 @@ Span<char> CordRepRing::GetAppendBuffer(size_t size) { } Span<char> CordRepRing::GetPrependBuffer(size_t size) { - assert(refcount.IsMutable()); + assert(refcount.IsMutable()); CordRep* child = entry_child(head_); size_t data_offset = entry_data_offset(head_); - if (data_offset && child->refcount.IsMutable() && child->tag >= FLAT) { + if (data_offset && child->refcount.IsMutable() && child->tag >= FLAT) { size_t n = (std::min)(data_offset, size); this->length += n; begin_pos_ -= n; @@ -327,12 +327,12 @@ Span<char> CordRepRing::GetPrependBuffer(size_t size) { } CordRepRing* CordRepRing::CreateFromLeaf(CordRep* child, size_t offset, - size_t len, size_t extra) { + size_t len, size_t extra) { CordRepRing* rep = CordRepRing::New(1, extra); rep->head_ = 0; rep->tail_ = rep->advance(0); - rep->length = len; - rep->entry_end_pos()[0] = len; + rep->length = len; + rep->entry_end_pos()[0] = len; rep->entry_child()[0] = child; rep->entry_data_offset()[0] = static_cast<offset_type>(offset); return Validate(rep); @@ -340,16 +340,16 @@ CordRepRing* CordRepRing::CreateFromLeaf(CordRep* child, size_t offset, CordRepRing* CordRepRing::CreateSlow(CordRep* child, size_t extra) { CordRepRing* rep = nullptr; - Consume(child, [&](CordRep* child_arg, size_t offset, size_t len) { - if (IsFlatOrExternal(child_arg)) { - rep = rep ? AppendLeaf(rep, child_arg, offset, len) - : CreateFromLeaf(child_arg, offset, len, extra); + Consume(child, [&](CordRep* child_arg, size_t offset, size_t len) { + if (IsFlatOrExternal(child_arg)) { + rep = rep ? AppendLeaf(rep, child_arg, offset, len) + : CreateFromLeaf(child_arg, offset, len, extra); } else if (rep) { - rep = AddRing<AddMode::kAppend>(rep, child_arg->ring(), offset, len); - } else if (offset == 0 && child_arg->length == len) { - rep = Mutable(child_arg->ring(), extra); + rep = AddRing<AddMode::kAppend>(rep, child_arg->ring(), offset, len); + } else if (offset == 0 && child_arg->length == len) { + rep = Mutable(child_arg->ring(), extra); } else { - rep = SubRing(child_arg->ring(), offset, len, extra); + rep = SubRing(child_arg->ring(), offset, len, extra); } }); return Validate(rep, nullptr, __LINE__); @@ -360,7 +360,7 @@ CordRepRing* CordRepRing::Create(CordRep* child, size_t extra) { if (IsFlatOrExternal(child)) { return CreateFromLeaf(child, 0, length, extra); } - if (child->IsRing()) { + if (child->IsRing()) { return Mutable(child->ring(), extra); } return CreateSlow(child, extra); @@ -368,18 +368,18 @@ CordRepRing* CordRepRing::Create(CordRep* child, size_t extra) { template <CordRepRing::AddMode mode> CordRepRing* CordRepRing::AddRing(CordRepRing* rep, CordRepRing* ring, - size_t offset, size_t len) { + size_t offset, size_t len) { assert(offset < ring->length); constexpr bool append = mode == AddMode::kAppend; Position head = ring->Find(offset); - Position tail = ring->FindTail(head.index, offset + len); + Position tail = ring->FindTail(head.index, offset + len); const index_type entries = ring->entries(head.index, tail.index); rep = Mutable(rep, entries); // The delta for making ring[head].end_pos into 'len - offset' const pos_type delta_length = - (append ? rep->begin_pos_ + rep->length : rep->begin_pos_ - len) - + (append ? rep->begin_pos_ + rep->length : rep->begin_pos_ - len) - ring->entry_begin_pos(head.index) - head.offset; // Start filling at `tail`, or `entries` before `head` @@ -420,36 +420,36 @@ CordRepRing* CordRepRing::AddRing(CordRepRing* rep, CordRepRing* ring, } // Commit changes - rep->length += len; + rep->length += len; if (append) { rep->tail_ = filler.pos(); } else { rep->head_ = filler.head(); - rep->begin_pos_ -= len; + rep->begin_pos_ -= len; } return Validate(rep); } CordRepRing* CordRepRing::AppendSlow(CordRepRing* rep, CordRep* child) { - Consume(child, [&rep](CordRep* child_arg, size_t offset, size_t len) { - if (child_arg->IsRing()) { - rep = AddRing<AddMode::kAppend>(rep, child_arg->ring(), offset, len); + Consume(child, [&rep](CordRep* child_arg, size_t offset, size_t len) { + if (child_arg->IsRing()) { + rep = AddRing<AddMode::kAppend>(rep, child_arg->ring(), offset, len); } else { - rep = AppendLeaf(rep, child_arg, offset, len); + rep = AppendLeaf(rep, child_arg, offset, len); } }); return rep; } CordRepRing* CordRepRing::AppendLeaf(CordRepRing* rep, CordRep* child, - size_t offset, size_t len) { + size_t offset, size_t len) { rep = Mutable(rep, 1); index_type back = rep->tail_; const pos_type begin_pos = rep->begin_pos_ + rep->length; rep->tail_ = rep->advance(rep->tail_); - rep->length += len; - rep->entry_end_pos()[back] = begin_pos + len; + rep->length += len; + rep->entry_end_pos()[back] = begin_pos + len; rep->entry_child()[back] = child; rep->entry_data_offset()[back] = static_cast<offset_type>(offset); return Validate(rep, nullptr, __LINE__); @@ -460,31 +460,31 @@ CordRepRing* CordRepRing::Append(CordRepRing* rep, CordRep* child) { if (IsFlatOrExternal(child)) { return AppendLeaf(rep, child, 0, length); } - if (child->IsRing()) { + if (child->IsRing()) { return AddRing<AddMode::kAppend>(rep, child->ring(), 0, length); } return AppendSlow(rep, child); } CordRepRing* CordRepRing::PrependSlow(CordRepRing* rep, CordRep* child) { - ReverseConsume(child, [&](CordRep* child_arg, size_t offset, size_t len) { - if (IsFlatOrExternal(child_arg)) { - rep = PrependLeaf(rep, child_arg, offset, len); + ReverseConsume(child, [&](CordRep* child_arg, size_t offset, size_t len) { + if (IsFlatOrExternal(child_arg)) { + rep = PrependLeaf(rep, child_arg, offset, len); } else { - rep = AddRing<AddMode::kPrepend>(rep, child_arg->ring(), offset, len); + rep = AddRing<AddMode::kPrepend>(rep, child_arg->ring(), offset, len); } }); return Validate(rep); } CordRepRing* CordRepRing::PrependLeaf(CordRepRing* rep, CordRep* child, - size_t offset, size_t len) { + size_t offset, size_t len) { rep = Mutable(rep, 1); index_type head = rep->retreat(rep->head_); pos_type end_pos = rep->begin_pos_; rep->head_ = head; - rep->length += len; - rep->begin_pos_ -= len; + rep->length += len; + rep->begin_pos_ -= len; rep->entry_end_pos()[head] = end_pos; rep->entry_child()[head] = child; rep->entry_data_offset()[head] = static_cast<offset_type>(offset); @@ -496,7 +496,7 @@ CordRepRing* CordRepRing::Prepend(CordRepRing* rep, CordRep* child) { if (IsFlatOrExternal(child)) { return PrependLeaf(rep, child, 0, length); } - if (child->IsRing()) { + if (child->IsRing()) { return AddRing<AddMode::kPrepend>(rep, child->ring(), 0, length); } return PrependSlow(rep, child); @@ -504,7 +504,7 @@ CordRepRing* CordRepRing::Prepend(CordRepRing* rep, CordRep* child) { CordRepRing* CordRepRing::Append(CordRepRing* rep, absl::string_view data, size_t extra) { - if (rep->refcount.IsMutable()) { + if (rep->refcount.IsMutable()) { Span<char> avail = rep->GetAppendBuffer(data.length()); if (!avail.empty()) { memcpy(avail.data(), data.data(), avail.length()); @@ -538,7 +538,7 @@ CordRepRing* CordRepRing::Append(CordRepRing* rep, absl::string_view data, CordRepRing* CordRepRing::Prepend(CordRepRing* rep, absl::string_view data, size_t extra) { - if (rep->refcount.IsMutable()) { + if (rep->refcount.IsMutable()) { Span<char> avail = rep->GetPrependBuffer(data.length()); if (!avail.empty()) { const char* tail = data.data() + data.length() - avail.length(); @@ -664,21 +664,21 @@ char CordRepRing::GetCharacter(size_t offset) const { } CordRepRing* CordRepRing::SubRing(CordRepRing* rep, size_t offset, - size_t len, size_t extra) { + size_t len, size_t extra) { assert(offset <= rep->length); - assert(offset <= rep->length - len); + assert(offset <= rep->length - len); - if (len == 0) { + if (len == 0) { CordRep::Unref(rep); return nullptr; } // Find position of first byte Position head = rep->Find(offset); - Position tail = rep->FindTail(head.index, offset + len); + Position tail = rep->FindTail(head.index, offset + len); const size_t new_entries = rep->entries(head.index, tail.index); - if (rep->refcount.IsMutable() && extra <= (rep->capacity() - new_entries)) { + if (rep->refcount.IsMutable() && extra <= (rep->capacity() - new_entries)) { // We adopt a privately owned rep and no extra entries needed. if (head.index != rep->head_) UnrefEntries(rep, rep->head_, head.index); if (tail.index != rep->tail_) UnrefEntries(rep, tail.index, rep->tail_); @@ -692,7 +692,7 @@ CordRepRing* CordRepRing::SubRing(CordRepRing* rep, size_t offset, } // Adjust begin_pos and length - rep->length = len; + rep->length = len; rep->begin_pos_ += offset; // Adjust head and tail blocks @@ -715,7 +715,7 @@ CordRepRing* CordRepRing::RemovePrefix(CordRepRing* rep, size_t len, } Position head = rep->Find(len); - if (rep->refcount.IsMutable()) { + if (rep->refcount.IsMutable()) { if (head.index != rep->head_) UnrefEntries(rep, rep->head_, head.index); rep->head_ = head.index; } else { @@ -745,7 +745,7 @@ CordRepRing* CordRepRing::RemoveSuffix(CordRepRing* rep, size_t len, } Position tail = rep->FindTail(rep->length - len); - if (rep->refcount.IsMutable()) { + if (rep->refcount.IsMutable()) { // We adopt a privately owned rep, scrub. if (tail.index != rep->tail_) UnrefEntries(rep, tail.index, rep->tail_); rep->tail_ = tail.index; diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_ring.h b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_ring.h index 2000e21ea0..958b24ea9c 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_ring.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_ring.h @@ -201,23 +201,23 @@ class CordRepRing : public CordRep { // referencing up to `size` capacity directly before the existing data. Span<char> GetPrependBuffer(size_t size); - // Returns a cord ring buffer containing `len` bytes of data starting at + // Returns a cord ring buffer containing `len` bytes of data starting at // `offset`. If the input is not shared, this function will remove all head // and tail child nodes outside of the requested range, and adjust the new // head and tail nodes as required. If the input is shared, this function // returns a new instance sharing some or all of the nodes from the input. - static CordRepRing* SubRing(CordRepRing* r, size_t offset, size_t len, + static CordRepRing* SubRing(CordRepRing* r, size_t offset, size_t len, size_t extra = 0); - // Returns a cord ring buffer with the first `len` bytes removed. + // Returns a cord ring buffer with the first `len` bytes removed. // If the input is not shared, this function will remove all head child nodes // fully inside the first `length` bytes, and adjust the new head as required. // If the input is shared, this function returns a new instance sharing some // or all of the nodes from the input. - static CordRepRing* RemoveSuffix(CordRepRing* r, size_t len, + static CordRepRing* RemoveSuffix(CordRepRing* r, size_t len, size_t extra = 0); - // Returns a cord ring buffer with the last `len` bytes removed. + // Returns a cord ring buffer with the last `len` bytes removed. // If the input is not shared, this function will remove all head child nodes // fully inside the first `length` bytes, and adjust the new head as required. // If the input is shared, this function returns a new instance sharing some @@ -228,18 +228,18 @@ class CordRepRing : public CordRep { // Returns the character at `offset`. Requires that `offset < length`. char GetCharacter(size_t offset) const; - // Returns true if this instance manages a single contiguous buffer, in which - // case the (optional) output parameter `fragment` is set. Otherwise, the - // function returns false, and `fragment` is left unchanged. - bool IsFlat(absl::string_view* fragment) const; - - // Returns true if the data starting at `offset` with length `len` is - // managed by this instance inside a single contiguous buffer, in which case - // the (optional) output parameter `fragment` is set to the contiguous memory - // starting at offset `offset` with length `length`. Otherwise, the function - // returns false, and `fragment` is left unchanged. - bool IsFlat(size_t offset, size_t len, absl::string_view* fragment) const; - + // Returns true if this instance manages a single contiguous buffer, in which + // case the (optional) output parameter `fragment` is set. Otherwise, the + // function returns false, and `fragment` is left unchanged. + bool IsFlat(absl::string_view* fragment) const; + + // Returns true if the data starting at `offset` with length `len` is + // managed by this instance inside a single contiguous buffer, in which case + // the (optional) output parameter `fragment` is set to the contiguous memory + // starting at offset `offset` with length `length`. Otherwise, the function + // returns false, and `fragment` is left unchanged. + bool IsFlat(size_t offset, size_t len, absl::string_view* fragment) const; + // Testing only: set capacity to requested capacity. void SetCapacityForTesting(size_t capacity); @@ -383,8 +383,8 @@ class CordRepRing : public CordRep { // Destroys the provided ring buffer, decrementing the reference count of all // contained child CordReps. The provided 1\`rep` should have a ref count of - // one (pre decrement destroy call observing `refcount.IsOne()`) or zero - // (post decrement destroy call observing `!refcount.Decrement()`). + // one (pre decrement destroy call observing `refcount.IsOne()`) or zero + // (post decrement destroy call observing `!refcount.Decrement()`). static void Destroy(CordRepRing* rep); // Returns a mutable reference to the logical end position array. @@ -464,10 +464,10 @@ class CordRepRing : public CordRep { size_t length, size_t extra); // Appends or prepends (depending on AddMode) the ring buffer in `ring' to - // `rep` starting at `offset` with length `len`. + // `rep` starting at `offset` with length `len`. template <AddMode mode> static CordRepRing* AddRing(CordRepRing* rep, CordRepRing* ring, - size_t offset, size_t len); + size_t offset, size_t len); // Increases the data offset for entry `index` by `n`. void AddDataOffset(index_type index, size_t n); @@ -570,34 +570,34 @@ inline CordRepRing::Position CordRepRing::FindTail(index_type head, // Now that CordRepRing is defined, we can define CordRep's helper casts: inline CordRepRing* CordRep::ring() { - assert(IsRing()); + assert(IsRing()); return static_cast<CordRepRing*>(this); } inline const CordRepRing* CordRep::ring() const { - assert(IsRing()); + assert(IsRing()); return static_cast<const CordRepRing*>(this); } -inline bool CordRepRing::IsFlat(absl::string_view* fragment) const { - if (entries() == 1) { - if (fragment) *fragment = entry_data(head()); - return true; - } - return false; -} - -inline bool CordRepRing::IsFlat(size_t offset, size_t len, - absl::string_view* fragment) const { - const Position pos = Find(offset); - const absl::string_view data = entry_data(pos.index); - if (data.length() >= len && data.length() - len >= pos.offset) { - if (fragment) *fragment = data.substr(pos.offset, len); - return true; - } - return false; -} - +inline bool CordRepRing::IsFlat(absl::string_view* fragment) const { + if (entries() == 1) { + if (fragment) *fragment = entry_data(head()); + return true; + } + return false; +} + +inline bool CordRepRing::IsFlat(size_t offset, size_t len, + absl::string_view* fragment) const { + const Position pos = Find(offset); + const absl::string_view data = entry_data(pos.index); + if (data.length() >= len && data.length() - len >= pos.offset) { + if (fragment) *fragment = data.substr(pos.offset, len); + return true; + } + return false; +} + std::ostream& operator<<(std::ostream& s, const CordRepRing& rep); } // namespace cord_internal diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_ring_reader.h b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_ring_reader.h index 7ceeaa000e..25a3fd0edf 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_ring_reader.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_ring_reader.h @@ -40,10 +40,10 @@ class CordRepRingReader { // The returned value is undefined if this instance is empty. CordRepRing::index_type index() const { return index_; } - // Returns the current node inside the ring buffer for this instance. - // The returned value is undefined if this instance is empty. - CordRep* node() const { return ring_->entry_child(index_); } - + // Returns the current node inside the ring buffer for this instance. + // The returned value is undefined if this instance is empty. + CordRep* node() const { return ring_->entry_child(index_); } + // Returns the length of the referenced ring buffer. // Requires the current instance to be non empty. size_t length() const { diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_test_util.h b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_test_util.h index ad828af2a5..9a0d4da75d 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_test_util.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_test_util.h @@ -1,220 +1,220 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_TEST_UTIL_H_ -#define ABSL_STRINGS_INTERNAL_CORD_REP_TEST_UTIL_H_ - -#include <cassert> -#include <memory> -#include <random> -#include <string> -#include <vector> - -#include "absl/base/config.h" -#include "absl/base/internal/raw_logging.h" -#include "absl/strings/internal/cord_internal.h" -#include "absl/strings/internal/cord_rep_btree.h" -#include "absl/strings/internal/cord_rep_flat.h" -#include "absl/strings/string_view.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace cordrep_testing { - -inline cord_internal::CordRepSubstring* MakeSubstring( - size_t start, size_t len, cord_internal::CordRep* rep) { - auto* sub = new cord_internal::CordRepSubstring; - sub->tag = cord_internal::SUBSTRING; - sub->start = start; - sub->length = len <= 0 ? rep->length - start + len : len; - sub->child = rep; - return sub; -} - -inline cord_internal::CordRepConcat* MakeConcat(cord_internal::CordRep* left, - cord_internal::CordRep* right, - int depth = 0) { - auto* concat = new cord_internal::CordRepConcat; - concat->tag = cord_internal::CONCAT; - concat->length = left->length + right->length; - concat->left = left; - concat->right = right; - concat->set_depth(depth); - return concat; -} - -inline cord_internal::CordRepFlat* MakeFlat(absl::string_view value) { - assert(value.length() <= cord_internal::kMaxFlatLength); - auto* flat = cord_internal::CordRepFlat::New(value.length()); - flat->length = value.length(); - memcpy(flat->Data(), value.data(), value.length()); - return flat; -} - -// Creates an external node for testing -inline cord_internal::CordRepExternal* MakeExternal(absl::string_view s) { - struct Rep : public cord_internal::CordRepExternal { - std::string s; - explicit Rep(absl::string_view sv) : s(sv) { - this->tag = cord_internal::EXTERNAL; - this->base = s.data(); - this->length = s.length(); - this->releaser_invoker = [](cord_internal::CordRepExternal* self) { - delete static_cast<Rep*>(self); - }; - } - }; - return new Rep(s); -} - -inline std::string CreateRandomString(size_t n) { - absl::string_view data = - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789~!@#$%^&*()_+=-<>?:\"{}[]|"; - std::minstd_rand rnd; - std::uniform_int_distribution<size_t> dist(0, data.size() - 1); - std::string s(n, ' '); - for (size_t i = 0; i < n; ++i) { - s[i] = data[dist(rnd)]; - } - return s; -} - -// Creates an array of flats from the provided string, chopping -// the provided string up into flats of size `chunk_size` characters -// resulting in roughly `data.size() / chunk_size` total flats. -inline std::vector<cord_internal::CordRep*> CreateFlatsFromString( - absl::string_view data, size_t chunk_size) { - assert(chunk_size > 0); - std::vector<cord_internal::CordRep*> flats; - for (absl::string_view s = data; !s.empty(); s.remove_prefix(chunk_size)) { - flats.push_back(MakeFlat(s.substr(0, chunk_size))); - } - return flats; -} - -inline cord_internal::CordRepBtree* CordRepBtreeFromFlats( - absl::Span<cord_internal::CordRep* const> flats) { - assert(!flats.empty()); - auto* node = cord_internal::CordRepBtree::Create(flats[0]); - for (size_t i = 1; i < flats.size(); ++i) { - node = cord_internal::CordRepBtree::Append(node, flats[i]); - } - return node; -} - -template <typename Fn> -inline void CordVisitReps(cord_internal::CordRep* rep, Fn&& fn) { - fn(rep); - while (rep->tag == cord_internal::SUBSTRING) { - rep = rep->substring()->child; - fn(rep); - } - if (rep->tag == cord_internal::BTREE) { - for (cord_internal::CordRep* edge : rep->btree()->Edges()) { - CordVisitReps(edge, fn); - } - } else if (rep->tag == cord_internal::CONCAT) { - CordVisitReps(rep->concat()->left, fn); - CordVisitReps(rep->concat()->right, fn); - } -} - -template <typename Predicate> -inline std::vector<cord_internal::CordRep*> CordCollectRepsIf( - Predicate&& predicate, cord_internal::CordRep* rep) { - std::vector<cord_internal::CordRep*> reps; - CordVisitReps(rep, [&reps, &predicate](cord_internal::CordRep* rep) { - if (predicate(rep)) reps.push_back(rep); - }); - return reps; -} - -inline std::vector<cord_internal::CordRep*> CordCollectReps( - cord_internal::CordRep* rep) { - std::vector<cord_internal::CordRep*> reps; - auto fn = [&reps](cord_internal::CordRep* rep) { reps.push_back(rep); }; - CordVisitReps(rep, fn); - return reps; -} - -inline void CordToString(cord_internal::CordRep* rep, std::string& s) { - size_t offset = 0; - size_t length = rep->length; - while (rep->tag == cord_internal::SUBSTRING) { - offset += rep->substring()->start; - rep = rep->substring()->child; - } - if (rep->tag == cord_internal::BTREE) { - for (cord_internal::CordRep* edge : rep->btree()->Edges()) { - CordToString(edge, s); - } - } else if (rep->tag >= cord_internal::FLAT) { - s.append(rep->flat()->Data() + offset, length); - } else if (rep->tag == cord_internal::EXTERNAL) { - s.append(rep->external()->base + offset, length); - } else { - ABSL_RAW_LOG(FATAL, "Unsupported tag %d", rep->tag); - } -} - -inline std::string CordToString(cord_internal::CordRep* rep) { - std::string s; - s.reserve(rep->length); - CordToString(rep, s); - return s; -} - -// RAII Helper class to automatically unref reps on destruction. -class AutoUnref { - public: - ~AutoUnref() { - for (CordRep* rep : unrefs_) CordRep::Unref(rep); - } - - // Adds `rep` to the list of reps to be unreffed at destruction. - template <typename CordRepType> - CordRepType* Add(CordRepType* rep) { - unrefs_.push_back(rep); - return rep; - } - - // Increments the reference count of `rep` by one, and adds it to - // the list of reps to be unreffed at destruction. - template <typename CordRepType> - CordRepType* Ref(CordRepType* rep) { - unrefs_.push_back(CordRep::Ref(rep)); - return rep; - } - - // Increments the reference count of `rep` by one if `condition` is true, - // and adds it to the list of reps to be unreffed at destruction. - template <typename CordRepType> - CordRepType* RefIf(bool condition, CordRepType* rep) { - if (condition) unrefs_.push_back(CordRep::Ref(rep)); - return rep; - } - - private: - using CordRep = absl::cord_internal::CordRep; - - std::vector<CordRep*> unrefs_; -}; - -} // namespace cordrep_testing -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STRINGS_INTERNAL_CORD_REP_TEST_UTIL_H_ +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_TEST_UTIL_H_ +#define ABSL_STRINGS_INTERNAL_CORD_REP_TEST_UTIL_H_ + +#include <cassert> +#include <memory> +#include <random> +#include <string> +#include <vector> + +#include "absl/base/config.h" +#include "absl/base/internal/raw_logging.h" +#include "absl/strings/internal/cord_internal.h" +#include "absl/strings/internal/cord_rep_btree.h" +#include "absl/strings/internal/cord_rep_flat.h" +#include "absl/strings/string_view.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cordrep_testing { + +inline cord_internal::CordRepSubstring* MakeSubstring( + size_t start, size_t len, cord_internal::CordRep* rep) { + auto* sub = new cord_internal::CordRepSubstring; + sub->tag = cord_internal::SUBSTRING; + sub->start = start; + sub->length = len <= 0 ? rep->length - start + len : len; + sub->child = rep; + return sub; +} + +inline cord_internal::CordRepConcat* MakeConcat(cord_internal::CordRep* left, + cord_internal::CordRep* right, + int depth = 0) { + auto* concat = new cord_internal::CordRepConcat; + concat->tag = cord_internal::CONCAT; + concat->length = left->length + right->length; + concat->left = left; + concat->right = right; + concat->set_depth(depth); + return concat; +} + +inline cord_internal::CordRepFlat* MakeFlat(absl::string_view value) { + assert(value.length() <= cord_internal::kMaxFlatLength); + auto* flat = cord_internal::CordRepFlat::New(value.length()); + flat->length = value.length(); + memcpy(flat->Data(), value.data(), value.length()); + return flat; +} + +// Creates an external node for testing +inline cord_internal::CordRepExternal* MakeExternal(absl::string_view s) { + struct Rep : public cord_internal::CordRepExternal { + std::string s; + explicit Rep(absl::string_view sv) : s(sv) { + this->tag = cord_internal::EXTERNAL; + this->base = s.data(); + this->length = s.length(); + this->releaser_invoker = [](cord_internal::CordRepExternal* self) { + delete static_cast<Rep*>(self); + }; + } + }; + return new Rep(s); +} + +inline std::string CreateRandomString(size_t n) { + absl::string_view data = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789~!@#$%^&*()_+=-<>?:\"{}[]|"; + std::minstd_rand rnd; + std::uniform_int_distribution<size_t> dist(0, data.size() - 1); + std::string s(n, ' '); + for (size_t i = 0; i < n; ++i) { + s[i] = data[dist(rnd)]; + } + return s; +} + +// Creates an array of flats from the provided string, chopping +// the provided string up into flats of size `chunk_size` characters +// resulting in roughly `data.size() / chunk_size` total flats. +inline std::vector<cord_internal::CordRep*> CreateFlatsFromString( + absl::string_view data, size_t chunk_size) { + assert(chunk_size > 0); + std::vector<cord_internal::CordRep*> flats; + for (absl::string_view s = data; !s.empty(); s.remove_prefix(chunk_size)) { + flats.push_back(MakeFlat(s.substr(0, chunk_size))); + } + return flats; +} + +inline cord_internal::CordRepBtree* CordRepBtreeFromFlats( + absl::Span<cord_internal::CordRep* const> flats) { + assert(!flats.empty()); + auto* node = cord_internal::CordRepBtree::Create(flats[0]); + for (size_t i = 1; i < flats.size(); ++i) { + node = cord_internal::CordRepBtree::Append(node, flats[i]); + } + return node; +} + +template <typename Fn> +inline void CordVisitReps(cord_internal::CordRep* rep, Fn&& fn) { + fn(rep); + while (rep->tag == cord_internal::SUBSTRING) { + rep = rep->substring()->child; + fn(rep); + } + if (rep->tag == cord_internal::BTREE) { + for (cord_internal::CordRep* edge : rep->btree()->Edges()) { + CordVisitReps(edge, fn); + } + } else if (rep->tag == cord_internal::CONCAT) { + CordVisitReps(rep->concat()->left, fn); + CordVisitReps(rep->concat()->right, fn); + } +} + +template <typename Predicate> +inline std::vector<cord_internal::CordRep*> CordCollectRepsIf( + Predicate&& predicate, cord_internal::CordRep* rep) { + std::vector<cord_internal::CordRep*> reps; + CordVisitReps(rep, [&reps, &predicate](cord_internal::CordRep* rep) { + if (predicate(rep)) reps.push_back(rep); + }); + return reps; +} + +inline std::vector<cord_internal::CordRep*> CordCollectReps( + cord_internal::CordRep* rep) { + std::vector<cord_internal::CordRep*> reps; + auto fn = [&reps](cord_internal::CordRep* rep) { reps.push_back(rep); }; + CordVisitReps(rep, fn); + return reps; +} + +inline void CordToString(cord_internal::CordRep* rep, std::string& s) { + size_t offset = 0; + size_t length = rep->length; + while (rep->tag == cord_internal::SUBSTRING) { + offset += rep->substring()->start; + rep = rep->substring()->child; + } + if (rep->tag == cord_internal::BTREE) { + for (cord_internal::CordRep* edge : rep->btree()->Edges()) { + CordToString(edge, s); + } + } else if (rep->tag >= cord_internal::FLAT) { + s.append(rep->flat()->Data() + offset, length); + } else if (rep->tag == cord_internal::EXTERNAL) { + s.append(rep->external()->base + offset, length); + } else { + ABSL_RAW_LOG(FATAL, "Unsupported tag %d", rep->tag); + } +} + +inline std::string CordToString(cord_internal::CordRep* rep) { + std::string s; + s.reserve(rep->length); + CordToString(rep, s); + return s; +} + +// RAII Helper class to automatically unref reps on destruction. +class AutoUnref { + public: + ~AutoUnref() { + for (CordRep* rep : unrefs_) CordRep::Unref(rep); + } + + // Adds `rep` to the list of reps to be unreffed at destruction. + template <typename CordRepType> + CordRepType* Add(CordRepType* rep) { + unrefs_.push_back(rep); + return rep; + } + + // Increments the reference count of `rep` by one, and adds it to + // the list of reps to be unreffed at destruction. + template <typename CordRepType> + CordRepType* Ref(CordRepType* rep) { + unrefs_.push_back(CordRep::Ref(rep)); + return rep; + } + + // Increments the reference count of `rep` by one if `condition` is true, + // and adds it to the list of reps to be unreffed at destruction. + template <typename CordRepType> + CordRepType* RefIf(bool condition, CordRepType* rep) { + if (condition) unrefs_.push_back(CordRep::Ref(rep)); + return rep; + } + + private: + using CordRep = absl::cord_internal::CordRep; + + std::vector<CordRep*> unrefs_; +}; + +} // namespace cordrep_testing +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STRINGS_INTERNAL_CORD_REP_TEST_UTIL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions.cc index 20d314f03c..5081d4b636 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions.cc @@ -1,96 +1,96 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/strings/internal/cordz_functions.h" - -#include <atomic> -#include <cmath> -#include <limits> -#include <random> - -#include "absl/base/attributes.h" -#include "absl/base/config.h" -#include "absl/base/internal/raw_logging.h" -#include "absl/profiling/internal/exponential_biased.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { -namespace { - -// The average interval until the next sample. A value of 0 disables profiling -// while a value of 1 will profile all Cords. -std::atomic<int> g_cordz_mean_interval(50000); - -} // namespace - -#ifdef ABSL_INTERNAL_CORDZ_ENABLED - -// Special negative 'not initialized' per thread value for cordz_next_sample. -static constexpr int64_t kInitCordzNextSample = -1; - -ABSL_CONST_INIT thread_local int64_t cordz_next_sample = kInitCordzNextSample; - -// kIntervalIfDisabled is the number of profile-eligible events need to occur -// before the code will confirm that cordz is still disabled. -constexpr int64_t kIntervalIfDisabled = 1 << 16; - -ABSL_ATTRIBUTE_NOINLINE bool cordz_should_profile_slow() { - - thread_local absl::profiling_internal::ExponentialBiased - exponential_biased_generator; - int32_t mean_interval = get_cordz_mean_interval(); - - // Check if we disabled profiling. If so, set the next sample to a "large" - // number to minimize the overhead of the should_profile codepath. - if (mean_interval <= 0) { - cordz_next_sample = kIntervalIfDisabled; - return false; - } - - // Check if we're always sampling. - if (mean_interval == 1) { - cordz_next_sample = 1; - return true; - } - - if (cordz_next_sample <= 0) { - // If first check on current thread, check cordz_should_profile() - // again using the created (initial) stride in cordz_next_sample. - const bool initialized = cordz_next_sample != kInitCordzNextSample; - cordz_next_sample = exponential_biased_generator.GetStride(mean_interval); - return initialized || cordz_should_profile(); - } - - --cordz_next_sample; - return false; -} - -void cordz_set_next_sample_for_testing(int64_t next_sample) { - cordz_next_sample = next_sample; -} - -#endif // ABSL_INTERNAL_CORDZ_ENABLED - -int32_t get_cordz_mean_interval() { - return g_cordz_mean_interval.load(std::memory_order_acquire); -} - -void set_cordz_mean_interval(int32_t mean_interval) { - g_cordz_mean_interval.store(mean_interval, std::memory_order_release); -} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace absl +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/strings/internal/cordz_functions.h" + +#include <atomic> +#include <cmath> +#include <limits> +#include <random> + +#include "absl/base/attributes.h" +#include "absl/base/config.h" +#include "absl/base/internal/raw_logging.h" +#include "absl/profiling/internal/exponential_biased.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { +namespace { + +// The average interval until the next sample. A value of 0 disables profiling +// while a value of 1 will profile all Cords. +std::atomic<int> g_cordz_mean_interval(50000); + +} // namespace + +#ifdef ABSL_INTERNAL_CORDZ_ENABLED + +// Special negative 'not initialized' per thread value for cordz_next_sample. +static constexpr int64_t kInitCordzNextSample = -1; + +ABSL_CONST_INIT thread_local int64_t cordz_next_sample = kInitCordzNextSample; + +// kIntervalIfDisabled is the number of profile-eligible events need to occur +// before the code will confirm that cordz is still disabled. +constexpr int64_t kIntervalIfDisabled = 1 << 16; + +ABSL_ATTRIBUTE_NOINLINE bool cordz_should_profile_slow() { + + thread_local absl::profiling_internal::ExponentialBiased + exponential_biased_generator; + int32_t mean_interval = get_cordz_mean_interval(); + + // Check if we disabled profiling. If so, set the next sample to a "large" + // number to minimize the overhead of the should_profile codepath. + if (mean_interval <= 0) { + cordz_next_sample = kIntervalIfDisabled; + return false; + } + + // Check if we're always sampling. + if (mean_interval == 1) { + cordz_next_sample = 1; + return true; + } + + if (cordz_next_sample <= 0) { + // If first check on current thread, check cordz_should_profile() + // again using the created (initial) stride in cordz_next_sample. + const bool initialized = cordz_next_sample != kInitCordzNextSample; + cordz_next_sample = exponential_biased_generator.GetStride(mean_interval); + return initialized || cordz_should_profile(); + } + + --cordz_next_sample; + return false; +} + +void cordz_set_next_sample_for_testing(int64_t next_sample) { + cordz_next_sample = next_sample; +} + +#endif // ABSL_INTERNAL_CORDZ_ENABLED + +int32_t get_cordz_mean_interval() { + return g_cordz_mean_interval.load(std::memory_order_acquire); +} + +void set_cordz_mean_interval(int32_t mean_interval) { + g_cordz_mean_interval.store(mean_interval, std::memory_order_release); +} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions.h b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions.h index c9ba14508a..f6d14770f3 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions.h @@ -1,85 +1,85 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_CORDZ_FUNCTIONS_H_ -#define ABSL_STRINGS_CORDZ_FUNCTIONS_H_ - -#include <stdint.h> - -#include "absl/base/attributes.h" -#include "absl/base/config.h" -#include "absl/base/optimization.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -// Returns the current sample rate. This represents the average interval -// between samples. -int32_t get_cordz_mean_interval(); - -// Sets the sample rate with the average interval between samples. -void set_cordz_mean_interval(int32_t mean_interval); - -// Enable cordz unless any of the following applies: -// - no thread local support -// - MSVC build -// - Android build -// - Apple build -// - DLL build -// Hashtablez is turned off completely in opensource builds. -// MSVC's static atomics are dynamically initialized in debug mode, which breaks -// sampling. -#if defined(ABSL_HAVE_THREAD_LOCAL) && !defined(_MSC_VER) && \ - !defined(ABSL_BUILD_DLL) && !defined(ABSL_CONSUME_DLL) && \ - !defined(__ANDROID__) && !defined(__APPLE__) -#define ABSL_INTERNAL_CORDZ_ENABLED 1 -#endif - -#ifdef ABSL_INTERNAL_CORDZ_ENABLED - -// cordz_next_sample is the number of events until the next sample event. If -// the value is 1 or less, the code will check on the next event if cordz is -// enabled, and if so, will sample the Cord. cordz is only enabled when we can -// use thread locals. -ABSL_CONST_INIT extern thread_local int64_t cordz_next_sample; - -// Determines if the next sample should be profiled. If it is, the value pointed -// at by next_sample will be set with the interval until the next sample. -bool cordz_should_profile_slow(); - -// Returns true if the next cord should be sampled. -inline bool cordz_should_profile() { - if (ABSL_PREDICT_TRUE(cordz_next_sample > 1)) { - cordz_next_sample--; - return false; - } - return cordz_should_profile_slow(); -} - -// Sets the interval until the next sample (for testing only) -void cordz_set_next_sample_for_testing(int64_t next_sample); - -#else // ABSL_INTERNAL_CORDZ_ENABLED - -inline bool cordz_should_profile() { return false; } -inline void cordz_set_next_sample_for_testing(int64_t) {} - -#endif // ABSL_INTERNAL_CORDZ_ENABLED - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STRINGS_CORDZ_FUNCTIONS_H_ +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_CORDZ_FUNCTIONS_H_ +#define ABSL_STRINGS_CORDZ_FUNCTIONS_H_ + +#include <stdint.h> + +#include "absl/base/attributes.h" +#include "absl/base/config.h" +#include "absl/base/optimization.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +// Returns the current sample rate. This represents the average interval +// between samples. +int32_t get_cordz_mean_interval(); + +// Sets the sample rate with the average interval between samples. +void set_cordz_mean_interval(int32_t mean_interval); + +// Enable cordz unless any of the following applies: +// - no thread local support +// - MSVC build +// - Android build +// - Apple build +// - DLL build +// Hashtablez is turned off completely in opensource builds. +// MSVC's static atomics are dynamically initialized in debug mode, which breaks +// sampling. +#if defined(ABSL_HAVE_THREAD_LOCAL) && !defined(_MSC_VER) && \ + !defined(ABSL_BUILD_DLL) && !defined(ABSL_CONSUME_DLL) && \ + !defined(__ANDROID__) && !defined(__APPLE__) +#define ABSL_INTERNAL_CORDZ_ENABLED 1 +#endif + +#ifdef ABSL_INTERNAL_CORDZ_ENABLED + +// cordz_next_sample is the number of events until the next sample event. If +// the value is 1 or less, the code will check on the next event if cordz is +// enabled, and if so, will sample the Cord. cordz is only enabled when we can +// use thread locals. +ABSL_CONST_INIT extern thread_local int64_t cordz_next_sample; + +// Determines if the next sample should be profiled. If it is, the value pointed +// at by next_sample will be set with the interval until the next sample. +bool cordz_should_profile_slow(); + +// Returns true if the next cord should be sampled. +inline bool cordz_should_profile() { + if (ABSL_PREDICT_TRUE(cordz_next_sample > 1)) { + cordz_next_sample--; + return false; + } + return cordz_should_profile_slow(); +} + +// Sets the interval until the next sample (for testing only) +void cordz_set_next_sample_for_testing(int64_t next_sample); + +#else // ABSL_INTERNAL_CORDZ_ENABLED + +inline bool cordz_should_profile() { return false; } +inline void cordz_set_next_sample_for_testing(int64_t) {} + +#endif // ABSL_INTERNAL_CORDZ_ENABLED + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STRINGS_CORDZ_FUNCTIONS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions/ya.make b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions/ya.make index 6dc8a23cc5..6bf5159263 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions/ya.make +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions/ya.make @@ -9,9 +9,9 @@ OWNER(g:cpp-contrib) LICENSE(Apache-2.0) PEERDIR( - contrib/restricted/abseil-cpp/absl/base/internal/raw_logging - contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp/absl/base/internal/raw_logging + contrib/restricted/abseil-cpp/absl/base/log_severity + contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased ) ADDINCL( @@ -26,10 +26,10 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/strings/internal) +SRCDIR(contrib/restricted/abseil-cpp/absl/strings/internal) SRCS( - cordz_functions.cc + cordz_functions.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle.cc index a73fefed59..a8d552c214 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle.cc @@ -1,139 +1,139 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#include "absl/strings/internal/cordz_handle.h" - -#include <atomic> - -#include "absl/base/internal/raw_logging.h" // For ABSL_RAW_CHECK -#include "absl/base/internal/spinlock.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -using ::absl::base_internal::SpinLockHolder; - -ABSL_CONST_INIT CordzHandle::Queue CordzHandle::global_queue_(absl::kConstInit); - -CordzHandle::CordzHandle(bool is_snapshot) : is_snapshot_(is_snapshot) { - if (is_snapshot) { - SpinLockHolder lock(&queue_->mutex); - CordzHandle* dq_tail = queue_->dq_tail.load(std::memory_order_acquire); - if (dq_tail != nullptr) { - dq_prev_ = dq_tail; - dq_tail->dq_next_ = this; - } - queue_->dq_tail.store(this, std::memory_order_release); - } -} - -CordzHandle::~CordzHandle() { - ODRCheck(); - if (is_snapshot_) { - std::vector<CordzHandle*> to_delete; - { - SpinLockHolder lock(&queue_->mutex); - CordzHandle* next = dq_next_; - if (dq_prev_ == nullptr) { - // We were head of the queue, delete every CordzHandle until we reach - // either the end of the list, or a snapshot handle. - while (next && !next->is_snapshot_) { - to_delete.push_back(next); - next = next->dq_next_; - } - } else { - // Another CordzHandle existed before this one, don't delete anything. - dq_prev_->dq_next_ = next; - } - if (next) { - next->dq_prev_ = dq_prev_; - } else { - queue_->dq_tail.store(dq_prev_, std::memory_order_release); - } - } - for (CordzHandle* handle : to_delete) { - delete handle; - } - } -} - -bool CordzHandle::SafeToDelete() const { - return is_snapshot_ || queue_->IsEmpty(); -} - -void CordzHandle::Delete(CordzHandle* handle) { - assert(handle); - if (handle) { - handle->ODRCheck(); - Queue* const queue = handle->queue_; - if (!handle->SafeToDelete()) { - SpinLockHolder lock(&queue->mutex); - CordzHandle* dq_tail = queue->dq_tail.load(std::memory_order_acquire); - if (dq_tail != nullptr) { - handle->dq_prev_ = dq_tail; - dq_tail->dq_next_ = handle; - queue->dq_tail.store(handle, std::memory_order_release); - return; - } - } - delete handle; - } -} - -std::vector<const CordzHandle*> CordzHandle::DiagnosticsGetDeleteQueue() { - std::vector<const CordzHandle*> handles; - SpinLockHolder lock(&global_queue_.mutex); - CordzHandle* dq_tail = global_queue_.dq_tail.load(std::memory_order_acquire); - for (const CordzHandle* p = dq_tail; p; p = p->dq_prev_) { - handles.push_back(p); - } - return handles; -} - -bool CordzHandle::DiagnosticsHandleIsSafeToInspect( - const CordzHandle* handle) const { - ODRCheck(); - if (!is_snapshot_) return false; - if (handle == nullptr) return true; - if (handle->is_snapshot_) return false; - bool snapshot_found = false; - SpinLockHolder lock(&queue_->mutex); - for (const CordzHandle* p = queue_->dq_tail; p; p = p->dq_prev_) { - if (p == handle) return !snapshot_found; - if (p == this) snapshot_found = true; - } - ABSL_ASSERT(snapshot_found); // Assert that 'this' is in delete queue. - return true; -} - -std::vector<const CordzHandle*> -CordzHandle::DiagnosticsGetSafeToInspectDeletedHandles() { - ODRCheck(); - std::vector<const CordzHandle*> handles; - if (!is_snapshot()) { - return handles; - } - - SpinLockHolder lock(&queue_->mutex); - for (const CordzHandle* p = dq_next_; p != nullptr; p = p->dq_next_) { - if (!p->is_snapshot()) { - handles.push_back(p); - } - } - return handles; -} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace absl +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "absl/strings/internal/cordz_handle.h" + +#include <atomic> + +#include "absl/base/internal/raw_logging.h" // For ABSL_RAW_CHECK +#include "absl/base/internal/spinlock.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +using ::absl::base_internal::SpinLockHolder; + +ABSL_CONST_INIT CordzHandle::Queue CordzHandle::global_queue_(absl::kConstInit); + +CordzHandle::CordzHandle(bool is_snapshot) : is_snapshot_(is_snapshot) { + if (is_snapshot) { + SpinLockHolder lock(&queue_->mutex); + CordzHandle* dq_tail = queue_->dq_tail.load(std::memory_order_acquire); + if (dq_tail != nullptr) { + dq_prev_ = dq_tail; + dq_tail->dq_next_ = this; + } + queue_->dq_tail.store(this, std::memory_order_release); + } +} + +CordzHandle::~CordzHandle() { + ODRCheck(); + if (is_snapshot_) { + std::vector<CordzHandle*> to_delete; + { + SpinLockHolder lock(&queue_->mutex); + CordzHandle* next = dq_next_; + if (dq_prev_ == nullptr) { + // We were head of the queue, delete every CordzHandle until we reach + // either the end of the list, or a snapshot handle. + while (next && !next->is_snapshot_) { + to_delete.push_back(next); + next = next->dq_next_; + } + } else { + // Another CordzHandle existed before this one, don't delete anything. + dq_prev_->dq_next_ = next; + } + if (next) { + next->dq_prev_ = dq_prev_; + } else { + queue_->dq_tail.store(dq_prev_, std::memory_order_release); + } + } + for (CordzHandle* handle : to_delete) { + delete handle; + } + } +} + +bool CordzHandle::SafeToDelete() const { + return is_snapshot_ || queue_->IsEmpty(); +} + +void CordzHandle::Delete(CordzHandle* handle) { + assert(handle); + if (handle) { + handle->ODRCheck(); + Queue* const queue = handle->queue_; + if (!handle->SafeToDelete()) { + SpinLockHolder lock(&queue->mutex); + CordzHandle* dq_tail = queue->dq_tail.load(std::memory_order_acquire); + if (dq_tail != nullptr) { + handle->dq_prev_ = dq_tail; + dq_tail->dq_next_ = handle; + queue->dq_tail.store(handle, std::memory_order_release); + return; + } + } + delete handle; + } +} + +std::vector<const CordzHandle*> CordzHandle::DiagnosticsGetDeleteQueue() { + std::vector<const CordzHandle*> handles; + SpinLockHolder lock(&global_queue_.mutex); + CordzHandle* dq_tail = global_queue_.dq_tail.load(std::memory_order_acquire); + for (const CordzHandle* p = dq_tail; p; p = p->dq_prev_) { + handles.push_back(p); + } + return handles; +} + +bool CordzHandle::DiagnosticsHandleIsSafeToInspect( + const CordzHandle* handle) const { + ODRCheck(); + if (!is_snapshot_) return false; + if (handle == nullptr) return true; + if (handle->is_snapshot_) return false; + bool snapshot_found = false; + SpinLockHolder lock(&queue_->mutex); + for (const CordzHandle* p = queue_->dq_tail; p; p = p->dq_prev_) { + if (p == handle) return !snapshot_found; + if (p == this) snapshot_found = true; + } + ABSL_ASSERT(snapshot_found); // Assert that 'this' is in delete queue. + return true; +} + +std::vector<const CordzHandle*> +CordzHandle::DiagnosticsGetSafeToInspectDeletedHandles() { + ODRCheck(); + std::vector<const CordzHandle*> handles; + if (!is_snapshot()) { + return handles; + } + + SpinLockHolder lock(&queue_->mutex); + for (const CordzHandle* p = dq_next_; p != nullptr; p = p->dq_next_) { + if (!p->is_snapshot()) { + handles.push_back(p); + } + } + return handles; +} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle.h b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle.h index 5df53c782a..955447e3e5 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle.h @@ -1,131 +1,131 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_CORDZ_HANDLE_H_ -#define ABSL_STRINGS_CORDZ_HANDLE_H_ - -#include <atomic> -#include <vector> - -#include "absl/base/config.h" -#include "absl/base/internal/raw_logging.h" -#include "absl/base/internal/spinlock.h" -#include "absl/synchronization/mutex.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -// This base class allows multiple types of object (CordzInfo and -// CordzSampleToken) to exist simultaneously on the delete queue (pointed to by -// global_dq_tail and traversed using dq_prev_ and dq_next_). The -// delete queue guarantees that once a profiler creates a CordzSampleToken and -// has gained visibility into a CordzInfo object, that CordzInfo object will not -// be deleted prematurely. This allows the profiler to inspect all CordzInfo -// objects that are alive without needing to hold a global lock. -class CordzHandle { - public: - CordzHandle() : CordzHandle(false) {} - - bool is_snapshot() const { return is_snapshot_; } - - // Returns true if this instance is safe to be deleted because it is either a - // snapshot, which is always safe to delete, or not included in the global - // delete queue and thus not included in any snapshot. - // Callers are responsible for making sure this instance can not be newly - // discovered by other threads. For example, CordzInfo instances first de-list - // themselves from the global CordzInfo list before determining if they are - // safe to be deleted directly. - // If SafeToDelete returns false, callers MUST use the Delete() method to - // safely queue CordzHandle instances for deletion. - bool SafeToDelete() const; - - // Deletes the provided instance, or puts it on the delete queue to be deleted - // once there are no more sample tokens (snapshot) instances potentially - // referencing the instance. `handle` should not be null. - static void Delete(CordzHandle* handle); - - // Returns the current entries in the delete queue in LIFO order. - static std::vector<const CordzHandle*> DiagnosticsGetDeleteQueue(); - - // Returns true if the provided handle is nullptr or guarded by this handle. - // Since the CordzSnapshot token is itself a CordzHandle, this method will - // allow tests to check if that token is keeping an arbitrary CordzHandle - // alive. - bool DiagnosticsHandleIsSafeToInspect(const CordzHandle* handle) const; - - // Returns the current entries in the delete queue, in LIFO order, that are - // protected by this. CordzHandle objects are only placed on the delete queue - // after CordzHandle::Delete is called with them as an argument. Only - // CordzHandle objects that are not also CordzSnapshot objects will be - // included in the return vector. For each of the handles in the return - // vector, the earliest that their memory can be freed is when this - // CordzSnapshot object is deleted. - std::vector<const CordzHandle*> DiagnosticsGetSafeToInspectDeletedHandles(); - - protected: - explicit CordzHandle(bool is_snapshot); - virtual ~CordzHandle(); - - private: - // Global queue data. CordzHandle stores a pointer to the global queue - // instance to harden against ODR violations. - struct Queue { - constexpr explicit Queue(absl::ConstInitType) - : mutex(absl::kConstInit, - absl::base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL) {} - - absl::base_internal::SpinLock mutex; - std::atomic<CordzHandle*> dq_tail ABSL_GUARDED_BY(mutex){nullptr}; - - // Returns true if this delete queue is empty. This method does not acquire - // the lock, but does a 'load acquire' observation on the delete queue tail. - // It is used inside Delete() to check for the presence of a delete queue - // without holding the lock. The assumption is that the caller is in the - // state of 'being deleted', and can not be newly discovered by a concurrent - // 'being constructed' snapshot instance. Practically, this means that any - // such discovery (`find`, 'first' or 'next', etc) must have proper 'happens - // before / after' semantics and atomic fences. - bool IsEmpty() const ABSL_NO_THREAD_SAFETY_ANALYSIS { - return dq_tail.load(std::memory_order_acquire) == nullptr; - } - }; - - void ODRCheck() const { -#ifndef NDEBUG - ABSL_RAW_CHECK(queue_ == &global_queue_, "ODR violation in Cord"); -#endif - } - - ABSL_CONST_INIT static Queue global_queue_; - Queue* const queue_ = &global_queue_; - const bool is_snapshot_; - - // dq_prev_ and dq_next_ require the global queue mutex to be held. - // Unfortunately we can't use thread annotations such that the thread safety - // analysis understands that queue_ and global_queue_ are one and the same. - CordzHandle* dq_prev_ = nullptr; - CordzHandle* dq_next_ = nullptr; -}; - -class CordzSnapshot : public CordzHandle { - public: - CordzSnapshot() : CordzHandle(true) {} -}; - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STRINGS_CORDZ_HANDLE_H_ +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_CORDZ_HANDLE_H_ +#define ABSL_STRINGS_CORDZ_HANDLE_H_ + +#include <atomic> +#include <vector> + +#include "absl/base/config.h" +#include "absl/base/internal/raw_logging.h" +#include "absl/base/internal/spinlock.h" +#include "absl/synchronization/mutex.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +// This base class allows multiple types of object (CordzInfo and +// CordzSampleToken) to exist simultaneously on the delete queue (pointed to by +// global_dq_tail and traversed using dq_prev_ and dq_next_). The +// delete queue guarantees that once a profiler creates a CordzSampleToken and +// has gained visibility into a CordzInfo object, that CordzInfo object will not +// be deleted prematurely. This allows the profiler to inspect all CordzInfo +// objects that are alive without needing to hold a global lock. +class CordzHandle { + public: + CordzHandle() : CordzHandle(false) {} + + bool is_snapshot() const { return is_snapshot_; } + + // Returns true if this instance is safe to be deleted because it is either a + // snapshot, which is always safe to delete, or not included in the global + // delete queue and thus not included in any snapshot. + // Callers are responsible for making sure this instance can not be newly + // discovered by other threads. For example, CordzInfo instances first de-list + // themselves from the global CordzInfo list before determining if they are + // safe to be deleted directly. + // If SafeToDelete returns false, callers MUST use the Delete() method to + // safely queue CordzHandle instances for deletion. + bool SafeToDelete() const; + + // Deletes the provided instance, or puts it on the delete queue to be deleted + // once there are no more sample tokens (snapshot) instances potentially + // referencing the instance. `handle` should not be null. + static void Delete(CordzHandle* handle); + + // Returns the current entries in the delete queue in LIFO order. + static std::vector<const CordzHandle*> DiagnosticsGetDeleteQueue(); + + // Returns true if the provided handle is nullptr or guarded by this handle. + // Since the CordzSnapshot token is itself a CordzHandle, this method will + // allow tests to check if that token is keeping an arbitrary CordzHandle + // alive. + bool DiagnosticsHandleIsSafeToInspect(const CordzHandle* handle) const; + + // Returns the current entries in the delete queue, in LIFO order, that are + // protected by this. CordzHandle objects are only placed on the delete queue + // after CordzHandle::Delete is called with them as an argument. Only + // CordzHandle objects that are not also CordzSnapshot objects will be + // included in the return vector. For each of the handles in the return + // vector, the earliest that their memory can be freed is when this + // CordzSnapshot object is deleted. + std::vector<const CordzHandle*> DiagnosticsGetSafeToInspectDeletedHandles(); + + protected: + explicit CordzHandle(bool is_snapshot); + virtual ~CordzHandle(); + + private: + // Global queue data. CordzHandle stores a pointer to the global queue + // instance to harden against ODR violations. + struct Queue { + constexpr explicit Queue(absl::ConstInitType) + : mutex(absl::kConstInit, + absl::base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL) {} + + absl::base_internal::SpinLock mutex; + std::atomic<CordzHandle*> dq_tail ABSL_GUARDED_BY(mutex){nullptr}; + + // Returns true if this delete queue is empty. This method does not acquire + // the lock, but does a 'load acquire' observation on the delete queue tail. + // It is used inside Delete() to check for the presence of a delete queue + // without holding the lock. The assumption is that the caller is in the + // state of 'being deleted', and can not be newly discovered by a concurrent + // 'being constructed' snapshot instance. Practically, this means that any + // such discovery (`find`, 'first' or 'next', etc) must have proper 'happens + // before / after' semantics and atomic fences. + bool IsEmpty() const ABSL_NO_THREAD_SAFETY_ANALYSIS { + return dq_tail.load(std::memory_order_acquire) == nullptr; + } + }; + + void ODRCheck() const { +#ifndef NDEBUG + ABSL_RAW_CHECK(queue_ == &global_queue_, "ODR violation in Cord"); +#endif + } + + ABSL_CONST_INIT static Queue global_queue_; + Queue* const queue_ = &global_queue_; + const bool is_snapshot_; + + // dq_prev_ and dq_next_ require the global queue mutex to be held. + // Unfortunately we can't use thread annotations such that the thread safety + // analysis understands that queue_ and global_queue_ are one and the same. + CordzHandle* dq_prev_ = nullptr; + CordzHandle* dq_next_ = nullptr; +}; + +class CordzSnapshot : public CordzHandle { + public: + CordzSnapshot() : CordzHandle(true) {} +}; + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STRINGS_CORDZ_HANDLE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle/ya.make b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle/ya.make index 47e1c6006c..c9b950c194 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle/ya.make +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle/ya.make @@ -10,23 +10,23 @@ LICENSE(Apache-2.0) PEERDIR( contrib/restricted/abseil-cpp/absl/base - contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc contrib/restricted/abseil-cpp/absl/base/internal/raw_logging contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/debugging - contrib/restricted/abseil-cpp/absl/debugging/stacktrace - contrib/restricted/abseil-cpp/absl/debugging/symbolize - contrib/restricted/abseil-cpp/absl/demangle + contrib/restricted/abseil-cpp/absl/debugging + contrib/restricted/abseil-cpp/absl/debugging/stacktrace + contrib/restricted/abseil-cpp/absl/debugging/symbolize + contrib/restricted/abseil-cpp/absl/demangle contrib/restricted/abseil-cpp/absl/numeric contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp/absl/synchronization - contrib/restricted/abseil-cpp/absl/synchronization/internal - contrib/restricted/abseil-cpp/absl/time - contrib/restricted/abseil-cpp/absl/time/civil_time - contrib/restricted/abseil-cpp/absl/time/time_zone + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/synchronization + contrib/restricted/abseil-cpp/absl/synchronization/internal + contrib/restricted/abseil-cpp/absl/time + contrib/restricted/abseil-cpp/absl/time/civil_time + contrib/restricted/abseil-cpp/absl/time/time_zone ) ADDINCL( @@ -41,10 +41,10 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/strings/internal) +SRCDIR(contrib/restricted/abseil-cpp/absl/strings/internal) SRCS( - cordz_handle.cc + cordz_handle.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info.cc index 5c18bbc566..937f0aad5c 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info.cc @@ -1,445 +1,445 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/strings/internal/cordz_info.h" - -#include "absl/base/config.h" -#include "absl/base/internal/spinlock.h" -#include "absl/container/inlined_vector.h" -#include "absl/debugging/stacktrace.h" -#include "absl/strings/internal/cord_internal.h" -#include "absl/strings/internal/cord_rep_btree.h" -#include "absl/strings/internal/cord_rep_ring.h" -#include "absl/strings/internal/cordz_handle.h" -#include "absl/strings/internal/cordz_statistics.h" -#include "absl/strings/internal/cordz_update_tracker.h" -#include "absl/synchronization/mutex.h" -#include "absl/types/span.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -using ::absl::base_internal::SpinLockHolder; - -constexpr int CordzInfo::kMaxStackDepth; - -ABSL_CONST_INIT CordzInfo::List CordzInfo::global_list_{absl::kConstInit}; - -namespace { - -// CordRepAnalyzer performs the analysis of a cord. -// -// It computes absolute node counts and total memory usage, and an 'estimated -// fair share memory usage` statistic. -// Conceptually, it divides the 'memory usage' at each location in the 'cord -// graph' by the cumulative reference count of that location. The cumulative -// reference count is the factored total of all edges leading into that node. -// -// The top level node is treated specially: we assume the current thread -// (typically called from the CordzHandler) to hold a reference purely to -// perform a safe analysis, and not being part of the application. So we -// substract 1 from the reference count of the top node to compute the -// 'application fair share' excluding the reference of the current thread. -// -// An example of fair sharing, and why we multiply reference counts: -// Assume we have 2 CordReps, both being a Substring referencing a Flat: -// CordSubstring A (refcount = 5) --> child Flat C (refcount = 2) -// CordSubstring B (refcount = 9) --> child Flat C (refcount = 2) -// -// Flat C has 2 incoming edges from the 2 substrings (refcount = 2) and is not -// referenced directly anywhere else. Translated into a 'fair share', we then -// attribute 50% of the memory (memory / refcount = 2) to each incoming edge. -// Rep A has a refcount of 5, so we attribute each incoming edge 1 / 5th of the -// memory cost below it, i.e.: the fair share of Rep A of the memory used by C -// is then 'memory C / (refcount C * refcount A) + (memory A / refcount A)'. -// It is also easy to see how all incoming edges add up to 100%. -class CordRepAnalyzer { - public: - // Creates an analyzer instance binding to `statistics`. - explicit CordRepAnalyzer(CordzStatistics& statistics) - : statistics_(statistics) {} - - // Analyzes the memory statistics and node counts for the provided `rep`, and - // adds the results to `statistics`. Note that node counts and memory sizes - // are not initialized, computed values are added to any existing values. - void AnalyzeCordRep(const CordRep* rep) { - // Process all linear nodes. - // As per the class comments, use refcout - 1 on the top level node, as the - // top level node is assumed to be referenced only for analysis purposes. - size_t refcount = rep->refcount.Get(); - RepRef repref{rep, (refcount > 1) ? refcount - 1 : 1}; - - // Process all top level linear nodes (substrings and flats). - repref = CountLinearReps(repref, memory_usage_); - - if (repref.rep != nullptr) { - if (repref.rep->tag == RING) { - AnalyzeRing(repref); - } else if (repref.rep->tag == BTREE) { - AnalyzeBtree(repref); - } else if (repref.rep->tag == CONCAT) { - AnalyzeConcat(repref); - } else { - // We should have either a concat, btree, or ring node if not null. - assert(false); - } - } - - // Adds values to output - statistics_.estimated_memory_usage += memory_usage_.total; - statistics_.estimated_fair_share_memory_usage += - static_cast<size_t>(memory_usage_.fair_share); - } - - private: - // RepRef identifies a CordRep* inside the Cord tree with its cumulative - // refcount including itself. For example, a tree consisting of a substring - // with a refcount of 3 and a child flat with a refcount of 4 will have RepRef - // refcounts of 3 and 12 respectively. - struct RepRef { - const CordRep* rep; - size_t refcount; - - // Returns a 'child' RepRef which contains the cumulative reference count of - // this instance multiplied by the child's reference count. - RepRef Child(const CordRep* child) const { - return RepRef{child, refcount * child->refcount.Get()}; - } - }; - - // Memory usage values - struct MemoryUsage { - size_t total = 0; - double fair_share = 0.0; - - // Adds 'size` memory usage to this class, with a cumulative (recursive) - // reference count of `refcount` - void Add(size_t size, size_t refcount) { - total += size; - fair_share += static_cast<double>(size) / refcount; - } - }; - - // Returns `rr` if `rr.rep` is not null and a CONCAT type. - // Asserts that `rr.rep` is a concat node or null. - static RepRef AssertConcat(RepRef repref) { - const CordRep* rep = repref.rep; - assert(rep == nullptr || rep->tag == CONCAT); - return (rep != nullptr && rep->tag == CONCAT) ? repref : RepRef{nullptr, 0}; - } - - // Counts a flat of the provide allocated size - void CountFlat(size_t size) { - statistics_.node_count++; - statistics_.node_counts.flat++; - if (size <= 64) { - statistics_.node_counts.flat_64++; - } else if (size <= 128) { - statistics_.node_counts.flat_128++; - } else if (size <= 256) { - statistics_.node_counts.flat_256++; - } else if (size <= 512) { - statistics_.node_counts.flat_512++; - } else if (size <= 1024) { - statistics_.node_counts.flat_1k++; - } - } - - // Processes 'linear' reps (substring, flat, external) not requiring iteration - // or recursion. Returns RefRep{null} if all reps were processed, else returns - // the top-most non-linear concat or ring cordrep. - // Node counts are updated into `statistics_`, memory usage is update into - // `memory_usage`, which typically references `memory_usage_` except for ring - // buffers where we count children unrounded. - RepRef CountLinearReps(RepRef rep, MemoryUsage& memory_usage) { - // Consume all substrings - while (rep.rep->tag == SUBSTRING) { - statistics_.node_count++; - statistics_.node_counts.substring++; - memory_usage.Add(sizeof(CordRepSubstring), rep.refcount); - rep = rep.Child(rep.rep->substring()->child); - } - - // Consume possible FLAT - if (rep.rep->tag >= FLAT) { - size_t size = rep.rep->flat()->AllocatedSize(); - CountFlat(size); - memory_usage.Add(size, rep.refcount); - return RepRef{nullptr, 0}; - } - - // Consume possible external - if (rep.rep->tag == EXTERNAL) { - statistics_.node_count++; - statistics_.node_counts.external++; - size_t size = rep.rep->length + sizeof(CordRepExternalImpl<intptr_t>); - memory_usage.Add(size, rep.refcount); - return RepRef{nullptr, 0}; - } - - return rep; - } - - // Analyzes the provided concat node in a flattened recursive way. - void AnalyzeConcat(RepRef rep) { - absl::InlinedVector<RepRef, 47> pending; - - while (rep.rep != nullptr) { - const CordRepConcat* concat = rep.rep->concat(); - RepRef left = rep.Child(concat->left); - RepRef right = rep.Child(concat->right); - - statistics_.node_count++; - statistics_.node_counts.concat++; - memory_usage_.Add(sizeof(CordRepConcat), rep.refcount); - - right = AssertConcat(CountLinearReps(right, memory_usage_)); - rep = AssertConcat(CountLinearReps(left, memory_usage_)); - if (rep.rep != nullptr) { - if (right.rep != nullptr) { - pending.push_back(right); - } - } else if (right.rep != nullptr) { - rep = right; - } else if (!pending.empty()) { - rep = pending.back(); - pending.pop_back(); - } - } - } - - // Analyzes the provided ring. - void AnalyzeRing(RepRef rep) { - statistics_.node_count++; - statistics_.node_counts.ring++; - const CordRepRing* ring = rep.rep->ring(); - memory_usage_.Add(CordRepRing::AllocSize(ring->capacity()), rep.refcount); - ring->ForEach([&](CordRepRing::index_type pos) { - CountLinearReps(rep.Child(ring->entry_child(pos)), memory_usage_); - }); - } - - // Analyzes the provided btree. - void AnalyzeBtree(RepRef rep) { - statistics_.node_count++; - statistics_.node_counts.btree++; - memory_usage_.Add(sizeof(CordRepBtree), rep.refcount); - const CordRepBtree* tree = rep.rep->btree(); - if (tree->height() > 0) { - for (CordRep* edge : tree->Edges()) { - AnalyzeBtree(rep.Child(edge)); - } - } else { - for (CordRep* edge : tree->Edges()) { - CountLinearReps(rep.Child(edge), memory_usage_); - } - } - } - - CordzStatistics& statistics_; - MemoryUsage memory_usage_; -}; - -} // namespace - -CordzInfo* CordzInfo::Head(const CordzSnapshot& snapshot) { - ABSL_ASSERT(snapshot.is_snapshot()); - - // We can do an 'unsafe' load of 'head', as we are guaranteed that the - // instance it points to is kept alive by the provided CordzSnapshot, so we - // can simply return the current value using an acquire load. - // We do enforce in DEBUG builds that the 'head' value is present in the - // delete queue: ODR violations may lead to 'snapshot' and 'global_list_' - // being in different libraries / modules. - CordzInfo* head = global_list_.head.load(std::memory_order_acquire); - ABSL_ASSERT(snapshot.DiagnosticsHandleIsSafeToInspect(head)); - return head; -} - -CordzInfo* CordzInfo::Next(const CordzSnapshot& snapshot) const { - ABSL_ASSERT(snapshot.is_snapshot()); - - // Similar to the 'Head()' function, we do not need a mutex here. - CordzInfo* next = ci_next_.load(std::memory_order_acquire); - ABSL_ASSERT(snapshot.DiagnosticsHandleIsSafeToInspect(this)); - ABSL_ASSERT(snapshot.DiagnosticsHandleIsSafeToInspect(next)); - return next; -} - -void CordzInfo::TrackCord(InlineData& cord, MethodIdentifier method) { - assert(cord.is_tree()); - assert(!cord.is_profiled()); - CordzInfo* cordz_info = new CordzInfo(cord.as_tree(), nullptr, method); - cord.set_cordz_info(cordz_info); - cordz_info->Track(); -} - -void CordzInfo::TrackCord(InlineData& cord, const InlineData& src, - MethodIdentifier method) { - assert(cord.is_tree()); - assert(src.is_tree()); - - // Unsample current as we the current cord is being replaced with 'src', - // so any method history is no longer relevant. - CordzInfo* cordz_info = cord.cordz_info(); - if (cordz_info != nullptr) cordz_info->Untrack(); - - // Start new cord sample - cordz_info = new CordzInfo(cord.as_tree(), src.cordz_info(), method); - cord.set_cordz_info(cordz_info); - cordz_info->Track(); -} - -void CordzInfo::MaybeTrackCordImpl(InlineData& cord, const InlineData& src, - MethodIdentifier method) { - if (src.is_profiled()) { - TrackCord(cord, src, method); - } else if (cord.is_profiled()) { - cord.cordz_info()->Untrack(); - cord.clear_cordz_info(); - } -} - -CordzInfo::MethodIdentifier CordzInfo::GetParentMethod(const CordzInfo* src) { - if (src == nullptr) return MethodIdentifier::kUnknown; - return src->parent_method_ != MethodIdentifier::kUnknown ? src->parent_method_ - : src->method_; -} - -int CordzInfo::FillParentStack(const CordzInfo* src, void** stack) { - assert(stack); - if (src == nullptr) return 0; - if (src->parent_stack_depth_) { - memcpy(stack, src->parent_stack_, src->parent_stack_depth_ * sizeof(void*)); - return src->parent_stack_depth_; - } - memcpy(stack, src->stack_, src->stack_depth_ * sizeof(void*)); - return src->stack_depth_; -} - -CordzInfo::CordzInfo(CordRep* rep, const CordzInfo* src, - MethodIdentifier method) - : rep_(rep), - stack_depth_(absl::GetStackTrace(stack_, /*max_depth=*/kMaxStackDepth, - /*skip_count=*/1)), - parent_stack_depth_(FillParentStack(src, parent_stack_)), - method_(method), - parent_method_(GetParentMethod(src)), - create_time_(absl::Now()) { - update_tracker_.LossyAdd(method); - if (src) { - // Copy parent counters. - update_tracker_.LossyAdd(src->update_tracker_); - } -} - -CordzInfo::~CordzInfo() { - // `rep_` is potentially kept alive if CordzInfo is included - // in a collection snapshot (which should be rare). - if (ABSL_PREDICT_FALSE(rep_)) { - CordRep::Unref(rep_); - } -} - -void CordzInfo::Track() { - SpinLockHolder l(&list_->mutex); - - CordzInfo* const head = list_->head.load(std::memory_order_acquire); - if (head != nullptr) { - head->ci_prev_.store(this, std::memory_order_release); - } - ci_next_.store(head, std::memory_order_release); - list_->head.store(this, std::memory_order_release); -} - -void CordzInfo::Untrack() { - ODRCheck(); - { - SpinLockHolder l(&list_->mutex); - - CordzInfo* const head = list_->head.load(std::memory_order_acquire); - CordzInfo* const next = ci_next_.load(std::memory_order_acquire); - CordzInfo* const prev = ci_prev_.load(std::memory_order_acquire); - - if (next) { - ABSL_ASSERT(next->ci_prev_.load(std::memory_order_acquire) == this); - next->ci_prev_.store(prev, std::memory_order_release); - } - if (prev) { - ABSL_ASSERT(head != this); - ABSL_ASSERT(prev->ci_next_.load(std::memory_order_acquire) == this); - prev->ci_next_.store(next, std::memory_order_release); - } else { - ABSL_ASSERT(head == this); - list_->head.store(next, std::memory_order_release); - } - } - - // We can no longer be discovered: perform a fast path check if we are not - // listed on any delete queue, so we can directly delete this instance. - if (SafeToDelete()) { - UnsafeSetCordRep(nullptr); - delete this; - return; - } - - // We are likely part of a snapshot, extend the life of the CordRep - { - absl::MutexLock lock(&mutex_); - if (rep_) CordRep::Ref(rep_); - } - CordzHandle::Delete(this); -} - -void CordzInfo::Lock(MethodIdentifier method) - ABSL_EXCLUSIVE_LOCK_FUNCTION(mutex_) { - mutex_.Lock(); - update_tracker_.LossyAdd(method); - assert(rep_); -} - -void CordzInfo::Unlock() ABSL_UNLOCK_FUNCTION(mutex_) { - bool tracked = rep_ != nullptr; - mutex_.Unlock(); - if (!tracked) { - Untrack(); - } -} - -absl::Span<void* const> CordzInfo::GetStack() const { - return absl::MakeConstSpan(stack_, stack_depth_); -} - -absl::Span<void* const> CordzInfo::GetParentStack() const { - return absl::MakeConstSpan(parent_stack_, parent_stack_depth_); -} - -CordzStatistics CordzInfo::GetCordzStatistics() const { - CordzStatistics stats; - stats.method = method_; - stats.parent_method = parent_method_; - stats.update_tracker = update_tracker_; - if (CordRep* rep = RefCordRep()) { - stats.size = rep->length; - CordRepAnalyzer analyzer(stats); - analyzer.AnalyzeCordRep(rep); - CordRep::Unref(rep); - } - return stats; -} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace absl +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/strings/internal/cordz_info.h" + +#include "absl/base/config.h" +#include "absl/base/internal/spinlock.h" +#include "absl/container/inlined_vector.h" +#include "absl/debugging/stacktrace.h" +#include "absl/strings/internal/cord_internal.h" +#include "absl/strings/internal/cord_rep_btree.h" +#include "absl/strings/internal/cord_rep_ring.h" +#include "absl/strings/internal/cordz_handle.h" +#include "absl/strings/internal/cordz_statistics.h" +#include "absl/strings/internal/cordz_update_tracker.h" +#include "absl/synchronization/mutex.h" +#include "absl/types/span.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +using ::absl::base_internal::SpinLockHolder; + +constexpr int CordzInfo::kMaxStackDepth; + +ABSL_CONST_INIT CordzInfo::List CordzInfo::global_list_{absl::kConstInit}; + +namespace { + +// CordRepAnalyzer performs the analysis of a cord. +// +// It computes absolute node counts and total memory usage, and an 'estimated +// fair share memory usage` statistic. +// Conceptually, it divides the 'memory usage' at each location in the 'cord +// graph' by the cumulative reference count of that location. The cumulative +// reference count is the factored total of all edges leading into that node. +// +// The top level node is treated specially: we assume the current thread +// (typically called from the CordzHandler) to hold a reference purely to +// perform a safe analysis, and not being part of the application. So we +// substract 1 from the reference count of the top node to compute the +// 'application fair share' excluding the reference of the current thread. +// +// An example of fair sharing, and why we multiply reference counts: +// Assume we have 2 CordReps, both being a Substring referencing a Flat: +// CordSubstring A (refcount = 5) --> child Flat C (refcount = 2) +// CordSubstring B (refcount = 9) --> child Flat C (refcount = 2) +// +// Flat C has 2 incoming edges from the 2 substrings (refcount = 2) and is not +// referenced directly anywhere else. Translated into a 'fair share', we then +// attribute 50% of the memory (memory / refcount = 2) to each incoming edge. +// Rep A has a refcount of 5, so we attribute each incoming edge 1 / 5th of the +// memory cost below it, i.e.: the fair share of Rep A of the memory used by C +// is then 'memory C / (refcount C * refcount A) + (memory A / refcount A)'. +// It is also easy to see how all incoming edges add up to 100%. +class CordRepAnalyzer { + public: + // Creates an analyzer instance binding to `statistics`. + explicit CordRepAnalyzer(CordzStatistics& statistics) + : statistics_(statistics) {} + + // Analyzes the memory statistics and node counts for the provided `rep`, and + // adds the results to `statistics`. Note that node counts and memory sizes + // are not initialized, computed values are added to any existing values. + void AnalyzeCordRep(const CordRep* rep) { + // Process all linear nodes. + // As per the class comments, use refcout - 1 on the top level node, as the + // top level node is assumed to be referenced only for analysis purposes. + size_t refcount = rep->refcount.Get(); + RepRef repref{rep, (refcount > 1) ? refcount - 1 : 1}; + + // Process all top level linear nodes (substrings and flats). + repref = CountLinearReps(repref, memory_usage_); + + if (repref.rep != nullptr) { + if (repref.rep->tag == RING) { + AnalyzeRing(repref); + } else if (repref.rep->tag == BTREE) { + AnalyzeBtree(repref); + } else if (repref.rep->tag == CONCAT) { + AnalyzeConcat(repref); + } else { + // We should have either a concat, btree, or ring node if not null. + assert(false); + } + } + + // Adds values to output + statistics_.estimated_memory_usage += memory_usage_.total; + statistics_.estimated_fair_share_memory_usage += + static_cast<size_t>(memory_usage_.fair_share); + } + + private: + // RepRef identifies a CordRep* inside the Cord tree with its cumulative + // refcount including itself. For example, a tree consisting of a substring + // with a refcount of 3 and a child flat with a refcount of 4 will have RepRef + // refcounts of 3 and 12 respectively. + struct RepRef { + const CordRep* rep; + size_t refcount; + + // Returns a 'child' RepRef which contains the cumulative reference count of + // this instance multiplied by the child's reference count. + RepRef Child(const CordRep* child) const { + return RepRef{child, refcount * child->refcount.Get()}; + } + }; + + // Memory usage values + struct MemoryUsage { + size_t total = 0; + double fair_share = 0.0; + + // Adds 'size` memory usage to this class, with a cumulative (recursive) + // reference count of `refcount` + void Add(size_t size, size_t refcount) { + total += size; + fair_share += static_cast<double>(size) / refcount; + } + }; + + // Returns `rr` if `rr.rep` is not null and a CONCAT type. + // Asserts that `rr.rep` is a concat node or null. + static RepRef AssertConcat(RepRef repref) { + const CordRep* rep = repref.rep; + assert(rep == nullptr || rep->tag == CONCAT); + return (rep != nullptr && rep->tag == CONCAT) ? repref : RepRef{nullptr, 0}; + } + + // Counts a flat of the provide allocated size + void CountFlat(size_t size) { + statistics_.node_count++; + statistics_.node_counts.flat++; + if (size <= 64) { + statistics_.node_counts.flat_64++; + } else if (size <= 128) { + statistics_.node_counts.flat_128++; + } else if (size <= 256) { + statistics_.node_counts.flat_256++; + } else if (size <= 512) { + statistics_.node_counts.flat_512++; + } else if (size <= 1024) { + statistics_.node_counts.flat_1k++; + } + } + + // Processes 'linear' reps (substring, flat, external) not requiring iteration + // or recursion. Returns RefRep{null} if all reps were processed, else returns + // the top-most non-linear concat or ring cordrep. + // Node counts are updated into `statistics_`, memory usage is update into + // `memory_usage`, which typically references `memory_usage_` except for ring + // buffers where we count children unrounded. + RepRef CountLinearReps(RepRef rep, MemoryUsage& memory_usage) { + // Consume all substrings + while (rep.rep->tag == SUBSTRING) { + statistics_.node_count++; + statistics_.node_counts.substring++; + memory_usage.Add(sizeof(CordRepSubstring), rep.refcount); + rep = rep.Child(rep.rep->substring()->child); + } + + // Consume possible FLAT + if (rep.rep->tag >= FLAT) { + size_t size = rep.rep->flat()->AllocatedSize(); + CountFlat(size); + memory_usage.Add(size, rep.refcount); + return RepRef{nullptr, 0}; + } + + // Consume possible external + if (rep.rep->tag == EXTERNAL) { + statistics_.node_count++; + statistics_.node_counts.external++; + size_t size = rep.rep->length + sizeof(CordRepExternalImpl<intptr_t>); + memory_usage.Add(size, rep.refcount); + return RepRef{nullptr, 0}; + } + + return rep; + } + + // Analyzes the provided concat node in a flattened recursive way. + void AnalyzeConcat(RepRef rep) { + absl::InlinedVector<RepRef, 47> pending; + + while (rep.rep != nullptr) { + const CordRepConcat* concat = rep.rep->concat(); + RepRef left = rep.Child(concat->left); + RepRef right = rep.Child(concat->right); + + statistics_.node_count++; + statistics_.node_counts.concat++; + memory_usage_.Add(sizeof(CordRepConcat), rep.refcount); + + right = AssertConcat(CountLinearReps(right, memory_usage_)); + rep = AssertConcat(CountLinearReps(left, memory_usage_)); + if (rep.rep != nullptr) { + if (right.rep != nullptr) { + pending.push_back(right); + } + } else if (right.rep != nullptr) { + rep = right; + } else if (!pending.empty()) { + rep = pending.back(); + pending.pop_back(); + } + } + } + + // Analyzes the provided ring. + void AnalyzeRing(RepRef rep) { + statistics_.node_count++; + statistics_.node_counts.ring++; + const CordRepRing* ring = rep.rep->ring(); + memory_usage_.Add(CordRepRing::AllocSize(ring->capacity()), rep.refcount); + ring->ForEach([&](CordRepRing::index_type pos) { + CountLinearReps(rep.Child(ring->entry_child(pos)), memory_usage_); + }); + } + + // Analyzes the provided btree. + void AnalyzeBtree(RepRef rep) { + statistics_.node_count++; + statistics_.node_counts.btree++; + memory_usage_.Add(sizeof(CordRepBtree), rep.refcount); + const CordRepBtree* tree = rep.rep->btree(); + if (tree->height() > 0) { + for (CordRep* edge : tree->Edges()) { + AnalyzeBtree(rep.Child(edge)); + } + } else { + for (CordRep* edge : tree->Edges()) { + CountLinearReps(rep.Child(edge), memory_usage_); + } + } + } + + CordzStatistics& statistics_; + MemoryUsage memory_usage_; +}; + +} // namespace + +CordzInfo* CordzInfo::Head(const CordzSnapshot& snapshot) { + ABSL_ASSERT(snapshot.is_snapshot()); + + // We can do an 'unsafe' load of 'head', as we are guaranteed that the + // instance it points to is kept alive by the provided CordzSnapshot, so we + // can simply return the current value using an acquire load. + // We do enforce in DEBUG builds that the 'head' value is present in the + // delete queue: ODR violations may lead to 'snapshot' and 'global_list_' + // being in different libraries / modules. + CordzInfo* head = global_list_.head.load(std::memory_order_acquire); + ABSL_ASSERT(snapshot.DiagnosticsHandleIsSafeToInspect(head)); + return head; +} + +CordzInfo* CordzInfo::Next(const CordzSnapshot& snapshot) const { + ABSL_ASSERT(snapshot.is_snapshot()); + + // Similar to the 'Head()' function, we do not need a mutex here. + CordzInfo* next = ci_next_.load(std::memory_order_acquire); + ABSL_ASSERT(snapshot.DiagnosticsHandleIsSafeToInspect(this)); + ABSL_ASSERT(snapshot.DiagnosticsHandleIsSafeToInspect(next)); + return next; +} + +void CordzInfo::TrackCord(InlineData& cord, MethodIdentifier method) { + assert(cord.is_tree()); + assert(!cord.is_profiled()); + CordzInfo* cordz_info = new CordzInfo(cord.as_tree(), nullptr, method); + cord.set_cordz_info(cordz_info); + cordz_info->Track(); +} + +void CordzInfo::TrackCord(InlineData& cord, const InlineData& src, + MethodIdentifier method) { + assert(cord.is_tree()); + assert(src.is_tree()); + + // Unsample current as we the current cord is being replaced with 'src', + // so any method history is no longer relevant. + CordzInfo* cordz_info = cord.cordz_info(); + if (cordz_info != nullptr) cordz_info->Untrack(); + + // Start new cord sample + cordz_info = new CordzInfo(cord.as_tree(), src.cordz_info(), method); + cord.set_cordz_info(cordz_info); + cordz_info->Track(); +} + +void CordzInfo::MaybeTrackCordImpl(InlineData& cord, const InlineData& src, + MethodIdentifier method) { + if (src.is_profiled()) { + TrackCord(cord, src, method); + } else if (cord.is_profiled()) { + cord.cordz_info()->Untrack(); + cord.clear_cordz_info(); + } +} + +CordzInfo::MethodIdentifier CordzInfo::GetParentMethod(const CordzInfo* src) { + if (src == nullptr) return MethodIdentifier::kUnknown; + return src->parent_method_ != MethodIdentifier::kUnknown ? src->parent_method_ + : src->method_; +} + +int CordzInfo::FillParentStack(const CordzInfo* src, void** stack) { + assert(stack); + if (src == nullptr) return 0; + if (src->parent_stack_depth_) { + memcpy(stack, src->parent_stack_, src->parent_stack_depth_ * sizeof(void*)); + return src->parent_stack_depth_; + } + memcpy(stack, src->stack_, src->stack_depth_ * sizeof(void*)); + return src->stack_depth_; +} + +CordzInfo::CordzInfo(CordRep* rep, const CordzInfo* src, + MethodIdentifier method) + : rep_(rep), + stack_depth_(absl::GetStackTrace(stack_, /*max_depth=*/kMaxStackDepth, + /*skip_count=*/1)), + parent_stack_depth_(FillParentStack(src, parent_stack_)), + method_(method), + parent_method_(GetParentMethod(src)), + create_time_(absl::Now()) { + update_tracker_.LossyAdd(method); + if (src) { + // Copy parent counters. + update_tracker_.LossyAdd(src->update_tracker_); + } +} + +CordzInfo::~CordzInfo() { + // `rep_` is potentially kept alive if CordzInfo is included + // in a collection snapshot (which should be rare). + if (ABSL_PREDICT_FALSE(rep_)) { + CordRep::Unref(rep_); + } +} + +void CordzInfo::Track() { + SpinLockHolder l(&list_->mutex); + + CordzInfo* const head = list_->head.load(std::memory_order_acquire); + if (head != nullptr) { + head->ci_prev_.store(this, std::memory_order_release); + } + ci_next_.store(head, std::memory_order_release); + list_->head.store(this, std::memory_order_release); +} + +void CordzInfo::Untrack() { + ODRCheck(); + { + SpinLockHolder l(&list_->mutex); + + CordzInfo* const head = list_->head.load(std::memory_order_acquire); + CordzInfo* const next = ci_next_.load(std::memory_order_acquire); + CordzInfo* const prev = ci_prev_.load(std::memory_order_acquire); + + if (next) { + ABSL_ASSERT(next->ci_prev_.load(std::memory_order_acquire) == this); + next->ci_prev_.store(prev, std::memory_order_release); + } + if (prev) { + ABSL_ASSERT(head != this); + ABSL_ASSERT(prev->ci_next_.load(std::memory_order_acquire) == this); + prev->ci_next_.store(next, std::memory_order_release); + } else { + ABSL_ASSERT(head == this); + list_->head.store(next, std::memory_order_release); + } + } + + // We can no longer be discovered: perform a fast path check if we are not + // listed on any delete queue, so we can directly delete this instance. + if (SafeToDelete()) { + UnsafeSetCordRep(nullptr); + delete this; + return; + } + + // We are likely part of a snapshot, extend the life of the CordRep + { + absl::MutexLock lock(&mutex_); + if (rep_) CordRep::Ref(rep_); + } + CordzHandle::Delete(this); +} + +void CordzInfo::Lock(MethodIdentifier method) + ABSL_EXCLUSIVE_LOCK_FUNCTION(mutex_) { + mutex_.Lock(); + update_tracker_.LossyAdd(method); + assert(rep_); +} + +void CordzInfo::Unlock() ABSL_UNLOCK_FUNCTION(mutex_) { + bool tracked = rep_ != nullptr; + mutex_.Unlock(); + if (!tracked) { + Untrack(); + } +} + +absl::Span<void* const> CordzInfo::GetStack() const { + return absl::MakeConstSpan(stack_, stack_depth_); +} + +absl::Span<void* const> CordzInfo::GetParentStack() const { + return absl::MakeConstSpan(parent_stack_, parent_stack_depth_); +} + +CordzStatistics CordzInfo::GetCordzStatistics() const { + CordzStatistics stats; + stats.method = method_; + stats.parent_method = parent_method_; + stats.update_tracker = update_tracker_; + if (CordRep* rep = RefCordRep()) { + stats.size = rep->length; + CordRepAnalyzer analyzer(stats); + analyzer.AnalyzeCordRep(rep); + CordRep::Unref(rep); + } + return stats; +} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info.h b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info.h index 026d5b9981..7f08fab8cd 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info.h @@ -1,298 +1,298 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_CORDZ_INFO_H_ -#define ABSL_STRINGS_CORDZ_INFO_H_ - -#include <atomic> -#include <cstdint> -#include <functional> - -#include "absl/base/config.h" -#include "absl/base/internal/raw_logging.h" -#include "absl/base/internal/spinlock.h" -#include "absl/base/thread_annotations.h" -#include "absl/strings/internal/cord_internal.h" -#include "absl/strings/internal/cordz_functions.h" -#include "absl/strings/internal/cordz_handle.h" -#include "absl/strings/internal/cordz_statistics.h" -#include "absl/strings/internal/cordz_update_tracker.h" -#include "absl/synchronization/mutex.h" -#include "absl/types/span.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -// CordzInfo tracks a profiled Cord. Each of these objects can be in two places. -// If a Cord is alive, the CordzInfo will be in the global_cordz_infos map, and -// can also be retrieved via the linked list starting with -// global_cordz_infos_head and continued via the cordz_info_next() method. When -// a Cord has reached the end of its lifespan, the CordzInfo object will be -// migrated out of the global_cordz_infos list and the global_cordz_infos_map, -// and will either be deleted or appended to the global_delete_queue. If it is -// placed on the global_delete_queue, the CordzInfo object will be cleaned in -// the destructor of a CordzSampleToken object. -class ABSL_LOCKABLE CordzInfo : public CordzHandle { - public: - using MethodIdentifier = CordzUpdateTracker::MethodIdentifier; - - // TrackCord creates a CordzInfo instance which tracks important metrics of - // a sampled cord, and stores the created CordzInfo instance into `cord'. All - // CordzInfo instances are placed in a global list which is used to discover - // and snapshot all actively tracked cords. Callers are responsible for - // calling UntrackCord() before the tracked Cord instance is deleted, or to - // stop tracking the sampled Cord. Callers are also responsible for guarding - // changes to the 'tree' value of a Cord (InlineData.tree) through the Lock() - // and Unlock() calls. Any change resulting in a new tree value for the cord - // requires a call to SetCordRep() before the old tree has been unreffed - // and/or deleted. `method` identifies the Cord public API method initiating - // the cord to be sampled. - // Requires `cord` to hold a tree, and `cord.cordz_info()` to be null. - static void TrackCord(InlineData& cord, MethodIdentifier method); - - // Identical to TrackCord(), except that this function fills the - // `parent_stack` and `parent_method` properties of the returned CordzInfo - // instance from the provided `src` instance if `src` is sampled. - // This function should be used for sampling 'copy constructed' and 'copy - // assigned' cords. This function allows 'cord` to be already sampled, in - // which case the CordzInfo will be newly created from `src`. - static void TrackCord(InlineData& cord, const InlineData& src, - MethodIdentifier method); - - // Maybe sample the cord identified by 'cord' for method 'method'. - // Uses `cordz_should_profile` to randomly pick cords to be sampled, and if - // so, invokes `TrackCord` to start sampling `cord`. - static void MaybeTrackCord(InlineData& cord, MethodIdentifier method); - - // Maybe sample the cord identified by 'cord' for method 'method'. - // `src` identifies a 'parent' cord which is assigned to `cord`, typically the - // input cord for a copy constructor, or an assign method such as `operator=` - // `cord` will be sampled if (and only if) `src` is sampled. - // If `cord` is currently being sampled and `src` is not being sampled, then - // this function will stop sampling the cord and reset the cord's cordz_info. - // - // Previously this function defined that `cord` will be sampled if either - // `src` is sampled, or if `cord` is randomly picked for sampling. However, - // this can cause issues, as there may be paths where some cord is assigned an - // indirect copy of it's own value. As such a 'string of copies' would then - // remain sampled (`src.is_profiled`), then assigning such a cord back to - // 'itself' creates a cycle where the cord will converge to 'always sampled`. - // - // For example: - // - // Cord x; - // for (...) { - // // Copy ctor --> y.is_profiled := x.is_profiled | random(...) - // Cord y = x; - // ... - // // Assign x = y --> x.is_profiled = y.is_profiled | random(...) - // // ==> x.is_profiled |= random(...) - // // ==> x converges to 'always profiled' - // x = y; - // } - static void MaybeTrackCord(InlineData& cord, const InlineData& src, - MethodIdentifier method); - - // Stops tracking changes for a sampled cord, and deletes the provided info. - // This function must be called before the sampled cord instance is deleted, - // and before the root cordrep of the sampled cord is unreffed. - // This function may extend the lifetime of the cordrep in cases where the - // CordInfo instance is being held by a concurrent collection thread. - void Untrack(); - - // Invokes UntrackCord() on `info` if `info` is not null. - static void MaybeUntrackCord(CordzInfo* info); - - CordzInfo() = delete; - CordzInfo(const CordzInfo&) = delete; - CordzInfo& operator=(const CordzInfo&) = delete; - - // Retrieves the oldest existing CordzInfo. - static CordzInfo* Head(const CordzSnapshot& snapshot) - ABSL_NO_THREAD_SAFETY_ANALYSIS; - - // Retrieves the next oldest existing CordzInfo older than 'this' instance. - CordzInfo* Next(const CordzSnapshot& snapshot) const - ABSL_NO_THREAD_SAFETY_ANALYSIS; - - // Locks this instance for the update identified by `method`. - // Increases the count for `method` in `update_tracker`. - void Lock(MethodIdentifier method) ABSL_EXCLUSIVE_LOCK_FUNCTION(mutex_); - - // Unlocks this instance. If the contained `rep` has been set to null - // indicating the Cord has been cleared or is otherwise no longer sampled, - // then this method will delete this CordzInfo instance. - void Unlock() ABSL_UNLOCK_FUNCTION(mutex_); - - // Asserts that this CordzInfo instance is locked. - void AssertHeld() ABSL_ASSERT_EXCLUSIVE_LOCK(mutex_); - - // Updates the `rep` property of this instance. This methods is invoked by - // Cord logic each time the root node of a sampled Cord changes, and before - // the old root reference count is deleted. This guarantees that collection - // code can always safely take a reference on the tracked cord. - // Requires a lock to be held through the `Lock()` method. - // TODO(b/117940323): annotate with ABSL_EXCLUSIVE_LOCKS_REQUIRED once all - // Cord code is in a state where this can be proven true by the compiler. - void SetCordRep(CordRep* rep); - - // Returns the current `rep` property of this instance with a reference - // added, or null if this instance represents a cord that has since been - // deleted or untracked. - CordRep* RefCordRep() const ABSL_LOCKS_EXCLUDED(mutex_); - - // Returns the current value of `rep_` for testing purposes only. - CordRep* GetCordRepForTesting() const ABSL_NO_THREAD_SAFETY_ANALYSIS { - return rep_; - } - - // Sets the current value of `rep_` for testing purposes only. - void SetCordRepForTesting(CordRep* rep) ABSL_NO_THREAD_SAFETY_ANALYSIS { - rep_ = rep; - } - - // Returns the stack trace for where the cord was first sampled. Cords are - // potentially sampled when they promote from an inlined cord to a tree or - // ring representation, which is not necessarily the location where the cord - // was first created. Some cords are created as inlined cords, and only as - // data is added do they become a non-inlined cord. However, typically the - // location represents reasonably well where the cord is 'created'. - absl::Span<void* const> GetStack() const; - - // Returns the stack trace for a sampled cord's 'parent stack trace'. This - // value may be set if the cord is sampled (promoted) after being created - // from, or being assigned the value of an existing (sampled) cord. - absl::Span<void* const> GetParentStack() const; - - // Retrieves the CordzStatistics associated with this Cord. The statistics - // are only updated when a Cord goes through a mutation, such as an Append - // or RemovePrefix. - CordzStatistics GetCordzStatistics() const; - - private: - using SpinLock = absl::base_internal::SpinLock; - using SpinLockHolder = ::absl::base_internal::SpinLockHolder; - - // Global cordz info list. CordzInfo stores a pointer to the global list - // instance to harden against ODR violations. - struct List { - constexpr explicit List(absl::ConstInitType) - : mutex(absl::kConstInit, - absl::base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL) {} - - SpinLock mutex; - std::atomic<CordzInfo*> head ABSL_GUARDED_BY(mutex){nullptr}; - }; - - static constexpr int kMaxStackDepth = 64; - - explicit CordzInfo(CordRep* rep, const CordzInfo* src, - MethodIdentifier method); - ~CordzInfo() override; - - // Sets `rep_` without holding a lock. - void UnsafeSetCordRep(CordRep* rep) ABSL_NO_THREAD_SAFETY_ANALYSIS; - - void Track(); - - // Returns the parent method from `src`, which is either `parent_method_` or - // `method_` depending on `parent_method_` being kUnknown. - // Returns kUnknown if `src` is null. - static MethodIdentifier GetParentMethod(const CordzInfo* src); - - // Fills the provided stack from `src`, copying either `parent_stack_` or - // `stack_` depending on `parent_stack_` being empty, returning the size of - // the parent stack. - // Returns 0 if `src` is null. - static int FillParentStack(const CordzInfo* src, void** stack); - - void ODRCheck() const { -#ifndef NDEBUG - ABSL_RAW_CHECK(list_ == &global_list_, "ODR violation in Cord"); -#endif - } - - // Non-inlined implementation of `MaybeTrackCord`, which is executed if - // either `src` is sampled or `cord` is sampled, and either untracks or - // tracks `cord` as documented per `MaybeTrackCord`. - static void MaybeTrackCordImpl(InlineData& cord, const InlineData& src, - MethodIdentifier method); - - ABSL_CONST_INIT static List global_list_; - List* const list_ = &global_list_; - - // ci_prev_ and ci_next_ require the global list mutex to be held. - // Unfortunately we can't use thread annotations such that the thread safety - // analysis understands that list_ and global_list_ are one and the same. - std::atomic<CordzInfo*> ci_prev_{nullptr}; - std::atomic<CordzInfo*> ci_next_{nullptr}; - - mutable absl::Mutex mutex_; - CordRep* rep_ ABSL_GUARDED_BY(mutex_); - - void* stack_[kMaxStackDepth]; - void* parent_stack_[kMaxStackDepth]; - const int stack_depth_; - const int parent_stack_depth_; - const MethodIdentifier method_; - const MethodIdentifier parent_method_; - CordzUpdateTracker update_tracker_; - const absl::Time create_time_; -}; - -inline ABSL_ATTRIBUTE_ALWAYS_INLINE void CordzInfo::MaybeTrackCord( - InlineData& cord, MethodIdentifier method) { - if (ABSL_PREDICT_FALSE(cordz_should_profile())) { - TrackCord(cord, method); - } -} - -inline ABSL_ATTRIBUTE_ALWAYS_INLINE void CordzInfo::MaybeTrackCord( - InlineData& cord, const InlineData& src, MethodIdentifier method) { - if (ABSL_PREDICT_FALSE(InlineData::is_either_profiled(cord, src))) { - MaybeTrackCordImpl(cord, src, method); - } -} - -inline ABSL_ATTRIBUTE_ALWAYS_INLINE void CordzInfo::MaybeUntrackCord( - CordzInfo* info) { - if (ABSL_PREDICT_FALSE(info)) { - info->Untrack(); - } -} - -inline void CordzInfo::AssertHeld() ABSL_ASSERT_EXCLUSIVE_LOCK(mutex_) { -#ifndef NDEBUG - mutex_.AssertHeld(); -#endif -} - -inline void CordzInfo::SetCordRep(CordRep* rep) { - AssertHeld(); - rep_ = rep; -} - -inline void CordzInfo::UnsafeSetCordRep(CordRep* rep) { rep_ = rep; } - -inline CordRep* CordzInfo::RefCordRep() const ABSL_LOCKS_EXCLUDED(mutex_) { - MutexLock lock(&mutex_); - return rep_ ? CordRep::Ref(rep_) : nullptr; -} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STRINGS_CORDZ_INFO_H_ +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_CORDZ_INFO_H_ +#define ABSL_STRINGS_CORDZ_INFO_H_ + +#include <atomic> +#include <cstdint> +#include <functional> + +#include "absl/base/config.h" +#include "absl/base/internal/raw_logging.h" +#include "absl/base/internal/spinlock.h" +#include "absl/base/thread_annotations.h" +#include "absl/strings/internal/cord_internal.h" +#include "absl/strings/internal/cordz_functions.h" +#include "absl/strings/internal/cordz_handle.h" +#include "absl/strings/internal/cordz_statistics.h" +#include "absl/strings/internal/cordz_update_tracker.h" +#include "absl/synchronization/mutex.h" +#include "absl/types/span.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +// CordzInfo tracks a profiled Cord. Each of these objects can be in two places. +// If a Cord is alive, the CordzInfo will be in the global_cordz_infos map, and +// can also be retrieved via the linked list starting with +// global_cordz_infos_head and continued via the cordz_info_next() method. When +// a Cord has reached the end of its lifespan, the CordzInfo object will be +// migrated out of the global_cordz_infos list and the global_cordz_infos_map, +// and will either be deleted or appended to the global_delete_queue. If it is +// placed on the global_delete_queue, the CordzInfo object will be cleaned in +// the destructor of a CordzSampleToken object. +class ABSL_LOCKABLE CordzInfo : public CordzHandle { + public: + using MethodIdentifier = CordzUpdateTracker::MethodIdentifier; + + // TrackCord creates a CordzInfo instance which tracks important metrics of + // a sampled cord, and stores the created CordzInfo instance into `cord'. All + // CordzInfo instances are placed in a global list which is used to discover + // and snapshot all actively tracked cords. Callers are responsible for + // calling UntrackCord() before the tracked Cord instance is deleted, or to + // stop tracking the sampled Cord. Callers are also responsible for guarding + // changes to the 'tree' value of a Cord (InlineData.tree) through the Lock() + // and Unlock() calls. Any change resulting in a new tree value for the cord + // requires a call to SetCordRep() before the old tree has been unreffed + // and/or deleted. `method` identifies the Cord public API method initiating + // the cord to be sampled. + // Requires `cord` to hold a tree, and `cord.cordz_info()` to be null. + static void TrackCord(InlineData& cord, MethodIdentifier method); + + // Identical to TrackCord(), except that this function fills the + // `parent_stack` and `parent_method` properties of the returned CordzInfo + // instance from the provided `src` instance if `src` is sampled. + // This function should be used for sampling 'copy constructed' and 'copy + // assigned' cords. This function allows 'cord` to be already sampled, in + // which case the CordzInfo will be newly created from `src`. + static void TrackCord(InlineData& cord, const InlineData& src, + MethodIdentifier method); + + // Maybe sample the cord identified by 'cord' for method 'method'. + // Uses `cordz_should_profile` to randomly pick cords to be sampled, and if + // so, invokes `TrackCord` to start sampling `cord`. + static void MaybeTrackCord(InlineData& cord, MethodIdentifier method); + + // Maybe sample the cord identified by 'cord' for method 'method'. + // `src` identifies a 'parent' cord which is assigned to `cord`, typically the + // input cord for a copy constructor, or an assign method such as `operator=` + // `cord` will be sampled if (and only if) `src` is sampled. + // If `cord` is currently being sampled and `src` is not being sampled, then + // this function will stop sampling the cord and reset the cord's cordz_info. + // + // Previously this function defined that `cord` will be sampled if either + // `src` is sampled, or if `cord` is randomly picked for sampling. However, + // this can cause issues, as there may be paths where some cord is assigned an + // indirect copy of it's own value. As such a 'string of copies' would then + // remain sampled (`src.is_profiled`), then assigning such a cord back to + // 'itself' creates a cycle where the cord will converge to 'always sampled`. + // + // For example: + // + // Cord x; + // for (...) { + // // Copy ctor --> y.is_profiled := x.is_profiled | random(...) + // Cord y = x; + // ... + // // Assign x = y --> x.is_profiled = y.is_profiled | random(...) + // // ==> x.is_profiled |= random(...) + // // ==> x converges to 'always profiled' + // x = y; + // } + static void MaybeTrackCord(InlineData& cord, const InlineData& src, + MethodIdentifier method); + + // Stops tracking changes for a sampled cord, and deletes the provided info. + // This function must be called before the sampled cord instance is deleted, + // and before the root cordrep of the sampled cord is unreffed. + // This function may extend the lifetime of the cordrep in cases where the + // CordInfo instance is being held by a concurrent collection thread. + void Untrack(); + + // Invokes UntrackCord() on `info` if `info` is not null. + static void MaybeUntrackCord(CordzInfo* info); + + CordzInfo() = delete; + CordzInfo(const CordzInfo&) = delete; + CordzInfo& operator=(const CordzInfo&) = delete; + + // Retrieves the oldest existing CordzInfo. + static CordzInfo* Head(const CordzSnapshot& snapshot) + ABSL_NO_THREAD_SAFETY_ANALYSIS; + + // Retrieves the next oldest existing CordzInfo older than 'this' instance. + CordzInfo* Next(const CordzSnapshot& snapshot) const + ABSL_NO_THREAD_SAFETY_ANALYSIS; + + // Locks this instance for the update identified by `method`. + // Increases the count for `method` in `update_tracker`. + void Lock(MethodIdentifier method) ABSL_EXCLUSIVE_LOCK_FUNCTION(mutex_); + + // Unlocks this instance. If the contained `rep` has been set to null + // indicating the Cord has been cleared or is otherwise no longer sampled, + // then this method will delete this CordzInfo instance. + void Unlock() ABSL_UNLOCK_FUNCTION(mutex_); + + // Asserts that this CordzInfo instance is locked. + void AssertHeld() ABSL_ASSERT_EXCLUSIVE_LOCK(mutex_); + + // Updates the `rep` property of this instance. This methods is invoked by + // Cord logic each time the root node of a sampled Cord changes, and before + // the old root reference count is deleted. This guarantees that collection + // code can always safely take a reference on the tracked cord. + // Requires a lock to be held through the `Lock()` method. + // TODO(b/117940323): annotate with ABSL_EXCLUSIVE_LOCKS_REQUIRED once all + // Cord code is in a state where this can be proven true by the compiler. + void SetCordRep(CordRep* rep); + + // Returns the current `rep` property of this instance with a reference + // added, or null if this instance represents a cord that has since been + // deleted or untracked. + CordRep* RefCordRep() const ABSL_LOCKS_EXCLUDED(mutex_); + + // Returns the current value of `rep_` for testing purposes only. + CordRep* GetCordRepForTesting() const ABSL_NO_THREAD_SAFETY_ANALYSIS { + return rep_; + } + + // Sets the current value of `rep_` for testing purposes only. + void SetCordRepForTesting(CordRep* rep) ABSL_NO_THREAD_SAFETY_ANALYSIS { + rep_ = rep; + } + + // Returns the stack trace for where the cord was first sampled. Cords are + // potentially sampled when they promote from an inlined cord to a tree or + // ring representation, which is not necessarily the location where the cord + // was first created. Some cords are created as inlined cords, and only as + // data is added do they become a non-inlined cord. However, typically the + // location represents reasonably well where the cord is 'created'. + absl::Span<void* const> GetStack() const; + + // Returns the stack trace for a sampled cord's 'parent stack trace'. This + // value may be set if the cord is sampled (promoted) after being created + // from, or being assigned the value of an existing (sampled) cord. + absl::Span<void* const> GetParentStack() const; + + // Retrieves the CordzStatistics associated with this Cord. The statistics + // are only updated when a Cord goes through a mutation, such as an Append + // or RemovePrefix. + CordzStatistics GetCordzStatistics() const; + + private: + using SpinLock = absl::base_internal::SpinLock; + using SpinLockHolder = ::absl::base_internal::SpinLockHolder; + + // Global cordz info list. CordzInfo stores a pointer to the global list + // instance to harden against ODR violations. + struct List { + constexpr explicit List(absl::ConstInitType) + : mutex(absl::kConstInit, + absl::base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL) {} + + SpinLock mutex; + std::atomic<CordzInfo*> head ABSL_GUARDED_BY(mutex){nullptr}; + }; + + static constexpr int kMaxStackDepth = 64; + + explicit CordzInfo(CordRep* rep, const CordzInfo* src, + MethodIdentifier method); + ~CordzInfo() override; + + // Sets `rep_` without holding a lock. + void UnsafeSetCordRep(CordRep* rep) ABSL_NO_THREAD_SAFETY_ANALYSIS; + + void Track(); + + // Returns the parent method from `src`, which is either `parent_method_` or + // `method_` depending on `parent_method_` being kUnknown. + // Returns kUnknown if `src` is null. + static MethodIdentifier GetParentMethod(const CordzInfo* src); + + // Fills the provided stack from `src`, copying either `parent_stack_` or + // `stack_` depending on `parent_stack_` being empty, returning the size of + // the parent stack. + // Returns 0 if `src` is null. + static int FillParentStack(const CordzInfo* src, void** stack); + + void ODRCheck() const { +#ifndef NDEBUG + ABSL_RAW_CHECK(list_ == &global_list_, "ODR violation in Cord"); +#endif + } + + // Non-inlined implementation of `MaybeTrackCord`, which is executed if + // either `src` is sampled or `cord` is sampled, and either untracks or + // tracks `cord` as documented per `MaybeTrackCord`. + static void MaybeTrackCordImpl(InlineData& cord, const InlineData& src, + MethodIdentifier method); + + ABSL_CONST_INIT static List global_list_; + List* const list_ = &global_list_; + + // ci_prev_ and ci_next_ require the global list mutex to be held. + // Unfortunately we can't use thread annotations such that the thread safety + // analysis understands that list_ and global_list_ are one and the same. + std::atomic<CordzInfo*> ci_prev_{nullptr}; + std::atomic<CordzInfo*> ci_next_{nullptr}; + + mutable absl::Mutex mutex_; + CordRep* rep_ ABSL_GUARDED_BY(mutex_); + + void* stack_[kMaxStackDepth]; + void* parent_stack_[kMaxStackDepth]; + const int stack_depth_; + const int parent_stack_depth_; + const MethodIdentifier method_; + const MethodIdentifier parent_method_; + CordzUpdateTracker update_tracker_; + const absl::Time create_time_; +}; + +inline ABSL_ATTRIBUTE_ALWAYS_INLINE void CordzInfo::MaybeTrackCord( + InlineData& cord, MethodIdentifier method) { + if (ABSL_PREDICT_FALSE(cordz_should_profile())) { + TrackCord(cord, method); + } +} + +inline ABSL_ATTRIBUTE_ALWAYS_INLINE void CordzInfo::MaybeTrackCord( + InlineData& cord, const InlineData& src, MethodIdentifier method) { + if (ABSL_PREDICT_FALSE(InlineData::is_either_profiled(cord, src))) { + MaybeTrackCordImpl(cord, src, method); + } +} + +inline ABSL_ATTRIBUTE_ALWAYS_INLINE void CordzInfo::MaybeUntrackCord( + CordzInfo* info) { + if (ABSL_PREDICT_FALSE(info)) { + info->Untrack(); + } +} + +inline void CordzInfo::AssertHeld() ABSL_ASSERT_EXCLUSIVE_LOCK(mutex_) { +#ifndef NDEBUG + mutex_.AssertHeld(); +#endif +} + +inline void CordzInfo::SetCordRep(CordRep* rep) { + AssertHeld(); + rep_ = rep; +} + +inline void CordzInfo::UnsafeSetCordRep(CordRep* rep) { rep_ = rep; } + +inline CordRep* CordzInfo::RefCordRep() const ABSL_LOCKS_EXCLUDED(mutex_) { + MutexLock lock(&mutex_); + return rep_ ? CordRep::Ref(rep_) : nullptr; +} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STRINGS_CORDZ_INFO_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info/ya.make b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info/ya.make index 56243dd401..aece416d5c 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info/ya.make +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info/ya.make @@ -10,27 +10,27 @@ LICENSE(Apache-2.0) PEERDIR( contrib/restricted/abseil-cpp/absl/base - contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc contrib/restricted/abseil-cpp/absl/base/internal/raw_logging contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/debugging - contrib/restricted/abseil-cpp/absl/debugging/stacktrace - contrib/restricted/abseil-cpp/absl/debugging/symbolize - contrib/restricted/abseil-cpp/absl/demangle + contrib/restricted/abseil-cpp/absl/debugging + contrib/restricted/abseil-cpp/absl/debugging/stacktrace + contrib/restricted/abseil-cpp/absl/debugging/symbolize + contrib/restricted/abseil-cpp/absl/demangle contrib/restricted/abseil-cpp/absl/numeric - contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle - contrib/restricted/abseil-cpp/absl/synchronization - contrib/restricted/abseil-cpp/absl/synchronization/internal - contrib/restricted/abseil-cpp/absl/time - contrib/restricted/abseil-cpp/absl/time/civil_time - contrib/restricted/abseil-cpp/absl/time/time_zone + contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle + contrib/restricted/abseil-cpp/absl/synchronization + contrib/restricted/abseil-cpp/absl/synchronization/internal + contrib/restricted/abseil-cpp/absl/time + contrib/restricted/abseil-cpp/absl/time/civil_time + contrib/restricted/abseil-cpp/absl/time/time_zone ) ADDINCL( @@ -45,10 +45,10 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/strings/internal) +SRCDIR(contrib/restricted/abseil-cpp/absl/strings/internal) SRCS( - cordz_info.cc + cordz_info.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_sample_token.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_sample_token.cc index ba1270d8f0..6485bbc406 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_sample_token.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_sample_token.cc @@ -1,64 +1,64 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/strings/internal/cordz_sample_token.h" - -#include "absl/base/config.h" -#include "absl/strings/internal/cordz_handle.h" -#include "absl/strings/internal/cordz_info.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -CordzSampleToken::Iterator& CordzSampleToken::Iterator::operator++() { - if (current_) { - current_ = current_->Next(*token_); - } - return *this; -} - -CordzSampleToken::Iterator CordzSampleToken::Iterator::operator++(int) { - Iterator it(*this); - operator++(); - return it; -} - -bool operator==(const CordzSampleToken::Iterator& lhs, - const CordzSampleToken::Iterator& rhs) { - return lhs.current_ == rhs.current_ && - (lhs.current_ == nullptr || lhs.token_ == rhs.token_); -} - -bool operator!=(const CordzSampleToken::Iterator& lhs, - const CordzSampleToken::Iterator& rhs) { - return !(lhs == rhs); -} - -CordzSampleToken::Iterator::reference CordzSampleToken::Iterator::operator*() - const { - return *current_; -} - -CordzSampleToken::Iterator::pointer CordzSampleToken::Iterator::operator->() - const { - return current_; -} - -CordzSampleToken::Iterator::Iterator(const CordzSampleToken* token) - : token_(token), current_(CordzInfo::Head(*token)) {} - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace absl +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/strings/internal/cordz_sample_token.h" + +#include "absl/base/config.h" +#include "absl/strings/internal/cordz_handle.h" +#include "absl/strings/internal/cordz_info.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +CordzSampleToken::Iterator& CordzSampleToken::Iterator::operator++() { + if (current_) { + current_ = current_->Next(*token_); + } + return *this; +} + +CordzSampleToken::Iterator CordzSampleToken::Iterator::operator++(int) { + Iterator it(*this); + operator++(); + return it; +} + +bool operator==(const CordzSampleToken::Iterator& lhs, + const CordzSampleToken::Iterator& rhs) { + return lhs.current_ == rhs.current_ && + (lhs.current_ == nullptr || lhs.token_ == rhs.token_); +} + +bool operator!=(const CordzSampleToken::Iterator& lhs, + const CordzSampleToken::Iterator& rhs) { + return !(lhs == rhs); +} + +CordzSampleToken::Iterator::reference CordzSampleToken::Iterator::operator*() + const { + return *current_; +} + +CordzSampleToken::Iterator::pointer CordzSampleToken::Iterator::operator->() + const { + return current_; +} + +CordzSampleToken::Iterator::Iterator(const CordzSampleToken* token) + : token_(token), current_(CordzInfo::Head(*token)) {} + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_sample_token.h b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_sample_token.h index 28a1d70ccc..55d179975e 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_sample_token.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_sample_token.h @@ -1,97 +1,97 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/base/config.h" -#include "absl/strings/internal/cordz_handle.h" -#include "absl/strings/internal/cordz_info.h" - -#ifndef ABSL_STRINGS_CORDZ_SAMPLE_TOKEN_H_ -#define ABSL_STRINGS_CORDZ_SAMPLE_TOKEN_H_ - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -// The existence of a CordzSampleToken guarantees that a reader can traverse the -// global_cordz_infos_head linked-list without needing to hold a mutex. When a -// CordzSampleToken exists, all CordzInfo objects that would be destroyed are -// instead appended to a deletion queue. When the CordzSampleToken is destroyed, -// it will also clean up any of these CordzInfo objects. -// -// E.g., ST are CordzSampleToken objects and CH are CordzHandle objects. -// ST1 <- CH1 <- CH2 <- ST2 <- CH3 <- global_delete_queue_tail -// -// This list tracks that CH1 and CH2 were created after ST1, so the thread -// holding ST1 might have a referece to CH1, CH2, ST2, and CH3. However, ST2 was -// created later, so the thread holding the ST2 token cannot have a reference to -// ST1, CH1, or CH2. If ST1 is cleaned up first, that thread will delete ST1, -// CH1, and CH2. If instead ST2 is cleaned up first, that thread will only -// delete ST2. -// -// If ST1 is cleaned up first, the new list will be: -// ST2 <- CH3 <- global_delete_queue_tail -// -// If ST2 is cleaned up first, the new list will be: -// ST1 <- CH1 <- CH2 <- CH3 <- global_delete_queue_tail -// -// All new CordzHandle objects are appended to the list, so if a new thread -// comes along before either ST1 or ST2 are cleaned up, the new list will be: -// ST1 <- CH1 <- CH2 <- ST2 <- CH3 <- ST3 <- global_delete_queue_tail -// -// A thread must hold the global_delete_queue_mu mutex whenever it's altering -// this list. -// -// It is safe for thread that holds a CordzSampleToken to read -// global_cordz_infos at any time since the objects it is able to retrieve will -// not be deleted while the CordzSampleToken exists. -class CordzSampleToken : public CordzSnapshot { - public: - class Iterator { - public: - using iterator_category = std::input_iterator_tag; - using value_type = const CordzInfo&; - using difference_type = ptrdiff_t; - using pointer = const CordzInfo*; - using reference = value_type; - - Iterator() = default; - - Iterator& operator++(); - Iterator operator++(int); - friend bool operator==(const Iterator& lhs, const Iterator& rhs); - friend bool operator!=(const Iterator& lhs, const Iterator& rhs); - reference operator*() const; - pointer operator->() const; - - private: - friend class CordzSampleToken; - explicit Iterator(const CordzSampleToken* token); - - const CordzSampleToken* token_ = nullptr; - pointer current_ = nullptr; - }; - - CordzSampleToken() = default; - CordzSampleToken(const CordzSampleToken&) = delete; - CordzSampleToken& operator=(const CordzSampleToken&) = delete; - - Iterator begin() { return Iterator(this); } - Iterator end() { return Iterator(); } -}; - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STRINGS_CORDZ_SAMPLE_TOKEN_H_ +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/base/config.h" +#include "absl/strings/internal/cordz_handle.h" +#include "absl/strings/internal/cordz_info.h" + +#ifndef ABSL_STRINGS_CORDZ_SAMPLE_TOKEN_H_ +#define ABSL_STRINGS_CORDZ_SAMPLE_TOKEN_H_ + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +// The existence of a CordzSampleToken guarantees that a reader can traverse the +// global_cordz_infos_head linked-list without needing to hold a mutex. When a +// CordzSampleToken exists, all CordzInfo objects that would be destroyed are +// instead appended to a deletion queue. When the CordzSampleToken is destroyed, +// it will also clean up any of these CordzInfo objects. +// +// E.g., ST are CordzSampleToken objects and CH are CordzHandle objects. +// ST1 <- CH1 <- CH2 <- ST2 <- CH3 <- global_delete_queue_tail +// +// This list tracks that CH1 and CH2 were created after ST1, so the thread +// holding ST1 might have a referece to CH1, CH2, ST2, and CH3. However, ST2 was +// created later, so the thread holding the ST2 token cannot have a reference to +// ST1, CH1, or CH2. If ST1 is cleaned up first, that thread will delete ST1, +// CH1, and CH2. If instead ST2 is cleaned up first, that thread will only +// delete ST2. +// +// If ST1 is cleaned up first, the new list will be: +// ST2 <- CH3 <- global_delete_queue_tail +// +// If ST2 is cleaned up first, the new list will be: +// ST1 <- CH1 <- CH2 <- CH3 <- global_delete_queue_tail +// +// All new CordzHandle objects are appended to the list, so if a new thread +// comes along before either ST1 or ST2 are cleaned up, the new list will be: +// ST1 <- CH1 <- CH2 <- ST2 <- CH3 <- ST3 <- global_delete_queue_tail +// +// A thread must hold the global_delete_queue_mu mutex whenever it's altering +// this list. +// +// It is safe for thread that holds a CordzSampleToken to read +// global_cordz_infos at any time since the objects it is able to retrieve will +// not be deleted while the CordzSampleToken exists. +class CordzSampleToken : public CordzSnapshot { + public: + class Iterator { + public: + using iterator_category = std::input_iterator_tag; + using value_type = const CordzInfo&; + using difference_type = ptrdiff_t; + using pointer = const CordzInfo*; + using reference = value_type; + + Iterator() = default; + + Iterator& operator++(); + Iterator operator++(int); + friend bool operator==(const Iterator& lhs, const Iterator& rhs); + friend bool operator!=(const Iterator& lhs, const Iterator& rhs); + reference operator*() const; + pointer operator->() const; + + private: + friend class CordzSampleToken; + explicit Iterator(const CordzSampleToken* token); + + const CordzSampleToken* token_ = nullptr; + pointer current_ = nullptr; + }; + + CordzSampleToken() = default; + CordzSampleToken(const CordzSampleToken&) = delete; + CordzSampleToken& operator=(const CordzSampleToken&) = delete; + + Iterator begin() { return Iterator(this); } + Iterator end() { return Iterator(); } +}; + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STRINGS_CORDZ_SAMPLE_TOKEN_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_sample_token/ya.make b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_sample_token/ya.make index 1ad95a8a05..166d65619e 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_sample_token/ya.make +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_sample_token/ya.make @@ -10,28 +10,28 @@ LICENSE(Apache-2.0) PEERDIR( contrib/restricted/abseil-cpp/absl/base - contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc contrib/restricted/abseil-cpp/absl/base/internal/raw_logging contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/debugging - contrib/restricted/abseil-cpp/absl/debugging/stacktrace - contrib/restricted/abseil-cpp/absl/debugging/symbolize - contrib/restricted/abseil-cpp/absl/demangle + contrib/restricted/abseil-cpp/absl/debugging + contrib/restricted/abseil-cpp/absl/debugging/stacktrace + contrib/restricted/abseil-cpp/absl/debugging/symbolize + contrib/restricted/abseil-cpp/absl/demangle contrib/restricted/abseil-cpp/absl/numeric - contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info - contrib/restricted/abseil-cpp/absl/synchronization - contrib/restricted/abseil-cpp/absl/synchronization/internal - contrib/restricted/abseil-cpp/absl/time - contrib/restricted/abseil-cpp/absl/time/civil_time - contrib/restricted/abseil-cpp/absl/time/time_zone + contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info + contrib/restricted/abseil-cpp/absl/synchronization + contrib/restricted/abseil-cpp/absl/synchronization/internal + contrib/restricted/abseil-cpp/absl/time + contrib/restricted/abseil-cpp/absl/time/civil_time + contrib/restricted/abseil-cpp/absl/time/time_zone ) ADDINCL( @@ -46,10 +46,10 @@ CFLAGS( -DNOMINMAX ) -SRCDIR(contrib/restricted/abseil-cpp/absl/strings/internal) +SRCDIR(contrib/restricted/abseil-cpp/absl/strings/internal) SRCS( - cordz_sample_token.cc + cordz_sample_token.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_statistics.h b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_statistics.h index da4c7dbb8c..5ab690b086 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_statistics.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_statistics.h @@ -1,87 +1,87 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_INTERNAL_CORDZ_STATISTICS_H_ -#define ABSL_STRINGS_INTERNAL_CORDZ_STATISTICS_H_ - -#include <cstdint> - -#include "absl/base/config.h" -#include "absl/strings/internal/cordz_update_tracker.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -// CordzStatistics captures some meta information about a Cord's shape. -struct CordzStatistics { - using MethodIdentifier = CordzUpdateTracker::MethodIdentifier; - - // Node counts information - struct NodeCounts { - size_t flat = 0; // #flats - size_t flat_64 = 0; // #flats up to 64 bytes - size_t flat_128 = 0; // #flats up to 128 bytes - size_t flat_256 = 0; // #flats up to 256 bytes - size_t flat_512 = 0; // #flats up to 512 bytes - size_t flat_1k = 0; // #flats up to 1K bytes - size_t external = 0; // #external reps - size_t substring = 0; // #substring reps - size_t concat = 0; // #concat reps - size_t ring = 0; // #ring buffer reps - size_t btree = 0; // #btree reps - }; - - // The size of the cord in bytes. This matches the result of Cord::size(). - int64_t size = 0; - - // The estimated memory used by the sampled cord. This value matches the - // value as reported by Cord::EstimatedMemoryUsage(). - // A value of 0 implies the property has not been recorded. - int64_t estimated_memory_usage = 0; - - // The effective memory used by the sampled cord, inversely weighted by the - // effective indegree of each allocated node. This is a representation of the - // fair share of memory usage that should be attributed to the sampled cord. - // This value is more useful for cases where one or more nodes are referenced - // by multiple Cord instances, and for cases where a Cord includes the same - // node multiple times (either directly or indirectly). - // A value of 0 implies the property has not been recorded. - int64_t estimated_fair_share_memory_usage = 0; - - // The total number of nodes referenced by this cord. - // For ring buffer Cords, this includes the 'ring buffer' node. - // For btree Cords, this includes all 'CordRepBtree' tree nodes as well as all - // the substring, flat and external nodes referenced by the tree. - // A value of 0 implies the property has not been recorded. - int64_t node_count = 0; - - // Detailed node counts per type - NodeCounts node_counts; - - // The cord method responsible for sampling the cord. - MethodIdentifier method = MethodIdentifier::kUnknown; - - // The cord method responsible for sampling the parent cord if applicable. - MethodIdentifier parent_method = MethodIdentifier::kUnknown; - - // Update tracker tracking invocation count per cord method. - CordzUpdateTracker update_tracker; -}; - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STRINGS_INTERNAL_CORDZ_STATISTICS_H_ +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_INTERNAL_CORDZ_STATISTICS_H_ +#define ABSL_STRINGS_INTERNAL_CORDZ_STATISTICS_H_ + +#include <cstdint> + +#include "absl/base/config.h" +#include "absl/strings/internal/cordz_update_tracker.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +// CordzStatistics captures some meta information about a Cord's shape. +struct CordzStatistics { + using MethodIdentifier = CordzUpdateTracker::MethodIdentifier; + + // Node counts information + struct NodeCounts { + size_t flat = 0; // #flats + size_t flat_64 = 0; // #flats up to 64 bytes + size_t flat_128 = 0; // #flats up to 128 bytes + size_t flat_256 = 0; // #flats up to 256 bytes + size_t flat_512 = 0; // #flats up to 512 bytes + size_t flat_1k = 0; // #flats up to 1K bytes + size_t external = 0; // #external reps + size_t substring = 0; // #substring reps + size_t concat = 0; // #concat reps + size_t ring = 0; // #ring buffer reps + size_t btree = 0; // #btree reps + }; + + // The size of the cord in bytes. This matches the result of Cord::size(). + int64_t size = 0; + + // The estimated memory used by the sampled cord. This value matches the + // value as reported by Cord::EstimatedMemoryUsage(). + // A value of 0 implies the property has not been recorded. + int64_t estimated_memory_usage = 0; + + // The effective memory used by the sampled cord, inversely weighted by the + // effective indegree of each allocated node. This is a representation of the + // fair share of memory usage that should be attributed to the sampled cord. + // This value is more useful for cases where one or more nodes are referenced + // by multiple Cord instances, and for cases where a Cord includes the same + // node multiple times (either directly or indirectly). + // A value of 0 implies the property has not been recorded. + int64_t estimated_fair_share_memory_usage = 0; + + // The total number of nodes referenced by this cord. + // For ring buffer Cords, this includes the 'ring buffer' node. + // For btree Cords, this includes all 'CordRepBtree' tree nodes as well as all + // the substring, flat and external nodes referenced by the tree. + // A value of 0 implies the property has not been recorded. + int64_t node_count = 0; + + // Detailed node counts per type + NodeCounts node_counts; + + // The cord method responsible for sampling the cord. + MethodIdentifier method = MethodIdentifier::kUnknown; + + // The cord method responsible for sampling the parent cord if applicable. + MethodIdentifier parent_method = MethodIdentifier::kUnknown; + + // Update tracker tracking invocation count per cord method. + CordzUpdateTracker update_tracker; +}; + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STRINGS_INTERNAL_CORDZ_STATISTICS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_update_scope.h b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_update_scope.h index 57ba75de93..d5ce5a2a0b 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_update_scope.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_update_scope.h @@ -1,71 +1,71 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_SCOPE_H_ -#define ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_SCOPE_H_ - -#include "absl/base/config.h" -#include "absl/base/optimization.h" -#include "absl/base/thread_annotations.h" -#include "absl/strings/internal/cord_internal.h" -#include "absl/strings/internal/cordz_info.h" -#include "absl/strings/internal/cordz_update_tracker.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -// CordzUpdateScope scopes an update to the provided CordzInfo. -// The class invokes `info->Lock(method)` and `info->Unlock()` to guard -// cordrep updates. This class does nothing if `info` is null. -// See also the 'Lock`, `Unlock` and `SetCordRep` methods in `CordzInfo`. -class ABSL_SCOPED_LOCKABLE CordzUpdateScope { - public: - CordzUpdateScope(CordzInfo* info, CordzUpdateTracker::MethodIdentifier method) - ABSL_EXCLUSIVE_LOCK_FUNCTION(info) - : info_(info) { - if (ABSL_PREDICT_FALSE(info_)) { - info->Lock(method); - } - } - - // CordzUpdateScope can not be copied or assigned to. - CordzUpdateScope(CordzUpdateScope&& rhs) = delete; - CordzUpdateScope(const CordzUpdateScope&) = delete; - CordzUpdateScope& operator=(CordzUpdateScope&& rhs) = delete; - CordzUpdateScope& operator=(const CordzUpdateScope&) = delete; - - ~CordzUpdateScope() ABSL_UNLOCK_FUNCTION() { - if (ABSL_PREDICT_FALSE(info_)) { - info_->Unlock(); - } - } - - void SetCordRep(CordRep* rep) const { - if (ABSL_PREDICT_FALSE(info_)) { - info_->SetCordRep(rep); - } - } - - CordzInfo* info() const { return info_; } - - private: - CordzInfo* info_; -}; - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_SCOPE_H_ +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_SCOPE_H_ +#define ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_SCOPE_H_ + +#include "absl/base/config.h" +#include "absl/base/optimization.h" +#include "absl/base/thread_annotations.h" +#include "absl/strings/internal/cord_internal.h" +#include "absl/strings/internal/cordz_info.h" +#include "absl/strings/internal/cordz_update_tracker.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +// CordzUpdateScope scopes an update to the provided CordzInfo. +// The class invokes `info->Lock(method)` and `info->Unlock()` to guard +// cordrep updates. This class does nothing if `info` is null. +// See also the 'Lock`, `Unlock` and `SetCordRep` methods in `CordzInfo`. +class ABSL_SCOPED_LOCKABLE CordzUpdateScope { + public: + CordzUpdateScope(CordzInfo* info, CordzUpdateTracker::MethodIdentifier method) + ABSL_EXCLUSIVE_LOCK_FUNCTION(info) + : info_(info) { + if (ABSL_PREDICT_FALSE(info_)) { + info->Lock(method); + } + } + + // CordzUpdateScope can not be copied or assigned to. + CordzUpdateScope(CordzUpdateScope&& rhs) = delete; + CordzUpdateScope(const CordzUpdateScope&) = delete; + CordzUpdateScope& operator=(CordzUpdateScope&& rhs) = delete; + CordzUpdateScope& operator=(const CordzUpdateScope&) = delete; + + ~CordzUpdateScope() ABSL_UNLOCK_FUNCTION() { + if (ABSL_PREDICT_FALSE(info_)) { + info_->Unlock(); + } + } + + void SetCordRep(CordRep* rep) const { + if (ABSL_PREDICT_FALSE(info_)) { + info_->SetCordRep(rep); + } + } + + CordzInfo* info() const { return info_; } + + private: + CordzInfo* info_; +}; + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_SCOPE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_update_tracker.h b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_update_tracker.h index 1f764486eb..c374097c7f 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_update_tracker.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_update_tracker.h @@ -1,121 +1,121 @@ -// Copyright 2021 The Abseil Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_TRACKER_H_ -#define ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_TRACKER_H_ - -#include <atomic> -#include <cstdint> - -#include "absl/base/config.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - -// CordzUpdateTracker tracks counters for Cord update methods. -// -// The purpose of CordzUpdateTracker is to track the number of calls to methods -// updating Cord data for sampled cords. The class internally uses 'lossy' -// atomic operations: Cord is thread-compatible, so there is no need to -// synchronize updates. However, Cordz collection threads may call 'Value()' at -// any point, so the class needs to provide thread safe access. -// -// This class is thread-safe. But as per above comments, all non-const methods -// should be used single-threaded only: updates are thread-safe but lossy. -class CordzUpdateTracker { - public: - // Tracked update methods. - enum MethodIdentifier { - kUnknown, - kAppendBuffer, - kAppendCord, - kAppendExternalMemory, - kAppendString, - kAssignCord, - kAssignString, - kClear, - kConstructorCord, - kConstructorString, - kCordReader, - kFlatten, - kGetAppendRegion, - kMakeCordFromExternal, - kMoveAppendCord, - kMoveAssignCord, - kMovePrependCord, - kPrependBuffer, - kPrependCord, - kPrependString, - kRemovePrefix, - kRemoveSuffix, - kSubCord, - - // kNumMethods defines the number of entries: must be the last entry. - kNumMethods, - }; - - // Constructs a new instance. All counters are zero-initialized. - constexpr CordzUpdateTracker() noexcept : values_{} {} - - // Copy constructs a new instance. - CordzUpdateTracker(const CordzUpdateTracker& rhs) noexcept { *this = rhs; } - - // Assigns the provided value to this instance. - CordzUpdateTracker& operator=(const CordzUpdateTracker& rhs) noexcept { - for (int i = 0; i < kNumMethods; ++i) { - values_[i].store(rhs.values_[i].load(std::memory_order_relaxed), - std::memory_order_relaxed); - } - return *this; - } - - // Returns the value for the specified method. - int64_t Value(MethodIdentifier method) const { - return values_[method].load(std::memory_order_relaxed); - } - - // Increases the value for the specified method by `n` - void LossyAdd(MethodIdentifier method, int64_t n = 1) { - auto& value = values_[method]; - value.store(value.load(std::memory_order_relaxed) + n, - std::memory_order_relaxed); - } - - // Adds all the values from `src` to this instance - void LossyAdd(const CordzUpdateTracker& src) { - for (int i = 0; i < kNumMethods; ++i) { - MethodIdentifier method = static_cast<MethodIdentifier>(i); - if (int64_t value = src.Value(method)) { - LossyAdd(method, value); - } - } - } - - private: - // Until C++20 std::atomic is not constexpr default-constructible, so we need - // a wrapper for this class to be constexpr constructible. - class Counter : public std::atomic<int64_t> { - public: - constexpr Counter() noexcept : std::atomic<int64_t>(0) {} - }; - - Counter values_[kNumMethods]; -}; - -} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_TRACKER_H_ +// Copyright 2021 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_TRACKER_H_ +#define ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_TRACKER_H_ + +#include <atomic> +#include <cstdint> + +#include "absl/base/config.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + +// CordzUpdateTracker tracks counters for Cord update methods. +// +// The purpose of CordzUpdateTracker is to track the number of calls to methods +// updating Cord data for sampled cords. The class internally uses 'lossy' +// atomic operations: Cord is thread-compatible, so there is no need to +// synchronize updates. However, Cordz collection threads may call 'Value()' at +// any point, so the class needs to provide thread safe access. +// +// This class is thread-safe. But as per above comments, all non-const methods +// should be used single-threaded only: updates are thread-safe but lossy. +class CordzUpdateTracker { + public: + // Tracked update methods. + enum MethodIdentifier { + kUnknown, + kAppendBuffer, + kAppendCord, + kAppendExternalMemory, + kAppendString, + kAssignCord, + kAssignString, + kClear, + kConstructorCord, + kConstructorString, + kCordReader, + kFlatten, + kGetAppendRegion, + kMakeCordFromExternal, + kMoveAppendCord, + kMoveAssignCord, + kMovePrependCord, + kPrependBuffer, + kPrependCord, + kPrependString, + kRemovePrefix, + kRemoveSuffix, + kSubCord, + + // kNumMethods defines the number of entries: must be the last entry. + kNumMethods, + }; + + // Constructs a new instance. All counters are zero-initialized. + constexpr CordzUpdateTracker() noexcept : values_{} {} + + // Copy constructs a new instance. + CordzUpdateTracker(const CordzUpdateTracker& rhs) noexcept { *this = rhs; } + + // Assigns the provided value to this instance. + CordzUpdateTracker& operator=(const CordzUpdateTracker& rhs) noexcept { + for (int i = 0; i < kNumMethods; ++i) { + values_[i].store(rhs.values_[i].load(std::memory_order_relaxed), + std::memory_order_relaxed); + } + return *this; + } + + // Returns the value for the specified method. + int64_t Value(MethodIdentifier method) const { + return values_[method].load(std::memory_order_relaxed); + } + + // Increases the value for the specified method by `n` + void LossyAdd(MethodIdentifier method, int64_t n = 1) { + auto& value = values_[method]; + value.store(value.load(std::memory_order_relaxed) + n, + std::memory_order_relaxed); + } + + // Adds all the values from `src` to this instance + void LossyAdd(const CordzUpdateTracker& src) { + for (int i = 0; i < kNumMethods; ++i) { + MethodIdentifier method = static_cast<MethodIdentifier>(i); + if (int64_t value = src.Value(method)) { + LossyAdd(method, value); + } + } + } + + private: + // Until C++20 std::atomic is not constexpr default-constructible, so we need + // a wrapper for this class to be constexpr constructible. + class Counter : public std::atomic<int64_t> { + public: + constexpr Counter() noexcept : std::atomic<int64_t>(0) {} + }; + + Counter values_[kNumMethods]; +}; + +} // namespace cord_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_TRACKER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/resize_uninitialized.h b/contrib/restricted/abseil-cpp/absl/strings/internal/resize_uninitialized.h index 49859dcc7d..a1c40824ee 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/resize_uninitialized.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/resize_uninitialized.h @@ -17,7 +17,7 @@ #ifndef ABSL_STRINGS_INTERNAL_RESIZE_UNINITIALIZED_H_ #define ABSL_STRINGS_INTERNAL_RESIZE_UNINITIALIZED_H_ -#include <algorithm> +#include <algorithm> #include <string> #include <type_traits> #include <utility> @@ -29,9 +29,9 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace strings_internal { -// In this type trait, we look for a __resize_default_init member function, and -// we use it if available, otherwise, we use resize. We provide HasMember to -// indicate whether __resize_default_init is present. +// In this type trait, we look for a __resize_default_init member function, and +// we use it if available, otherwise, we use resize. We provide HasMember to +// indicate whether __resize_default_init is present. template <typename string_type, typename = void> struct ResizeUninitializedTraits { using HasMember = std::false_type; @@ -68,50 +68,50 @@ inline void STLStringResizeUninitialized(string_type* s, size_t new_size) { ResizeUninitializedTraits<string_type>::Resize(s, new_size); } -// Used to ensure exponential growth so that the amortized complexity of -// increasing the string size by a small amount is O(1), in contrast to -// O(str->size()) in the case of precise growth. -template <typename string_type> -void STLStringReserveAmortized(string_type* s, size_t new_size) { - const size_t cap = s->capacity(); - if (new_size > cap) { - // Make sure to always grow by at least a factor of 2x. - s->reserve((std::max)(new_size, 2 * cap)); - } -} - -// In this type trait, we look for an __append_default_init member function, and -// we use it if available, otherwise, we use append. -template <typename string_type, typename = void> -struct AppendUninitializedTraits { - static void Append(string_type* s, size_t n) { - s->append(n, typename string_type::value_type()); - } -}; - -template <typename string_type> -struct AppendUninitializedTraits< - string_type, absl::void_t<decltype(std::declval<string_type&>() - .__append_default_init(237))> > { - static void Append(string_type* s, size_t n) { - s->__append_default_init(n); - } -}; - -// Like STLStringResizeUninitialized(str, new_size), except guaranteed to use -// exponential growth so that the amortized complexity of increasing the string -// size by a small amount is O(1), in contrast to O(str->size()) in the case of -// precise growth. -template <typename string_type> -void STLStringResizeUninitializedAmortized(string_type* s, size_t new_size) { - const size_t size = s->size(); - if (new_size > size) { - AppendUninitializedTraits<string_type>::Append(s, new_size - size); - } else { - s->erase(new_size); - } -} - +// Used to ensure exponential growth so that the amortized complexity of +// increasing the string size by a small amount is O(1), in contrast to +// O(str->size()) in the case of precise growth. +template <typename string_type> +void STLStringReserveAmortized(string_type* s, size_t new_size) { + const size_t cap = s->capacity(); + if (new_size > cap) { + // Make sure to always grow by at least a factor of 2x. + s->reserve((std::max)(new_size, 2 * cap)); + } +} + +// In this type trait, we look for an __append_default_init member function, and +// we use it if available, otherwise, we use append. +template <typename string_type, typename = void> +struct AppendUninitializedTraits { + static void Append(string_type* s, size_t n) { + s->append(n, typename string_type::value_type()); + } +}; + +template <typename string_type> +struct AppendUninitializedTraits< + string_type, absl::void_t<decltype(std::declval<string_type&>() + .__append_default_init(237))> > { + static void Append(string_type* s, size_t n) { + s->__append_default_init(n); + } +}; + +// Like STLStringResizeUninitialized(str, new_size), except guaranteed to use +// exponential growth so that the amortized complexity of increasing the string +// size by a small amount is O(1), in contrast to O(str->size()) in the case of +// precise growth. +template <typename string_type> +void STLStringResizeUninitializedAmortized(string_type* s, size_t new_size) { + const size_t size = s->size(); + if (new_size > size) { + AppendUninitializedTraits<string_type>::Append(s, new_size - size); + } else { + s->erase(new_size); + } +} + } // namespace strings_internal ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.h b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.h index 3c91be701f..8d251c53ac 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.h @@ -122,14 +122,14 @@ StringConvertResult FormatConvertImpl(const std::string& v, StringConvertResult FormatConvertImpl(string_view v, FormatConversionSpecImpl conv, FormatSinkImpl* sink); -#if defined(ABSL_HAVE_STD_STRING_VIEW) && !defined(ABSL_USES_STD_STRING_VIEW) -inline StringConvertResult FormatConvertImpl(std::string_view v, - FormatConversionSpecImpl conv, - FormatSinkImpl* sink) { - return FormatConvertImpl(absl::string_view(v.data(), v.size()), conv, sink); -} -#endif // ABSL_HAVE_STD_STRING_VIEW && !ABSL_USES_STD_STRING_VIEW - +#if defined(ABSL_HAVE_STD_STRING_VIEW) && !defined(ABSL_USES_STD_STRING_VIEW) +inline StringConvertResult FormatConvertImpl(std::string_view v, + FormatConversionSpecImpl conv, + FormatSinkImpl* sink) { + return FormatConvertImpl(absl::string_view(v.data(), v.size()), conv, sink); +} +#endif // ABSL_HAVE_STD_STRING_VIEW && !ABSL_USES_STD_STRING_VIEW + ArgConvertResult<FormatConversionCharSetUnion( FormatConversionCharSetInternal::s, FormatConversionCharSetInternal::p)> FormatConvertImpl(const char* v, const FormatConversionSpecImpl conv, diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.cc index c988ba8fd2..cedef974fb 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.cc @@ -58,7 +58,7 @@ inline bool ArgContext::Bind(const UnboundConversion* unbound, if (static_cast<size_t>(arg_position - 1) >= pack_.size()) return false; arg = &pack_[arg_position - 1]; // 1-based - if (unbound->flags != Flags::kBasic) { + if (unbound->flags != Flags::kBasic) { int width = unbound->width.value(); bool force_left = false; if (unbound->width.is_from_arg()) { @@ -84,8 +84,8 @@ inline bool ArgContext::Bind(const UnboundConversion* unbound, FormatConversionSpecImplFriend::SetPrecision(precision, bound); if (force_left) { - FormatConversionSpecImplFriend::SetFlags(unbound->flags | Flags::kLeft, - bound); + FormatConversionSpecImplFriend::SetFlags(unbound->flags | Flags::kLeft, + bound); } else { FormatConversionSpecImplFriend::SetFlags(unbound->flags, bound); } diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.h b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.h index b26cff6648..8ade065063 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.h @@ -100,7 +100,7 @@ class FormatSpecTemplate // We use the 'unavailable' attribute to give a better compiler error than // just 'method is deleted'. // To avoid checking the format twice, we just check that the format is - // constexpr. If it is valid, then the overload below will kick in. + // constexpr. If it is valid, then the overload below will kick in. // We add the template here to make this overload have lower priority. template <typename = void> FormatSpecTemplate(const char* s) // NOLINT diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/extension.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/extension.cc index 484f6ebfc1..5fcafbdf10 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/extension.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/extension.cc @@ -23,13 +23,13 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace str_format_internal { -std::string FlagsToString(Flags v) { +std::string FlagsToString(Flags v) { std::string s; - s.append(FlagsContains(v, Flags::kLeft) ? "-" : ""); - s.append(FlagsContains(v, Flags::kShowPos) ? "+" : ""); - s.append(FlagsContains(v, Flags::kSignCol) ? " " : ""); - s.append(FlagsContains(v, Flags::kAlt) ? "#" : ""); - s.append(FlagsContains(v, Flags::kZero) ? "0" : ""); + s.append(FlagsContains(v, Flags::kLeft) ? "-" : ""); + s.append(FlagsContains(v, Flags::kShowPos) ? "+" : ""); + s.append(FlagsContains(v, Flags::kSignCol) ? " " : ""); + s.append(FlagsContains(v, Flags::kAlt) ? "#" : ""); + s.append(FlagsContains(v, Flags::kZero) ? "0" : ""); return s; } diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/extension.h b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/extension.h index 55cbb56d0a..b8b850ae47 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/extension.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/extension.h @@ -128,33 +128,33 @@ class FormatSinkImpl { char buf_[1024]; }; -enum class Flags : uint8_t { - kBasic = 0, - kLeft = 1 << 0, - kShowPos = 1 << 1, - kSignCol = 1 << 2, - kAlt = 1 << 3, - kZero = 1 << 4, - // This is not a real flag. It just exists to turn off kBasic when no other - // flags are set. This is for when width/precision are specified. - kNonBasic = 1 << 5, +enum class Flags : uint8_t { + kBasic = 0, + kLeft = 1 << 0, + kShowPos = 1 << 1, + kSignCol = 1 << 2, + kAlt = 1 << 3, + kZero = 1 << 4, + // This is not a real flag. It just exists to turn off kBasic when no other + // flags are set. This is for when width/precision are specified. + kNonBasic = 1 << 5, }; -constexpr Flags operator|(Flags a, Flags b) { - return static_cast<Flags>(static_cast<uint8_t>(a) | static_cast<uint8_t>(b)); -} - -constexpr bool FlagsContains(Flags haystack, Flags needle) { - return (static_cast<uint8_t>(haystack) & static_cast<uint8_t>(needle)) == - static_cast<uint8_t>(needle); -} - -std::string FlagsToString(Flags v); - -inline std::ostream& operator<<(std::ostream& os, Flags v) { - return os << FlagsToString(v); -} - +constexpr Flags operator|(Flags a, Flags b) { + return static_cast<Flags>(static_cast<uint8_t>(a) | static_cast<uint8_t>(b)); +} + +constexpr bool FlagsContains(Flags haystack, Flags needle) { + return (static_cast<uint8_t>(haystack) & static_cast<uint8_t>(needle)) == + static_cast<uint8_t>(needle); +} + +std::string FlagsToString(Flags v); + +inline std::ostream& operator<<(std::ostream& os, Flags v) { + return os << FlagsToString(v); +} + // clang-format off #define ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(X_VAL, X_SEP) \ /* text */ \ @@ -271,16 +271,16 @@ struct FormatConversionSpecImplFriend; class FormatConversionSpecImpl { public: // Width and precison are not specified, no flags are set. - bool is_basic() const { return flags_ == Flags::kBasic; } - bool has_left_flag() const { return FlagsContains(flags_, Flags::kLeft); } - bool has_show_pos_flag() const { - return FlagsContains(flags_, Flags::kShowPos); - } - bool has_sign_col_flag() const { - return FlagsContains(flags_, Flags::kSignCol); - } - bool has_alt_flag() const { return FlagsContains(flags_, Flags::kAlt); } - bool has_zero_flag() const { return FlagsContains(flags_, Flags::kZero); } + bool is_basic() const { return flags_ == Flags::kBasic; } + bool has_left_flag() const { return FlagsContains(flags_, Flags::kLeft); } + bool has_show_pos_flag() const { + return FlagsContains(flags_, Flags::kShowPos); + } + bool has_sign_col_flag() const { + return FlagsContains(flags_, Flags::kSignCol); + } + bool has_alt_flag() const { return FlagsContains(flags_, Flags::kAlt); } + bool has_zero_flag() const { return FlagsContains(flags_, Flags::kZero); } FormatConversionChar conversion_char() const { // Keep this field first in the struct . It generates better code when @@ -324,7 +324,7 @@ struct FormatConversionSpecImplFriend final { conv->precision_ = p; } static std::string FlagsToString(const FormatConversionSpecImpl& spec) { - return str_format_internal::FlagsToString(spec.flags_); + return str_format_internal::FlagsToString(spec.flags_); } }; diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/parser.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/parser.cc index 2c9c07dacc..08bd3404ff 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/parser.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/parser.cc @@ -34,67 +34,67 @@ namespace str_format_internal { using CC = FormatConversionCharInternal; using LM = LengthMod; -// Abbreviations to fit in the table below. -constexpr auto f_sign = Flags::kSignCol; -constexpr auto f_alt = Flags::kAlt; -constexpr auto f_pos = Flags::kShowPos; -constexpr auto f_left = Flags::kLeft; -constexpr auto f_zero = Flags::kZero; - +// Abbreviations to fit in the table below. +constexpr auto f_sign = Flags::kSignCol; +constexpr auto f_alt = Flags::kAlt; +constexpr auto f_pos = Flags::kShowPos; +constexpr auto f_left = Flags::kLeft; +constexpr auto f_zero = Flags::kZero; + ABSL_CONST_INIT const ConvTag kTags[256] = { - {}, {}, {}, {}, {}, {}, {}, {}, // 00-07 - {}, {}, {}, {}, {}, {}, {}, {}, // 08-0f - {}, {}, {}, {}, {}, {}, {}, {}, // 10-17 - {}, {}, {}, {}, {}, {}, {}, {}, // 18-1f - f_sign, {}, {}, f_alt, {}, {}, {}, {}, // !"#$%&' - {}, {}, {}, f_pos, {}, f_left, {}, {}, // ()*+,-./ - f_zero, {}, {}, {}, {}, {}, {}, {}, // 01234567 - {}, {}, {}, {}, {}, {}, {}, {}, // 89:;<=>? - {}, CC::A, {}, {}, {}, CC::E, CC::F, CC::G, // @ABCDEFG - {}, {}, {}, {}, LM::L, {}, {}, {}, // HIJKLMNO - {}, {}, {}, {}, {}, {}, {}, {}, // PQRSTUVW - CC::X, {}, {}, {}, {}, {}, {}, {}, // XYZ[\]^_ - {}, CC::a, {}, CC::c, CC::d, CC::e, CC::f, CC::g, // `abcdefg - LM::h, CC::i, LM::j, {}, LM::l, {}, CC::n, CC::o, // hijklmno - CC::p, LM::q, {}, CC::s, LM::t, CC::u, {}, {}, // pqrstuvw - CC::x, {}, LM::z, {}, {}, {}, {}, {}, // xyz{|}! - {}, {}, {}, {}, {}, {}, {}, {}, // 80-87 - {}, {}, {}, {}, {}, {}, {}, {}, // 88-8f - {}, {}, {}, {}, {}, {}, {}, {}, // 90-97 - {}, {}, {}, {}, {}, {}, {}, {}, // 98-9f - {}, {}, {}, {}, {}, {}, {}, {}, // a0-a7 - {}, {}, {}, {}, {}, {}, {}, {}, // a8-af - {}, {}, {}, {}, {}, {}, {}, {}, // b0-b7 - {}, {}, {}, {}, {}, {}, {}, {}, // b8-bf - {}, {}, {}, {}, {}, {}, {}, {}, // c0-c7 - {}, {}, {}, {}, {}, {}, {}, {}, // c8-cf - {}, {}, {}, {}, {}, {}, {}, {}, // d0-d7 - {}, {}, {}, {}, {}, {}, {}, {}, // d8-df - {}, {}, {}, {}, {}, {}, {}, {}, // e0-e7 - {}, {}, {}, {}, {}, {}, {}, {}, // e8-ef - {}, {}, {}, {}, {}, {}, {}, {}, // f0-f7 - {}, {}, {}, {}, {}, {}, {}, {}, // f8-ff + {}, {}, {}, {}, {}, {}, {}, {}, // 00-07 + {}, {}, {}, {}, {}, {}, {}, {}, // 08-0f + {}, {}, {}, {}, {}, {}, {}, {}, // 10-17 + {}, {}, {}, {}, {}, {}, {}, {}, // 18-1f + f_sign, {}, {}, f_alt, {}, {}, {}, {}, // !"#$%&' + {}, {}, {}, f_pos, {}, f_left, {}, {}, // ()*+,-./ + f_zero, {}, {}, {}, {}, {}, {}, {}, // 01234567 + {}, {}, {}, {}, {}, {}, {}, {}, // 89:;<=>? + {}, CC::A, {}, {}, {}, CC::E, CC::F, CC::G, // @ABCDEFG + {}, {}, {}, {}, LM::L, {}, {}, {}, // HIJKLMNO + {}, {}, {}, {}, {}, {}, {}, {}, // PQRSTUVW + CC::X, {}, {}, {}, {}, {}, {}, {}, // XYZ[\]^_ + {}, CC::a, {}, CC::c, CC::d, CC::e, CC::f, CC::g, // `abcdefg + LM::h, CC::i, LM::j, {}, LM::l, {}, CC::n, CC::o, // hijklmno + CC::p, LM::q, {}, CC::s, LM::t, CC::u, {}, {}, // pqrstuvw + CC::x, {}, LM::z, {}, {}, {}, {}, {}, // xyz{|}! + {}, {}, {}, {}, {}, {}, {}, {}, // 80-87 + {}, {}, {}, {}, {}, {}, {}, {}, // 88-8f + {}, {}, {}, {}, {}, {}, {}, {}, // 90-97 + {}, {}, {}, {}, {}, {}, {}, {}, // 98-9f + {}, {}, {}, {}, {}, {}, {}, {}, // a0-a7 + {}, {}, {}, {}, {}, {}, {}, {}, // a8-af + {}, {}, {}, {}, {}, {}, {}, {}, // b0-b7 + {}, {}, {}, {}, {}, {}, {}, {}, // b8-bf + {}, {}, {}, {}, {}, {}, {}, {}, // c0-c7 + {}, {}, {}, {}, {}, {}, {}, {}, // c8-cf + {}, {}, {}, {}, {}, {}, {}, {}, // d0-d7 + {}, {}, {}, {}, {}, {}, {}, {}, // d8-df + {}, {}, {}, {}, {}, {}, {}, {}, // e0-e7 + {}, {}, {}, {}, {}, {}, {}, {}, // e8-ef + {}, {}, {}, {}, {}, {}, {}, {}, // f0-f7 + {}, {}, {}, {}, {}, {}, {}, {}, // f8-ff }; namespace { bool CheckFastPathSetting(const UnboundConversion& conv) { - bool width_precision_needed = - conv.width.value() >= 0 || conv.precision.value() >= 0; - if (width_precision_needed && conv.flags == Flags::kBasic) { + bool width_precision_needed = + conv.width.value() >= 0 || conv.precision.value() >= 0; + if (width_precision_needed && conv.flags == Flags::kBasic) { fprintf(stderr, "basic=%d left=%d show_pos=%d sign_col=%d alt=%d zero=%d " "width=%d precision=%d\n", - conv.flags == Flags::kBasic ? 1 : 0, - FlagsContains(conv.flags, Flags::kLeft) ? 1 : 0, - FlagsContains(conv.flags, Flags::kShowPos) ? 1 : 0, - FlagsContains(conv.flags, Flags::kSignCol) ? 1 : 0, - FlagsContains(conv.flags, Flags::kAlt) ? 1 : 0, - FlagsContains(conv.flags, Flags::kZero) ? 1 : 0, conv.width.value(), - conv.precision.value()); - return false; + conv.flags == Flags::kBasic ? 1 : 0, + FlagsContains(conv.flags, Flags::kLeft) ? 1 : 0, + FlagsContains(conv.flags, Flags::kShowPos) ? 1 : 0, + FlagsContains(conv.flags, Flags::kSignCol) ? 1 : 0, + FlagsContains(conv.flags, Flags::kAlt) ? 1 : 0, + FlagsContains(conv.flags, Flags::kZero) ? 1 : 0, conv.width.value(), + conv.precision.value()); + return false; } - return true; + return true; } template <bool is_positional> @@ -138,19 +138,19 @@ const char *ConsumeConversion(const char *pos, const char *const end, ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR(); // We should start with the basic flag on. - assert(conv->flags == Flags::kBasic); + assert(conv->flags == Flags::kBasic); // Any non alpha character makes this conversion not basic. // This includes flags (-+ #0), width (1-9, *) or precision (.). // All conversion characters and length modifiers are alpha characters. if (c < 'A') { - while (c <= '0') { - auto tag = GetTagForChar(c); - if (tag.is_flags()) { - conv->flags = conv->flags | tag.as_flags(); - ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR(); - } else { - break; + while (c <= '0') { + auto tag = GetTagForChar(c); + if (tag.is_flags()) { + conv->flags = conv->flags | tag.as_flags(); + ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR(); + } else { + break; } } @@ -163,10 +163,10 @@ const char *ConsumeConversion(const char *pos, const char *const end, *next_arg = -1; return ConsumeConversion<true>(original_pos, end, conv, next_arg); } - conv->flags = conv->flags | Flags::kNonBasic; + conv->flags = conv->flags | Flags::kNonBasic; conv->width.set_value(maybe_width); } else if (c == '*') { - conv->flags = conv->flags | Flags::kNonBasic; + conv->flags = conv->flags | Flags::kNonBasic; ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR(); if (is_positional) { if (ABSL_PREDICT_FALSE(c < '1' || c > '9')) return nullptr; @@ -180,7 +180,7 @@ const char *ConsumeConversion(const char *pos, const char *const end, } if (c == '.') { - conv->flags = conv->flags | Flags::kNonBasic; + conv->flags = conv->flags | Flags::kNonBasic; ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR(); if (std::isdigit(c)) { conv->precision.set_value(parse_digits()); diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/parser.h b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/parser.h index ad8646edff..5aee2c1601 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/parser.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/parser.h @@ -41,7 +41,7 @@ std::string LengthModToString(LengthMod v); // The analyzed properties of a single specified conversion. struct UnboundConversion { - UnboundConversion() {} + UnboundConversion() {} class InputValue { public: @@ -76,7 +76,7 @@ struct UnboundConversion { InputValue width; InputValue precision; - Flags flags = Flags::kBasic; + Flags flags = Flags::kBasic; LengthMod length_mod = LengthMod::none; FormatConversionChar conv = FormatConversionCharInternal::kNone; }; @@ -90,43 +90,43 @@ const char* ConsumeUnboundConversion(const char* p, const char* end, UnboundConversion* conv, int* next_arg); // Helper tag class for the table below. -// It allows fast `char -> ConversionChar/LengthMod/Flags` checking and +// It allows fast `char -> ConversionChar/LengthMod/Flags` checking and // conversions. class ConvTag { public: constexpr ConvTag(FormatConversionChar conversion_char) // NOLINT - : tag_(static_cast<uint8_t>(conversion_char)) {} + : tag_(static_cast<uint8_t>(conversion_char)) {} constexpr ConvTag(LengthMod length_mod) // NOLINT - : tag_(0x80 | static_cast<uint8_t>(length_mod)) {} - constexpr ConvTag(Flags flags) // NOLINT - : tag_(0xc0 | static_cast<uint8_t>(flags)) {} - constexpr ConvTag() : tag_(0xFF) {} - - bool is_conv() const { return (tag_ & 0x80) == 0; } - bool is_length() const { return (tag_ & 0xC0) == 0x80; } - bool is_flags() const { return (tag_ & 0xE0) == 0xC0; } - + : tag_(0x80 | static_cast<uint8_t>(length_mod)) {} + constexpr ConvTag(Flags flags) // NOLINT + : tag_(0xc0 | static_cast<uint8_t>(flags)) {} + constexpr ConvTag() : tag_(0xFF) {} + + bool is_conv() const { return (tag_ & 0x80) == 0; } + bool is_length() const { return (tag_ & 0xC0) == 0x80; } + bool is_flags() const { return (tag_ & 0xE0) == 0xC0; } + FormatConversionChar as_conv() const { assert(is_conv()); - assert(!is_length()); - assert(!is_flags()); + assert(!is_length()); + assert(!is_flags()); return static_cast<FormatConversionChar>(tag_); } LengthMod as_length() const { - assert(!is_conv()); + assert(!is_conv()); assert(is_length()); - assert(!is_flags()); - return static_cast<LengthMod>(tag_ & 0x3F); - } - Flags as_flags() const { - assert(!is_conv()); - assert(!is_length()); - assert(is_flags()); - return static_cast<Flags>(tag_ & 0x1F); + assert(!is_flags()); + return static_cast<LengthMod>(tag_ & 0x3F); } + Flags as_flags() const { + assert(!is_conv()); + assert(!is_length()); + assert(is_flags()); + return static_cast<Flags>(tag_ & 0x1F); + } private: - uint8_t tag_; + uint8_t tag_; }; extern const ConvTag kTags[256]; diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/ya.make b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/ya.make index 1f07f02b2e..9a4c265a69 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/ya.make +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/ya.make @@ -6,8 +6,8 @@ OWNER(g:cpp-contrib) LICENSE(Apache-2.0) -LICENSE_TEXTS(.yandex_meta/licenses.list.txt) - +LICENSE_TEXTS(.yandex_meta/licenses.list.txt) + PEERDIR( contrib/restricted/abseil-cpp/absl/base contrib/restricted/abseil-cpp/absl/base/internal/raw_logging @@ -16,7 +16,7 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/base/log_severity contrib/restricted/abseil-cpp/absl/numeric contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal ) ADDINCL( @@ -32,12 +32,12 @@ CFLAGS( ) SRCS( - arg.cc - bind.cc - extension.cc - float_conversion.cc - output.cc - parser.cc + arg.cc + bind.cc + extension.cc + float_conversion.cc + output.cc + parser.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_split_internal.h b/contrib/restricted/abseil-cpp/absl/strings/internal/str_split_internal.h index e766421617..1b26399c1d 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_split_internal.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_split_internal.h @@ -32,7 +32,7 @@ #include <array> #include <initializer_list> #include <iterator> -#include <tuple> +#include <tuple> #include <type_traits> #include <utility> #include <vector> @@ -64,7 +64,7 @@ class ConvertibleToStringView { ConvertibleToStringView(const std::string& s) // NOLINT(runtime/explicit) : value_(s) {} - // Disable conversion from rvalue strings. + // Disable conversion from rvalue strings. ConvertibleToStringView(std::string&& s) = delete; ConvertibleToStringView(const std::string&& s) = delete; @@ -182,13 +182,13 @@ template <typename T> struct HasConstIterator<T, absl::void_t<typename T::const_iterator>> : std::true_type {}; -// HasEmplace<T>::value is true iff there exists a method T::emplace(). -template <typename T, typename = void> -struct HasEmplace : std::false_type {}; -template <typename T> -struct HasEmplace<T, absl::void_t<decltype(std::declval<T>().emplace())>> - : std::true_type {}; - +// HasEmplace<T>::value is true iff there exists a method T::emplace(). +template <typename T, typename = void> +struct HasEmplace : std::false_type {}; +template <typename T> +struct HasEmplace<T, absl::void_t<decltype(std::declval<T>().emplace())>> + : std::true_type {}; + // IsInitializerList<T>::value is true iff T is an std::initializer_list. More // details below in Splitter<> where this is used. std::false_type IsInitializerListDispatch(...); // default: No @@ -379,43 +379,43 @@ class Splitter { // value. template <typename Container, typename First, typename Second> struct ConvertToContainer<Container, std::pair<const First, Second>, true> { - using iterator = typename Container::iterator; - + using iterator = typename Container::iterator; + Container operator()(const Splitter& splitter) const { Container m; - iterator it; + iterator it; bool insert = true; - for (const absl::string_view sv : splitter) { + for (const absl::string_view sv : splitter) { if (insert) { - it = InsertOrEmplace(&m, sv); + it = InsertOrEmplace(&m, sv); } else { - it->second = Second(sv); + it->second = Second(sv); } insert = !insert; } return m; } - // Inserts the key and an empty value into the map, returning an iterator to - // the inserted item. We use emplace() if available, otherwise insert(). - template <typename M> - static absl::enable_if_t<HasEmplace<M>::value, iterator> InsertOrEmplace( - M* m, absl::string_view key) { - // Use piecewise_construct to support old versions of gcc in which pair - // constructor can't otherwise construct string from string_view. - return ToIter(m->emplace(std::piecewise_construct, std::make_tuple(key), - std::tuple<>())); - } - template <typename M> - static absl::enable_if_t<!HasEmplace<M>::value, iterator> InsertOrEmplace( - M* m, absl::string_view key) { - return ToIter(m->insert(std::make_pair(First(key), Second("")))); - } - - static iterator ToIter(std::pair<iterator, bool> pair) { - return pair.first; - } - static iterator ToIter(iterator iter) { return iter; } + // Inserts the key and an empty value into the map, returning an iterator to + // the inserted item. We use emplace() if available, otherwise insert(). + template <typename M> + static absl::enable_if_t<HasEmplace<M>::value, iterator> InsertOrEmplace( + M* m, absl::string_view key) { + // Use piecewise_construct to support old versions of gcc in which pair + // constructor can't otherwise construct string from string_view. + return ToIter(m->emplace(std::piecewise_construct, std::make_tuple(key), + std::tuple<>())); + } + template <typename M> + static absl::enable_if_t<!HasEmplace<M>::value, iterator> InsertOrEmplace( + M* m, absl::string_view key) { + return ToIter(m->insert(std::make_pair(First(key), Second("")))); + } + + static iterator ToIter(std::pair<iterator, bool> pair) { + return pair.first; + } + static iterator ToIter(iterator iter) { return iter; } }; StringType text_; diff --git a/contrib/restricted/abseil-cpp/absl/strings/numbers.cc b/contrib/restricted/abseil-cpp/absl/strings/numbers.cc index cbd84c918b..faf1357172 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/numbers.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/numbers.cc @@ -505,7 +505,7 @@ size_t numbers_internal::SixDigitsToBuffer(double d, char* const buffer) { *out++ = '-'; d = -d; } - if (d > std::numeric_limits<double>::max()) { + if (d > std::numeric_limits<double>::max()) { strcpy(out, "inf"); // NOLINT(runtime/printf) return out + 3 - buffer; } diff --git a/contrib/restricted/abseil-cpp/absl/strings/numbers.h b/contrib/restricted/abseil-cpp/absl/strings/numbers.h index 899e623c8c..cc05bdd964 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/numbers.h +++ b/contrib/restricted/abseil-cpp/absl/strings/numbers.h @@ -100,25 +100,25 @@ ABSL_MUST_USE_RESULT bool SimpleAtod(absl::string_view str, double* out); // unspecified state. ABSL_MUST_USE_RESULT bool SimpleAtob(absl::string_view str, bool* out); -// SimpleHexAtoi() -// -// Converts a hexadecimal string (optionally followed or preceded by ASCII -// whitespace) to an integer, returning `true` if successful. Only valid base-16 -// hexadecimal integers whose value falls within the range of the integer type -// (optionally preceded by a `+` or `-`) can be converted. A valid hexadecimal -// value may include both upper and lowercase character symbols, and may -// optionally include a leading "0x" (or "0X") number prefix, which is ignored -// by this function. If any errors are encountered, this function returns -// `false`, leaving `out` in an unspecified state. -template <typename int_type> -ABSL_MUST_USE_RESULT bool SimpleHexAtoi(absl::string_view str, int_type* out); - -// Overloads of SimpleHexAtoi() for 128 bit integers. -ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(absl::string_view str, - absl::int128* out); -ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(absl::string_view str, - absl::uint128* out); - +// SimpleHexAtoi() +// +// Converts a hexadecimal string (optionally followed or preceded by ASCII +// whitespace) to an integer, returning `true` if successful. Only valid base-16 +// hexadecimal integers whose value falls within the range of the integer type +// (optionally preceded by a `+` or `-`) can be converted. A valid hexadecimal +// value may include both upper and lowercase character symbols, and may +// optionally include a leading "0x" (or "0X") number prefix, which is ignored +// by this function. If any errors are encountered, this function returns +// `false`, leaving `out` in an unspecified state. +template <typename int_type> +ABSL_MUST_USE_RESULT bool SimpleHexAtoi(absl::string_view str, int_type* out); + +// Overloads of SimpleHexAtoi() for 128 bit integers. +ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(absl::string_view str, + absl::int128* out); +ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(absl::string_view str, + absl::uint128* out); + ABSL_NAMESPACE_END } // namespace absl @@ -283,21 +283,21 @@ ABSL_MUST_USE_RESULT inline bool SimpleAtoi(absl::string_view str, return numbers_internal::safe_strtou128_base(str, out, 10); } -template <typename int_type> -ABSL_MUST_USE_RESULT bool SimpleHexAtoi(absl::string_view str, int_type* out) { - return numbers_internal::safe_strtoi_base(str, out, 16); -} - -ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(absl::string_view str, - absl::int128* out) { - return numbers_internal::safe_strto128_base(str, out, 16); -} - -ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(absl::string_view str, - absl::uint128* out) { - return numbers_internal::safe_strtou128_base(str, out, 16); -} - +template <typename int_type> +ABSL_MUST_USE_RESULT bool SimpleHexAtoi(absl::string_view str, int_type* out) { + return numbers_internal::safe_strtoi_base(str, out, 16); +} + +ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(absl::string_view str, + absl::int128* out) { + return numbers_internal::safe_strto128_base(str, out, 16); +} + +ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(absl::string_view str, + absl::uint128* out) { + return numbers_internal::safe_strtou128_base(str, out, 16); +} + ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/str_cat.cc b/contrib/restricted/abseil-cpp/absl/strings/str_cat.cc index f4a77493a4..d709c3a0bc 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/str_cat.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/str_cat.cc @@ -174,7 +174,7 @@ void AppendPieces(std::string* dest, ASSERT_NO_OVERLAP(*dest, piece); total_size += piece.size(); } - strings_internal::STLStringResizeUninitializedAmortized(dest, total_size); + strings_internal::STLStringResizeUninitializedAmortized(dest, total_size); char* const begin = &(*dest)[0]; char* out = begin + old_size; @@ -199,7 +199,7 @@ void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b) { ASSERT_NO_OVERLAP(*dest, a); ASSERT_NO_OVERLAP(*dest, b); std::string::size_type old_size = dest->size(); - strings_internal::STLStringResizeUninitializedAmortized( + strings_internal::STLStringResizeUninitializedAmortized( dest, old_size + a.size() + b.size()); char* const begin = &(*dest)[0]; char* out = begin + old_size; @@ -214,7 +214,7 @@ void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b, ASSERT_NO_OVERLAP(*dest, b); ASSERT_NO_OVERLAP(*dest, c); std::string::size_type old_size = dest->size(); - strings_internal::STLStringResizeUninitializedAmortized( + strings_internal::STLStringResizeUninitializedAmortized( dest, old_size + a.size() + b.size() + c.size()); char* const begin = &(*dest)[0]; char* out = begin + old_size; @@ -231,7 +231,7 @@ void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b, ASSERT_NO_OVERLAP(*dest, c); ASSERT_NO_OVERLAP(*dest, d); std::string::size_type old_size = dest->size(); - strings_internal::STLStringResizeUninitializedAmortized( + strings_internal::STLStringResizeUninitializedAmortized( dest, old_size + a.size() + b.size() + c.size() + d.size()); char* const begin = &(*dest)[0]; char* out = begin + old_size; diff --git a/contrib/restricted/abseil-cpp/absl/strings/str_format.h b/contrib/restricted/abseil-cpp/absl/strings/str_format.h index 4b05c70c23..cc40343e80 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/str_format.h +++ b/contrib/restricted/abseil-cpp/absl/strings/str_format.h @@ -536,7 +536,7 @@ using FormatArg = str_format_internal::FormatArgImpl; // The arguments are provided in an `absl::Span<const absl::FormatArg>`. // Each `absl::FormatArg` object binds to a single argument and keeps a // reference to it. The values used to create the `FormatArg` objects must -// outlive this function call. +// outlive this function call. // // Example: // diff --git a/contrib/restricted/abseil-cpp/absl/strings/string_view.cc b/contrib/restricted/abseil-cpp/absl/strings/string_view.cc index d596e08cde..98b8cb5ebd 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/string_view.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/string_view.cc @@ -78,8 +78,8 @@ std::ostream& operator<<(std::ostream& o, string_view piece) { return o; } -string_view::size_type string_view::find(string_view s, - size_type pos) const noexcept { +string_view::size_type string_view::find(string_view s, + size_type pos) const noexcept { if (empty() || pos > length_) { if (empty() && pos == 0 && s.empty()) return 0; return npos; @@ -98,8 +98,8 @@ string_view::size_type string_view::find(char c, size_type pos) const noexcept { return result != nullptr ? result - ptr_ : npos; } -string_view::size_type string_view::rfind(string_view s, - size_type pos) const noexcept { +string_view::size_type string_view::rfind(string_view s, + size_type pos) const noexcept { if (length_ < s.length_) return npos; if (s.empty()) return std::min(length_, pos); const char* last = ptr_ + std::min(length_ - s.length_, pos) + s.length_; @@ -108,8 +108,8 @@ string_view::size_type string_view::rfind(string_view s, } // Search range is [0..pos] inclusive. If pos == npos, search everything. -string_view::size_type string_view::rfind(char c, - size_type pos) const noexcept { +string_view::size_type string_view::rfind(char c, + size_type pos) const noexcept { // Note: memrchr() is not available on Windows. if (empty()) return npos; for (size_type i = std::min(pos, length_ - 1);; --i) { @@ -121,8 +121,8 @@ string_view::size_type string_view::rfind(char c, return npos; } -string_view::size_type string_view::find_first_of( - string_view s, size_type pos) const noexcept { +string_view::size_type string_view::find_first_of( + string_view s, size_type pos) const noexcept { if (empty() || s.empty()) { return npos; } @@ -137,8 +137,8 @@ string_view::size_type string_view::find_first_of( return npos; } -string_view::size_type string_view::find_first_not_of( - string_view s, size_type pos) const noexcept { +string_view::size_type string_view::find_first_not_of( + string_view s, size_type pos) const noexcept { if (empty()) return npos; // Avoid the cost of LookupTable() for a single-character search. if (s.length_ == 1) return find_first_not_of(s.ptr_[0], pos); @@ -151,8 +151,8 @@ string_view::size_type string_view::find_first_not_of( return npos; } -string_view::size_type string_view::find_first_not_of( - char c, size_type pos) const noexcept { +string_view::size_type string_view::find_first_not_of( + char c, size_type pos) const noexcept { if (empty()) return npos; for (; pos < length_; ++pos) { if (ptr_[pos] != c) { @@ -177,8 +177,8 @@ string_view::size_type string_view::find_last_of(string_view s, return npos; } -string_view::size_type string_view::find_last_not_of( - string_view s, size_type pos) const noexcept { +string_view::size_type string_view::find_last_not_of( + string_view s, size_type pos) const noexcept { if (empty()) return npos; size_type i = std::min(pos, length_ - 1); if (s.empty()) return i; @@ -194,8 +194,8 @@ string_view::size_type string_view::find_last_not_of( return npos; } -string_view::size_type string_view::find_last_not_of( - char c, size_type pos) const noexcept { +string_view::size_type string_view::find_last_not_of( + char c, size_type pos) const noexcept { if (empty()) return npos; size_type i = std::min(pos, length_ - 1); for (;; --i) { diff --git a/contrib/restricted/abseil-cpp/absl/strings/string_view.h b/contrib/restricted/abseil-cpp/absl/strings/string_view.h index 65e74ccb1d..b6b60bde00 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/string_view.h +++ b/contrib/restricted/abseil-cpp/absl/strings/string_view.h @@ -36,7 +36,7 @@ #include <limits> #include <string> -#include "absl/base/attributes.h" +#include "absl/base/attributes.h" #include "absl/base/config.h" #include "absl/base/internal/throw_delegate.h" #include "absl/base/macros.h" @@ -55,8 +55,8 @@ ABSL_NAMESPACE_END #else // ABSL_USES_STD_STRING_VIEW -#error "std::string_view should be used in all configurations" - +#error "std::string_view should be used in all configurations" + #if ABSL_HAVE_BUILTIN(__builtin_memcmp) || \ (defined(__GNUC__) && !defined(__clang__)) #define ABSL_INTERNAL_STRING_VIEW_MEMCMP __builtin_memcmp @@ -64,12 +64,12 @@ ABSL_NAMESPACE_END #define ABSL_INTERNAL_STRING_VIEW_MEMCMP memcmp #endif // ABSL_HAVE_BUILTIN(__builtin_memcmp) -#if defined(__cplusplus) && __cplusplus >= 201402L -#define ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR constexpr -#else -#define ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR -#endif - +#if defined(__cplusplus) && __cplusplus >= 201402L +#define ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR constexpr +#else +#define ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR +#endif + namespace absl { ABSL_NAMESPACE_BEGIN @@ -189,20 +189,20 @@ class string_view { template <typename Allocator> string_view( // NOLINT(runtime/explicit) - const std::basic_string<char, std::char_traits<char>, Allocator>& str - ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept + const std::basic_string<char, std::char_traits<char>, Allocator>& str + ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept // This is implemented in terms of `string_view(p, n)` so `str.size()` // doesn't need to be reevaluated after `ptr_` is set. - // The length check is also skipped since it is unnecessary and causes - // code bloat. - : string_view(str.data(), str.size(), SkipCheckLengthTag{}) {} + // The length check is also skipped since it is unnecessary and causes + // code bloat. + : string_view(str.data(), str.size(), SkipCheckLengthTag{}) {} // Implicit constructor of a `string_view` from NUL-terminated `str`. When // accepting possibly null strings, use `absl::NullSafeStringView(str)` // instead (see below). - // The length check is skipped since it is unnecessary and causes code bloat. + // The length check is skipped since it is unnecessary and causes code bloat. constexpr string_view(const char* str) // NOLINT(runtime/explicit) - : ptr_(str), length_(str ? StrlenInternal(str) : 0) {} + : ptr_(str), length_(str ? StrlenInternal(str) : 0) {} // Implicit constructor of a `string_view` from a `const char*` and length. constexpr string_view(const char* data, size_type len) @@ -275,7 +275,7 @@ class string_view { // string_view::size() // // Returns the number of characters in the `string_view`. - constexpr size_type size() const noexcept { return length_; } + constexpr size_type size() const noexcept { return length_; } // string_view::length() // @@ -342,7 +342,7 @@ class string_view { // // Removes the first `n` characters from the `string_view`. Note that the // underlying string is not changed, only the view. - ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void remove_prefix(size_type n) { + ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void remove_prefix(size_type n) { ABSL_HARDENING_ASSERT(n <= length_); ptr_ += n; length_ -= n; @@ -352,7 +352,7 @@ class string_view { // // Removes the last `n` characters from the `string_view`. Note that the // underlying string is not changed, only the view. - ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void remove_suffix(size_type n) { + ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void remove_suffix(size_type n) { ABSL_HARDENING_ASSERT(n <= length_); length_ -= n; } @@ -360,7 +360,7 @@ class string_view { // string_view::swap() // // Swaps this `string_view` with another `string_view`. - ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void swap(string_view& s) noexcept { + ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void swap(string_view& s) noexcept { auto t = *this; *this = s; s = t; @@ -397,7 +397,7 @@ class string_view { // `n`) as another string_view. This function throws `std::out_of_bounds` if // `pos > size`. // Use absl::ClippedSubstr if you need a truncating substr operation. - constexpr string_view substr(size_type pos = 0, size_type n = npos) const { + constexpr string_view substr(size_type pos = 0, size_type n = npos) const { return ABSL_PREDICT_FALSE(pos > length_) ? (base_internal::ThrowStdOutOfRange( "absl::string_view::substr"), @@ -407,10 +407,10 @@ class string_view { // string_view::compare() // - // Performs a lexicographical comparison between this `string_view` and - // another `string_view` `x`, returning a negative value if `*this` is less - // than `x`, 0 if `*this` is equal to `x`, and a positive value if `*this` - // is greater than `x`. + // Performs a lexicographical comparison between this `string_view` and + // another `string_view` `x`, returning a negative value if `*this` is less + // than `x`, 0 if `*this` is equal to `x`, and a positive value if `*this` + // is greater than `x`. constexpr int compare(string_view x) const noexcept { return CompareImpl(length_, x.length_, Min(length_, x.length_) == 0 @@ -421,31 +421,31 @@ class string_view { // Overload of `string_view::compare()` for comparing a substring of the // 'string_view` and another `absl::string_view`. - constexpr int compare(size_type pos1, size_type count1, string_view v) const { + constexpr int compare(size_type pos1, size_type count1, string_view v) const { return substr(pos1, count1).compare(v); } // Overload of `string_view::compare()` for comparing a substring of the // `string_view` and a substring of another `absl::string_view`. - constexpr int compare(size_type pos1, size_type count1, string_view v, - size_type pos2, size_type count2) const { + constexpr int compare(size_type pos1, size_type count1, string_view v, + size_type pos2, size_type count2) const { return substr(pos1, count1).compare(v.substr(pos2, count2)); } // Overload of `string_view::compare()` for comparing a `string_view` and a - // a different C-style string `s`. - constexpr int compare(const char* s) const { return compare(string_view(s)); } + // a different C-style string `s`. + constexpr int compare(const char* s) const { return compare(string_view(s)); } // Overload of `string_view::compare()` for comparing a substring of the // `string_view` and a different string C-style string `s`. - constexpr int compare(size_type pos1, size_type count1, const char* s) const { + constexpr int compare(size_type pos1, size_type count1, const char* s) const { return substr(pos1, count1).compare(string_view(s)); } // Overload of `string_view::compare()` for comparing a substring of the // `string_view` and a substring of a different C-style string `s`. - constexpr int compare(size_type pos1, size_type count1, const char* s, - size_type count2) const { + constexpr int compare(size_type pos1, size_type count1, const char* s, + size_type count2) const { return substr(pos1, count1).compare(string_view(s, count2)); } @@ -462,92 +462,92 @@ class string_view { // within the `string_view`. size_type find(char c, size_type pos = 0) const noexcept; - // Overload of `string_view::find()` for finding a substring of a different - // C-style string `s` within the `string_view`. - size_type find(const char* s, size_type pos, size_type count) const { - return find(string_view(s, count), pos); - } - - // Overload of `string_view::find()` for finding a different C-style string - // `s` within the `string_view`. - size_type find(const char* s, size_type pos = 0) const { - return find(string_view(s), pos); - } - + // Overload of `string_view::find()` for finding a substring of a different + // C-style string `s` within the `string_view`. + size_type find(const char* s, size_type pos, size_type count) const { + return find(string_view(s, count), pos); + } + + // Overload of `string_view::find()` for finding a different C-style string + // `s` within the `string_view`. + size_type find(const char* s, size_type pos = 0) const { + return find(string_view(s), pos); + } + // string_view::rfind() // // Finds the last occurrence of a substring `s` within the `string_view`, // returning the position of the first character's match, or `npos` if no // match was found. - size_type rfind(string_view s, size_type pos = npos) const noexcept; + size_type rfind(string_view s, size_type pos = npos) const noexcept; // Overload of `string_view::rfind()` for finding the last given character `c` // within the `string_view`. size_type rfind(char c, size_type pos = npos) const noexcept; - // Overload of `string_view::rfind()` for finding a substring of a different - // C-style string `s` within the `string_view`. - size_type rfind(const char* s, size_type pos, size_type count) const { - return rfind(string_view(s, count), pos); - } - - // Overload of `string_view::rfind()` for finding a different C-style string - // `s` within the `string_view`. - size_type rfind(const char* s, size_type pos = npos) const { - return rfind(string_view(s), pos); - } - + // Overload of `string_view::rfind()` for finding a substring of a different + // C-style string `s` within the `string_view`. + size_type rfind(const char* s, size_type pos, size_type count) const { + return rfind(string_view(s, count), pos); + } + + // Overload of `string_view::rfind()` for finding a different C-style string + // `s` within the `string_view`. + size_type rfind(const char* s, size_type pos = npos) const { + return rfind(string_view(s), pos); + } + // string_view::find_first_of() // // Finds the first occurrence of any of the characters in `s` within the // `string_view`, returning the start position of the match, or `npos` if no // match was found. - size_type find_first_of(string_view s, size_type pos = 0) const noexcept; + size_type find_first_of(string_view s, size_type pos = 0) const noexcept; // Overload of `string_view::find_first_of()` for finding a character `c` // within the `string_view`. - size_type find_first_of(char c, size_type pos = 0) const noexcept { + size_type find_first_of(char c, size_type pos = 0) const noexcept { return find(c, pos); } - // Overload of `string_view::find_first_of()` for finding a substring of a - // different C-style string `s` within the `string_view`. - size_type find_first_of(const char* s, size_type pos, - size_type count) const { - return find_first_of(string_view(s, count), pos); - } - - // Overload of `string_view::find_first_of()` for finding a different C-style - // string `s` within the `string_view`. - size_type find_first_of(const char* s, size_type pos = 0) const { - return find_first_of(string_view(s), pos); - } - + // Overload of `string_view::find_first_of()` for finding a substring of a + // different C-style string `s` within the `string_view`. + size_type find_first_of(const char* s, size_type pos, + size_type count) const { + return find_first_of(string_view(s, count), pos); + } + + // Overload of `string_view::find_first_of()` for finding a different C-style + // string `s` within the `string_view`. + size_type find_first_of(const char* s, size_type pos = 0) const { + return find_first_of(string_view(s), pos); + } + // string_view::find_last_of() // // Finds the last occurrence of any of the characters in `s` within the // `string_view`, returning the start position of the match, or `npos` if no // match was found. - size_type find_last_of(string_view s, size_type pos = npos) const noexcept; + size_type find_last_of(string_view s, size_type pos = npos) const noexcept; // Overload of `string_view::find_last_of()` for finding a character `c` // within the `string_view`. - size_type find_last_of(char c, size_type pos = npos) const noexcept { + size_type find_last_of(char c, size_type pos = npos) const noexcept { return rfind(c, pos); } - // Overload of `string_view::find_last_of()` for finding a substring of a - // different C-style string `s` within the `string_view`. - size_type find_last_of(const char* s, size_type pos, size_type count) const { - return find_last_of(string_view(s, count), pos); - } - - // Overload of `string_view::find_last_of()` for finding a different C-style - // string `s` within the `string_view`. - size_type find_last_of(const char* s, size_type pos = npos) const { - return find_last_of(string_view(s), pos); - } - + // Overload of `string_view::find_last_of()` for finding a substring of a + // different C-style string `s` within the `string_view`. + size_type find_last_of(const char* s, size_type pos, size_type count) const { + return find_last_of(string_view(s, count), pos); + } + + // Overload of `string_view::find_last_of()` for finding a different C-style + // string `s` within the `string_view`. + size_type find_last_of(const char* s, size_type pos = npos) const { + return find_last_of(string_view(s), pos); + } + // string_view::find_first_not_of() // // Finds the first occurrence of any of the characters not in `s` within the @@ -559,51 +559,51 @@ class string_view { // that is not `c` within the `string_view`. size_type find_first_not_of(char c, size_type pos = 0) const noexcept; - // Overload of `string_view::find_first_not_of()` for finding a substring of a - // different C-style string `s` within the `string_view`. - size_type find_first_not_of(const char* s, size_type pos, - size_type count) const { - return find_first_not_of(string_view(s, count), pos); - } - - // Overload of `string_view::find_first_not_of()` for finding a different - // C-style string `s` within the `string_view`. - size_type find_first_not_of(const char* s, size_type pos = 0) const { - return find_first_not_of(string_view(s), pos); - } - + // Overload of `string_view::find_first_not_of()` for finding a substring of a + // different C-style string `s` within the `string_view`. + size_type find_first_not_of(const char* s, size_type pos, + size_type count) const { + return find_first_not_of(string_view(s, count), pos); + } + + // Overload of `string_view::find_first_not_of()` for finding a different + // C-style string `s` within the `string_view`. + size_type find_first_not_of(const char* s, size_type pos = 0) const { + return find_first_not_of(string_view(s), pos); + } + // string_view::find_last_not_of() // // Finds the last occurrence of any of the characters not in `s` within the // `string_view`, returning the start position of the last non-match, or // `npos` if no non-match was found. size_type find_last_not_of(string_view s, - size_type pos = npos) const noexcept; + size_type pos = npos) const noexcept; // Overload of `string_view::find_last_not_of()` for finding a character // that is not `c` within the `string_view`. - size_type find_last_not_of(char c, size_type pos = npos) const noexcept; - - // Overload of `string_view::find_last_not_of()` for finding a substring of a - // different C-style string `s` within the `string_view`. - size_type find_last_not_of(const char* s, size_type pos, - size_type count) const { - return find_last_not_of(string_view(s, count), pos); - } - - // Overload of `string_view::find_last_not_of()` for finding a different - // C-style string `s` within the `string_view`. - size_type find_last_not_of(const char* s, size_type pos = npos) const { - return find_last_not_of(string_view(s), pos); - } - + size_type find_last_not_of(char c, size_type pos = npos) const noexcept; + + // Overload of `string_view::find_last_not_of()` for finding a substring of a + // different C-style string `s` within the `string_view`. + size_type find_last_not_of(const char* s, size_type pos, + size_type count) const { + return find_last_not_of(string_view(s, count), pos); + } + + // Overload of `string_view::find_last_not_of()` for finding a different + // C-style string `s` within the `string_view`. + size_type find_last_not_of(const char* s, size_type pos = npos) const { + return find_last_not_of(string_view(s), pos); + } + private: - // The constructor from std::string delegates to this constructor. - // See the comment on that constructor for the rationale. - struct SkipCheckLengthTag {}; - string_view(const char* data, size_type len, SkipCheckLengthTag) noexcept - : ptr_(data), length_(len) {} - + // The constructor from std::string delegates to this constructor. + // See the comment on that constructor for the rationale. + struct SkipCheckLengthTag {}; + string_view(const char* data, size_type len, SkipCheckLengthTag) noexcept + : ptr_(data), length_(len) {} + static constexpr size_type kMaxSize = (std::numeric_limits<difference_type>::max)(); @@ -679,7 +679,7 @@ std::ostream& operator<<(std::ostream& o, string_view piece); ABSL_NAMESPACE_END } // namespace absl -#undef ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR +#undef ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR #undef ABSL_INTERNAL_STRING_VIEW_MEMCMP #endif // ABSL_USES_STD_STRING_VIEW diff --git a/contrib/restricted/abseil-cpp/absl/strings/substitute.cc b/contrib/restricted/abseil-cpp/absl/strings/substitute.cc index 8980b198c2..a6b911d7a0 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/substitute.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/substitute.cc @@ -75,8 +75,8 @@ void SubstituteAndAppendArray(std::string* output, absl::string_view format, // Build the string. size_t original_size = output->size(); - strings_internal::STLStringResizeUninitializedAmortized(output, - original_size + size); + strings_internal::STLStringResizeUninitializedAmortized(output, + original_size + size); char* target = &(*output)[original_size]; for (size_t i = 0; i < format.size(); i++) { if (format[i] == '$') { diff --git a/contrib/restricted/abseil-cpp/absl/strings/substitute.h b/contrib/restricted/abseil-cpp/absl/strings/substitute.h index 151c56f543..e9aa1588cb 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/substitute.h +++ b/contrib/restricted/abseil-cpp/absl/strings/substitute.h @@ -361,49 +361,49 @@ inline void SubstituteAndAppend( // This body of functions catches cases where the number of placeholders // doesn't match the number of data arguments. void SubstituteAndAppend(std::string* output, const char* format) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 0, - "There were no substitution arguments " - "but this format string either has a $[0-9] in it or contains " - "an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 0, + "There were no substitution arguments " + "but this format string either has a $[0-9] in it or contains " + "an unescaped $ character (use $$ instead)"); void SubstituteAndAppend(std::string* output, const char* format, const substitute_internal::Arg& a0) ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 1, "There was 1 substitution argument given, but " - "this format string is missing its $0, contains " - "one of $1-$9, or contains an unescaped $ character (use " - "$$ instead)"); + "this format string is missing its $0, contains " + "one of $1-$9, or contains an unescaped $ character (use " + "$$ instead)"); void SubstituteAndAppend(std::string* output, const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 3, - "There were 2 substitution arguments given, but this format string is " - "missing its $0/$1, contains one of $2-$9, or contains an " - "unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 3, + "There were 2 substitution arguments given, but this format string is " + "missing its $0/$1, contains one of $2-$9, or contains an " + "unescaped $ character (use $$ instead)"); void SubstituteAndAppend(std::string* output, const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1, const substitute_internal::Arg& a2) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 7, - "There were 3 substitution arguments given, but " - "this format string is missing its $0/$1/$2, contains one of " - "$3-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 7, + "There were 3 substitution arguments given, but " + "this format string is missing its $0/$1/$2, contains one of " + "$3-$9, or contains an unescaped $ character (use $$ instead)"); void SubstituteAndAppend(std::string* output, const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1, const substitute_internal::Arg& a2, const substitute_internal::Arg& a3) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 15, - "There were 4 substitution arguments given, but " - "this format string is missing its $0-$3, contains one of " - "$4-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 15, + "There were 4 substitution arguments given, but " + "this format string is missing its $0-$3, contains one of " + "$4-$9, or contains an unescaped $ character (use $$ instead)"); void SubstituteAndAppend(std::string* output, const char* format, const substitute_internal::Arg& a0, @@ -411,11 +411,11 @@ void SubstituteAndAppend(std::string* output, const char* format, const substitute_internal::Arg& a2, const substitute_internal::Arg& a3, const substitute_internal::Arg& a4) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 31, - "There were 5 substitution arguments given, but " - "this format string is missing its $0-$4, contains one of " - "$5-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 31, + "There were 5 substitution arguments given, but " + "this format string is missing its $0-$4, contains one of " + "$5-$9, or contains an unescaped $ character (use $$ instead)"); void SubstituteAndAppend(std::string* output, const char* format, const substitute_internal::Arg& a0, @@ -424,22 +424,22 @@ void SubstituteAndAppend(std::string* output, const char* format, const substitute_internal::Arg& a3, const substitute_internal::Arg& a4, const substitute_internal::Arg& a5) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 63, - "There were 6 substitution arguments given, but " - "this format string is missing its $0-$5, contains one of " - "$6-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 63, + "There were 6 substitution arguments given, but " + "this format string is missing its $0-$5, contains one of " + "$6-$9, or contains an unescaped $ character (use $$ instead)"); void SubstituteAndAppend( std::string* output, const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1, const substitute_internal::Arg& a2, const substitute_internal::Arg& a3, const substitute_internal::Arg& a4, const substitute_internal::Arg& a5, const substitute_internal::Arg& a6) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 127, - "There were 7 substitution arguments given, but " - "this format string is missing its $0-$6, contains one of " - "$7-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 127, + "There were 7 substitution arguments given, but " + "this format string is missing its $0-$6, contains one of " + "$7-$9, or contains an unescaped $ character (use $$ instead)"); void SubstituteAndAppend( std::string* output, const char* format, const substitute_internal::Arg& a0, @@ -447,11 +447,11 @@ void SubstituteAndAppend( const substitute_internal::Arg& a3, const substitute_internal::Arg& a4, const substitute_internal::Arg& a5, const substitute_internal::Arg& a6, const substitute_internal::Arg& a7) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 255, - "There were 8 substitution arguments given, but " - "this format string is missing its $0-$7, contains one of " - "$8-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 255, + "There were 8 substitution arguments given, but " + "this format string is missing its $0-$7, contains one of " + "$8-$9, or contains an unescaped $ character (use $$ instead)"); void SubstituteAndAppend( std::string* output, const char* format, const substitute_internal::Arg& a0, @@ -462,8 +462,8 @@ void SubstituteAndAppend( ABSL_BAD_CALL_IF( substitute_internal::PlaceholderBitmask(format) != 511, "There were 9 substitution arguments given, but " - "this format string is missing its $0-$8, contains a $9, or " - "contains an unescaped $ character (use $$ instead)"); + "this format string is missing its $0-$8, contains a $9, or " + "contains an unescaped $ character (use $$ instead)"); void SubstituteAndAppend( std::string* output, const char* format, const substitute_internal::Arg& a0, @@ -472,11 +472,11 @@ void SubstituteAndAppend( const substitute_internal::Arg& a5, const substitute_internal::Arg& a6, const substitute_internal::Arg& a7, const substitute_internal::Arg& a8, const substitute_internal::Arg& a9) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 1023, - "There were 10 substitution arguments given, but this " - "format string either doesn't contain all of $0 through $9 or " - "contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 1023, + "There were 10 substitution arguments given, but this " + "format string either doesn't contain all of $0 through $9 or " + "contains an unescaped $ character (use $$ instead)"); #endif // ABSL_BAD_CALL_IF // Substitute() @@ -602,53 +602,53 @@ ABSL_MUST_USE_RESULT inline std::string Substitute( std::string Substitute(const char* format) ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 0, "There were no substitution arguments " - "but this format string either has a $[0-9] in it or " - "contains an unescaped $ character (use $$ instead)"); + "but this format string either has a $[0-9] in it or " + "contains an unescaped $ character (use $$ instead)"); std::string Substitute(const char* format, const substitute_internal::Arg& a0) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 1, - "There was 1 substitution argument given, but " - "this format string is missing its $0, contains one of $1-$9, " - "or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 1, + "There was 1 substitution argument given, but " + "this format string is missing its $0, contains one of $1-$9, " + "or contains an unescaped $ character (use $$ instead)"); std::string Substitute(const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 3, - "There were 2 substitution arguments given, but " - "this format string is missing its $0/$1, contains one of " - "$2-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 3, + "There were 2 substitution arguments given, but " + "this format string is missing its $0/$1, contains one of " + "$2-$9, or contains an unescaped $ character (use $$ instead)"); std::string Substitute(const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1, const substitute_internal::Arg& a2) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 7, - "There were 3 substitution arguments given, but " - "this format string is missing its $0/$1/$2, contains one of " - "$3-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 7, + "There were 3 substitution arguments given, but " + "this format string is missing its $0/$1/$2, contains one of " + "$3-$9, or contains an unescaped $ character (use $$ instead)"); std::string Substitute(const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1, const substitute_internal::Arg& a2, const substitute_internal::Arg& a3) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 15, - "There were 4 substitution arguments given, but " - "this format string is missing its $0-$3, contains one of " - "$4-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 15, + "There were 4 substitution arguments given, but " + "this format string is missing its $0-$3, contains one of " + "$4-$9, or contains an unescaped $ character (use $$ instead)"); std::string Substitute(const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1, const substitute_internal::Arg& a2, const substitute_internal::Arg& a3, const substitute_internal::Arg& a4) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 31, - "There were 5 substitution arguments given, but " - "this format string is missing its $0-$4, contains one of " - "$5-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 31, + "There were 5 substitution arguments given, but " + "this format string is missing its $0-$4, contains one of " + "$5-$9, or contains an unescaped $ character (use $$ instead)"); std::string Substitute(const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1, @@ -656,11 +656,11 @@ std::string Substitute(const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a3, const substitute_internal::Arg& a4, const substitute_internal::Arg& a5) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 63, - "There were 6 substitution arguments given, but " - "this format string is missing its $0-$5, contains one of " - "$6-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 63, + "There were 6 substitution arguments given, but " + "this format string is missing its $0-$5, contains one of " + "$6-$9, or contains an unescaped $ character (use $$ instead)"); std::string Substitute(const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1, @@ -669,11 +669,11 @@ std::string Substitute(const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a4, const substitute_internal::Arg& a5, const substitute_internal::Arg& a6) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 127, - "There were 7 substitution arguments given, but " - "this format string is missing its $0-$6, contains one of " - "$7-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 127, + "There were 7 substitution arguments given, but " + "this format string is missing its $0-$6, contains one of " + "$7-$9, or contains an unescaped $ character (use $$ instead)"); std::string Substitute(const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a1, @@ -683,11 +683,11 @@ std::string Substitute(const char* format, const substitute_internal::Arg& a0, const substitute_internal::Arg& a5, const substitute_internal::Arg& a6, const substitute_internal::Arg& a7) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 255, - "There were 8 substitution arguments given, but " - "this format string is missing its $0-$7, contains one of " - "$8-$9, or contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 255, + "There were 8 substitution arguments given, but " + "this format string is missing its $0-$7, contains one of " + "$8-$9, or contains an unescaped $ character (use $$ instead)"); std::string Substitute( const char* format, const substitute_internal::Arg& a0, @@ -698,8 +698,8 @@ std::string Substitute( ABSL_BAD_CALL_IF( substitute_internal::PlaceholderBitmask(format) != 511, "There were 9 substitution arguments given, but " - "this format string is missing its $0-$8, contains a $9, or " - "contains an unescaped $ character (use $$ instead)"); + "this format string is missing its $0-$8, contains a $9, or " + "contains an unescaped $ character (use $$ instead)"); std::string Substitute( const char* format, const substitute_internal::Arg& a0, @@ -708,11 +708,11 @@ std::string Substitute( const substitute_internal::Arg& a5, const substitute_internal::Arg& a6, const substitute_internal::Arg& a7, const substitute_internal::Arg& a8, const substitute_internal::Arg& a9) - ABSL_BAD_CALL_IF( - substitute_internal::PlaceholderBitmask(format) != 1023, - "There were 10 substitution arguments given, but this " - "format string either doesn't contain all of $0 through $9 or " - "contains an unescaped $ character (use $$ instead)"); + ABSL_BAD_CALL_IF( + substitute_internal::PlaceholderBitmask(format) != 1023, + "There were 10 substitution arguments given, but this " + "format string either doesn't contain all of $0 through $9 or " + "contains an unescaped $ character (use $$ instead)"); #endif // ABSL_BAD_CALL_IF ABSL_NAMESPACE_END diff --git a/contrib/restricted/abseil-cpp/absl/strings/ya.make b/contrib/restricted/abseil-cpp/absl/strings/ya.make index bc11193f12..d0cb0df637 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/ya.make +++ b/contrib/restricted/abseil-cpp/absl/strings/ya.make @@ -12,10 +12,10 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/base contrib/restricted/abseil-cpp/absl/base/internal/raw_logging contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait - contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate + contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/numeric - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/numeric + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal ) ADDINCL( @@ -31,19 +31,19 @@ CFLAGS( ) SRCS( - ascii.cc - charconv.cc + ascii.cc + charconv.cc escaping.cc - internal/charconv_bigint.cc - internal/charconv_parse.cc - internal/memutil.cc - match.cc - numbers.cc - str_cat.cc - str_replace.cc - str_split.cc - string_view.cc - substitute.cc + internal/charconv_bigint.cc + internal/charconv_parse.cc + internal/memutil.cc + match.cc + numbers.cc + str_cat.cc + str_replace.cc + str_split.cc + string_view.cc + substitute.cc ) END() diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.cc b/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.cc index d2f82da3bb..cd660b3f0c 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.cc +++ b/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.cc @@ -14,37 +14,37 @@ #include "absl/synchronization/blocking_counter.h" -#include <atomic> - +#include <atomic> + #include "absl/base/internal/raw_logging.h" namespace absl { ABSL_NAMESPACE_BEGIN -namespace { - -// Return whether int *arg is true. -bool IsDone(void *arg) { return *reinterpret_cast<bool *>(arg); } - -} // namespace - -BlockingCounter::BlockingCounter(int initial_count) - : count_(initial_count), - num_waiting_(0), - done_{initial_count == 0 ? true : false} { - ABSL_RAW_CHECK(initial_count >= 0, "BlockingCounter initial_count negative"); +namespace { + +// Return whether int *arg is true. +bool IsDone(void *arg) { return *reinterpret_cast<bool *>(arg); } + +} // namespace + +BlockingCounter::BlockingCounter(int initial_count) + : count_(initial_count), + num_waiting_(0), + done_{initial_count == 0 ? true : false} { + ABSL_RAW_CHECK(initial_count >= 0, "BlockingCounter initial_count negative"); } bool BlockingCounter::DecrementCount() { - int count = count_.fetch_sub(1, std::memory_order_acq_rel) - 1; - ABSL_RAW_CHECK(count >= 0, - "BlockingCounter::DecrementCount() called too many times"); - if (count == 0) { - MutexLock l(&lock_); - done_ = true; - return true; + int count = count_.fetch_sub(1, std::memory_order_acq_rel) - 1; + ABSL_RAW_CHECK(count >= 0, + "BlockingCounter::DecrementCount() called too many times"); + if (count == 0) { + MutexLock l(&lock_); + done_ = true; + return true; } - return false; + return false; } void BlockingCounter::Wait() { @@ -55,10 +55,10 @@ void BlockingCounter::Wait() { ABSL_RAW_CHECK(num_waiting_ == 0, "multiple threads called Wait()"); num_waiting_++; - this->lock_.Await(Condition(IsDone, &this->done_)); + this->lock_.Await(Condition(IsDone, &this->done_)); - // At this point, we know that all threads executing DecrementCount - // will not touch this object again. + // At this point, we know that all threads executing DecrementCount + // will not touch this object again. // Therefore, the thread calling this method is free to delete the object // after we return from this method. } diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.h b/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.h index 1908fdb1d9..24d08c3a7b 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.h +++ b/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.h @@ -20,8 +20,8 @@ #ifndef ABSL_SYNCHRONIZATION_BLOCKING_COUNTER_H_ #define ABSL_SYNCHRONIZATION_BLOCKING_COUNTER_H_ -#include <atomic> - +#include <atomic> + #include "absl/base/thread_annotations.h" #include "absl/synchronization/mutex.h" @@ -62,7 +62,7 @@ ABSL_NAMESPACE_BEGIN // class BlockingCounter { public: - explicit BlockingCounter(int initial_count); + explicit BlockingCounter(int initial_count); BlockingCounter(const BlockingCounter&) = delete; BlockingCounter& operator=(const BlockingCounter&) = delete; @@ -90,9 +90,9 @@ class BlockingCounter { private: Mutex lock_; - std::atomic<int> count_; + std::atomic<int> count_; int num_waiting_ ABSL_GUARDED_BY(lock_); - bool done_ ABSL_GUARDED_BY(lock_); + bool done_ ABSL_GUARDED_BY(lock_); }; ABSL_NAMESPACE_END diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/internal/waiter.cc b/contrib/restricted/abseil-cpp/absl/synchronization/internal/waiter.cc index 28ef311e4a..d2ccde48b6 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/internal/waiter.cc +++ b/contrib/restricted/abseil-cpp/absl/synchronization/internal/waiter.cc @@ -79,7 +79,7 @@ bool Waiter::Wait(KernelTimeout t) { // Note that, since the thread ticker is just reset, we don't need to check // whether the thread is idle on the very first pass of the loop. bool first_pass = true; - + while (true) { int32_t x = futex_.load(std::memory_order_relaxed); while (x != 0) { diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/mutex.h b/contrib/restricted/abseil-cpp/absl/synchronization/mutex.h index 38338f24df..23685360b2 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/mutex.h +++ b/contrib/restricted/abseil-cpp/absl/synchronization/mutex.h @@ -778,9 +778,9 @@ class Condition { // // Usage to wake T is: // mu.Lock(); -// // process data, possibly establishing C -// if (C) { cv->Signal(); } -// mu.Unlock(); +// // process data, possibly establishing C +// if (C) { cv->Signal(); } +// mu.Unlock(); // // If C may be useful to more than one waiter, use `SignalAll()` instead of // `Signal()`. diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/ya.make b/contrib/restricted/abseil-cpp/absl/synchronization/ya.make index 06f72b69e9..f05dc9b8da 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/ya.make +++ b/contrib/restricted/abseil-cpp/absl/synchronization/ya.make @@ -21,7 +21,7 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/demangle contrib/restricted/abseil-cpp/absl/numeric contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal contrib/restricted/abseil-cpp/absl/synchronization/internal contrib/restricted/abseil-cpp/absl/time contrib/restricted/abseil-cpp/absl/time/civil_time diff --git a/contrib/restricted/abseil-cpp/absl/time/civil_time.cc b/contrib/restricted/abseil-cpp/absl/time/civil_time.cc index 6a231edb2d..ab34f117fa 100644 --- a/contrib/restricted/abseil-cpp/absl/time/civil_time.cc +++ b/contrib/restricted/abseil-cpp/absl/time/civil_time.cc @@ -38,7 +38,7 @@ std::string FormatYearAnd(string_view fmt, CivilSecond cs) { const CivilSecond ncs(NormalizeYear(cs.year()), cs.month(), cs.day(), cs.hour(), cs.minute(), cs.second()); const TimeZone utc = UTCTimeZone(); - return StrCat(cs.year(), FormatTime(fmt, FromCivil(ncs, utc), utc)); + return StrCat(cs.year(), FormatTime(fmt, FromCivil(ncs, utc), utc)); } template <typename CivilT> diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h index 6e382dc6c9..21cbf8574c 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h @@ -22,7 +22,7 @@ #include <chrono> #include <cstdint> -#include <limits> +#include <limits> #include <string> #include <utility> @@ -42,9 +42,9 @@ using sys_seconds = seconds; // Deprecated. Use cctz::seconds instead. namespace detail { template <typename D> -std::pair<time_point<seconds>, D> split_seconds(const time_point<D>& tp); -std::pair<time_point<seconds>, seconds> split_seconds( - const time_point<seconds>& tp); +std::pair<time_point<seconds>, D> split_seconds(const time_point<D>& tp); +std::pair<time_point<seconds>, seconds> split_seconds( + const time_point<seconds>& tp); } // namespace detail // cctz::time_zone is an opaque, small, value-type class representing a @@ -269,20 +269,20 @@ std::string format(const std::string&, const time_point<seconds>&, const femtoseconds&, const time_zone&); bool parse(const std::string&, const std::string&, const time_zone&, time_point<seconds>*, femtoseconds*, std::string* err = nullptr); -template <typename Rep, std::intmax_t Denom> -bool join_seconds( - const time_point<seconds>& sec, const femtoseconds& fs, - time_point<std::chrono::duration<Rep, std::ratio<1, Denom>>>* tpp); -template <typename Rep, std::intmax_t Num> -bool join_seconds( - const time_point<seconds>& sec, const femtoseconds& fs, - time_point<std::chrono::duration<Rep, std::ratio<Num, 1>>>* tpp); -template <typename Rep> -bool join_seconds( - const time_point<seconds>& sec, const femtoseconds& fs, - time_point<std::chrono::duration<Rep, std::ratio<1, 1>>>* tpp); -bool join_seconds(const time_point<seconds>& sec, const femtoseconds&, - time_point<seconds>* tpp); +template <typename Rep, std::intmax_t Denom> +bool join_seconds( + const time_point<seconds>& sec, const femtoseconds& fs, + time_point<std::chrono::duration<Rep, std::ratio<1, Denom>>>* tpp); +template <typename Rep, std::intmax_t Num> +bool join_seconds( + const time_point<seconds>& sec, const femtoseconds& fs, + time_point<std::chrono::duration<Rep, std::ratio<Num, 1>>>* tpp); +template <typename Rep> +bool join_seconds( + const time_point<seconds>& sec, const femtoseconds& fs, + time_point<std::chrono::duration<Rep, std::ratio<1, 1>>>* tpp); +bool join_seconds(const time_point<seconds>& sec, const femtoseconds&, + time_point<seconds>* tpp); } // namespace detail // Formats the given time_point in the given cctz::time_zone according to @@ -373,84 +373,84 @@ inline bool parse(const std::string& fmt, const std::string& input, const time_zone& tz, time_point<D>* tpp) { time_point<seconds> sec; detail::femtoseconds fs; - return detail::parse(fmt, input, tz, &sec, &fs) && - detail::join_seconds(sec, fs, tpp); -} - -namespace detail { - -// Split a time_point<D> into a time_point<seconds> and a D subseconds. -// Undefined behavior if time_point<seconds> is not of sufficient range. -// Note that this means it is UB to call cctz::time_zone::lookup(tp) or -// cctz::format(fmt, tp, tz) with a time_point that is outside the range -// of a 64-bit std::time_t. -template <typename D> -std::pair<time_point<seconds>, D> split_seconds(const time_point<D>& tp) { - auto sec = std::chrono::time_point_cast<seconds>(tp); - auto sub = tp - sec; - if (sub.count() < 0) { - sec -= seconds(1); - sub += seconds(1); + return detail::parse(fmt, input, tz, &sec, &fs) && + detail::join_seconds(sec, fs, tpp); +} + +namespace detail { + +// Split a time_point<D> into a time_point<seconds> and a D subseconds. +// Undefined behavior if time_point<seconds> is not of sufficient range. +// Note that this means it is UB to call cctz::time_zone::lookup(tp) or +// cctz::format(fmt, tp, tz) with a time_point that is outside the range +// of a 64-bit std::time_t. +template <typename D> +std::pair<time_point<seconds>, D> split_seconds(const time_point<D>& tp) { + auto sec = std::chrono::time_point_cast<seconds>(tp); + auto sub = tp - sec; + if (sub.count() < 0) { + sec -= seconds(1); + sub += seconds(1); } - return {sec, std::chrono::duration_cast<D>(sub)}; -} - -inline std::pair<time_point<seconds>, seconds> split_seconds( - const time_point<seconds>& tp) { - return {tp, seconds::zero()}; -} - -// Join a time_point<seconds> and femto subseconds into a time_point<D>. -// Floors to the resolution of time_point<D>. Returns false if time_point<D> -// is not of sufficient range. -template <typename Rep, std::intmax_t Denom> -bool join_seconds( - const time_point<seconds>& sec, const femtoseconds& fs, - time_point<std::chrono::duration<Rep, std::ratio<1, Denom>>>* tpp) { - using D = std::chrono::duration<Rep, std::ratio<1, Denom>>; - // TODO(#199): Return false if result unrepresentable as a time_point<D>. - *tpp = std::chrono::time_point_cast<D>(sec); - *tpp += std::chrono::duration_cast<D>(fs); - return true; + return {sec, std::chrono::duration_cast<D>(sub)}; } -template <typename Rep, std::intmax_t Num> -bool join_seconds( - const time_point<seconds>& sec, const femtoseconds&, - time_point<std::chrono::duration<Rep, std::ratio<Num, 1>>>* tpp) { - using D = std::chrono::duration<Rep, std::ratio<Num, 1>>; - auto count = sec.time_since_epoch().count(); - if (count >= 0 || count % Num == 0) { - count /= Num; - } else { - count /= Num; - count -= 1; - } - if (count > (std::numeric_limits<Rep>::max)()) return false; - if (count < (std::numeric_limits<Rep>::min)()) return false; - *tpp = time_point<D>() + D{static_cast<Rep>(count)}; - return true; -} - -template <typename Rep> -bool join_seconds( - const time_point<seconds>& sec, const femtoseconds&, - time_point<std::chrono::duration<Rep, std::ratio<1, 1>>>* tpp) { - using D = std::chrono::duration<Rep, std::ratio<1, 1>>; - auto count = sec.time_since_epoch().count(); - if (count > (std::numeric_limits<Rep>::max)()) return false; - if (count < (std::numeric_limits<Rep>::min)()) return false; - *tpp = time_point<D>() + D{static_cast<Rep>(count)}; - return true; -} - -inline bool join_seconds(const time_point<seconds>& sec, const femtoseconds&, - time_point<seconds>* tpp) { - *tpp = sec; - return true; -} - -} // namespace detail +inline std::pair<time_point<seconds>, seconds> split_seconds( + const time_point<seconds>& tp) { + return {tp, seconds::zero()}; +} + +// Join a time_point<seconds> and femto subseconds into a time_point<D>. +// Floors to the resolution of time_point<D>. Returns false if time_point<D> +// is not of sufficient range. +template <typename Rep, std::intmax_t Denom> +bool join_seconds( + const time_point<seconds>& sec, const femtoseconds& fs, + time_point<std::chrono::duration<Rep, std::ratio<1, Denom>>>* tpp) { + using D = std::chrono::duration<Rep, std::ratio<1, Denom>>; + // TODO(#199): Return false if result unrepresentable as a time_point<D>. + *tpp = std::chrono::time_point_cast<D>(sec); + *tpp += std::chrono::duration_cast<D>(fs); + return true; +} + +template <typename Rep, std::intmax_t Num> +bool join_seconds( + const time_point<seconds>& sec, const femtoseconds&, + time_point<std::chrono::duration<Rep, std::ratio<Num, 1>>>* tpp) { + using D = std::chrono::duration<Rep, std::ratio<Num, 1>>; + auto count = sec.time_since_epoch().count(); + if (count >= 0 || count % Num == 0) { + count /= Num; + } else { + count /= Num; + count -= 1; + } + if (count > (std::numeric_limits<Rep>::max)()) return false; + if (count < (std::numeric_limits<Rep>::min)()) return false; + *tpp = time_point<D>() + D{static_cast<Rep>(count)}; + return true; +} + +template <typename Rep> +bool join_seconds( + const time_point<seconds>& sec, const femtoseconds&, + time_point<std::chrono::duration<Rep, std::ratio<1, 1>>>* tpp) { + using D = std::chrono::duration<Rep, std::ratio<1, 1>>; + auto count = sec.time_since_epoch().count(); + if (count > (std::numeric_limits<Rep>::max)()) return false; + if (count < (std::numeric_limits<Rep>::min)()) return false; + *tpp = time_point<D>() + D{static_cast<Rep>(count)}; + return true; +} + +inline bool join_seconds(const time_point<seconds>& sec, const femtoseconds&, + time_point<seconds>* tpp) { + *tpp = sec; + return true; +} + +} // namespace detail } // namespace cctz } // namespace time_internal ABSL_NAMESPACE_END diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc index f2b3294ef7..a067fe5621 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc @@ -53,7 +53,7 @@ int Parse02d(const char* p) { } // namespace bool FixedOffsetFromName(const std::string& name, seconds* offset) { - if (name == "UTC" || name == "UTC0") { + if (name == "UTC" || name == "UTC0") { *offset = seconds::zero(); return true; } diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.h b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.h index 7d3e42d3cd..20e753a147 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.h +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.h @@ -56,8 +56,8 @@ class TimeZoneIf { // Convert between time_point<seconds> and a count of seconds since the // Unix epoch. We assume that the std::chrono::system_clock and the -// Unix clock are second aligned, and that the results are representable. -// (That is, that they share an epoch, which is required since C++20.) +// Unix clock are second aligned, and that the results are representable. +// (That is, that they share an epoch, which is required since C++20.) inline std::int_fast64_t ToUnixSeconds(const time_point<seconds>& tp) { return (tp - std::chrono::time_point_cast<seconds>( std::chrono::system_clock::from_time_t(0))) diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc index 4f175d95fc..04ab1dd70f 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc @@ -39,12 +39,12 @@ #include <cstdio> #include <cstdlib> #include <cstring> -#include <fstream> +#include <fstream> #include <functional> #include <memory> #include <sstream> #include <string> -#include <utility> +#include <utility> #include "absl/base/config.h" #include "absl/time/internal/cctz/include/cctz/civil_time.h" @@ -578,17 +578,17 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) { namespace { -using FilePtr = std::unique_ptr<FILE, int (*)(FILE*)>; - +using FilePtr = std::unique_ptr<FILE, int (*)(FILE*)>; + // fopen(3) adaptor. -inline FilePtr FOpen(const char* path, const char* mode) { +inline FilePtr FOpen(const char* path, const char* mode) { #if defined(_MSC_VER) FILE* fp; if (fopen_s(&fp, path, mode) != 0) fp = nullptr; - return FilePtr(fp, fclose); + return FilePtr(fp, fclose); #else - // TODO: Enable the close-on-exec flag. - return FilePtr(fopen(path, mode), fclose); + // TODO: Enable the close-on-exec flag. + return FilePtr(fopen(path, mode), fclose); #endif } @@ -616,11 +616,11 @@ class FileZoneInfoSource : public ZoneInfoSource { protected: explicit FileZoneInfoSource( - FilePtr fp, std::size_t len = std::numeric_limits<std::size_t>::max()) - : fp_(std::move(fp)), len_(len) {} + FilePtr fp, std::size_t len = std::numeric_limits<std::size_t>::max()) + : fp_(std::move(fp)), len_(len) {} private: - FilePtr fp_; + FilePtr fp_; std::size_t len_; }; @@ -649,9 +649,9 @@ std::unique_ptr<ZoneInfoSource> FileZoneInfoSource::Open( path.append(name, pos, std::string::npos); // Open the zoneinfo file. - auto fp = FOpen(path.c_str(), "rb"); + auto fp = FOpen(path.c_str(), "rb"); if (fp == nullptr) return nullptr; - return std::unique_ptr<ZoneInfoSource>(new FileZoneInfoSource(std::move(fp))); + return std::unique_ptr<ZoneInfoSource>(new FileZoneInfoSource(std::move(fp))); } class AndroidZoneInfoSource : public FileZoneInfoSource { @@ -660,9 +660,9 @@ class AndroidZoneInfoSource : public FileZoneInfoSource { std::string Version() const override { return version_; } private: - explicit AndroidZoneInfoSource(FilePtr fp, std::size_t len, - std::string version) - : FileZoneInfoSource(std::move(fp), len), version_(std::move(version)) {} + explicit AndroidZoneInfoSource(FilePtr fp, std::size_t len, + std::string version) + : FileZoneInfoSource(std::move(fp), len), version_(std::move(version)) {} std::string version_; }; @@ -674,8 +674,8 @@ std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open( // See Android's libc/tzcode/bionic.cpp for additional information. for (const char* tzdata : {"/data/misc/zoneinfo/current/tzdata", "/system/usr/share/zoneinfo/tzdata"}) { - auto fp = FOpen(tzdata, "rb"); - if (fp == nullptr) continue; + auto fp = FOpen(tzdata, "rb"); + if (fp == nullptr) continue; char hbuf[24]; // covers header.zonetab_offset too if (fread(hbuf, 1, sizeof(hbuf), fp.get()) != sizeof(hbuf)) continue; @@ -701,7 +701,7 @@ std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open( if (strcmp(name.c_str() + pos, ebuf) == 0) { if (fseek(fp.get(), static_cast<long>(start), SEEK_SET) != 0) break; return std::unique_ptr<ZoneInfoSource>(new AndroidZoneInfoSource( - std::move(fp), static_cast<std::size_t>(length), vers)); + std::move(fp), static_cast<std::size_t>(length), vers)); } } } @@ -709,69 +709,69 @@ std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open( return nullptr; } -// A zoneinfo source for use inside Fuchsia components. This attempts to -// read zoneinfo files from one of several known paths in a component's -// incoming namespace. [Config data][1] is preferred, but package-specific -// resources are also supported. -// -// Fuchsia's implementation supports `FileZoneInfoSource::Version()`. -// -// [1]: -// https://fuchsia.dev/fuchsia-src/development/components/data#using_config_data_in_your_component -class FuchsiaZoneInfoSource : public FileZoneInfoSource { - public: - static std::unique_ptr<ZoneInfoSource> Open(const std::string& name); - std::string Version() const override { return version_; } - - private: - explicit FuchsiaZoneInfoSource(FilePtr fp, std::string version) - : FileZoneInfoSource(std::move(fp)), version_(std::move(version)) {} - std::string version_; -}; - -std::unique_ptr<ZoneInfoSource> FuchsiaZoneInfoSource::Open( - const std::string& name) { - // Use of the "file:" prefix is intended for testing purposes only. - const std::size_t pos = (name.compare(0, 5, "file:") == 0) ? 5 : 0; - - // Prefixes where a Fuchsia component might find zoneinfo files, - // in descending order of preference. - const auto kTzdataPrefixes = { - "/config/data/tzdata/", - "/pkg/data/tzdata/", - "/data/tzdata/", - }; - const auto kEmptyPrefix = {""}; - const bool name_absolute = (pos != name.size() && name[pos] == '/'); - const auto prefixes = name_absolute ? kEmptyPrefix : kTzdataPrefixes; - - // Fuchsia builds place zoneinfo files at "<prefix><format><name>". - for (const std::string prefix : prefixes) { - std::string path = prefix; - if (!prefix.empty()) path += "zoneinfo/tzif2/"; // format - path.append(name, pos, std::string::npos); - - auto fp = FOpen(path.c_str(), "rb"); - if (fp == nullptr) continue; - - std::string version; - if (!prefix.empty()) { - // Fuchsia builds place the version in "<prefix>revision.txt". - std::ifstream version_stream(prefix + "revision.txt"); - if (version_stream.is_open()) { - // revision.txt should contain no newlines, but to be - // defensive we read just the first line. - std::getline(version_stream, version); - } - } - - return std::unique_ptr<ZoneInfoSource>( - new FuchsiaZoneInfoSource(std::move(fp), std::move(version))); - } - - return nullptr; -} - +// A zoneinfo source for use inside Fuchsia components. This attempts to +// read zoneinfo files from one of several known paths in a component's +// incoming namespace. [Config data][1] is preferred, but package-specific +// resources are also supported. +// +// Fuchsia's implementation supports `FileZoneInfoSource::Version()`. +// +// [1]: +// https://fuchsia.dev/fuchsia-src/development/components/data#using_config_data_in_your_component +class FuchsiaZoneInfoSource : public FileZoneInfoSource { + public: + static std::unique_ptr<ZoneInfoSource> Open(const std::string& name); + std::string Version() const override { return version_; } + + private: + explicit FuchsiaZoneInfoSource(FilePtr fp, std::string version) + : FileZoneInfoSource(std::move(fp)), version_(std::move(version)) {} + std::string version_; +}; + +std::unique_ptr<ZoneInfoSource> FuchsiaZoneInfoSource::Open( + const std::string& name) { + // Use of the "file:" prefix is intended for testing purposes only. + const std::size_t pos = (name.compare(0, 5, "file:") == 0) ? 5 : 0; + + // Prefixes where a Fuchsia component might find zoneinfo files, + // in descending order of preference. + const auto kTzdataPrefixes = { + "/config/data/tzdata/", + "/pkg/data/tzdata/", + "/data/tzdata/", + }; + const auto kEmptyPrefix = {""}; + const bool name_absolute = (pos != name.size() && name[pos] == '/'); + const auto prefixes = name_absolute ? kEmptyPrefix : kTzdataPrefixes; + + // Fuchsia builds place zoneinfo files at "<prefix><format><name>". + for (const std::string prefix : prefixes) { + std::string path = prefix; + if (!prefix.empty()) path += "zoneinfo/tzif2/"; // format + path.append(name, pos, std::string::npos); + + auto fp = FOpen(path.c_str(), "rb"); + if (fp == nullptr) continue; + + std::string version; + if (!prefix.empty()) { + // Fuchsia builds place the version in "<prefix>revision.txt". + std::ifstream version_stream(prefix + "revision.txt"); + if (version_stream.is_open()) { + // revision.txt should contain no newlines, but to be + // defensive we read just the first line. + std::getline(version_stream, version); + } + } + + return std::unique_ptr<ZoneInfoSource>( + new FuchsiaZoneInfoSource(std::move(fp), std::move(version))); + } + + return nullptr; +} + } // namespace bool TimeZoneInfo::Load(const std::string& name) { @@ -789,7 +789,7 @@ bool TimeZoneInfo::Load(const std::string& name) { name, [](const std::string& n) -> std::unique_ptr<ZoneInfoSource> { if (auto z = FileZoneInfoSource::Open(n)) return z; if (auto z = AndroidZoneInfoSource::Open(n)) return z; - if (auto z = FuchsiaZoneInfoSource::Open(n)) return z; + if (auto z = FuchsiaZoneInfoSource::Open(n)) return z; return nullptr; }); return zip != nullptr && Load(zip.get()); diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc index 55843c5e5b..a15554fac5 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc @@ -28,13 +28,13 @@ #include <vector> #endif -#if defined(__Fuchsia__) -#error #include <fuchsia/intl/cpp/fidl.h> -#error #include <lib/async-loop/cpp/loop.h> -#error #include <lib/sys/cpp/component_context.h> -#error #include <zircon/types.h> -#endif - +#if defined(__Fuchsia__) +#error #include <fuchsia/intl/cpp/fidl.h> +#error #include <lib/async-loop/cpp/loop.h> +#error #include <lib/sys/cpp/component_context.h> +#error #include <zircon/types.h> +#endif + #include <cstdlib> #include <cstring> #include <string> @@ -147,49 +147,49 @@ time_zone local_time_zone() { } CFRelease(tz_default); #endif -#if defined(__Fuchsia__) - std::string primary_tz; - [&]() { - // Note: We can't use the synchronous FIDL API here because it doesn't - // allow timeouts; if the FIDL call failed, local_time_zone() would never - // return. - - const zx::duration kTimeout = zx::msec(500); - - // Don't attach to the thread because otherwise the thread's dispatcher - // would be set to null when the loop is destroyed, causing any other FIDL - // code running on the same thread to crash. - async::Loop loop(&kAsyncLoopConfigNeverAttachToThread); - std::unique_ptr<sys::ComponentContext> context = - sys::ComponentContext::Create(); - - fuchsia::intl::PropertyProviderHandle handle; - zx_status_t status = context->svc()->Connect(handle.NewRequest()); - if (status != ZX_OK) { - return; - } - - fuchsia::intl::PropertyProviderPtr intl_provider; - status = intl_provider.Bind(std::move(handle), loop.dispatcher()); - if (status != ZX_OK) { - return; - } - - intl_provider->GetProfile( - [&loop, &primary_tz](fuchsia::intl::Profile profile) { - if (!profile.time_zones().empty()) { - primary_tz = profile.time_zones()[0].id; - } - loop.Quit(); - }); - loop.Run(zx::deadline_after(kTimeout)); - }(); - - if (!primary_tz.empty()) { - zone = primary_tz.c_str(); - } -#endif - +#if defined(__Fuchsia__) + std::string primary_tz; + [&]() { + // Note: We can't use the synchronous FIDL API here because it doesn't + // allow timeouts; if the FIDL call failed, local_time_zone() would never + // return. + + const zx::duration kTimeout = zx::msec(500); + + // Don't attach to the thread because otherwise the thread's dispatcher + // would be set to null when the loop is destroyed, causing any other FIDL + // code running on the same thread to crash. + async::Loop loop(&kAsyncLoopConfigNeverAttachToThread); + std::unique_ptr<sys::ComponentContext> context = + sys::ComponentContext::Create(); + + fuchsia::intl::PropertyProviderHandle handle; + zx_status_t status = context->svc()->Connect(handle.NewRequest()); + if (status != ZX_OK) { + return; + } + + fuchsia::intl::PropertyProviderPtr intl_provider; + status = intl_provider.Bind(std::move(handle), loop.dispatcher()); + if (status != ZX_OK) { + return; + } + + intl_provider->GetProfile( + [&loop, &primary_tz](fuchsia::intl::Profile profile) { + if (!profile.time_zones().empty()) { + primary_tz = profile.time_zones()[0].id; + } + loop.Quit(); + }); + loop.Run(zx::deadline_after(kTimeout)); + }(); + + if (!primary_tz.empty()) { + zone = primary_tz.c_str(); + } +#endif + // Allow ${TZ} to override to default zone. char* tz_env = nullptr; #if defined(_MSC_VER) diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/tzfile.h b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/tzfile.h index 31e8598257..88f5b477dc 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/tzfile.h +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/tzfile.h @@ -43,7 +43,7 @@ struct tzhead { char tzh_magic[4]; /* TZ_MAGIC */ - char tzh_version[1]; /* '\0' or '2'-'4' as of 2021 */ + char tzh_version[1]; /* '\0' or '2'-'4' as of 2021 */ char tzh_reserved[15]; /* reserved; must be zero */ char tzh_ttisutcnt[4]; /* coded number of trans. time flags */ char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc index 5ab5a59ecf..4813160630 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc @@ -65,7 +65,7 @@ ZoneInfoSourceFactory zone_info_source_factory __attribute__((weak)) = extern ZoneInfoSourceFactory zone_info_source_factory; extern ZoneInfoSourceFactory default_factory; ZoneInfoSourceFactory default_factory = DefaultFactory; -#if defined(_M_IX86) || defined(_M_ARM) +#if defined(_M_IX86) || defined(_M_ARM) #pragma comment( \ linker, \ "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@" ABSL_INTERNAL_MANGLED_NS \ @@ -83,7 +83,7 @@ ZoneInfoSourceFactory default_factory = DefaultFactory; "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ "@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ "@@ZA") -#elif defined(_M_IA_64) || defined(_M_AMD64) || defined(_M_ARM64) +#elif defined(_M_IA_64) || defined(_M_AMD64) || defined(_M_ARM64) #pragma comment( \ linker, \ "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@" ABSL_INTERNAL_MANGLED_NS \ diff --git a/contrib/restricted/abseil-cpp/absl/time/time.h b/contrib/restricted/abseil-cpp/absl/time/time.h index 5abd815a79..ec18030cfe 100644 --- a/contrib/restricted/abseil-cpp/absl/time/time.h +++ b/contrib/restricted/abseil-cpp/absl/time/time.h @@ -182,30 +182,30 @@ class Duration { // Overloads that forward to either the int64_t or double overloads above. // Integer operands must be representable as int64_t. - template <typename T, time_internal::EnableIfIntegral<T> = 0> + template <typename T, time_internal::EnableIfIntegral<T> = 0> Duration& operator*=(T r) { int64_t x = r; return *this *= x; } - - template <typename T, time_internal::EnableIfIntegral<T> = 0> + + template <typename T, time_internal::EnableIfIntegral<T> = 0> Duration& operator/=(T r) { int64_t x = r; return *this /= x; } - template <typename T, time_internal::EnableIfFloat<T> = 0> - Duration& operator*=(T r) { - double x = r; - return *this *= x; - } - - template <typename T, time_internal::EnableIfFloat<T> = 0> - Duration& operator/=(T r) { - double x = r; - return *this /= x; - } - + template <typename T, time_internal::EnableIfFloat<T> = 0> + Duration& operator*=(T r) { + double x = r; + return *this *= x; + } + + template <typename T, time_internal::EnableIfFloat<T> = 0> + Duration& operator/=(T r) { + double x = r; + return *this /= x; + } + template <typename H> friend H AbslHashValue(H h, Duration d) { return H::combine(std::move(h), d.rep_hi_, d.rep_lo_); @@ -403,30 +403,30 @@ constexpr Duration InfiniteDuration(); // // absl::Duration a = absl::Seconds(60); // absl::Duration b = absl::Minutes(1); // b == a -template <typename T, time_internal::EnableIfIntegral<T> = 0> -constexpr Duration Nanoseconds(T n) { - return time_internal::FromInt64(n, std::nano{}); -} -template <typename T, time_internal::EnableIfIntegral<T> = 0> -constexpr Duration Microseconds(T n) { - return time_internal::FromInt64(n, std::micro{}); -} -template <typename T, time_internal::EnableIfIntegral<T> = 0> -constexpr Duration Milliseconds(T n) { - return time_internal::FromInt64(n, std::milli{}); -} -template <typename T, time_internal::EnableIfIntegral<T> = 0> -constexpr Duration Seconds(T n) { - return time_internal::FromInt64(n, std::ratio<1>{}); -} -template <typename T, time_internal::EnableIfIntegral<T> = 0> -constexpr Duration Minutes(T n) { - return time_internal::FromInt64(n, std::ratio<60>{}); -} -template <typename T, time_internal::EnableIfIntegral<T> = 0> -constexpr Duration Hours(T n) { - return time_internal::FromInt64(n, std::ratio<3600>{}); -} +template <typename T, time_internal::EnableIfIntegral<T> = 0> +constexpr Duration Nanoseconds(T n) { + return time_internal::FromInt64(n, std::nano{}); +} +template <typename T, time_internal::EnableIfIntegral<T> = 0> +constexpr Duration Microseconds(T n) { + return time_internal::FromInt64(n, std::micro{}); +} +template <typename T, time_internal::EnableIfIntegral<T> = 0> +constexpr Duration Milliseconds(T n) { + return time_internal::FromInt64(n, std::milli{}); +} +template <typename T, time_internal::EnableIfIntegral<T> = 0> +constexpr Duration Seconds(T n) { + return time_internal::FromInt64(n, std::ratio<1>{}); +} +template <typename T, time_internal::EnableIfIntegral<T> = 0> +constexpr Duration Minutes(T n) { + return time_internal::FromInt64(n, std::ratio<60>{}); +} +template <typename T, time_internal::EnableIfIntegral<T> = 0> +constexpr Duration Hours(T n) { + return time_internal::FromInt64(n, std::ratio<3600>{}); +} // Factory overloads for constructing `Duration` values from a floating-point // number of the unit indicated by the factory function's name. These functions @@ -480,9 +480,9 @@ Duration Hours(T n) { // ToInt64Hours() // // Helper functions that convert a Duration to an integral count of the -// indicated unit. These return the same results as the `IDivDuration()` -// function, though they usually do so more efficiently; see the -// documentation of `IDivDuration()` for details about overflow, etc. +// indicated unit. These return the same results as the `IDivDuration()` +// function, though they usually do so more efficiently; see the +// documentation of `IDivDuration()` for details about overflow, etc. // // Example: // @@ -577,20 +577,20 @@ inline std::ostream& operator<<(std::ostream& os, Duration d) { // `ZeroDuration()`. Parses "inf" and "-inf" as +/- `InfiniteDuration()`. bool ParseDuration(absl::string_view dur_string, Duration* d); -// AbslParseFlag() -// -// Parses a command-line flag string representation `text` into a a Duration -// value. Duration flags must be specified in a format that is valid input for -// `absl::ParseDuration()`. +// AbslParseFlag() +// +// Parses a command-line flag string representation `text` into a a Duration +// value. Duration flags must be specified in a format that is valid input for +// `absl::ParseDuration()`. bool AbslParseFlag(absl::string_view text, Duration* dst, std::string* error); - - -// AbslUnparseFlag() -// -// Unparses a Duration value into a command-line string representation using -// the format specified by `absl::ParseDuration()`. + + +// AbslUnparseFlag() +// +// Unparses a Duration value into a command-line string representation using +// the format specified by `absl::ParseDuration()`. std::string AbslUnparseFlag(Duration d); - + ABSL_DEPRECATED("Use AbslParseFlag() instead.") bool ParseFlag(const std::string& text, Duration* dst, std::string* error); ABSL_DEPRECATED("Use AbslUnparseFlag() instead.") @@ -853,13 +853,13 @@ Time FromChrono(const std::chrono::system_clock::time_point& tp); // // tp == std::chrono::system_clock::from_time_t(123); std::chrono::system_clock::time_point ToChronoTime(Time); -// AbslParseFlag() -// -// Parses the command-line flag string representation `text` into a Time value. -// Time flags must be specified in a format that matches absl::RFC3339_full. -// -// For example: +// AbslParseFlag() // +// Parses the command-line flag string representation `text` into a Time value. +// Time flags must be specified in a format that matches absl::RFC3339_full. +// +// For example: +// // --start_time=2016-01-02T03:04:05.678+08:00 // // Note: A UTC offset (or 'Z' indicating a zero-offset from UTC) is required. @@ -868,13 +868,13 @@ std::chrono::system_clock::time_point ToChronoTime(Time); // seconds/milliseconds/etc from the Unix epoch, use an absl::Duration flag // and add that duration to absl::UnixEpoch() to get an absl::Time. bool AbslParseFlag(absl::string_view text, Time* t, std::string* error); - -// AbslUnparseFlag() -// -// Unparses a Time value into a command-line string representation using -// the format specified by `absl::ParseTime()`. + +// AbslUnparseFlag() +// +// Unparses a Time value into a command-line string representation using +// the format specified by `absl::ParseTime()`. std::string AbslUnparseFlag(Time t); - + ABSL_DEPRECATED("Use AbslParseFlag() instead.") bool ParseFlag(const std::string& text, Time* t, std::string* error); ABSL_DEPRECATED("Use AbslUnparseFlag() instead.") @@ -1402,7 +1402,7 @@ constexpr Duration MakeDuration(int64_t hi, int64_t lo) { inline Duration MakePosDoubleDuration(double n) { const int64_t int_secs = static_cast<int64_t>(n); const uint32_t ticks = static_cast<uint32_t>( - std::round((n - static_cast<double>(int_secs)) * kTicksPerSecond)); + std::round((n - static_cast<double>(int_secs)) * kTicksPerSecond)); return ticks < kTicksPerSecond ? MakeDuration(int_secs, ticks) : MakeDuration(int_secs + 1, ticks - kTicksPerSecond); diff --git a/contrib/restricted/abseil-cpp/absl/time/ya.make b/contrib/restricted/abseil-cpp/absl/time/ya.make index feb835cc53..290ec6780a 100644 --- a/contrib/restricted/abseil-cpp/absl/time/ya.make +++ b/contrib/restricted/abseil-cpp/absl/time/ya.make @@ -19,7 +19,7 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/base/log_severity contrib/restricted/abseil-cpp/absl/numeric contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal contrib/restricted/abseil-cpp/absl/time/civil_time contrib/restricted/abseil-cpp/absl/time/time_zone ) diff --git a/contrib/restricted/abseil-cpp/absl/types/bad_optional_access.h b/contrib/restricted/abseil-cpp/absl/types/bad_optional_access.h index 049e72ad9a..3227b03fbe 100644 --- a/contrib/restricted/abseil-cpp/absl/types/bad_optional_access.h +++ b/contrib/restricted/abseil-cpp/absl/types/bad_optional_access.h @@ -67,7 +67,7 @@ class bad_optional_access : public std::exception { namespace optional_internal { // throw delegator -[[noreturn]] ABSL_DLL void throw_bad_optional_access(); +[[noreturn]] ABSL_DLL void throw_bad_optional_access(); } // namespace optional_internal ABSL_NAMESPACE_END diff --git a/contrib/restricted/abseil-cpp/absl/types/bad_variant_access.h b/contrib/restricted/abseil-cpp/absl/types/bad_variant_access.h index 8ab215e97d..09ee477a05 100644 --- a/contrib/restricted/abseil-cpp/absl/types/bad_variant_access.h +++ b/contrib/restricted/abseil-cpp/absl/types/bad_variant_access.h @@ -70,8 +70,8 @@ class bad_variant_access : public std::exception { namespace variant_internal { -[[noreturn]] ABSL_DLL void ThrowBadVariantAccess(); -[[noreturn]] ABSL_DLL void Rethrow(); +[[noreturn]] ABSL_DLL void ThrowBadVariantAccess(); +[[noreturn]] ABSL_DLL void Rethrow(); } // namespace variant_internal ABSL_NAMESPACE_END diff --git a/contrib/restricted/abseil-cpp/absl/types/internal/ya.make b/contrib/restricted/abseil-cpp/absl/types/internal/ya.make index 49b33a9a65..b00f8a9374 100644 --- a/contrib/restricted/abseil-cpp/absl/types/internal/ya.make +++ b/contrib/restricted/abseil-cpp/absl/types/internal/ya.make @@ -1,5 +1,5 @@ -# Generated by devtools/yamaker. - +# Generated by devtools/yamaker. + LIBRARY() OWNER(g:cpp-contrib) diff --git a/contrib/restricted/abseil-cpp/absl/types/span.h b/contrib/restricted/abseil-cpp/absl/types/span.h index 6272bb7ad1..6ecbada6f8 100644 --- a/contrib/restricted/abseil-cpp/absl/types/span.h +++ b/contrib/restricted/abseil-cpp/absl/types/span.h @@ -169,7 +169,7 @@ class Span { typename std::enable_if<!std::is_const<T>::value, U>::type; public: - using element_type = T; + using element_type = T; using value_type = absl::remove_cv_t<T>; using pointer = T*; using const_pointer = const T*; @@ -243,8 +243,8 @@ class Span { // template <typename LazyT = T, typename = EnableIfConstView<LazyT>> - Span(std::initializer_list<value_type> v - ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept // NOLINT(runtime/explicit) + Span(std::initializer_list<value_type> v + ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept // NOLINT(runtime/explicit) : Span(v.begin(), v.size()) {} // Accessors diff --git a/contrib/restricted/abseil-cpp/provides.pbtxt b/contrib/restricted/abseil-cpp/provides.pbtxt index 5e5f196730..d92f73bcdb 100644 --- a/contrib/restricted/abseil-cpp/provides.pbtxt +++ b/contrib/restricted/abseil-cpp/provides.pbtxt @@ -1,66 +1,66 @@ -p { i: "abseil-cpp" x: "absl_bad_any_cast_impl" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/types/bad_any_cast" } -p { i: "abseil-cpp" x: "absl_bad_optional_access" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/types/bad_optional_access" } -p { i: "abseil-cpp" x: "absl_bad_variant_access" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/types/bad_variant_access" } -p { i: "abseil-cpp" x: "absl_base" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/base" } -p { i: "abseil-cpp" x: "absl_city" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/city" } -p { i: "abseil-cpp" x: "absl_civil_time" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/time/civil_time" } -p { i: "abseil-cpp" x: "absl_cord" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/strings/cord" } -p { i: "abseil-cpp" x: "absl_cord_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal" } -p { i: "abseil-cpp" x: "absl_cordz_functions" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions" } -p { i: "abseil-cpp" x: "absl_cordz_handle" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle" } -p { i: "abseil-cpp" x: "absl_cordz_info" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info" } -p { i: "abseil-cpp" x: "absl_cordz_sample_token" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/strings/internal/cordz_sample_token" } -p { i: "abseil-cpp" x: "absl_debugging_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/debugging" } -p { i: "abseil-cpp" x: "absl_demangle_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/demangle" } -p { i: "abseil-cpp" x: "absl_examine_stack" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/debugging/internal" } -p { i: "abseil-cpp" x: "absl_exponential_biased" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased" } -p { i: "abseil-cpp" x: "absl_failure_signal_handler" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler" } -p { i: "abseil-cpp" x: "absl_flags" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags" } -p { i: "abseil-cpp" x: "absl_flags_commandlineflag" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/commandlineflag" } -p { i: "abseil-cpp" x: "absl_flags_commandlineflag_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag" } -p { i: "abseil-cpp" x: "absl_flags_config" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/usage_config" } -p { i: "abseil-cpp" x: "absl_flags_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/internal/flag" } -p { i: "abseil-cpp" x: "absl_flags_marshalling" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/marshalling" } -p { i: "abseil-cpp" x: "absl_flags_parse" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/parse" } -p { i: "abseil-cpp" x: "absl_flags_private_handle_accessor" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor" } -p { i: "abseil-cpp" x: "absl_flags_program_name" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/internal/program_name" } -p { i: "abseil-cpp" x: "absl_flags_reflection" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/reflection" } -p { i: "abseil-cpp" x: "absl_flags_usage" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/usage" } -p { i: "abseil-cpp" x: "absl_flags_usage_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/internal/usage" } -p { i: "abseil-cpp" x: "absl_graphcycles_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/synchronization/internal" } -p { i: "abseil-cpp" x: "absl_hash" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/hash" } -p { i: "abseil-cpp" x: "absl_hashtablez_sampler" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/container/internal/absl_hashtablez_sampler" } -p { i: "abseil-cpp" x: "absl_int128" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/numeric" } -p { i: "abseil-cpp" x: "absl_leak_check" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/debugging/leak_check" } -p { i: "abseil-cpp" x: "absl_leak_check_disable" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/debugging/leak_check_disable" } -p { i: "abseil-cpp" x: "absl_log_severity" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/base/log_severity" } -p { i: "abseil-cpp" x: "absl_low_level_hash" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/hash/internal" } -p { i: "abseil-cpp" x: "absl_malloc_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc" } -p { i: "abseil-cpp" x: "absl_periodic_sampler" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler" } -p { i: "abseil-cpp" x: "absl_random_distributions" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/absl_random_distributions" } -p { i: "abseil-cpp" x: "absl_random_internal_distribution_test_util" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/internal/absl_random_internal_distribution_test_util" } -p { i: "abseil-cpp" x: "absl_random_internal_platform" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys" } -p { i: "abseil-cpp" x: "absl_random_internal_pool_urbg" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg" } -p { i: "abseil-cpp" x: "absl_random_internal_randen" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/internal/randen" } -p { i: "abseil-cpp" x: "absl_random_internal_randen_hwaes" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/internal/randen_detect" } -p { i: "abseil-cpp" x: "absl_random_internal_randen_hwaes_impl" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes" } -p { i: "abseil-cpp" x: "absl_random_internal_randen_slow" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/internal/randen_slow" } -p { i: "abseil-cpp" x: "absl_random_internal_seed_material" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/internal/seed_material" } -p { i: "abseil-cpp" x: "absl_random_seed_gen_exception" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/seed_gen_exception" } -p { i: "abseil-cpp" x: "absl_random_seed_sequences" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/seed_sequences" } -p { i: "abseil-cpp" x: "absl_raw_hash_set" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set" } -p { i: "abseil-cpp" x: "absl_raw_logging_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/base/internal/raw_logging" } -p { i: "abseil-cpp" x: "absl_scoped_set_env" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/base/internal/scoped_set_env" } -p { i: "abseil-cpp" x: "absl_spinlock_wait" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait" } -p { i: "abseil-cpp" x: "absl_stacktrace" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/debugging/stacktrace" } -p { i: "abseil-cpp" x: "absl_status" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/status" } -p { i: "abseil-cpp" x: "absl_statusor" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/status/statusor" } -p { i: "abseil-cpp" x: "absl_str_format_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/strings/internal/str_format" } -p { i: "abseil-cpp" x: "absl_strerror" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/base/internal/strerror" } -p { i: "abseil-cpp" x: "absl_strings" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/strings" } -p { i: "abseil-cpp" x: "absl_strings_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal" } -p { i: "abseil-cpp" x: "absl_symbolize" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/debugging/symbolize" } -p { i: "abseil-cpp" x: "absl_synchronization" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/synchronization" } -p { i: "abseil-cpp" x: "absl_throw_delegate" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate" } -p { i: "abseil-cpp" x: "absl_time" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/time" } -p { i: "abseil-cpp" x: "absl_time_zone" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/time/time_zone" } +p { i: "abseil-cpp" x: "absl_bad_any_cast_impl" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/types/bad_any_cast" } +p { i: "abseil-cpp" x: "absl_bad_optional_access" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/types/bad_optional_access" } +p { i: "abseil-cpp" x: "absl_bad_variant_access" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/types/bad_variant_access" } +p { i: "abseil-cpp" x: "absl_base" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/base" } +p { i: "abseil-cpp" x: "absl_city" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/city" } +p { i: "abseil-cpp" x: "absl_civil_time" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/time/civil_time" } +p { i: "abseil-cpp" x: "absl_cord" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/strings/cord" } +p { i: "abseil-cpp" x: "absl_cord_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal" } +p { i: "abseil-cpp" x: "absl_cordz_functions" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions" } +p { i: "abseil-cpp" x: "absl_cordz_handle" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle" } +p { i: "abseil-cpp" x: "absl_cordz_info" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info" } +p { i: "abseil-cpp" x: "absl_cordz_sample_token" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/strings/internal/cordz_sample_token" } +p { i: "abseil-cpp" x: "absl_debugging_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/debugging" } +p { i: "abseil-cpp" x: "absl_demangle_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/demangle" } +p { i: "abseil-cpp" x: "absl_examine_stack" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/debugging/internal" } +p { i: "abseil-cpp" x: "absl_exponential_biased" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased" } +p { i: "abseil-cpp" x: "absl_failure_signal_handler" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler" } +p { i: "abseil-cpp" x: "absl_flags" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags" } +p { i: "abseil-cpp" x: "absl_flags_commandlineflag" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/commandlineflag" } +p { i: "abseil-cpp" x: "absl_flags_commandlineflag_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag" } +p { i: "abseil-cpp" x: "absl_flags_config" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/usage_config" } +p { i: "abseil-cpp" x: "absl_flags_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/internal/flag" } +p { i: "abseil-cpp" x: "absl_flags_marshalling" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/marshalling" } +p { i: "abseil-cpp" x: "absl_flags_parse" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/parse" } +p { i: "abseil-cpp" x: "absl_flags_private_handle_accessor" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor" } +p { i: "abseil-cpp" x: "absl_flags_program_name" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/internal/program_name" } +p { i: "abseil-cpp" x: "absl_flags_reflection" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/reflection" } +p { i: "abseil-cpp" x: "absl_flags_usage" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/usage" } +p { i: "abseil-cpp" x: "absl_flags_usage_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/flags/internal/usage" } +p { i: "abseil-cpp" x: "absl_graphcycles_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/synchronization/internal" } +p { i: "abseil-cpp" x: "absl_hash" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/hash" } +p { i: "abseil-cpp" x: "absl_hashtablez_sampler" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/container/internal/absl_hashtablez_sampler" } +p { i: "abseil-cpp" x: "absl_int128" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/numeric" } +p { i: "abseil-cpp" x: "absl_leak_check" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/debugging/leak_check" } +p { i: "abseil-cpp" x: "absl_leak_check_disable" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/debugging/leak_check_disable" } +p { i: "abseil-cpp" x: "absl_log_severity" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/base/log_severity" } +p { i: "abseil-cpp" x: "absl_low_level_hash" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/hash/internal" } +p { i: "abseil-cpp" x: "absl_malloc_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc" } +p { i: "abseil-cpp" x: "absl_periodic_sampler" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler" } +p { i: "abseil-cpp" x: "absl_random_distributions" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/absl_random_distributions" } +p { i: "abseil-cpp" x: "absl_random_internal_distribution_test_util" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/internal/absl_random_internal_distribution_test_util" } +p { i: "abseil-cpp" x: "absl_random_internal_platform" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys" } +p { i: "abseil-cpp" x: "absl_random_internal_pool_urbg" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg" } +p { i: "abseil-cpp" x: "absl_random_internal_randen" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/internal/randen" } +p { i: "abseil-cpp" x: "absl_random_internal_randen_hwaes" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/internal/randen_detect" } +p { i: "abseil-cpp" x: "absl_random_internal_randen_hwaes_impl" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes" } +p { i: "abseil-cpp" x: "absl_random_internal_randen_slow" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/internal/randen_slow" } +p { i: "abseil-cpp" x: "absl_random_internal_seed_material" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/internal/seed_material" } +p { i: "abseil-cpp" x: "absl_random_seed_gen_exception" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/seed_gen_exception" } +p { i: "abseil-cpp" x: "absl_random_seed_sequences" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/random/seed_sequences" } +p { i: "abseil-cpp" x: "absl_raw_hash_set" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set" } +p { i: "abseil-cpp" x: "absl_raw_logging_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/base/internal/raw_logging" } +p { i: "abseil-cpp" x: "absl_scoped_set_env" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/base/internal/scoped_set_env" } +p { i: "abseil-cpp" x: "absl_spinlock_wait" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait" } +p { i: "abseil-cpp" x: "absl_stacktrace" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/debugging/stacktrace" } +p { i: "abseil-cpp" x: "absl_status" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/status" } +p { i: "abseil-cpp" x: "absl_statusor" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/status/statusor" } +p { i: "abseil-cpp" x: "absl_str_format_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/strings/internal/str_format" } +p { i: "abseil-cpp" x: "absl_strerror" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/base/internal/strerror" } +p { i: "abseil-cpp" x: "absl_strings" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/strings" } +p { i: "abseil-cpp" x: "absl_strings_internal" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal" } +p { i: "abseil-cpp" x: "absl_symbolize" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/debugging/symbolize" } +p { i: "abseil-cpp" x: "absl_synchronization" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/synchronization" } +p { i: "abseil-cpp" x: "absl_throw_delegate" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate" } +p { i: "abseil-cpp" x: "absl_time" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/time" } +p { i: "abseil-cpp" x: "absl_time_zone" ix: true peerdir: "contrib/restricted/abseil-cpp/absl/time/time_zone" } diff --git a/contrib/restricted/abseil-cpp/ya.make b/contrib/restricted/abseil-cpp/ya.make index f69125bf2d..67e9690748 100644 --- a/contrib/restricted/abseil-cpp/ya.make +++ b/contrib/restricted/abseil-cpp/ya.make @@ -1,13 +1,13 @@ -# Generated by devtools/yamaker from nixpkgs 21.11. +# Generated by devtools/yamaker from nixpkgs 21.11. LIBRARY() OWNER(g:cpp-contrib) -VERSION(20211102.0) +VERSION(20211102.0) LICENSE(Apache-2.0) - + LICENSE_TEXTS(.yandex_meta/licenses.list.txt) PEERDIR( @@ -47,11 +47,11 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/functional contrib/restricted/abseil-cpp/absl/hash contrib/restricted/abseil-cpp/absl/hash/internal - contrib/restricted/abseil-cpp/absl/memory - contrib/restricted/abseil-cpp/absl/meta + contrib/restricted/abseil-cpp/absl/memory + contrib/restricted/abseil-cpp/absl/meta contrib/restricted/abseil-cpp/absl/numeric - contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased - contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler + contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased + contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler contrib/restricted/abseil-cpp/absl/random/absl_random_distributions contrib/restricted/abseil-cpp/absl/random/internal/absl_random_internal_distribution_test_util contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg @@ -66,13 +66,13 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/status contrib/restricted/abseil-cpp/absl/status/statusor contrib/restricted/abseil-cpp/absl/strings - contrib/restricted/abseil-cpp/absl/strings/cord - contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal - contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info - contrib/restricted/abseil-cpp/absl/strings/internal/cordz_sample_token + contrib/restricted/abseil-cpp/absl/strings/cord + contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal + contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info + contrib/restricted/abseil-cpp/absl/strings/internal/cordz_sample_token contrib/restricted/abseil-cpp/absl/strings/internal/str_format contrib/restricted/abseil-cpp/absl/synchronization contrib/restricted/abseil-cpp/absl/synchronization/internal @@ -83,11 +83,11 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/types/bad_any_cast contrib/restricted/abseil-cpp/absl/types/bad_optional_access contrib/restricted/abseil-cpp/absl/types/bad_variant_access - contrib/restricted/abseil-cpp/absl/types/internal + contrib/restricted/abseil-cpp/absl/types/internal contrib/restricted/abseil-cpp/absl/utility ) -NO_RUNTIME() +NO_RUNTIME() END() @@ -128,11 +128,11 @@ RECURSE( absl/functional absl/hash absl/hash/internal - absl/memory - absl/meta + absl/memory + absl/meta absl/numeric - absl/profiling/internal/exponential_biased - absl/profiling/internal/periodic_sampler + absl/profiling/internal/exponential_biased + absl/profiling/internal/periodic_sampler absl/random/absl_random_distributions absl/random/internal/absl_random_internal_distribution_test_util absl/random/internal/pool_urbg @@ -147,13 +147,13 @@ RECURSE( absl/status absl/status/statusor absl/strings - absl/strings/cord - absl/strings/internal/absl_cord_internal - absl/strings/internal/absl_strings_internal - absl/strings/internal/cordz_functions - absl/strings/internal/cordz_handle - absl/strings/internal/cordz_info - absl/strings/internal/cordz_sample_token + absl/strings/cord + absl/strings/internal/absl_cord_internal + absl/strings/internal/absl_strings_internal + absl/strings/internal/cordz_functions + absl/strings/internal/cordz_handle + absl/strings/internal/cordz_info + absl/strings/internal/cordz_sample_token absl/strings/internal/str_format absl/synchronization absl/synchronization/internal @@ -164,6 +164,6 @@ RECURSE( absl/types/bad_any_cast absl/types/bad_optional_access absl/types/bad_variant_access - absl/types/internal + absl/types/internal absl/utility ) diff --git a/contrib/restricted/aws/aws-checksums/ya.make b/contrib/restricted/aws/aws-checksums/ya.make index a08a095ee1..a843fe218b 100644 --- a/contrib/restricted/aws/aws-checksums/ya.make +++ b/contrib/restricted/aws/aws-checksums/ya.make @@ -30,7 +30,7 @@ CFLAGS( -Daws_checksums_EXPORTS ) -IF (BUILD_TYPE == "DEBUG") +IF (BUILD_TYPE == "DEBUG") CFLAGS( -DDEBUG_BUILD ) diff --git a/contrib/restricted/boost/boost/asio/detail/string_view.hpp b/contrib/restricted/boost/boost/asio/detail/string_view.hpp index 7f601199b1..6647b9204b 100644 --- a/contrib/restricted/boost/boost/asio/detail/string_view.hpp +++ b/contrib/restricted/boost/boost/asio/detail/string_view.hpp @@ -22,7 +22,7 @@ #if defined(BOOST_ASIO_HAS_STD_STRING_VIEW) # include <string_view> #elif defined(BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) -# error include <experimental/string_view> +# error include <experimental/string_view> #else // defined(BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) # error BOOST_ASIO_HAS_STRING_VIEW is set but no string_view is available #endif // defined(BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) diff --git a/contrib/restricted/boost/boost/bimap/detail/bimap_core.hpp b/contrib/restricted/boost/boost/bimap/detail/bimap_core.hpp index 6d4593d20e..ffe49c9f82 100644 --- a/contrib/restricted/boost/boost/bimap/detail/bimap_core.hpp +++ b/contrib/restricted/boost/boost/bimap/detail/bimap_core.hpp @@ -404,7 +404,7 @@ class bimap_core < relation, core_indices, - BOOST_DEDUCED_TYPENAME std::allocator_traits<typename parameters::allocator>::template rebind_alloc<relation> + BOOST_DEDUCED_TYPENAME std::allocator_traits<typename parameters::allocator>::template rebind_alloc<relation> > core_type; diff --git a/contrib/restricted/boost/boost/config/detail/suffix.hpp b/contrib/restricted/boost/boost/config/detail/suffix.hpp index e5d9785697..409e19e914 100644 --- a/contrib/restricted/boost/boost/config/detail/suffix.hpp +++ b/contrib/restricted/boost/boost/config/detail/suffix.hpp @@ -994,7 +994,7 @@ namespace std{ using ::type_info; } // on unsupported compilers. // #ifndef BOOST_FALLTHROUGH -# define BOOST_FALLTHROUGH [[fallthrough]] +# define BOOST_FALLTHROUGH [[fallthrough]] #endif // diff --git a/contrib/restricted/boost/boost/container/new_allocator.hpp b/contrib/restricted/boost/boost/container/new_allocator.hpp index 9af015d1d6..48f761c31b 100644 --- a/contrib/restricted/boost/boost/container/new_allocator.hpp +++ b/contrib/restricted/boost/boost/container/new_allocator.hpp @@ -72,13 +72,13 @@ class new_allocator<void> new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW {} - //!Copy assignment operator from other new_allocator. - //!Never throws - new_allocator& operator=(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW - { - return *this; - } - + //!Copy assignment operator from other new_allocator. + //!Never throws + new_allocator& operator=(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + { + return *this; + } + //!Constructor from related new_allocator. //!Never throws template<class T2> @@ -137,13 +137,13 @@ class new_allocator new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW {} - //!Copy assignment operator from other new_allocator. - //!Never throws - new_allocator& operator=(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW - { - return *this; - } - + //!Copy assignment operator from other new_allocator. + //!Never throws + new_allocator& operator=(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + { + return *this; + } + //!Constructor from related new_allocator. //!Never throws template<class T2> diff --git a/contrib/restricted/boost/boost/core/demangle.hpp b/contrib/restricted/boost/boost/core/demangle.hpp index 5c996931ce..1ff76fcb04 100644 --- a/contrib/restricted/boost/boost/core/demangle.hpp +++ b/contrib/restricted/boost/boost/core/demangle.hpp @@ -20,7 +20,7 @@ // __has_include is currently supported by GCC and Clang. However GCC 4.9 may have issues and // returns 1 for 'defined( __has_include )', while '__has_include' is actually not supported: // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63662 -#if !defined(_MSC_VER) && defined( __has_include ) && (!defined( BOOST_GCC ) || (__GNUC__ + 0) >= 5) +#if !defined(_MSC_VER) && defined( __has_include ) && (!defined( BOOST_GCC ) || (__GNUC__ + 0) >= 5) # if __has_include(<cxxabi.h>) # define BOOST_CORE_HAS_CXXABI_H # endif diff --git a/contrib/restricted/boost/boost/date_time/posix_time/ptime.hpp b/contrib/restricted/boost/boost/date_time/posix_time/ptime.hpp index 99e5663830..691b558218 100644 --- a/contrib/restricted/boost/boost/date_time/posix_time/ptime.hpp +++ b/contrib/restricted/boost/boost/date_time/posix_time/ptime.hpp @@ -54,8 +54,8 @@ namespace posix_time { ptime() : date_time::base_time<time_type,time_system_type>(gregorian::date(not_a_date_time), time_duration_type(not_a_date_time)) {} #endif // DATE_TIME_NO_DEFAULT_CONSTRUCTOR - using base = date_time::base_time<ptime, posix_time_system>; - using base::operator==; + using base = date_time::base_time<ptime, posix_time_system>; + using base::operator==; }; diff --git a/contrib/restricted/boost/boost/format/alt_sstream_impl.hpp b/contrib/restricted/boost/boost/format/alt_sstream_impl.hpp index 41e6c5ca8e..8a940d6bb9 100644 --- a/contrib/restricted/boost/boost/format/alt_sstream_impl.hpp +++ b/contrib/restricted/boost/boost/format/alt_sstream_impl.hpp @@ -258,7 +258,7 @@ namespace boost { void *vdptr = alloc_.allocate(new_size, is_allocated_? oldptr : 0); newptr = static_cast<Ch *>(vdptr); #else - newptr = alloc_.allocate(new_size); + newptr = alloc_.allocate(new_size); #endif } diff --git a/contrib/restricted/boost/boost/fusion/adapted/boost_tuple/boost_tuple_iterator.hpp b/contrib/restricted/boost/boost/fusion/adapted/boost_tuple/boost_tuple_iterator.hpp index e68cd7cedd..26e8519579 100644 --- a/contrib/restricted/boost/boost/fusion/adapted/boost_tuple/boost_tuple_iterator.hpp +++ b/contrib/restricted/boost/boost/fusion/adapted/boost_tuple/boost_tuple_iterator.hpp @@ -147,7 +147,7 @@ namespace boost { namespace fusion {}; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(boost_tuple_iterator& operator= (boost_tuple_iterator const&)) + BOOST_DELETED_FUNCTION(boost_tuple_iterator& operator= (boost_tuple_iterator const&)) }; template <typename Null> diff --git a/contrib/restricted/boost/boost/fusion/container/deque/deque_iterator.hpp b/contrib/restricted/boost/boost/fusion/container/deque/deque_iterator.hpp index b0335e5f2b..2875af15c8 100644 --- a/contrib/restricted/boost/boost/fusion/container/deque/deque_iterator.hpp +++ b/contrib/restricted/boost/boost/fusion/container/deque/deque_iterator.hpp @@ -112,7 +112,7 @@ namespace boost { namespace fusion { Seq& seq_; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(deque_iterator& operator= (deque_iterator const&)) + BOOST_DELETED_FUNCTION(deque_iterator& operator= (deque_iterator const&)) }; }} diff --git a/contrib/restricted/boost/boost/fusion/container/list/cons_iterator.hpp b/contrib/restricted/boost/boost/fusion/container/list/cons_iterator.hpp index 5c0491dbc8..1f9742f55f 100644 --- a/contrib/restricted/boost/boost/fusion/container/list/cons_iterator.hpp +++ b/contrib/restricted/boost/boost/fusion/container/list/cons_iterator.hpp @@ -43,7 +43,7 @@ namespace boost { namespace fusion cons_type& cons; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(cons_iterator& operator= (cons_iterator const&)) + BOOST_DELETED_FUNCTION(cons_iterator& operator= (cons_iterator const&)) }; struct nil_iterator : iterator_base<nil_iterator> diff --git a/contrib/restricted/boost/boost/fusion/container/map/map_iterator.hpp b/contrib/restricted/boost/boost/fusion/container/map/map_iterator.hpp index 3db7344b22..d55e1e610f 100644 --- a/contrib/restricted/boost/boost/fusion/container/map/map_iterator.hpp +++ b/contrib/restricted/boost/boost/fusion/container/map/map_iterator.hpp @@ -157,7 +157,7 @@ namespace boost { namespace fusion Seq& seq_; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(map_iterator& operator= (map_iterator const&)) + BOOST_DELETED_FUNCTION(map_iterator& operator= (map_iterator const&)) }; }} diff --git a/contrib/restricted/boost/boost/fusion/container/vector/vector_iterator.hpp b/contrib/restricted/boost/boost/fusion/container/vector/vector_iterator.hpp index 33a68dae58..21f87582ff 100644 --- a/contrib/restricted/boost/boost/fusion/container/vector/vector_iterator.hpp +++ b/contrib/restricted/boost/boost/fusion/container/vector/vector_iterator.hpp @@ -46,7 +46,7 @@ namespace boost { namespace fusion Vector& vec; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(vector_iterator& operator= (vector_iterator const&)) + BOOST_DELETED_FUNCTION(vector_iterator& operator= (vector_iterator const&)) }; }} diff --git a/contrib/restricted/boost/boost/fusion/sequence/io/detail/manip.hpp b/contrib/restricted/boost/boost/fusion/sequence/io/detail/manip.hpp index fc0d7d8204..31077b032d 100644 --- a/contrib/restricted/boost/boost/fusion/sequence/io/detail/manip.hpp +++ b/contrib/restricted/boost/boost/fusion/sequence/io/detail/manip.hpp @@ -145,7 +145,7 @@ namespace boost { namespace fusion Stream& stream; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(string_ios_manip& operator= (string_ios_manip const&)) + BOOST_DELETED_FUNCTION(string_ios_manip& operator= (string_ios_manip const&)) }; } // detail diff --git a/contrib/restricted/boost/boost/fusion/view/filter_view/filter_view.hpp b/contrib/restricted/boost/boost/fusion/view/filter_view/filter_view.hpp index c56fb3cbf1..51c8b67bbb 100644 --- a/contrib/restricted/boost/boost/fusion/view/filter_view/filter_view.hpp +++ b/contrib/restricted/boost/boost/fusion/view/filter_view/filter_view.hpp @@ -58,7 +58,7 @@ namespace boost { namespace fusion typename mpl::if_<traits::is_view<Sequence>, Sequence, Sequence&>::type seq; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(filter_view& operator= (filter_view const&)) + BOOST_DELETED_FUNCTION(filter_view& operator= (filter_view const&)) }; }} diff --git a/contrib/restricted/boost/boost/fusion/view/filter_view/filter_view_iterator.hpp b/contrib/restricted/boost/boost/fusion/view/filter_view/filter_view_iterator.hpp index 9403356c42..fcb3ca5282 100644 --- a/contrib/restricted/boost/boost/fusion/view/filter_view/filter_view_iterator.hpp +++ b/contrib/restricted/boost/boost/fusion/view/filter_view/filter_view_iterator.hpp @@ -62,7 +62,7 @@ namespace boost { namespace fusion first_type first; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(filter_iterator& operator= (filter_iterator const&)) + BOOST_DELETED_FUNCTION(filter_iterator& operator= (filter_iterator const&)) }; }} diff --git a/contrib/restricted/boost/boost/fusion/view/joint_view/joint_view.hpp b/contrib/restricted/boost/boost/fusion/view/joint_view/joint_view.hpp index 03e38d694c..cbebc7f2a8 100644 --- a/contrib/restricted/boost/boost/fusion/view/joint_view/joint_view.hpp +++ b/contrib/restricted/boost/boost/fusion/view/joint_view/joint_view.hpp @@ -70,9 +70,9 @@ namespace boost { namespace fusion concat_last_type concat_last() const { return fusion::end(seq2); } // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(joint_view& operator= (joint_view const&)) + BOOST_DELETED_FUNCTION(joint_view& operator= (joint_view const&)) - private: + private: typename mpl::if_<traits::is_view<Sequence1>, Sequence1, Sequence1&>::type seq1; typename mpl::if_<traits::is_view<Sequence2>, Sequence2, Sequence2&>::type seq2; }; diff --git a/contrib/restricted/boost/boost/fusion/view/joint_view/joint_view_iterator.hpp b/contrib/restricted/boost/boost/fusion/view/joint_view/joint_view_iterator.hpp index f6db30915e..131d77b000 100644 --- a/contrib/restricted/boost/boost/fusion/view/joint_view/joint_view_iterator.hpp +++ b/contrib/restricted/boost/boost/fusion/view/joint_view/joint_view_iterator.hpp @@ -51,7 +51,7 @@ namespace boost { namespace fusion concat_type concat; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(joint_view_iterator& operator= (joint_view_iterator const&)) + BOOST_DELETED_FUNCTION(joint_view_iterator& operator= (joint_view_iterator const&)) }; }} diff --git a/contrib/restricted/boost/boost/fusion/view/nview/nview_iterator.hpp b/contrib/restricted/boost/boost/fusion/view/nview/nview_iterator.hpp index 79c82dd963..cf535ba5f5 100644 --- a/contrib/restricted/boost/boost/fusion/view/nview/nview_iterator.hpp +++ b/contrib/restricted/boost/boost/fusion/view/nview/nview_iterator.hpp @@ -48,7 +48,7 @@ namespace boost { namespace fusion Sequence& seq; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(nview_iterator& operator= (nview_iterator const&)) + BOOST_DELETED_FUNCTION(nview_iterator& operator= (nview_iterator const&)) }; }} diff --git a/contrib/restricted/boost/boost/fusion/view/repetitive_view/repetitive_view.hpp b/contrib/restricted/boost/boost/fusion/view/repetitive_view/repetitive_view.hpp index 71dc51bc8f..ca4703d0cb 100644 --- a/contrib/restricted/boost/boost/fusion/view/repetitive_view/repetitive_view.hpp +++ b/contrib/restricted/boost/boost/fusion/view/repetitive_view/repetitive_view.hpp @@ -45,7 +45,7 @@ namespace boost { namespace fusion stored_seq_type seq; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(repetitive_view& operator= (repetitive_view const&)) + BOOST_DELETED_FUNCTION(repetitive_view& operator= (repetitive_view const&)) }; }} diff --git a/contrib/restricted/boost/boost/fusion/view/repetitive_view/repetitive_view_iterator.hpp b/contrib/restricted/boost/boost/fusion/view/repetitive_view/repetitive_view_iterator.hpp index 775249ff36..4d3505e8d2 100644 --- a/contrib/restricted/boost/boost/fusion/view/repetitive_view/repetitive_view_iterator.hpp +++ b/contrib/restricted/boost/boost/fusion/view/repetitive_view/repetitive_view_iterator.hpp @@ -48,7 +48,7 @@ namespace boost { namespace fusion pos_type pos; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(repetitive_view_iterator& operator= (repetitive_view_iterator const&)) + BOOST_DELETED_FUNCTION(repetitive_view_iterator& operator= (repetitive_view_iterator const&)) }; }} diff --git a/contrib/restricted/boost/boost/fusion/view/reverse_view/reverse_view.hpp b/contrib/restricted/boost/boost/fusion/view/reverse_view/reverse_view.hpp index 0aa3d10664..382c6ccda4 100644 --- a/contrib/restricted/boost/boost/fusion/view/reverse_view/reverse_view.hpp +++ b/contrib/restricted/boost/boost/fusion/view/reverse_view/reverse_view.hpp @@ -62,7 +62,7 @@ namespace boost { namespace fusion typename mpl::if_<traits::is_view<Sequence>, Sequence, Sequence&>::type seq; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(reverse_view& operator= (reverse_view const&)) + BOOST_DELETED_FUNCTION(reverse_view& operator= (reverse_view const&)) }; }} diff --git a/contrib/restricted/boost/boost/fusion/view/reverse_view/reverse_view_iterator.hpp b/contrib/restricted/boost/boost/fusion/view/reverse_view/reverse_view_iterator.hpp index 0a582f4032..bad3369b25 100644 --- a/contrib/restricted/boost/boost/fusion/view/reverse_view/reverse_view_iterator.hpp +++ b/contrib/restricted/boost/boost/fusion/view/reverse_view/reverse_view_iterator.hpp @@ -49,7 +49,7 @@ namespace boost { namespace fusion first_type first; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(reverse_view_iterator& operator= (reverse_view_iterator const&)) + BOOST_DELETED_FUNCTION(reverse_view_iterator& operator= (reverse_view_iterator const&)) }; }} diff --git a/contrib/restricted/boost/boost/fusion/view/transform_view/transform_view.hpp b/contrib/restricted/boost/boost/fusion/view/transform_view/transform_view.hpp index f0633018ee..b79d817bdf 100644 --- a/contrib/restricted/boost/boost/fusion/view/transform_view/transform_view.hpp +++ b/contrib/restricted/boost/boost/fusion/view/transform_view/transform_view.hpp @@ -77,7 +77,7 @@ namespace boost { namespace fusion typename mpl::if_<traits::is_view<Sequence2>, Sequence2, Sequence2&>::type seq2; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(transform_view& operator= (transform_view const&)) + BOOST_DELETED_FUNCTION(transform_view& operator= (transform_view const&)) }; // Unary Version @@ -113,7 +113,7 @@ namespace boost { namespace fusion transform_type f; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(transform_view& operator= (transform_view const&)) + BOOST_DELETED_FUNCTION(transform_view& operator= (transform_view const&)) }; }} diff --git a/contrib/restricted/boost/boost/fusion/view/transform_view/transform_view_iterator.hpp b/contrib/restricted/boost/boost/fusion/view/transform_view/transform_view_iterator.hpp index 2689ae8aab..3d39bf200d 100644 --- a/contrib/restricted/boost/boost/fusion/view/transform_view/transform_view_iterator.hpp +++ b/contrib/restricted/boost/boost/fusion/view/transform_view/transform_view_iterator.hpp @@ -43,7 +43,7 @@ namespace boost { namespace fusion transform_type f; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(transform_view_iterator& operator= (transform_view_iterator const&)) + BOOST_DELETED_FUNCTION(transform_view_iterator& operator= (transform_view_iterator const&)) }; // Binary Version @@ -70,7 +70,7 @@ namespace boost { namespace fusion transform_type f; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(transform_view_iterator2& operator= (transform_view_iterator2 const&)) + BOOST_DELETED_FUNCTION(transform_view_iterator2& operator= (transform_view_iterator2 const&)) }; }} diff --git a/contrib/restricted/boost/boost/graph/dijkstra_shortest_paths.hpp b/contrib/restricted/boost/boost/graph/dijkstra_shortest_paths.hpp index 25c982d14b..f73ddd21fe 100644 --- a/contrib/restricted/boost/boost/graph/dijkstra_shortest_paths.hpp +++ b/contrib/restricted/boost/boost/graph/dijkstra_shortest_paths.hpp @@ -101,7 +101,7 @@ namespace boost { } private: template <class Edge, class Graph> - void tree_edge(Edge /* u */, Graph& /* g */) { } + void tree_edge(Edge /* u */, Graph& /* g */) { } }; template <class Visitors> dijkstra_visitor<Visitors> @@ -228,7 +228,7 @@ namespace boost { template <class Graph, class IndexMap, class Value> struct vertex_property_map_generator_helper<Graph, IndexMap, Value, false> { typedef boost::vector_property_map<Value, IndexMap> type; - static type build(const Graph& /* g */, const IndexMap& index, boost::scoped_array<Value>& /* array_holder */) { + static type build(const Graph& /* g */, const IndexMap& index, boost::scoped_array<Value>& /* array_holder */) { return boost::make_vector_property_map<Value>(index); } }; @@ -263,7 +263,7 @@ namespace boost { template <class Graph, class IndexMap> struct default_color_map_generator_helper<Graph, IndexMap, false> { typedef boost::vector_property_map<boost::two_bit_color_type, IndexMap> type; - static type build(const Graph& /* g */, const IndexMap& index) { + static type build(const Graph& /* g */, const IndexMap& index) { return boost::make_vector_property_map<boost::two_bit_color_type>(index); } }; diff --git a/contrib/restricted/boost/boost/heap/d_ary_heap.hpp b/contrib/restricted/boost/boost/heap/d_ary_heap.hpp index dac22e22c7..a221be77a2 100644 --- a/contrib/restricted/boost/boost/heap/d_ary_heap.hpp +++ b/contrib/restricted/boost/boost/heap/d_ary_heap.hpp @@ -15,7 +15,7 @@ #include <boost/assert.hpp> -#include <boost/core/allocator_access.hpp> +#include <boost/core/allocator_access.hpp> #include <boost/mem_fn.hpp> #include <boost/heap/detail/heap_comparison.hpp> #include <boost/heap/detail/ordered_adaptor_iterator.hpp> @@ -67,7 +67,7 @@ class d_ary_heap: typedef typename heap_base_maker::type super_t; typedef typename super_t::internal_type internal_type; - typedef typename boost::allocator_rebind<typename heap_base_maker::allocator_argument, internal_type>::type internal_type_allocator; + typedef typename boost::allocator_rebind<typename heap_base_maker::allocator_argument, internal_type>::type internal_type_allocator; typedef std::vector<internal_type, internal_type_allocator> container_type; typedef typename container_type::const_iterator container_iterator; diff --git a/contrib/restricted/boost/boost/heap/detail/mutable_heap.hpp b/contrib/restricted/boost/boost/heap/detail/mutable_heap.hpp index d0b98e5f84..5dce906586 100644 --- a/contrib/restricted/boost/boost/heap/detail/mutable_heap.hpp +++ b/contrib/restricted/boost/boost/heap/detail/mutable_heap.hpp @@ -16,7 +16,7 @@ #include <list> #include <utility> -#include <boost/core/allocator_access.hpp> +#include <boost/core/allocator_access.hpp> #include <boost/iterator/iterator_adaptor.hpp> #include <boost/heap/detail/ordered_adaptor_iterator.hpp> @@ -48,7 +48,7 @@ public: private: typedef std::pair<value_type, size_type> node_type; - typedef std::list<node_type, typename boost::allocator_rebind<allocator_type, node_type>::type> object_list; + typedef std::list<node_type, typename boost::allocator_rebind<allocator_type, node_type>::type> object_list; typedef typename object_list::iterator list_iterator; typedef typename object_list::const_iterator const_list_iterator; diff --git a/contrib/restricted/boost/boost/heap/detail/ordered_adaptor_iterator.hpp b/contrib/restricted/boost/boost/heap/detail/ordered_adaptor_iterator.hpp index 1ec2871806..934b23f1cb 100644 --- a/contrib/restricted/boost/boost/heap/detail/ordered_adaptor_iterator.hpp +++ b/contrib/restricted/boost/boost/heap/detail/ordered_adaptor_iterator.hpp @@ -80,7 +80,7 @@ public: unvisited_nodes(compare_by_heap_value(NULL, ValueCompare())) {} - ordered_adaptor_iterator(const ContainerType * container, ValueCompare const & /* cmp */): + ordered_adaptor_iterator(const ContainerType * container, ValueCompare const & /* cmp */): container(container), current_index(container->size()), unvisited_nodes(compare_by_heap_value(container, ValueCompare())) {} diff --git a/contrib/restricted/boost/boost/heap/detail/stable_heap.hpp b/contrib/restricted/boost/boost/heap/detail/stable_heap.hpp index 9bdbfcd0b9..e0afb9ee94 100644 --- a/contrib/restricted/boost/boost/heap/detail/stable_heap.hpp +++ b/contrib/restricted/boost/boost/heap/detail/stable_heap.hpp @@ -96,18 +96,18 @@ struct size_holder<false, SizeType> {} #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - size_holder(size_holder && /* rhs */) BOOST_NOEXCEPT + size_holder(size_holder && /* rhs */) BOOST_NOEXCEPT {} - size_holder(size_holder const & /* rhs */) BOOST_NOEXCEPT + size_holder(size_holder const & /* rhs */) BOOST_NOEXCEPT {} - size_holder & operator=(size_holder && /* rhs */) BOOST_NOEXCEPT + size_holder & operator=(size_holder && /* rhs */) BOOST_NOEXCEPT { return *this; } - size_holder & operator=(size_holder const & /* rhs */) BOOST_NOEXCEPT + size_holder & operator=(size_holder const & /* rhs */) BOOST_NOEXCEPT { return *this; } @@ -566,12 +566,12 @@ struct make_heap_base template <typename Alloc> struct extract_allocator_types { - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef typename std::allocator_traits<Alloc>::value_type& reference; - typedef const typename std::allocator_traits<Alloc>::value_type& const_reference; - typedef typename std::allocator_traits<Alloc>::pointer pointer; - typedef typename std::allocator_traits<Alloc>::const_pointer const_pointer; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef typename std::allocator_traits<Alloc>::value_type& reference; + typedef const typename std::allocator_traits<Alloc>::value_type& const_reference; + typedef typename std::allocator_traits<Alloc>::pointer pointer; + typedef typename std::allocator_traits<Alloc>::const_pointer const_pointer; }; diff --git a/contrib/restricted/boost/boost/heap/detail/tree_iterator.hpp b/contrib/restricted/boost/boost/heap/detail/tree_iterator.hpp index ced7b9ba48..d4fc1bbe9b 100644 --- a/contrib/restricted/boost/boost/heap/detail/tree_iterator.hpp +++ b/contrib/restricted/boost/boost/heap/detail/tree_iterator.hpp @@ -57,7 +57,7 @@ template <typename HandleType, > struct unordered_tree_iterator_storage { - unordered_tree_iterator_storage(ValueCompare const & /* cmp */) + unordered_tree_iterator_storage(ValueCompare const & /* cmp */) {} void push(HandleType h) diff --git a/contrib/restricted/boost/boost/heap/heap_merge.hpp b/contrib/restricted/boost/boost/heap/heap_merge.hpp index 133194d2a9..30b403adfd 100644 --- a/contrib/restricted/boost/boost/heap/heap_merge.hpp +++ b/contrib/restricted/boost/boost/heap/heap_merge.hpp @@ -27,7 +27,7 @@ struct heap_merge_emulate { struct dummy_reserver { - static void reserve (Heap1 & /* lhs */, std::size_t /* required_size */) + static void reserve (Heap1 & /* lhs */, std::size_t /* required_size */) {} }; diff --git a/contrib/restricted/boost/boost/log/attributes/named_scope.hpp b/contrib/restricted/boost/boost/log/attributes/named_scope.hpp index dea5c651e8..1e65d10aab 100644 --- a/contrib/restricted/boost/boost/log/attributes/named_scope.hpp +++ b/contrib/restricted/boost/boost/log/attributes/named_scope.hpp @@ -124,13 +124,13 @@ public: typedef std::allocator< named_scope_entry > allocator_type; // Standard types - typedef named_scope_entry value_type; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef value_type const& const_reference; + typedef named_scope_entry value_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef value_type const& const_reference; #ifndef BOOST_LOG_DOXYGEN_PASS diff --git a/contrib/restricted/boost/boost/move/algo/predicate.hpp b/contrib/restricted/boost/boost/move/algo/predicate.hpp index 01f9586e89..1dbc4b1dc7 100644 --- a/contrib/restricted/boost/boost/move/algo/predicate.hpp +++ b/contrib/restricted/boost/boost/move/algo/predicate.hpp @@ -28,10 +28,10 @@ struct antistable : m_comp(comp) {} - antistable(const antistable & other) - : m_comp(other.m_comp) - {} - + antistable(const antistable & other) + : m_comp(other.m_comp) + {} + template<class U, class V> bool operator()(const U &u, const V & v) { return !m_comp(v, u); } diff --git a/contrib/restricted/boost/boost/multi_array.hpp b/contrib/restricted/boost/boost/multi_array.hpp index 44dfab3928..0fb36dc0e3 100644 --- a/contrib/restricted/boost/boost/multi_array.hpp +++ b/contrib/restricted/boost/boost/multi_array.hpp @@ -475,7 +475,7 @@ public: private: void allocate_space() { - base_ = allocator_.allocate(this->num_elements()); + base_ = allocator_.allocate(this->num_elements()); this->set_base_ptr(base_); allocated_elements_ = this->num_elements(); std::uninitialized_fill_n(base_,allocated_elements_,T()); @@ -484,7 +484,7 @@ private: void deallocate_space() { if(base_) { for(T* i = base_; i != base_+allocated_elements_; ++i) - std::destroy_at(i); + std::destroy_at(i); allocator_.deallocate(base_,allocated_elements_); } } diff --git a/contrib/restricted/boost/boost/numeric/ublas/banded.hpp b/contrib/restricted/boost/boost/numeric/ublas/banded.hpp index 6e866d975b..bf61c22dcb 100644 --- a/contrib/restricted/boost/boost/numeric/ublas/banded.hpp +++ b/contrib/restricted/boost/boost/numeric/ublas/banded.hpp @@ -493,11 +493,11 @@ public: const_iterator1 (const iterator1 &it): container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -673,11 +673,11 @@ public: iterator1 (self_type &m, size_type it1, size_type it2): container_reference<self_type> (m), it1_ (it1), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator1 (const iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator1 (const iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator1 &operator ++ () { @@ -823,11 +823,11 @@ public: const_iterator2 (const iterator2 &it): container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -1004,11 +1004,11 @@ public: iterator2 (self_type &m, size_type it1, size_type it2): container_reference<self_type> (m), it1_ (it1), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator2 (const iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator2 (const iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator2 &operator ++ () { @@ -1598,11 +1598,11 @@ public: const_iterator1 (const iterator1 &it): container_const_reference<self_type> (it ()), it1_ (it.it1_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -1791,11 +1791,11 @@ public: iterator1 (self_type &m, const subiterator1_type &it1): container_reference<self_type> (m), it1_ (it1) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator1 (const iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator1 (const iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator1 &operator ++ () { @@ -1954,11 +1954,11 @@ public: const_iterator2 (const iterator2 &it): container_const_reference<self_type> (it ()), it2_ (it.it2_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -2147,11 +2147,11 @@ public: iterator2 (self_type &m, const subiterator2_type &it2): container_reference<self_type> (m), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator2 (const iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator2 (const iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator2 &operator ++ () { diff --git a/contrib/restricted/boost/boost/numeric/ublas/detail/iterator.hpp b/contrib/restricted/boost/boost/numeric/ublas/detail/iterator.hpp index 033f2d8d9a..9bbd893a84 100644 --- a/contrib/restricted/boost/boost/numeric/ublas/detail/iterator.hpp +++ b/contrib/restricted/boost/boost/numeric/ublas/detail/iterator.hpp @@ -663,11 +663,11 @@ namespace boost { namespace numeric { namespace ublas { indexed_iterator (container_type &c, size_type it): container_reference<container_type> (c), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - indexed_iterator (const indexed_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + indexed_iterator (const indexed_iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE indexed_iterator &operator ++ () { diff --git a/contrib/restricted/boost/boost/numeric/ublas/matrix.hpp b/contrib/restricted/boost/boost/numeric/ublas/matrix.hpp index 2ab35a8738..24c66ddb22 100644 --- a/contrib/restricted/boost/boost/numeric/ublas/matrix.hpp +++ b/contrib/restricted/boost/boost/numeric/ublas/matrix.hpp @@ -481,11 +481,11 @@ namespace boost { namespace numeric { const_iterator1 (const iterator1 &it): container_const_reference<self_type> (it ()), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -664,11 +664,11 @@ namespace boost { namespace numeric { iterator1 (self_type &m, const subiterator_type &it): container_reference<self_type> (m), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator1 (const iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator1 (const iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator1 &operator ++ () { @@ -814,11 +814,11 @@ namespace boost { namespace numeric { const_iterator2 (const iterator2 &it): container_const_reference<self_type> (it ()), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -997,11 +997,11 @@ namespace boost { namespace numeric { iterator2 (self_type &m, const subiterator_type &it): container_reference<self_type> (m), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator2 (const iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator2 (const iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator2 &operator ++ () { @@ -1583,11 +1583,11 @@ namespace boost { namespace numeric { const_iterator1 (const iterator1 &it): container_const_reference<self_type> (it ()), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -1766,11 +1766,11 @@ namespace boost { namespace numeric { iterator1 (self_type &m, const subiterator_type &it): container_reference<self_type> (m), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator1 (const iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator1 (const iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator1 &operator ++ () { @@ -1916,11 +1916,11 @@ namespace boost { namespace numeric { const_iterator2 (const iterator2 &it): container_const_reference<self_type> (it ()), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -2099,11 +2099,11 @@ namespace boost { namespace numeric { iterator2 (self_type &m, const subiterator_type &it): container_reference<self_type> (m), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator2 (const iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator2 (const iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator2 &operator ++ () { @@ -2686,11 +2686,11 @@ namespace boost { namespace numeric { const_iterator1 (const iterator1 &it): container_const_reference<self_type> (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -2886,11 +2886,11 @@ namespace boost { namespace numeric { iterator1 (self_type &m, size_type i, size_type j, const subiterator_type &it): container_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator1 (const iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator1 (const iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator1 &operator ++ () { @@ -3053,11 +3053,11 @@ namespace boost { namespace numeric { const_iterator2 (const iterator2 &it): container_const_reference<self_type> (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -3253,11 +3253,11 @@ namespace boost { namespace numeric { iterator2 (self_type &m, size_type i, size_type j, const subiterator_type &it): container_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator2 (const iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator2 (const iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator2 &operator ++ () { @@ -3615,11 +3615,11 @@ namespace boost { namespace numeric { const_iterator1 (const self_type &m): container_const_reference<self_type> (m) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -3766,11 +3766,11 @@ namespace boost { namespace numeric { const_iterator2 (const self_type &m): container_const_reference<self_type> (m) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -4268,11 +4268,11 @@ namespace boost { namespace numeric { const_iterator2 (const self_type &m, const const_subiterator_type &it): container_const_reference<self_type> (m), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -4615,11 +4615,11 @@ namespace boost { namespace numeric { const_iterator1 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2): container_const_reference<scalar_matrix> (m), it1_ (it1), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -4801,11 +4801,11 @@ namespace boost { namespace numeric { const_iterator2 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2): container_const_reference<scalar_matrix> (m), it1_ (it1), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -5364,11 +5364,11 @@ namespace boost { namespace numeric { const_iterator1 (const iterator1 &it): container_const_reference<self_type> (it ()), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -5548,11 +5548,11 @@ namespace boost { namespace numeric { iterator1 (self_type &m, const subiterator_type &it): container_reference<self_type> (m), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator1 (const iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator1 (const iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator1 &operator ++ () { @@ -5698,11 +5698,11 @@ namespace boost { namespace numeric { const_iterator2 (const iterator2 &it): container_const_reference<self_type> (it ()), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -5881,11 +5881,11 @@ namespace boost { namespace numeric { iterator2 (self_type &m, const subiterator_type &it): container_reference<self_type> (m), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator2 (const iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator2 (const iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator2 &operator ++ () { diff --git a/contrib/restricted/boost/boost/numeric/ublas/matrix_expression.hpp b/contrib/restricted/boost/boost/numeric/ublas/matrix_expression.hpp index 0a2837310a..ccec94abea 100644 --- a/contrib/restricted/boost/boost/numeric/ublas/matrix_expression.hpp +++ b/contrib/restricted/boost/boost/numeric/ublas/matrix_expression.hpp @@ -49,11 +49,11 @@ namespace boost { namespace numeric { namespace ublas { explicit matrix_reference (referred_type &e): e_ (e) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - matrix_reference (const matrix_reference&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + matrix_reference (const matrix_reference&) = default; +#endif + // Accessors BOOST_UBLAS_INLINE size_type size1 () const { @@ -1581,11 +1581,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator1 (const self_type &mu, const const_subiterator1_type &it): container_const_reference<self_type> (mu), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -1757,11 +1757,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator2 (const self_type &mu, const const_subiterator2_type &it): container_const_reference<self_type> (mu), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -2142,11 +2142,11 @@ namespace boost { namespace numeric { namespace ublas { const const_iterator21_type &it2, const const_iterator21_type &it2_end): container_const_reference<self_type> (mb), i_ (i), j_ (j), it1_ (it1), it1_end_ (it1_end), it2_ (it2), it2_end_ (it2_end) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + private: // Dense specializations BOOST_UBLAS_INLINE @@ -2498,11 +2498,11 @@ namespace boost { namespace numeric { namespace ublas { const const_iterator22_type &it2, const const_iterator22_type &it2_end): container_const_reference<self_type> (mb), i_ (i), j_ (j), it1_ (it1), it1_end_ (it1_end), it2_ (it2), it2_end_ (it2_end) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + private: // Dense access specializations BOOST_UBLAS_INLINE @@ -3047,11 +3047,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator1 (const self_type &mbs, const const_subiterator1_type &it1, const const_iterator21_type &it2): container_const_reference<self_type> (mbs), it1_ (it1), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -3231,11 +3231,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator2 (const self_type &mbs, const const_subiterator1_type &it1, const const_iterator22_type &it2): container_const_reference<self_type> (mbs), it1_ (it1), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -3580,11 +3580,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator1 (const self_type &mbs, const const_iterator11_type &it1, const const_subiterator2_type &it2): container_const_reference<self_type> (mbs), it1_ (it1), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -3764,11 +3764,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator2 (const self_type &mbs, const const_iterator12_type &it1, const const_subiterator2_type &it2): container_const_reference<self_type> (mbs), it1_ (it1), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -4123,11 +4123,11 @@ namespace boost { namespace numeric { namespace ublas { container_const_reference<self_type> (mvb), it1_ (it1) {} #endif -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + private: // Dense random access specialization BOOST_UBLAS_INLINE @@ -4534,11 +4534,11 @@ namespace boost { namespace numeric { namespace ublas { container_const_reference<self_type> (mvb), it2_ (it2) {} #endif -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + private: // Dense random access specialization BOOST_UBLAS_INLINE @@ -4984,11 +4984,11 @@ namespace boost { namespace numeric { namespace ublas { container_const_reference<self_type> (mmb), it1_ (it1), it2_ (it2) {} #endif -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + private: // Random access specialization BOOST_UBLAS_INLINE @@ -5251,11 +5251,11 @@ namespace boost { namespace numeric { namespace ublas { container_const_reference<self_type> (mmb), it1_ (it1), it2_ (it2) {} #endif -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + private: // Random access specialization BOOST_UBLAS_INLINE diff --git a/contrib/restricted/boost/boost/numeric/ublas/matrix_proxy.hpp b/contrib/restricted/boost/boost/numeric/ublas/matrix_proxy.hpp index ba61c5d6a6..3c661ca328 100644 --- a/contrib/restricted/boost/boost/numeric/ublas/matrix_proxy.hpp +++ b/contrib/restricted/boost/boost/numeric/ublas/matrix_proxy.hpp @@ -57,11 +57,11 @@ namespace boost { namespace numeric { namespace ublas { // BOOST_UBLAS_CHECK (i_ < data_.size1 (), bad_index ()); } -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - matrix_row (const matrix_row&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + matrix_row (const matrix_row&) = default; +#endif + // Accessors BOOST_UBLAS_INLINE size_type size () const { @@ -262,11 +262,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here container_const_reference<self_type> (it ()), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { @@ -372,11 +372,11 @@ namespace boost { namespace numeric { namespace ublas { iterator (self_type &mr, const subiterator_type &it): container_reference<self_type> (mr), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator (const iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator (const iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator &operator ++ () { @@ -545,11 +545,11 @@ namespace boost { namespace numeric { namespace ublas { // BOOST_UBLAS_CHECK (j_ < data_.size2 (), bad_index ()); } -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - matrix_column (const matrix_column&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + matrix_column (const matrix_column&) = default; +#endif + // Accessors BOOST_UBLAS_INLINE size_type size () const { @@ -750,11 +750,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here container_const_reference<self_type> (it ()), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { @@ -1032,11 +1032,11 @@ namespace boost { namespace numeric { namespace ublas { // BOOST_UBLAS_CHECK (r1_.size () == r2_.size (), bad_size ()); } -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - matrix_vector_range (const matrix_vector_range&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + matrix_vector_range (const matrix_vector_range&) = default; +#endif + // Accessors BOOST_UBLAS_INLINE size_type start1 () const { @@ -1228,11 +1228,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { @@ -1346,11 +1346,11 @@ namespace boost { namespace numeric { namespace ublas { iterator (self_type &mvr, const subiterator1_type &it1, const subiterator2_type &it2): container_reference<self_type> (mvr), it1_ (it1), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator (const iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator (const iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator &operator ++ () { @@ -1518,11 +1518,11 @@ namespace boost { namespace numeric { namespace ublas { // s2_.start () + s2_.stride () * (s2_.size () - (s2_.size () > 0)) <= data_.size2 (), bad_index ()); } -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - matrix_vector_slice (const matrix_vector_slice&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + matrix_vector_slice (const matrix_vector_slice&) = default; +#endif + // Accessors BOOST_UBLAS_INLINE size_type start1 () const { @@ -1724,11 +1724,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator (const typename self_type::iterator &it): // ISSUE vector:: stops VC8 using std::iterator here container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { @@ -1842,11 +1842,11 @@ namespace boost { namespace numeric { namespace ublas { iterator (self_type &mvs, const subiterator1_type &it1, const subiterator2_type &it2): container_reference<self_type> (mvs), it1_ (it1), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator (const iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator (const iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator &operator ++ () { @@ -2215,11 +2215,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { @@ -2333,11 +2333,11 @@ namespace boost { namespace numeric { namespace ublas { iterator (self_type &mvi, const subiterator1_type &it1, const subiterator2_type &it2): container_reference<self_type> (mvi), it1_ (it1), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator (const iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator (const iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator &operator ++ () { @@ -2514,11 +2514,11 @@ namespace boost { namespace numeric { namespace ublas { // r2_.start () + r2_.size () <= data_.size2 (), bad_index ()); } -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - matrix_range (const matrix_range&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + matrix_range (const matrix_range&) = default; +#endif + // Accessors BOOST_UBLAS_INLINE size_type start1 () const { @@ -2752,11 +2752,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator1 (const iterator1 &it): container_const_reference<self_type> (it ()), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -2928,11 +2928,11 @@ namespace boost { namespace numeric { namespace ublas { iterator1 (self_type &mr, const subiterator1_type &it): container_reference<self_type> (mr), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator1 (const iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator1 (const iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator1 &operator ++ () { @@ -3073,11 +3073,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator2 (const iterator2 &it): container_const_reference<self_type> (it ()), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -3249,11 +3249,11 @@ namespace boost { namespace numeric { namespace ublas { iterator2 (self_type &mr, const subiterator2_type &it): container_reference<self_type> (mr), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator2 (const iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator2 (const iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator2 &operator ++ () { @@ -3531,11 +3531,11 @@ namespace boost { namespace numeric { namespace ublas { // s2_.start () + s2_.stride () * (s2_.size () - (s2_.size () > 0)) <= data_.size2 (), bad_index ()); } -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - matrix_slice (const matrix_slice&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + matrix_slice (const matrix_slice&) = default; +#endif + // Accessors BOOST_UBLAS_INLINE size_type start1 () const { @@ -3775,11 +3775,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator1 (const iterator1 &it): container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -3955,11 +3955,11 @@ namespace boost { namespace numeric { namespace ublas { iterator1 (self_type &ms, const subiterator1_type &it1, const subiterator2_type &it2): container_reference<self_type> (ms), it1_ (it1), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator1 (const iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator1 (const iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator1 &operator ++ () { @@ -4104,11 +4104,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator2 (const iterator2 &it): container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -4284,11 +4284,11 @@ namespace boost { namespace numeric { namespace ublas { iterator2 (self_type &ms, const subiterator1_type &it1, const subiterator2_type &it2): container_reference<self_type> (ms), it1_ (it1), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator2 (const iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator2 (const iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator2 &operator ++ () { @@ -4835,11 +4835,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator1 (const iterator1 &it): container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -5015,11 +5015,11 @@ namespace boost { namespace numeric { namespace ublas { iterator1 (self_type &mi, const subiterator1_type &it1, const subiterator2_type &it2): container_reference<self_type> (mi), it1_ (it1), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator1 (const iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator1 (const iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator1 &operator ++ () { @@ -5164,11 +5164,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator2 (const iterator2 &it): container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -5344,11 +5344,11 @@ namespace boost { namespace numeric { namespace ublas { iterator2 (self_type &mi, const subiterator1_type &it1, const subiterator2_type &it2): container_reference<self_type> (mi), it1_ (it1), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator2 (const iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator2 (const iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator2 &operator ++ () { diff --git a/contrib/restricted/boost/boost/numeric/ublas/matrix_sparse.hpp b/contrib/restricted/boost/boost/numeric/ublas/matrix_sparse.hpp index 13f715dd24..ed43b76c18 100644 --- a/contrib/restricted/boost/boost/numeric/ublas/matrix_sparse.hpp +++ b/contrib/restricted/boost/boost/numeric/ublas/matrix_sparse.hpp @@ -699,11 +699,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator1 (const iterator1 &it): container_const_reference<self_type> (it ()), rank_ (it.rank_), i_ (it.i_), j_ (it.j_), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -886,11 +886,11 @@ namespace boost { namespace numeric { namespace ublas { iterator1 (self_type &m, int rank, size_type i, size_type j, const subiterator_type &it): container_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator1 (const iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator1 (const iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator1 &operator ++ () { @@ -1042,11 +1042,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator2 (const iterator2 &it): container_const_reference<self_type> (it ()), rank_ (it.rank_), i_ (it.i_), j_ (it.j_), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -1229,11 +1229,11 @@ namespace boost { namespace numeric { namespace ublas { iterator2 (self_type &m, int rank, size_type i, size_type j, const subiterator_type &it): container_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator2 (const iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator2 (const iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator2 &operator ++ () { @@ -1976,11 +1976,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator1 (const iterator1 &it): container_const_reference<self_type> (it ()), rank_ (it.rank_), i_ (it.i_), j_ (it.j_), itv_ (it.itv_), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -2192,11 +2192,11 @@ namespace boost { namespace numeric { namespace ublas { iterator1 (self_type &m, int rank, size_type i, size_type j, const vector_subiterator_type &itv, const subiterator_type &it): container_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator1 (const iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator1 (const iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator1 &operator ++ () { @@ -2377,11 +2377,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator2 (const iterator2 &it): container_const_reference<self_type> (it ()), rank_ (it.rank_), i_ (it.i_), j_ (it.j_), itv_ (it.itv_), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -2593,11 +2593,11 @@ namespace boost { namespace numeric { namespace ublas { iterator2 (self_type &m, int rank, size_type i, size_type j, const vector_subiterator_type &itv, const subiterator_type &it): container_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator2 (const iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator2 (const iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator2 &operator ++ () { @@ -3523,11 +3523,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator1 (const iterator1 &it): container_const_reference<self_type> (it ()), rank_ (it.rank_), i_ (it.i_), j_ (it.j_), itv_ (it.itv_), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -3716,11 +3716,11 @@ namespace boost { namespace numeric { namespace ublas { iterator1 (self_type &m, int rank, size_type i, size_type j, const vector_subiterator_type &itv, const subiterator_type &it): container_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator1 (const iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator1 (const iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator1 &operator ++ () { @@ -3878,11 +3878,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator2 (const iterator2 &it): container_const_reference<self_type> (it ()), rank_ (it.rank_), i_ (it.i_), j_ (it.j_), itv_ (it.itv_), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -4071,11 +4071,11 @@ namespace boost { namespace numeric { namespace ublas { iterator2 (self_type &m, int rank, size_type i, size_type j, const vector_subiterator_type &itv, const subiterator_type &it): container_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator2(const iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator2(const iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator2 &operator ++ () { @@ -5047,11 +5047,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator1 (const iterator1 &it): container_const_reference<self_type> (it ()), rank_ (it.rank_), i_ (it.i_), j_ (it.j_), itv_ (it.itv_), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -5240,11 +5240,11 @@ namespace boost { namespace numeric { namespace ublas { iterator1 (self_type &m, int rank, size_type i, size_type j, const vector_subiterator_type &itv, const subiterator_type &it): container_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator1 (const iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator1 (const iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator1 &operator ++ () { @@ -5402,11 +5402,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator2 (const iterator2 &it): container_const_reference<self_type> (it ()), rank_ (it.rank_), i_ (it.i_), j_ (it.j_), itv_ (it.itv_), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -5595,11 +5595,11 @@ namespace boost { namespace numeric { namespace ublas { iterator2 (self_type &m, int rank, size_type i, size_type j, const vector_subiterator_type &itv, const subiterator_type &it): container_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator2 (const iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator2 (const iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator2 &operator ++ () { diff --git a/contrib/restricted/boost/boost/numeric/ublas/storage.hpp b/contrib/restricted/boost/boost/numeric/ublas/storage.hpp index 819979994d..bfe90a7e3c 100644 --- a/contrib/restricted/boost/boost/numeric/ublas/storage.hpp +++ b/contrib/restricted/boost/boost/numeric/ublas/storage.hpp @@ -1056,11 +1056,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator (const basic_range &r, const const_subiterator_type &it): container_const_reference<basic_range> (r), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { @@ -1298,11 +1298,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator (const basic_slice &s, const const_subiterator_type &it): container_const_reference<basic_slice> (s), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { @@ -1584,11 +1584,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator (const indirect_array &ia, const const_subiterator_type &it): container_const_reference<indirect_array> (ia), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { diff --git a/contrib/restricted/boost/boost/numeric/ublas/symmetric.hpp b/contrib/restricted/boost/boost/numeric/ublas/symmetric.hpp index 27beb1e323..1f51b0869d 100644 --- a/contrib/restricted/boost/boost/numeric/ublas/symmetric.hpp +++ b/contrib/restricted/boost/boost/numeric/ublas/symmetric.hpp @@ -326,11 +326,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator1 (const iterator1 &it): container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -505,11 +505,11 @@ namespace boost { namespace numeric { namespace ublas { iterator1 (self_type &m, size_type it1, size_type it2): container_reference<self_type> (m), it1_ (it1), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator1 (const iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator1 (const iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator1 &operator ++ () { @@ -654,11 +654,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator2 (const iterator2 &it): container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -834,11 +834,11 @@ namespace boost { namespace numeric { namespace ublas { iterator2 (self_type &m, size_type it1, size_type it2): container_reference<self_type> (m), it1_ (it1), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator2 (const iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator2 (const iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator2 &operator ++ () { @@ -1339,11 +1339,11 @@ namespace boost { namespace numeric { namespace ublas { (current_ == 1 && it2_ != it2_end_), internal_logic ()); } -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -1659,11 +1659,11 @@ namespace boost { namespace numeric { namespace ublas { iterator1 (self_type &m, const subiterator1_type &it1): container_reference<self_type> (m), it1_ (it1) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator1 (const iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator1 (const iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator1 &operator ++ () { @@ -1832,11 +1832,11 @@ namespace boost { namespace numeric { namespace ublas { (current_ == 1 && it2_ != it2_end_), internal_logic ()); } -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -2152,11 +2152,11 @@ namespace boost { namespace numeric { namespace ublas { iterator2 (self_type &m, const subiterator2_type &it2): container_reference<self_type> (m), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator2 (const iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator2 (const iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator2 &operator ++ () { diff --git a/contrib/restricted/boost/boost/numeric/ublas/triangular.hpp b/contrib/restricted/boost/boost/numeric/ublas/triangular.hpp index 3e9a834253..2f4969d7c0 100644 --- a/contrib/restricted/boost/boost/numeric/ublas/triangular.hpp +++ b/contrib/restricted/boost/boost/numeric/ublas/triangular.hpp @@ -368,11 +368,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator1 (const iterator1 &it): container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -548,11 +548,11 @@ namespace boost { namespace numeric { namespace ublas { iterator1 (self_type &m, size_type it1, size_type it2): container_reference<self_type> (m), it1_ (it1), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator1 (const iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator1 (const iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator1 &operator ++ () { @@ -697,11 +697,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator2 (const iterator2 &it): container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -878,11 +878,11 @@ namespace boost { namespace numeric { namespace ublas { iterator2 (self_type &m, size_type it1, size_type it2): container_reference<self_type> (m), it1_ (it1), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator2 (const iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator2 (const iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator2 &operator ++ () { @@ -1336,11 +1336,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator1 (const iterator1 &it): container_const_reference<self_type> (it ()), it1_ (it.it1_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator1 (const const_iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator1 (const const_iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { @@ -1520,11 +1520,11 @@ namespace boost { namespace numeric { namespace ublas { iterator1 (self_type &m, const subiterator1_type &it1): container_reference<self_type> (m), it1_ (it1) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator1 (const iterator1&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator1 (const iterator1&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator1 &operator ++ () { @@ -1672,11 +1672,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator2 (const iterator2 &it): container_const_reference<self_type> (it ()), it2_ (it.it2_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator2 (const const_iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator2 (const const_iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { @@ -1855,11 +1855,11 @@ namespace boost { namespace numeric { namespace ublas { iterator2 (self_type &m, const subiterator2_type &it2): container_reference<self_type> (m), it2_ (it2) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator2 (const iterator2&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator2 (const iterator2&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator2 &operator ++ () { diff --git a/contrib/restricted/boost/boost/numeric/ublas/vector.hpp b/contrib/restricted/boost/boost/numeric/ublas/vector.hpp index e867ff625c..291da6f9f5 100644 --- a/contrib/restricted/boost/boost/numeric/ublas/vector.hpp +++ b/contrib/restricted/boost/boost/numeric/ublas/vector.hpp @@ -537,12 +537,12 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_INLINE const_iterator (const typename self_type::iterator &it): // ISSUE vector:: stops VC8 using std::iterator here container_const_reference<self_type> (it ()), it_ (it.it_) {} - -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - + +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + // ---------- // Arithmetic // ---------- @@ -690,11 +690,11 @@ namespace boost { namespace numeric { namespace ublas { iterator (self_type &v, const subiterator_type &it): container_reference<self_type> (v), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator (const iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator (const iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator &operator ++ () { @@ -1326,11 +1326,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator (const typename self_type::iterator &it): // ISSUE vector:: stops VC8 using std::iterator here container_const_reference<self_type> (it ()), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + // ---------- // Arithmetic // ---------- @@ -1478,11 +1478,11 @@ namespace boost { namespace numeric { namespace ublas { iterator (self_type &v, const subiterator_type &it): container_reference<self_type> (v), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator (const iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator (const iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator &operator ++ () { @@ -1822,11 +1822,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator (const self_type &v): container_const_reference<self_type> (v) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { @@ -2082,11 +2082,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator (const unit_vector &v, const const_subiterator_type &it): container_const_reference<unit_vector> (v), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { @@ -2328,11 +2328,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator (const scalar_vector &v, const const_subiterator_type &it): container_const_reference<scalar_vector> (v), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { @@ -2743,11 +2743,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here container_const_reference<self_type> (it ()), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { @@ -2857,11 +2857,11 @@ namespace boost { namespace numeric { namespace ublas { iterator (self_type &v, const subiterator_type &it): container_reference<self_type> (v), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator (const iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator (const iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator &operator ++ () { diff --git a/contrib/restricted/boost/boost/numeric/ublas/vector_expression.hpp b/contrib/restricted/boost/boost/numeric/ublas/vector_expression.hpp index fc481549e2..31ce3258e6 100644 --- a/contrib/restricted/boost/boost/numeric/ublas/vector_expression.hpp +++ b/contrib/restricted/boost/boost/numeric/ublas/vector_expression.hpp @@ -49,11 +49,11 @@ namespace boost { namespace numeric { namespace ublas { explicit vector_reference (referred_type &e): e_ (e) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - vector_reference (const vector_reference&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + vector_reference (const vector_reference&) = default; +#endif + // Accessors BOOST_UBLAS_INLINE size_type size () const { diff --git a/contrib/restricted/boost/boost/numeric/ublas/vector_proxy.hpp b/contrib/restricted/boost/boost/numeric/ublas/vector_proxy.hpp index b85e29d635..1fbc74bb1e 100644 --- a/contrib/restricted/boost/boost/numeric/ublas/vector_proxy.hpp +++ b/contrib/restricted/boost/boost/numeric/ublas/vector_proxy.hpp @@ -73,11 +73,11 @@ namespace boost { namespace numeric { namespace ublas { // r_.start () + r_.size () <= data_.size (), bad_index ()); } -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - vector_range (const vector_range&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + vector_range (const vector_range&) = default; +#endif + // Accessors BOOST_UBLAS_INLINE size_type start () const { @@ -286,11 +286,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here container_const_reference<self_type> (it ()), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { @@ -655,11 +655,11 @@ namespace boost { namespace numeric { namespace ublas { // s_.start () + s_.stride () * (s_.size () - (s_.size () > 0)) <= data_.size (), bad_index ()); } -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - vector_slice (const vector_slice&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + vector_slice (const vector_slice&) = default; +#endif + // Accessors BOOST_UBLAS_INLINE size_type start () const { @@ -873,11 +873,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here container_const_reference<self_type> (it ()), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { @@ -984,11 +984,11 @@ namespace boost { namespace numeric { namespace ublas { iterator (self_type &vs, const subiterator_type &it): container_reference<self_type> (vs), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator (const iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator (const iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator &operator ++ () { @@ -1444,11 +1444,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here container_const_reference<self_type> (it ()), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { @@ -1555,11 +1555,11 @@ namespace boost { namespace numeric { namespace ublas { iterator (self_type &vi, const subiterator_type &it): container_reference<self_type> (vi), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator (const iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator (const iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator &operator ++ () { diff --git a/contrib/restricted/boost/boost/numeric/ublas/vector_sparse.hpp b/contrib/restricted/boost/boost/numeric/ublas/vector_sparse.hpp index e9d3bd6f99..d2b3f0d92d 100644 --- a/contrib/restricted/boost/boost/numeric/ublas/vector_sparse.hpp +++ b/contrib/restricted/boost/boost/numeric/ublas/vector_sparse.hpp @@ -598,11 +598,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here container_const_reference<self_type> (it ()), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { @@ -1231,11 +1231,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here container_const_reference<self_type> (it ()), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { @@ -1317,11 +1317,11 @@ namespace boost { namespace numeric { namespace ublas { iterator (self_type &v, const subiterator_type &it): container_reference<self_type> (v), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator (const iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator (const iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator &operator ++ () { @@ -2003,11 +2003,11 @@ namespace boost { namespace numeric { namespace ublas { const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here container_const_reference<self_type> (it ()), it_ (it.it_) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - const_iterator (const const_iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + const_iterator (const const_iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { @@ -2089,11 +2089,11 @@ namespace boost { namespace numeric { namespace ublas { iterator (self_type &v, const subiterator_type &it): container_reference<self_type> (v), it_ (it) {} -#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS - BOOST_UBLAS_INLINE - iterator (const iterator&) = default; -#endif - +#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_UBLAS_INLINE + iterator (const iterator&) = default; +#endif + // Arithmetic BOOST_UBLAS_INLINE iterator &operator ++ () { diff --git a/contrib/restricted/boost/boost/phoenix/core/actor.hpp b/contrib/restricted/boost/boost/phoenix/core/actor.hpp index 8b42a988fc..4646d98d18 100644 --- a/contrib/restricted/boost/boost/phoenix/core/actor.hpp +++ b/contrib/restricted/boost/boost/phoenix/core/actor.hpp @@ -145,7 +145,7 @@ namespace boost { namespace phoenix BOOST_PROTO_BASIC_EXTENDS(expr_type, actor<Expr>, phoenix_domain) BOOST_PROTO_EXTENDS_SUBSCRIPT() - BOOST_PROTO_EXTENDS_ASSIGN_() + BOOST_PROTO_EXTENDS_ASSIGN_() template <typename Sig> struct result; @@ -224,8 +224,8 @@ namespace boost { namespace phoenix return phoenix::eval(*this, phoenix::context(env, default_actions())); } #endif - - BOOST_DELETED_FUNCTION(actor& operator=(actor const&)) + + BOOST_DELETED_FUNCTION(actor& operator=(actor const&)) }; }} diff --git a/contrib/restricted/boost/boost/phoenix/stl/algorithm/detail/is_unordered_set_or_map.hpp b/contrib/restricted/boost/boost/phoenix/stl/algorithm/detail/is_unordered_set_or_map.hpp index 0c4920924a..8dfbb5f629 100644 --- a/contrib/restricted/boost/boost/phoenix/stl/algorithm/detail/is_unordered_set_or_map.hpp +++ b/contrib/restricted/boost/boost/phoenix/stl/algorithm/detail/is_unordered_set_or_map.hpp @@ -24,8 +24,8 @@ #include <boost/mpl/bool.hpp> #ifdef BOOST_PHOENIX_HAS_UNORDERED_SET_AND_MAP -#include <unordered_set> -#include <unordered_map> +#include <unordered_set> +#include <unordered_map> #endif namespace boost diff --git a/contrib/restricted/boost/boost/range/algorithm/random_shuffle.hpp b/contrib/restricted/boost/boost/range/algorithm/random_shuffle.hpp index 33e98e04be..1e656d7390 100644 --- a/contrib/restricted/boost/boost/range/algorithm/random_shuffle.hpp +++ b/contrib/restricted/boost/boost/range/algorithm/random_shuffle.hpp @@ -14,85 +14,85 @@ #include <boost/range/end.hpp> #include <boost/range/concepts.hpp> #include <algorithm> -#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE -#include <cstdlib> -#endif +#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE +#include <cstdlib> +#endif namespace boost { namespace range { - namespace detail - { -#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE - -// wrap std::rand as UniformRandomBitGenerator -struct wrap_rand -{ - typedef unsigned int result_type; - - static BOOST_CONSTEXPR result_type (min)() - { - return 0; - } - - static BOOST_CONSTEXPR result_type (max)() - { - return RAND_MAX; - } - - result_type operator()() - { - return std::rand(); - } -}; - -template< class RandomIt > -inline void random_shuffle(RandomIt first, RandomIt last) -{ - std::shuffle(first, last, wrap_rand()); -} - -// wrap Generator as UniformRandomBitGenerator -template< class Generator > -struct wrap_generator -{ - typedef unsigned int result_type; - static const int max_arg = ((0u - 1u) >> 2) + 1; - Generator& g; - - wrap_generator(Generator& gen) : g(gen) {} - - static BOOST_CONSTEXPR result_type (min)() - { - return 0; - } - - static BOOST_CONSTEXPR result_type (max)() - { - return max_arg - 1; - } - - result_type operator()() - { - return static_cast<result_type>(g(max_arg)); - } -}; - -template< class RandomIt, class Generator > -inline void random_shuffle(RandomIt first, RandomIt last, Generator& gen) -{ - std::shuffle(first, last, wrap_generator< Generator >(gen)); -} - -#else - -using std::random_shuffle; - -#endif - } // namespace detail - + namespace detail + { +#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE + +// wrap std::rand as UniformRandomBitGenerator +struct wrap_rand +{ + typedef unsigned int result_type; + + static BOOST_CONSTEXPR result_type (min)() + { + return 0; + } + + static BOOST_CONSTEXPR result_type (max)() + { + return RAND_MAX; + } + + result_type operator()() + { + return std::rand(); + } +}; + +template< class RandomIt > +inline void random_shuffle(RandomIt first, RandomIt last) +{ + std::shuffle(first, last, wrap_rand()); +} + +// wrap Generator as UniformRandomBitGenerator +template< class Generator > +struct wrap_generator +{ + typedef unsigned int result_type; + static const int max_arg = ((0u - 1u) >> 2) + 1; + Generator& g; + + wrap_generator(Generator& gen) : g(gen) {} + + static BOOST_CONSTEXPR result_type (min)() + { + return 0; + } + + static BOOST_CONSTEXPR result_type (max)() + { + return max_arg - 1; + } + + result_type operator()() + { + return static_cast<result_type>(g(max_arg)); + } +}; + +template< class RandomIt, class Generator > +inline void random_shuffle(RandomIt first, RandomIt last, Generator& gen) +{ + std::shuffle(first, last, wrap_generator< Generator >(gen)); +} + +#else + +using std::random_shuffle; + +#endif + } // namespace detail + /// \brief template function random_shuffle /// /// range-based version of the random_shuffle std algorithm @@ -103,7 +103,7 @@ template<class RandomAccessRange> inline RandomAccessRange& random_shuffle(RandomAccessRange& rng) { BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> )); - detail::random_shuffle(boost::begin(rng), boost::end(rng)); + detail::random_shuffle(boost::begin(rng), boost::end(rng)); return rng; } @@ -112,7 +112,7 @@ template<class RandomAccessRange> inline const RandomAccessRange& random_shuffle(const RandomAccessRange& rng) { BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> )); - detail::random_shuffle(boost::begin(rng), boost::end(rng)); + detail::random_shuffle(boost::begin(rng), boost::end(rng)); return rng; } @@ -121,7 +121,7 @@ template<class RandomAccessRange, class Generator> inline RandomAccessRange& random_shuffle(RandomAccessRange& rng, Generator& gen) { BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> )); - detail::random_shuffle(boost::begin(rng), boost::end(rng), gen); + detail::random_shuffle(boost::begin(rng), boost::end(rng), gen); return rng; } @@ -130,7 +130,7 @@ template<class RandomAccessRange, class Generator> inline const RandomAccessRange& random_shuffle(const RandomAccessRange& rng, Generator& gen) { BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> )); - detail::random_shuffle(boost::begin(rng), boost::end(rng), gen); + detail::random_shuffle(boost::begin(rng), boost::end(rng), gen); return rng; } diff --git a/contrib/restricted/boost/boost/regex/v4/match_results.hpp b/contrib/restricted/boost/boost/regex/v4/match_results.hpp index fc4105d462..4b18bb9c3c 100644 --- a/contrib/restricted/boost/boost/regex/v4/match_results.hpp +++ b/contrib/restricted/boost/boost/regex/v4/match_results.hpp @@ -62,7 +62,7 @@ public: typedef const_iterator iterator; typedef typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits< BidiIterator>::difference_type difference_type; - typedef size_t size_type; + typedef size_t size_type; typedef Allocator allocator_type; typedef typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits< BidiIterator>::value_type char_type; diff --git a/contrib/restricted/boost/boost/spirit/home/karma/auto/auto.hpp b/contrib/restricted/boost/boost/spirit/home/karma/auto/auto.hpp index e660298887..77328ec574 100644 --- a/contrib/restricted/boost/boost/spirit/home/karma/auto/auto.hpp +++ b/contrib/restricted/boost/boost/spirit/home/karma/auto/auto.hpp @@ -147,7 +147,7 @@ namespace boost { namespace spirit { namespace karma generator_impl_type generator_; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(lit_auto_generator& operator= (lit_auto_generator const&)); + BOOST_DELETED_FUNCTION(lit_auto_generator& operator= (lit_auto_generator const&)); }; /////////////////////////////////////////////////////////////////////////// diff --git a/contrib/restricted/boost/boost/spirit/home/karma/auxiliary/lazy.hpp b/contrib/restricted/boost/boost/spirit/home/karma/auxiliary/lazy.hpp index ada7bc5187..704c4bb356 100644 --- a/contrib/restricted/boost/boost/spirit/home/karma/auxiliary/lazy.hpp +++ b/contrib/restricted/boost/boost/spirit/home/karma/auxiliary/lazy.hpp @@ -140,7 +140,7 @@ namespace boost { namespace spirit { namespace karma Modifiers modifiers; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(lazy_generator& operator= (lazy_generator const&)); + BOOST_DELETED_FUNCTION(lazy_generator& operator= (lazy_generator const&)); }; /////////////////////////////////////////////////////////////////////////// diff --git a/contrib/restricted/boost/boost/spirit/home/karma/detail/alternative_function.hpp b/contrib/restricted/boost/boost/spirit/home/karma/detail/alternative_function.hpp index adb601a977..40250392bd 100644 --- a/contrib/restricted/boost/boost/spirit/home/karma/detail/alternative_function.hpp +++ b/contrib/restricted/boost/boost/spirit/home/karma/detail/alternative_function.hpp @@ -192,7 +192,7 @@ namespace boost { namespace spirit { namespace karma { namespace detail Attribute const& attr; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(alternative_generate_function& operator= (alternative_generate_function const&)); + BOOST_DELETED_FUNCTION(alternative_generate_function& operator= (alternative_generate_function const&)); }; // specialization for strict alternatives @@ -241,7 +241,7 @@ namespace boost { namespace spirit { namespace karma { namespace detail bool failed; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(alternative_generate_function& operator= (alternative_generate_function const&)); + BOOST_DELETED_FUNCTION(alternative_generate_function& operator= (alternative_generate_function const&)); }; }}}} diff --git a/contrib/restricted/boost/boost/spirit/home/karma/detail/fail_function.hpp b/contrib/restricted/boost/boost/spirit/home/karma/detail/fail_function.hpp index c4c84df1c6..94c4910329 100644 --- a/contrib/restricted/boost/boost/spirit/home/karma/detail/fail_function.hpp +++ b/contrib/restricted/boost/boost/spirit/home/karma/detail/fail_function.hpp @@ -51,7 +51,7 @@ namespace boost { namespace spirit { namespace karma { namespace detail Delimiter const& delim; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(fail_function& operator= (fail_function const&)); + BOOST_DELETED_FUNCTION(fail_function& operator= (fail_function const&)); }; }}}} diff --git a/contrib/restricted/boost/boost/spirit/home/karma/detail/pass_container.hpp b/contrib/restricted/boost/boost/spirit/home/karma/detail/pass_container.hpp index 21adf54ee7..0234f6db50 100644 --- a/contrib/restricted/boost/boost/spirit/home/karma/detail/pass_container.hpp +++ b/contrib/restricted/boost/boost/spirit/home/karma/detail/pass_container.hpp @@ -384,7 +384,7 @@ namespace boost { namespace spirit { namespace karma { namespace detail F f; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(pass_container& operator= (pass_container const&)); + BOOST_DELETED_FUNCTION(pass_container& operator= (pass_container const&)); }; }}}} diff --git a/contrib/restricted/boost/boost/spirit/home/karma/detail/unused_delimiter.hpp b/contrib/restricted/boost/boost/spirit/home/karma/detail/unused_delimiter.hpp index acb4fe2df5..5681db1d19 100644 --- a/contrib/restricted/boost/boost/spirit/home/karma/detail/unused_delimiter.hpp +++ b/contrib/restricted/boost/boost/spirit/home/karma/detail/unused_delimiter.hpp @@ -22,7 +22,7 @@ namespace boost { namespace spirit { namespace karma { namespace detail Delimiter const& delimiter; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(unused_delimiter& operator= (unused_delimiter const&)); + BOOST_DELETED_FUNCTION(unused_delimiter& operator= (unused_delimiter const&)); }; // If a surrounding verbatim[] directive was specified, the current diff --git a/contrib/restricted/boost/boost/spirit/home/karma/directive/columns.hpp b/contrib/restricted/boost/boost/spirit/home/karma/directive/columns.hpp index 274ab9a9f5..7b1958325e 100644 --- a/contrib/restricted/boost/boost/spirit/home/karma/directive/columns.hpp +++ b/contrib/restricted/boost/boost/spirit/home/karma/directive/columns.hpp @@ -110,7 +110,7 @@ namespace boost { namespace spirit { namespace karma mutable unsigned int count; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(columns_delimiter& operator= (columns_delimiter const&)); + BOOST_DELETED_FUNCTION(columns_delimiter& operator= (columns_delimiter const&)); }; } diff --git a/contrib/restricted/boost/boost/spirit/home/karma/directive/repeat.hpp b/contrib/restricted/boost/boost/spirit/home/karma/directive/repeat.hpp index fd3f528049..d202077108 100644 --- a/contrib/restricted/boost/boost/spirit/home/karma/directive/repeat.hpp +++ b/contrib/restricted/boost/boost/spirit/home/karma/directive/repeat.hpp @@ -92,7 +92,7 @@ namespace boost { namespace spirit { namespace karma T const exact; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(exact_iterator& operator= (exact_iterator const&)); + BOOST_DELETED_FUNCTION(exact_iterator& operator= (exact_iterator const&)); }; // handles repeat(min, max)[p] @@ -112,7 +112,7 @@ namespace boost { namespace spirit { namespace karma T const max; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(finite_iterator& operator= (finite_iterator const&)); + BOOST_DELETED_FUNCTION(finite_iterator& operator= (finite_iterator const&)); }; // handles repeat(min, inf)[p] @@ -130,7 +130,7 @@ namespace boost { namespace spirit { namespace karma T const min; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(infinite_iterator& operator= (infinite_iterator const&)); + BOOST_DELETED_FUNCTION(infinite_iterator& operator= (infinite_iterator const&)); }; /////////////////////////////////////////////////////////////////////////// diff --git a/contrib/restricted/boost/boost/spirit/home/karma/stream/detail/format_manip.hpp b/contrib/restricted/boost/boost/spirit/home/karma/stream/detail/format_manip.hpp index 982aed8e09..e876ee9b18 100644 --- a/contrib/restricted/boost/boost/spirit/home/karma/stream/detail/format_manip.hpp +++ b/contrib/restricted/boost/boost/spirit/home/karma/stream/detail/format_manip.hpp @@ -44,7 +44,7 @@ namespace boost { namespace spirit { namespace karma { namespace detail Attribute const& attr; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(format_manip& operator= (format_manip const&)); + BOOST_DELETED_FUNCTION(format_manip& operator= (format_manip const&)); }; template <typename Expr, typename Delimiter, typename Attribute> @@ -63,7 +63,7 @@ namespace boost { namespace spirit { namespace karma { namespace detail Attribute attr; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(format_manip& operator= (format_manip const&)); + BOOST_DELETED_FUNCTION(format_manip& operator= (format_manip const&)); }; template <typename Expr, typename Delimiter, typename Attribute> @@ -82,7 +82,7 @@ namespace boost { namespace spirit { namespace karma { namespace detail Attribute const& attr; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(format_manip& operator= (format_manip const&)); + BOOST_DELETED_FUNCTION(format_manip& operator= (format_manip const&)); }; /////////////////////////////////////////////////////////////////////////// diff --git a/contrib/restricted/boost/boost/spirit/home/karma/stream/detail/iterator_sink.hpp b/contrib/restricted/boost/boost/spirit/home/karma/stream/detail/iterator_sink.hpp index 290fbd712b..cd347634c4 100644 --- a/contrib/restricted/boost/boost/spirit/home/karma/stream/detail/iterator_sink.hpp +++ b/contrib/restricted/boost/boost/spirit/home/karma/stream/detail/iterator_sink.hpp @@ -46,7 +46,7 @@ namespace boost { namespace spirit { namespace karma { namespace detail OutputIterator& sink; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(iterator_sink& operator= (iterator_sink const&)); + BOOST_DELETED_FUNCTION(iterator_sink& operator= (iterator_sink const&)); }; }}}} diff --git a/contrib/restricted/boost/boost/spirit/home/karma/stream/stream.hpp b/contrib/restricted/boost/boost/spirit/home/karma/stream/stream.hpp index 32313b3cc3..0ecca43483 100644 --- a/contrib/restricted/boost/boost/spirit/home/karma/stream/stream.hpp +++ b/contrib/restricted/boost/boost/spirit/home/karma/stream/stream.hpp @@ -286,7 +286,7 @@ namespace boost { namespace spirit { namespace karma T t_; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(lit_stream_generator& operator= (lit_stream_generator const&)); + BOOST_DELETED_FUNCTION(lit_stream_generator& operator= (lit_stream_generator const&)); }; /////////////////////////////////////////////////////////////////////////// diff --git a/contrib/restricted/boost/boost/spirit/home/karma/string/symbols.hpp b/contrib/restricted/boost/boost/spirit/home/karma/string/symbols.hpp index 92626ff99f..1a8ec4ad97 100644 --- a/contrib/restricted/boost/boost/spirit/home/karma/string/symbols.hpp +++ b/contrib/restricted/boost/boost/spirit/home/karma/string/symbols.hpp @@ -412,7 +412,7 @@ namespace boost { namespace spirit { namespace karma symbols& sym; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(adder& operator= (adder const&)); + BOOST_DELETED_FUNCTION(adder& operator= (adder const&)); }; struct remover @@ -444,7 +444,7 @@ namespace boost { namespace spirit { namespace karma symbols& sym; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(remover& operator= (remover const&)); + BOOST_DELETED_FUNCTION(remover& operator= (remover const&)); }; adder add; @@ -669,7 +669,7 @@ namespace boost { namespace spirit { namespace karma symbols& sym; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(adder& operator= (adder const&)); + BOOST_DELETED_FUNCTION(adder& operator= (adder const&)); }; struct remover @@ -701,7 +701,7 @@ namespace boost { namespace spirit { namespace karma symbols& sym; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(remover& operator= (remover const&)); + BOOST_DELETED_FUNCTION(remover& operator= (remover const&)); }; adder add; diff --git a/contrib/restricted/boost/boost/spirit/home/lex/detail/sequence_function.hpp b/contrib/restricted/boost/boost/spirit/home/lex/detail/sequence_function.hpp index 8f560f1ed6..1bf021f654 100644 --- a/contrib/restricted/boost/boost/spirit/home/lex/detail/sequence_function.hpp +++ b/contrib/restricted/boost/boost/spirit/home/lex/detail/sequence_function.hpp @@ -34,7 +34,7 @@ namespace boost { namespace spirit { namespace lex { namespace detail String const& targetstate; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(sequence_collect_function& operator= (sequence_collect_function const&)); + BOOST_DELETED_FUNCTION(sequence_collect_function& operator= (sequence_collect_function const&)); }; template <typename LexerDef> @@ -53,7 +53,7 @@ namespace boost { namespace spirit { namespace lex { namespace detail LexerDef& def; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(sequence_add_actions_function& operator= (sequence_add_actions_function const&)); + BOOST_DELETED_FUNCTION(sequence_add_actions_function& operator= (sequence_add_actions_function const&)); }; }}}} diff --git a/contrib/restricted/boost/boost/spirit/home/lex/lexer/action.hpp b/contrib/restricted/boost/boost/spirit/home/lex/lexer/action.hpp index b2fa14668a..84f814c029 100644 --- a/contrib/restricted/boost/boost/spirit/home/lex/lexer/action.hpp +++ b/contrib/restricted/boost/boost/spirit/home/lex/lexer/action.hpp @@ -52,7 +52,7 @@ namespace boost { namespace spirit { namespace lex Action f; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(action& operator= (action const&)); + BOOST_DELETED_FUNCTION(action& operator= (action const&)); }; }}} diff --git a/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexer.hpp b/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexer.hpp index 9a8f0d3919..eef9248f39 100644 --- a/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexer.hpp +++ b/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexer.hpp @@ -182,7 +182,7 @@ namespace boost { namespace spirit { namespace lex lexer_def_& def; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(adder& operator= (adder const&)); + BOOST_DELETED_FUNCTION(adder& operator= (adder const&)); }; friend struct adder; @@ -203,7 +203,7 @@ namespace boost { namespace spirit { namespace lex lexer_def_& def; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(pattern_adder& operator= (pattern_adder const&)); + BOOST_DELETED_FUNCTION(pattern_adder& operator= (pattern_adder const&)); }; friend struct pattern_adder; @@ -279,7 +279,7 @@ namespace boost { namespace spirit { namespace lex string_type targetstate; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(lexer_def_& operator= (lexer_def_ const&)); + BOOST_DELETED_FUNCTION(lexer_def_& operator= (lexer_def_ const&)); }; #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) diff --git a/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexertl/functor.hpp b/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexertl/functor.hpp index 061ebd7064..c8f0378f5c 100644 --- a/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexertl/functor.hpp +++ b/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexertl/functor.hpp @@ -93,7 +93,7 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl T const& src_; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(assign_on_exit& operator= (assign_on_exit const&)); + BOOST_DELETED_FUNCTION(assign_on_exit& operator= (assign_on_exit const&)); }; public: diff --git a/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexertl/functor_data.hpp b/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexertl/functor_data.hpp index 55ffb902f3..51db0f4218 100644 --- a/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexertl/functor_data.hpp +++ b/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexertl/functor_data.hpp @@ -193,7 +193,7 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl bool bol_; // helper storing whether last character was \n // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(data& operator= (data const&)); + BOOST_DELETED_FUNCTION(data& operator= (data const&)); }; /////////////////////////////////////////////////////////////////////// @@ -265,7 +265,7 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl std::size_t state_; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(data& operator= (data const&)); + BOOST_DELETED_FUNCTION(data& operator= (data const&)); }; /////////////////////////////////////////////////////////////////////// @@ -400,7 +400,7 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl bool has_hold_; // 'true' if hold_ is valid // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(data& operator= (data const&)); + BOOST_DELETED_FUNCTION(data& operator= (data const&)); }; /////////////////////////////////////////////////////////////////////// @@ -539,7 +539,7 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl bool has_hold_; // 'true' if hold_ is valid // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(data& operator= (data const&)); + BOOST_DELETED_FUNCTION(data& operator= (data const&)); }; } }}}} diff --git a/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexertl/lexer.hpp b/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexertl/lexer.hpp index 874046a3a4..2f2f7e058e 100644 --- a/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexertl/lexer.hpp +++ b/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexertl/lexer.hpp @@ -188,7 +188,7 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl semantic_actions_type const& actions_; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(iterator_data_type& operator= (iterator_data_type const&)); + BOOST_DELETED_FUNCTION(iterator_data_type& operator= (iterator_data_type const&)); }; public: diff --git a/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexertl/static_functor_data.hpp b/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexertl/static_functor_data.hpp index da784abbc3..b880f28975 100644 --- a/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexertl/static_functor_data.hpp +++ b/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexertl/static_functor_data.hpp @@ -209,7 +209,7 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl bool bol_; // helper storing whether last character was \n // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(static_data& operator= (static_data const&)); + BOOST_DELETED_FUNCTION(static_data& operator= (static_data const&)); }; /////////////////////////////////////////////////////////////////////// @@ -283,7 +283,7 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl std::size_t num_states_; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(static_data& operator= (static_data const&)); + BOOST_DELETED_FUNCTION(static_data& operator= (static_data const&)); }; /////////////////////////////////////////////////////////////////////// @@ -421,7 +421,7 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl bool has_hold_; // 'true' if hold_ is valid // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(static_data& operator= (static_data const&)); + BOOST_DELETED_FUNCTION(static_data& operator= (static_data const&)); }; /////////////////////////////////////////////////////////////////////// @@ -560,7 +560,7 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl bool has_hold_; // 'true' if hold_ is valid // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(static_data& operator= (static_data const&)); + BOOST_DELETED_FUNCTION(static_data& operator= (static_data const&)); }; } }}}} diff --git a/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexertl/static_lexer.hpp b/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexertl/static_lexer.hpp index 1747002ebf..fd41bb971c 100644 --- a/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexertl/static_lexer.hpp +++ b/contrib/restricted/boost/boost/spirit/home/lex/lexer/lexertl/static_lexer.hpp @@ -152,7 +152,7 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl bool bol_; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(iterator_data_type& operator= (iterator_data_type const&)); + BOOST_DELETED_FUNCTION(iterator_data_type& operator= (iterator_data_type const&)); }; typedef LexerTables tables_type; diff --git a/contrib/restricted/boost/boost/spirit/home/lex/qi/state_switcher.hpp b/contrib/restricted/boost/boost/spirit/home/lex/qi/state_switcher.hpp index fd39c2f656..f98e89144c 100644 --- a/contrib/restricted/boost/boost/spirit/home/lex/qi/state_switcher.hpp +++ b/contrib/restricted/boost/boost/spirit/home/lex/qi/state_switcher.hpp @@ -155,7 +155,7 @@ namespace boost { namespace spirit { namespace qi std::size_t state; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(reset_state_on_exit& operator= (reset_state_on_exit const&)); + BOOST_DELETED_FUNCTION(reset_state_on_exit& operator= (reset_state_on_exit const&)); }; } @@ -214,7 +214,7 @@ namespace boost { namespace spirit { namespace qi State state; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(state_switcher_context& operator= (state_switcher_context const&)); + BOOST_DELETED_FUNCTION(state_switcher_context& operator= (state_switcher_context const&)); }; /////////////////////////////////////////////////////////////////////////// diff --git a/contrib/restricted/boost/boost/spirit/home/qi/action/action.hpp b/contrib/restricted/boost/boost/spirit/home/qi/action/action.hpp index dbaa3f7727..db63fffc57 100644 --- a/contrib/restricted/boost/boost/spirit/home/qi/action/action.hpp +++ b/contrib/restricted/boost/boost/spirit/home/qi/action/action.hpp @@ -145,7 +145,7 @@ namespace boost { namespace spirit { namespace qi Action f; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(action& operator= (action const&)); + BOOST_DELETED_FUNCTION(action& operator= (action const&)); }; }}} diff --git a/contrib/restricted/boost/boost/spirit/home/qi/auxiliary/attr.hpp b/contrib/restricted/boost/boost/spirit/home/qi/auxiliary/attr.hpp index 8b24083533..d4dd97436a 100644 --- a/contrib/restricted/boost/boost/spirit/home/qi/auxiliary/attr.hpp +++ b/contrib/restricted/boost/boost/spirit/home/qi/auxiliary/attr.hpp @@ -74,7 +74,7 @@ namespace boost { namespace spirit { namespace qi Value value_; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(attr_parser& operator= (attr_parser const&)); + BOOST_DELETED_FUNCTION(attr_parser& operator= (attr_parser const&)); }; /////////////////////////////////////////////////////////////////////////// diff --git a/contrib/restricted/boost/boost/spirit/home/qi/auxiliary/attr_cast.hpp b/contrib/restricted/boost/boost/spirit/home/qi/auxiliary/attr_cast.hpp index eef496ca5c..7286cd09e1 100644 --- a/contrib/restricted/boost/boost/spirit/home/qi/auxiliary/attr_cast.hpp +++ b/contrib/restricted/boost/boost/spirit/home/qi/auxiliary/attr_cast.hpp @@ -115,7 +115,7 @@ namespace boost { namespace spirit { namespace qi Subject subject; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(attr_cast_parser& operator= (attr_cast_parser const&)); + BOOST_DELETED_FUNCTION(attr_cast_parser& operator= (attr_cast_parser const&)); }; /////////////////////////////////////////////////////////////////////////// diff --git a/contrib/restricted/boost/boost/spirit/home/qi/detail/alternative_function.hpp b/contrib/restricted/boost/boost/spirit/home/qi/detail/alternative_function.hpp index dcb5af3d0a..b07fe17cbd 100644 --- a/contrib/restricted/boost/boost/spirit/home/qi/detail/alternative_function.hpp +++ b/contrib/restricted/boost/boost/spirit/home/qi/detail/alternative_function.hpp @@ -177,7 +177,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail Attribute& attr; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(alternative_function& operator= (alternative_function const&)); + BOOST_DELETED_FUNCTION(alternative_function& operator= (alternative_function const&)); }; template <typename Iterator, typename Context, typename Skipper> @@ -204,7 +204,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail Skipper const& skipper; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(alternative_function& operator= (alternative_function const&)); + BOOST_DELETED_FUNCTION(alternative_function& operator= (alternative_function const&)); }; }}}} diff --git a/contrib/restricted/boost/boost/spirit/home/qi/detail/expect_function.hpp b/contrib/restricted/boost/boost/spirit/home/qi/detail/expect_function.hpp index e7c1ee3550..6e72dec89b 100644 --- a/contrib/restricted/boost/boost/spirit/home/qi/detail/expect_function.hpp +++ b/contrib/restricted/boost/boost/spirit/home/qi/detail/expect_function.hpp @@ -97,7 +97,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail mutable bool is_first; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(expect_function& operator= (expect_function const&)); + BOOST_DELETED_FUNCTION(expect_function& operator= (expect_function const&)); }; }}}} diff --git a/contrib/restricted/boost/boost/spirit/home/qi/detail/fail_function.hpp b/contrib/restricted/boost/boost/spirit/home/qi/detail/fail_function.hpp index 45972a4b5d..551f38b9d5 100644 --- a/contrib/restricted/boost/boost/spirit/home/qi/detail/fail_function.hpp +++ b/contrib/restricted/boost/boost/spirit/home/qi/detail/fail_function.hpp @@ -51,7 +51,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail Skipper const& skipper; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(fail_function& operator= (fail_function const&)); + BOOST_DELETED_FUNCTION(fail_function& operator= (fail_function const&)); }; }}}} diff --git a/contrib/restricted/boost/boost/spirit/home/qi/detail/pass_container.hpp b/contrib/restricted/boost/boost/spirit/home/qi/detail/pass_container.hpp index 97e2906e2c..d1de04977f 100644 --- a/contrib/restricted/boost/boost/spirit/home/qi/detail/pass_container.hpp +++ b/contrib/restricted/boost/boost/spirit/home/qi/detail/pass_container.hpp @@ -355,7 +355,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail Attr& attr; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(pass_container& operator= (pass_container const&)); + BOOST_DELETED_FUNCTION(pass_container& operator= (pass_container const&)); }; /////////////////////////////////////////////////////////////////////////// diff --git a/contrib/restricted/boost/boost/spirit/home/qi/detail/pass_function.hpp b/contrib/restricted/boost/boost/spirit/home/qi/detail/pass_function.hpp index 8bfd6dcb83..af88b96fb4 100644 --- a/contrib/restricted/boost/boost/spirit/home/qi/detail/pass_function.hpp +++ b/contrib/restricted/boost/boost/spirit/home/qi/detail/pass_function.hpp @@ -62,7 +62,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail Skipper const& skipper; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(pass_function& operator= (pass_function const&)); + BOOST_DELETED_FUNCTION(pass_function& operator= (pass_function const&)); }; }}}} diff --git a/contrib/restricted/boost/boost/spirit/home/qi/detail/permute_function.hpp b/contrib/restricted/boost/boost/spirit/home/qi/detail/permute_function.hpp index bec82d9c15..f1dab702b9 100644 --- a/contrib/restricted/boost/boost/spirit/home/qi/detail/permute_function.hpp +++ b/contrib/restricted/boost/boost/spirit/home/qi/detail/permute_function.hpp @@ -64,7 +64,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail bool* taken; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(permute_function& operator= (permute_function const&)); + BOOST_DELETED_FUNCTION(permute_function& operator= (permute_function const&)); }; }}}} diff --git a/contrib/restricted/boost/boost/spirit/home/qi/detail/unused_skipper.hpp b/contrib/restricted/boost/boost/spirit/home/qi/detail/unused_skipper.hpp index 494881820e..0ea7cb4b6f 100644 --- a/contrib/restricted/boost/boost/spirit/home/qi/detail/unused_skipper.hpp +++ b/contrib/restricted/boost/boost/spirit/home/qi/detail/unused_skipper.hpp @@ -23,7 +23,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail Skipper const& skipper; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(unused_skipper& operator= (unused_skipper const&)); + BOOST_DELETED_FUNCTION(unused_skipper& operator= (unused_skipper const&)); }; template <typename Skipper> diff --git a/contrib/restricted/boost/boost/spirit/home/qi/directive/matches.hpp b/contrib/restricted/boost/boost/spirit/home/qi/directive/matches.hpp index 31daaaefab..bf41e351ac 100644 --- a/contrib/restricted/boost/boost/spirit/home/qi/directive/matches.hpp +++ b/contrib/restricted/boost/boost/spirit/home/qi/directive/matches.hpp @@ -72,7 +72,7 @@ namespace boost { namespace spirit { namespace qi Subject subject; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(matches_directive& operator= (matches_directive const&)); + BOOST_DELETED_FUNCTION(matches_directive& operator= (matches_directive const&)); }; /////////////////////////////////////////////////////////////////////////// diff --git a/contrib/restricted/boost/boost/spirit/home/qi/directive/omit.hpp b/contrib/restricted/boost/boost/spirit/home/qi/directive/omit.hpp index 6946f56347..4df5425197 100644 --- a/contrib/restricted/boost/boost/spirit/home/qi/directive/omit.hpp +++ b/contrib/restricted/boost/boost/spirit/home/qi/directive/omit.hpp @@ -71,7 +71,7 @@ namespace boost { namespace spirit { namespace qi Subject subject; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(omit_directive& operator= (omit_directive const&)); + BOOST_DELETED_FUNCTION(omit_directive& operator= (omit_directive const&)); }; /////////////////////////////////////////////////////////////////////////// diff --git a/contrib/restricted/boost/boost/spirit/home/qi/directive/repeat.hpp b/contrib/restricted/boost/boost/spirit/home/qi/directive/repeat.hpp index d9e334e812..79d55e0411 100644 --- a/contrib/restricted/boost/boost/spirit/home/qi/directive/repeat.hpp +++ b/contrib/restricted/boost/boost/spirit/home/qi/directive/repeat.hpp @@ -92,7 +92,7 @@ namespace boost { namespace spirit { namespace qi T const exact; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(exact_iterator& operator= (exact_iterator const&)); + BOOST_DELETED_FUNCTION(exact_iterator& operator= (exact_iterator const&)); }; template <typename T> @@ -111,7 +111,7 @@ namespace boost { namespace spirit { namespace qi T const max; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(finite_iterator& operator= (finite_iterator const&)); + BOOST_DELETED_FUNCTION(finite_iterator& operator= (finite_iterator const&)); }; template <typename T> @@ -128,7 +128,7 @@ namespace boost { namespace spirit { namespace qi T const min; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(infinite_iterator& operator= (infinite_iterator const&)); + BOOST_DELETED_FUNCTION(infinite_iterator& operator= (infinite_iterator const&)); }; template <typename Subject, typename LoopIter> @@ -207,7 +207,7 @@ namespace boost { namespace spirit { namespace qi LoopIter iter; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(repeat_parser& operator= (repeat_parser const&)); + BOOST_DELETED_FUNCTION(repeat_parser& operator= (repeat_parser const&)); }; /////////////////////////////////////////////////////////////////////////// diff --git a/contrib/restricted/boost/boost/spirit/home/qi/stream/detail/match_manip.hpp b/contrib/restricted/boost/boost/spirit/home/qi/stream/detail/match_manip.hpp index 37b6a6435a..96f319cd26 100644 --- a/contrib/restricted/boost/boost/spirit/home/qi/stream/detail/match_manip.hpp +++ b/contrib/restricted/boost/boost/spirit/home/qi/stream/detail/match_manip.hpp @@ -47,7 +47,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail BOOST_SCOPED_ENUM(skip_flag) const post_skip; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(match_manip& operator= (match_manip const&)); + BOOST_DELETED_FUNCTION(match_manip& operator= (match_manip const&)); }; template <typename Expr, typename Skipper, typename Attribute> @@ -66,7 +66,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail BOOST_SCOPED_ENUM(skip_flag) const post_skip; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(match_manip& operator= (match_manip const&)); + BOOST_DELETED_FUNCTION(match_manip& operator= (match_manip const&)); }; template <typename Expr, typename Skipper, typename Attribute> @@ -85,7 +85,7 @@ namespace boost { namespace spirit { namespace qi { namespace detail BOOST_SCOPED_ENUM(skip_flag) const post_skip; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(match_manip& operator= (match_manip const&)); + BOOST_DELETED_FUNCTION(match_manip& operator= (match_manip const&)); }; /////////////////////////////////////////////////////////////////////////// diff --git a/contrib/restricted/boost/boost/spirit/home/qi/string/lit.hpp b/contrib/restricted/boost/boost/spirit/home/qi/string/lit.hpp index 2e423c28c8..c7f1e354f8 100644 --- a/contrib/restricted/boost/boost/spirit/home/qi/string/lit.hpp +++ b/contrib/restricted/boost/boost/spirit/home/qi/string/lit.hpp @@ -119,7 +119,7 @@ namespace boost { namespace spirit { namespace qi String str; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(literal_string& operator= (literal_string const&)); + BOOST_DELETED_FUNCTION(literal_string& operator= (literal_string const&)); }; template <typename String, bool no_attribute> diff --git a/contrib/restricted/boost/boost/spirit/home/qi/string/symbols.hpp b/contrib/restricted/boost/boost/spirit/home/qi/string/symbols.hpp index 91f6e7f3b4..4477d866a9 100644 --- a/contrib/restricted/boost/boost/spirit/home/qi/string/symbols.hpp +++ b/contrib/restricted/boost/boost/spirit/home/qi/string/symbols.hpp @@ -324,7 +324,7 @@ public: symbols& sym; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(adder& operator= (adder const&)); + BOOST_DELETED_FUNCTION(adder& operator= (adder const&)); }; struct remover @@ -366,7 +366,7 @@ public: symbols& sym; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(remover& operator= (remover const&)); + BOOST_DELETED_FUNCTION(remover& operator= (remover const&)); }; adder add; diff --git a/contrib/restricted/boost/boost/spirit/home/support/detail/what_function.hpp b/contrib/restricted/boost/boost/spirit/home/support/detail/what_function.hpp index c256cd86e8..7b9d128586 100644 --- a/contrib/restricted/boost/boost/spirit/home/support/detail/what_function.hpp +++ b/contrib/restricted/boost/boost/spirit/home/support/detail/what_function.hpp @@ -40,7 +40,7 @@ namespace boost { namespace spirit { namespace detail Context& context; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(what_function& operator= (what_function const&)); + BOOST_DELETED_FUNCTION(what_function& operator= (what_function const&)); }; }}} diff --git a/contrib/restricted/boost/boost/spirit/home/support/info.hpp b/contrib/restricted/boost/boost/spirit/home/support/info.hpp index 099772bfc6..b4c987dae7 100644 --- a/contrib/restricted/boost/boost/spirit/home/support/info.hpp +++ b/contrib/restricted/boost/boost/spirit/home/support/info.hpp @@ -118,7 +118,7 @@ namespace boost { namespace spirit int depth; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(basic_info_walker& operator= (basic_info_walker const&)); + BOOST_DELETED_FUNCTION(basic_info_walker& operator= (basic_info_walker const&)); }; // bare-bones print support @@ -141,7 +141,7 @@ namespace boost { namespace spirit Out& out; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(simple_printer& operator= (simple_printer const&)); + BOOST_DELETED_FUNCTION(simple_printer& operator= (simple_printer const&)); }; template <typename Out> diff --git a/contrib/restricted/boost/boost/spirit/home/support/iterators/detail/split_functor_input_policy.hpp b/contrib/restricted/boost/boost/spirit/home/support/iterators/detail/split_functor_input_policy.hpp index 34908148ef..0555d2aeeb 100644 --- a/contrib/restricted/boost/boost/spirit/home/support/iterators/detail/split_functor_input_policy.hpp +++ b/contrib/restricted/boost/boost/spirit/home/support/iterators/detail/split_functor_input_policy.hpp @@ -191,7 +191,7 @@ namespace boost { namespace spirit { namespace iterator_policies result_type curtok; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(shared& operator= (shared const&)); + BOOST_DELETED_FUNCTION(shared& operator= (shared const&)); }; }; diff --git a/contrib/restricted/boost/boost/spirit/home/support/nonterminal/expand_arg.hpp b/contrib/restricted/boost/boost/spirit/home/support/nonterminal/expand_arg.hpp index 6c9b2113d4..1c2aa8341f 100644 --- a/contrib/restricted/boost/boost/spirit/home/support/nonterminal/expand_arg.hpp +++ b/contrib/restricted/boost/boost/spirit/home/support/nonterminal/expand_arg.hpp @@ -79,7 +79,7 @@ namespace boost { namespace spirit { namespace detail Context& context; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(expand_arg& operator= (expand_arg const&)); + BOOST_DELETED_FUNCTION(expand_arg& operator= (expand_arg const&)); }; }}} diff --git a/contrib/restricted/boost/boost/spirit/home/support/terminal.hpp b/contrib/restricted/boost/boost/spirit/home/support/terminal.hpp index 9515a69b01..f2b378ccf4 100644 --- a/contrib/restricted/boost/boost/spirit/home/support/terminal.hpp +++ b/contrib/restricted/boost/boost/spirit/home/support/terminal.hpp @@ -486,7 +486,7 @@ namespace boost { namespace spirit } // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(terminal& operator= (terminal const&)); + BOOST_DELETED_FUNCTION(terminal& operator= (terminal const&)); }; /////////////////////////////////////////////////////////////////////////// @@ -543,7 +543,7 @@ namespace boost { namespace spirit data_type data_; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(stateful_tag& operator= (stateful_tag const&)); + BOOST_DELETED_FUNCTION(stateful_tag& operator= (stateful_tag const&)); }; } @@ -561,7 +561,7 @@ namespace boost { namespace spirit {} // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(stateful_tag_type& operator= (stateful_tag_type const&)); + BOOST_DELETED_FUNCTION(stateful_tag_type& operator= (stateful_tag_type const&)); }; namespace detail diff --git a/contrib/restricted/boost/boost/spirit/home/x3/auxiliary/attr.hpp b/contrib/restricted/boost/boost/spirit/home/x3/auxiliary/attr.hpp index 0459e55255..ac7bf3ec23 100644 --- a/contrib/restricted/boost/boost/spirit/home/x3/auxiliary/attr.hpp +++ b/contrib/restricted/boost/boost/spirit/home/x3/auxiliary/attr.hpp @@ -51,7 +51,7 @@ namespace boost { namespace spirit { namespace x3 Value value_; // silence MSVC warning C4512: assignment operator could not be generated - attr_parser& operator= (attr_parser const&) = delete; + attr_parser& operator= (attr_parser const&) = delete; }; template <typename Value, std::size_t N> @@ -86,7 +86,7 @@ namespace boost { namespace spirit { namespace x3 Value value_[N]; // silence MSVC warning C4512: assignment operator could not be generated - attr_parser& operator= (attr_parser const&) = delete; + attr_parser& operator= (attr_parser const&) = delete; }; template <typename Value> diff --git a/contrib/restricted/boost/boost/spirit/repository/home/qi/directive/kwd.hpp b/contrib/restricted/boost/boost/spirit/repository/home/qi/directive/kwd.hpp index 32af179e62..06c57894fa 100644 --- a/contrib/restricted/boost/boost/spirit/repository/home/qi/directive/kwd.hpp +++ b/contrib/restricted/boost/boost/spirit/repository/home/qi/directive/kwd.hpp @@ -173,7 +173,7 @@ template <typename T> // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(kwd_pass_iterator& operator= (kwd_pass_iterator const&)); + BOOST_DELETED_FUNCTION(kwd_pass_iterator& operator= (kwd_pass_iterator const&)); }; template <typename T> @@ -203,7 +203,7 @@ template <typename T> T const exact; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(kwd_exact_iterator& operator= (kwd_exact_iterator const&)); + BOOST_DELETED_FUNCTION(kwd_exact_iterator& operator= (kwd_exact_iterator const&)); }; template <typename T> @@ -234,7 +234,7 @@ template <typename T> T const max; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(kwd_finite_iterator& operator= (kwd_finite_iterator const&)); + BOOST_DELETED_FUNCTION(kwd_finite_iterator& operator= (kwd_finite_iterator const&)); }; template <typename T> @@ -253,7 +253,7 @@ template <typename T> T const min; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(kwd_infinite_iterator& operator= (kwd_infinite_iterator const&)); + BOOST_DELETED_FUNCTION(kwd_infinite_iterator& operator= (kwd_infinite_iterator const&)); }; // This class enables the transportation of parameters needed to call @@ -437,7 +437,7 @@ template <typename T> spirit::qi::literal_string<KeywordType, true> >::type keyword_string_type; keyword_string_type keyword; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(kwd_parser& operator= (kwd_parser const&)); + BOOST_DELETED_FUNCTION(kwd_parser& operator= (kwd_parser const&)); template <typename Iterator, typename Context, typename Skipper> static spirit::qi::detail::fail_function<Iterator, Context, Skipper> @@ -581,7 +581,7 @@ template <typename Subject, typename KeywordType, typename LoopIter, typename Di KeywordType keyword; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(complex_kwd_parser& operator= (complex_kwd_parser const&)); + BOOST_DELETED_FUNCTION(complex_kwd_parser& operator= (complex_kwd_parser const&)); template <typename Iterator, typename Context, typename Skipper> static spirit::qi::detail::fail_function<Iterator, Context, Skipper> diff --git a/contrib/restricted/boost/boost/spirit/repository/home/qi/operator/detail/keywords.hpp b/contrib/restricted/boost/boost/spirit/repository/home/qi/operator/detail/keywords.hpp index 5b0b527a2a..a898a9b158 100644 --- a/contrib/restricted/boost/boost/spirit/repository/home/qi/operator/detail/keywords.hpp +++ b/contrib/restricted/boost/boost/spirit/repository/home/qi/operator/detail/keywords.hpp @@ -690,7 +690,7 @@ namespace boost { namespace spirit { namespace repository { namespace qi { names ParseDispatcher const& dispatcher; // silence MSVC warning C4512: assignment operator could not be generated - BOOST_DELETED_FUNCTION(complex_kwd_function& operator= (complex_kwd_function const&)); + BOOST_DELETED_FUNCTION(complex_kwd_function& operator= (complex_kwd_function const&)); }; diff --git a/contrib/restricted/boost/libs/context/ya.make b/contrib/restricted/boost/libs/context/ya.make index 0ed9d696fe..ae262177d9 100644 --- a/contrib/restricted/boost/libs/context/ya.make +++ b/contrib/restricted/boost/libs/context/ya.make @@ -16,18 +16,18 @@ CFLAGS( -DBOOST_CONTEXT_SOURCE ) -# https://www.boost.org/doc/libs/1_74_0/libs/context/doc/html/context/stack/sanitizers.html -IF (SANITIZER_TYPE == "address") - CFLAGS( - GLOBAL -DBOOST_USE_UCONTEXT - GLOBAL -DBOOST_USE_ASAN - ) - SRCS( - src/continuation.cpp - src/fiber.cpp - ) -ENDIF() - +# https://www.boost.org/doc/libs/1_74_0/libs/context/doc/html/context/stack/sanitizers.html +IF (SANITIZER_TYPE == "address") + CFLAGS( + GLOBAL -DBOOST_USE_UCONTEXT + GLOBAL -DBOOST_USE_ASAN + ) + SRCS( + src/continuation.cpp + src/fiber.cpp + ) +ENDIF() + IF (OS_WINDOWS) IF (ARCH_X86_64 OR ARCH_I386) MASMFLAGS('-DBOOST_CONTEXT_EXPORT= /safeseh') diff --git a/contrib/restricted/boost/libs/log/src/attribute_set_impl.hpp b/contrib/restricted/boost/libs/log/src/attribute_set_impl.hpp index f6c829b648..5cc161812d 100644 --- a/contrib/restricted/boost/libs/log/src/attribute_set_impl.hpp +++ b/contrib/restricted/boost/libs/log/src/attribute_set_impl.hpp @@ -62,13 +62,13 @@ public: #if BOOST_LOG_ATTRIBUTE_SET_MAX_POOL_SIZE > 0 - typedef T value_type; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; + typedef T value_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; private: array< pointer, BOOST_LOG_ATTRIBUTE_SET_MAX_POOL_SIZE > m_Pool; @@ -114,7 +114,7 @@ public: return *this; } - pointer allocate(size_type n) + pointer allocate(size_type n) { if (m_PooledCount > 0) { @@ -122,7 +122,7 @@ public: return m_Pool[m_PooledCount]; } else - return base_type::allocate(n); + return base_type::allocate(n); } void deallocate(pointer p, size_type n) @@ -233,7 +233,7 @@ public: node_list::const_iterator it = that.m_Nodes.begin(), end = that.m_Nodes.end(); for (; it != end; ++it) { - node* const n = m_Allocator.allocate(1); + node* const n = m_Allocator.allocate(1); new (n) node(it->m_Value.first, it->m_Value.second); m_Nodes.push_back(*n); @@ -274,7 +274,7 @@ public: return std::make_pair(iterator(p), false); } - node* const n = m_Allocator.allocate(1); + node* const n = m_Allocator.allocate(1); new (n) node(key, data); node_list::iterator it; diff --git a/contrib/restricted/boost/libs/log/src/named_scope.cpp b/contrib/restricted/boost/libs/log/src/named_scope.cpp index c59a9aebef..91d7782825 100644 --- a/contrib/restricted/boost/libs/log/src/named_scope.cpp +++ b/contrib/restricted/boost/libs/log/src/named_scope.cpp @@ -214,7 +214,7 @@ BOOST_LOG_API named_scope_list::named_scope_list(named_scope_list const& that) : aux::named_scope_list_node* prev = &m_RootNode; for (const_iterator src = that.begin(), end = that.end(); src != end; ++src, ++p) { - new((void*)p) value_type(*src); // won't throw + new((void*)p) value_type(*src); // won't throw p->_m_pPrev = prev; prev->_m_pNext = p; prev = p; @@ -232,7 +232,7 @@ BOOST_LOG_API named_scope_list::~named_scope_list() iterator it(m_RootNode._m_pNext); iterator end(&m_RootNode); while (it != end) - it->~value_type(); + it->~value_type(); allocator_type::deallocate(static_cast< pointer >(m_RootNode._m_pNext), m_Size); } } diff --git a/contrib/restricted/boost/libs/log/ya.make b/contrib/restricted/boost/libs/log/ya.make index 09429ee0cd..eb403fed72 100644 --- a/contrib/restricted/boost/libs/log/ya.make +++ b/contrib/restricted/boost/libs/log/ya.make @@ -28,7 +28,7 @@ IF (OS_WINDOWS) -D_SCL_SECURE_NO_WARNINGS ) ELSE() - IF (OS_LINUX AND OS_SDK != "ubuntu-10") + IF (OS_LINUX AND OS_SDK != "ubuntu-10") CFLAGS( -DBOOST_LOG_HAS_PTHREAD_MUTEX_ROBUST ) diff --git a/contrib/restricted/boost/libs/ya.make b/contrib/restricted/boost/libs/ya.make index c42a994cdc..0e92ebc239 100644 --- a/contrib/restricted/boost/libs/ya.make +++ b/contrib/restricted/boost/libs/ya.make @@ -63,9 +63,9 @@ RECURSE( thread timer ) - -IF (NOT OS_ANDROID) - RECURSE( - python - ) -ENDIF() + +IF (NOT OS_ANDROID) + RECURSE( + python + ) +ENDIF() diff --git a/contrib/restricted/boost/patches/README.md b/contrib/restricted/boost/patches/README.md index 14e02c6708..466cffad35 100644 --- a/contrib/restricted/boost/patches/README.md +++ b/contrib/restricted/boost/patches/README.md @@ -1,8 +1,8 @@ -The following PRs have been upstreamed from certain commits applied locally: - -* [r8940310](https://a.yandex-team.ru/arc/commit/r8940310): https://github.com/boostorg/circular_buffer/pull/41 -* https://github.com/boostorg/context/pull/188 -* https://github.com/boostorg/interprocess/pull/155 -* https://github.com/boostorg/process/pull/223 -* https://github.com/boostorg/algorithm/pull/88 (ещё не вмержен) -* https://github.com/boostorg/ublas/pull/153 +The following PRs have been upstreamed from certain commits applied locally: + +* [r8940310](https://a.yandex-team.ru/arc/commit/r8940310): https://github.com/boostorg/circular_buffer/pull/41 +* https://github.com/boostorg/context/pull/188 +* https://github.com/boostorg/interprocess/pull/155 +* https://github.com/boostorg/process/pull/223 +* https://github.com/boostorg/algorithm/pull/88 (ещё не вмержен) +* https://github.com/boostorg/ublas/pull/153 diff --git a/contrib/restricted/fast_float/AUTHORS b/contrib/restricted/fast_float/AUTHORS index 60c9425823..8baed3a829 100644 --- a/contrib/restricted/fast_float/AUTHORS +++ b/contrib/restricted/fast_float/AUTHORS @@ -1,2 +1,2 @@ -Daniel Lemire -João Paulo Magalhaes +Daniel Lemire +João Paulo Magalhaes diff --git a/contrib/restricted/fast_float/CONTRIBUTORS b/contrib/restricted/fast_float/CONTRIBUTORS index 58a037cc55..c5cf18a70e 100644 --- a/contrib/restricted/fast_float/CONTRIBUTORS +++ b/contrib/restricted/fast_float/CONTRIBUTORS @@ -1,6 +1,6 @@ -Eugene Golushkov -Maksim Kita -Marcin Wojdyr -Neal Richardson -Tim Paine -Fabio Pellacini +Eugene Golushkov +Maksim Kita +Marcin Wojdyr +Neal Richardson +Tim Paine +Fabio Pellacini diff --git a/contrib/restricted/fast_float/LICENSE-MIT b/contrib/restricted/fast_float/LICENSE-MIT index 2fb2a37ad7..44d6aa8fad 100644 --- a/contrib/restricted/fast_float/LICENSE-MIT +++ b/contrib/restricted/fast_float/LICENSE-MIT @@ -2,26 +2,26 @@ MIT License Copyright (c) 2021 The fast_float authors -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/contrib/restricted/fast_float/README.md b/contrib/restricted/fast_float/README.md index 1e1c06d0a3..5195c5c85d 100644 --- a/contrib/restricted/fast_float/README.md +++ b/contrib/restricted/fast_float/README.md @@ -1,16 +1,16 @@ -## fast_float number parsing library: 4x faster than strtod +## fast_float number parsing library: 4x faster than strtod ![Ubuntu 20.04 CI (GCC 9)](https://github.com/lemire/fast_float/workflows/Ubuntu%2020.04%20CI%20(GCC%209)/badge.svg) ![Ubuntu 18.04 CI (GCC 7)](https://github.com/lemire/fast_float/workflows/Ubuntu%2018.04%20CI%20(GCC%207)/badge.svg) ![Alpine Linux](https://github.com/lemire/fast_float/workflows/Alpine%20Linux/badge.svg) ![MSYS2-CI](https://github.com/lemire/fast_float/workflows/MSYS2-CI/badge.svg) ![VS16-CLANG-CI](https://github.com/lemire/fast_float/workflows/VS16-CLANG-CI/badge.svg) -[![VS16-CI](https://github.com/fastfloat/fast_float/actions/workflows/vs16-ci.yml/badge.svg)](https://github.com/fastfloat/fast_float/actions/workflows/vs16-ci.yml) +[![VS16-CI](https://github.com/fastfloat/fast_float/actions/workflows/vs16-ci.yml/badge.svg)](https://github.com/fastfloat/fast_float/actions/workflows/vs16-ci.yml) The fast_float library provides fast header-only implementations for the C++ from_chars functions for `float` and `double` types. These functions convert ASCII strings representing decimal values (e.g., `1.3e10`) into binary types. We provide exact rounding (including -round to even). In our experience, these `fast_float` functions many times faster than comparable number-parsing functions from existing C++ standard libraries. +round to even). In our experience, these `fast_float` functions many times faster than comparable number-parsing functions from existing C++ standard libraries. Specifically, `fast_float` provides the following two functions with a C++17-like syntax (the library itself only requires C++11): @@ -69,7 +69,7 @@ The library seeks to follow the C++17 (see [20.19.3](http://eel.is/c++draft/char * The `from_chars` function does not skip leading white-space characters. * [A leading `+` sign](https://en.cppreference.com/w/cpp/utility/from_chars) is forbidden. * It is generally impossible to represent a decimal value exactly as binary floating-point number (`float` and `double` types). We seek the nearest value. We round to an even mantissa when we are in-between two binary floating-point numbers. - + Furthermore, we have the following restrictions: * We only support `float` and `double` types at this time. * We only support the decimal format: we do not support hexadecimal strings. @@ -79,61 +79,61 @@ We support Visual Studio, macOS, Linux, freeBSD. We support big and little endia -## Using commas as decimal separator - - -The C++ standard stipulate that `from_chars` has to be locale-independent. In -particular, the decimal separator has to be the period (`.`). However, -some users still want to use the `fast_float` library with in a locale-dependent -manner. Using a separate function called `from_chars_advanced`, we allow the users -to pass a `parse_options` instance which contains a custom decimal separator (e.g., -the comma). You may use it as follows. - -```C++ -#include "fast_float/fast_float.h" -#include <iostream> +## Using commas as decimal separator + + +The C++ standard stipulate that `from_chars` has to be locale-independent. In +particular, the decimal separator has to be the period (`.`). However, +some users still want to use the `fast_float` library with in a locale-dependent +manner. Using a separate function called `from_chars_advanced`, we allow the users +to pass a `parse_options` instance which contains a custom decimal separator (e.g., +the comma). You may use it as follows. + +```C++ +#include "fast_float/fast_float.h" +#include <iostream> + +int main() { + const std::string input = "3,1416 xyz "; + double result; + fast_float::parse_options options{fast_float::chars_format::general, ','}; + auto answer = fast_float::from_chars_advanced(input.data(), input.data()+input.size(), result, options); + if((answer.ec != std::errc()) || ((result != 3.1416))) { std::cerr << "parsing failure\n"; return EXIT_FAILURE; } + std::cout << "parsed the number " << result << std::endl; + return EXIT_SUCCESS; +} +``` + + +## Reference + +- Daniel Lemire, [Number Parsing at a Gigabyte per Second](https://arxiv.org/abs/2101.11408), Software: Pratice and Experience 51 (8), 2021. + +## Other programming languages + +- [There is an R binding](https://github.com/eddelbuettel/rcppfastfloat) called `rcppfastfloat`. +- [There is a Rust port of the fast_float library](https://github.com/aldanor/fast-float-rust/) called `fast-float-rust`. +- [There is a Java port of the fast_float library](https://github.com/wrandelshofer/FastDoubleParser) called `FastDoubleParser`. +- [There is a C# port of the fast_float library](https://github.com/CarlVerret/csFastFloat) called `csFastFloat`. + -int main() { - const std::string input = "3,1416 xyz "; - double result; - fast_float::parse_options options{fast_float::chars_format::general, ','}; - auto answer = fast_float::from_chars_advanced(input.data(), input.data()+input.size(), result, options); - if((answer.ec != std::errc()) || ((result != 3.1416))) { std::cerr << "parsing failure\n"; return EXIT_FAILURE; } - std::cout << "parsed the number " << result << std::endl; - return EXIT_SUCCESS; -} -``` - - -## Reference - -- Daniel Lemire, [Number Parsing at a Gigabyte per Second](https://arxiv.org/abs/2101.11408), Software: Pratice and Experience 51 (8), 2021. - -## Other programming languages - -- [There is an R binding](https://github.com/eddelbuettel/rcppfastfloat) called `rcppfastfloat`. -- [There is a Rust port of the fast_float library](https://github.com/aldanor/fast-float-rust/) called `fast-float-rust`. -- [There is a Java port of the fast_float library](https://github.com/wrandelshofer/FastDoubleParser) called `FastDoubleParser`. -- [There is a C# port of the fast_float library](https://github.com/CarlVerret/csFastFloat) called `csFastFloat`. - - ## Relation With Other Work The fastfloat algorithm is part of the [LLVM standard libraries](https://github.com/llvm/llvm-project/commit/87c016078ad72c46505461e4ff8bfa04819fe7ba). -The fast_float library provides a performance similar to that of the [fast_double_parser](https://github.com/lemire/fast_double_parser) library but using an updated algorithm reworked from the ground up, and while offering an API more in line with the expectations of C++ programmers. The fast_double_parser library is part of the [Microsoft LightGBM machine-learning framework](https://github.com/microsoft/LightGBM). +The fast_float library provides a performance similar to that of the [fast_double_parser](https://github.com/lemire/fast_double_parser) library but using an updated algorithm reworked from the ground up, and while offering an API more in line with the expectations of C++ programmers. The fast_double_parser library is part of the [Microsoft LightGBM machine-learning framework](https://github.com/microsoft/LightGBM). ## Users -The fast_float library is used by [Apache Arrow](https://github.com/apache/arrow/pull/8494) where it multiplied the number parsing speed by two or three times. It is also used by [Yandex ClickHouse](https://github.com/ClickHouse/ClickHouse) and by [Google Jsonnet](https://github.com/google/jsonnet). +The fast_float library is used by [Apache Arrow](https://github.com/apache/arrow/pull/8494) where it multiplied the number parsing speed by two or three times. It is also used by [Yandex ClickHouse](https://github.com/ClickHouse/ClickHouse) and by [Google Jsonnet](https://github.com/google/jsonnet). ## How fast is it? It can parse random floating-point numbers at a speed of 1 GB/s on some systems. We find that it is often twice as fast as the best available competitor, and many times faster than many standard-library implementations. -<img src="http://lemire.me/blog/wp-content/uploads/2020/11/fastfloat_speed.png" width="400"> - +<img src="http://lemire.me/blog/wp-content/uploads/2020/11/fastfloat_speed.png" width="400"> + ``` $ ./build/benchmarks/benchmark # parsing random integers in the range [0,1) @@ -147,11 +147,11 @@ fastfloat : 1042.38 MB/s (+/- 9.9 %) 49.68 Mfl See https://github.com/lemire/simple_fastfloat_benchmark for our benchmarking code. - -## Video - -[![Go Systems 2020](http://img.youtube.com/vi/AVXgvlMeIm4/0.jpg)](http://www.youtube.com/watch?v=AVXgvlMeIm4)<br /> - + +## Video + +[![Go Systems 2020](http://img.youtube.com/vi/AVXgvlMeIm4/0.jpg)](http://www.youtube.com/watch?v=AVXgvlMeIm4)<br /> + ## Using as a CMake dependency This library is header-only by design. The CMake file provides the `fast_float` target @@ -171,7 +171,7 @@ Or you may want to retrieve the dependency automatically if you have a sufficien FetchContent_Declare( fast_float GIT_REPOSITORY https://github.com/lemire/fast_float.git - GIT_TAG tags/v1.1.2 + GIT_TAG tags/v1.1.2 GIT_SHALLOW TRUE) FetchContent_MakeAvailable(fast_float) @@ -179,19 +179,19 @@ target_link_libraries(myprogram PUBLIC fast_float) ``` -You should change the `GIT_TAG` line so that you recover the version you wish to use. +You should change the `GIT_TAG` line so that you recover the version you wish to use. -## Using as single header +## Using as single header -The script `script/amalgamate.py` may be used to generate a single header -version of the library if so desired. -Just run the script from the root directory of this repository. -You can customize the license type and output file if desired as described in -the command line help. +The script `script/amalgamate.py` may be used to generate a single header +version of the library if so desired. +Just run the script from the root directory of this repository. +You can customize the license type and output file if desired as described in +the command line help. -You may directly download automatically generated single-header files: +You may directly download automatically generated single-header files: -https://github.com/fastfloat/fast_float/releases/download/v1.1.2/fast_float.h +https://github.com/fastfloat/fast_float/releases/download/v1.1.2/fast_float.h ## Credit @@ -201,18 +201,18 @@ invaluable feedback. Rémy Oudompheng first implemented a fast path we use in th The library includes code adapted from Google Wuffs (written by Nigel Tao) which was originally published under the Apache 2.0 license. - -## License - -<sup> -Licensed under either of <a href="LICENSE-APACHE">Apache License, Version -2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option. -</sup> - -<br> - -<sub> -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in this repository by you, as defined in the Apache-2.0 license, -shall be dual licensed as above, without any additional terms or conditions. -</sub> + +## License + +<sup> +Licensed under either of <a href="LICENSE-APACHE">Apache License, Version +2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option. +</sup> + +<br> + +<sub> +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this repository by you, as defined in the Apache-2.0 license, +shall be dual licensed as above, without any additional terms or conditions. +</sub> diff --git a/contrib/restricted/fast_float/include/fast_float/ascii_number.h b/contrib/restricted/fast_float/include/fast_float/ascii_number.h index 3e6bb3e9ef..dbc25c46c3 100644 --- a/contrib/restricted/fast_float/include/fast_float/ascii_number.h +++ b/contrib/restricted/fast_float/include/fast_float/ascii_number.h @@ -14,35 +14,35 @@ namespace fast_float { // able to optimize it well. fastfloat_really_inline bool is_integer(char c) noexcept { return c >= '0' && c <= '9'; } -fastfloat_really_inline uint64_t byteswap(uint64_t val) { - return (val & 0xFF00000000000000) >> 56 - | (val & 0x00FF000000000000) >> 40 - | (val & 0x0000FF0000000000) >> 24 - | (val & 0x000000FF00000000) >> 8 - | (val & 0x00000000FF000000) << 8 - | (val & 0x0000000000FF0000) << 24 - | (val & 0x000000000000FF00) << 40 - | (val & 0x00000000000000FF) << 56; -} - -fastfloat_really_inline uint64_t read_u64(const char *chars) { - uint64_t val; - ::memcpy(&val, chars, sizeof(uint64_t)); -#if FASTFLOAT_IS_BIG_ENDIAN == 1 - // Need to read as-if the number was in little-endian order. - val = byteswap(val); -#endif - return val; -} - -fastfloat_really_inline void write_u64(uint8_t *chars, uint64_t val) { -#if FASTFLOAT_IS_BIG_ENDIAN == 1 - // Need to read as-if the number was in little-endian order. - val = byteswap(val); -#endif - ::memcpy(chars, &val, sizeof(uint64_t)); -} - +fastfloat_really_inline uint64_t byteswap(uint64_t val) { + return (val & 0xFF00000000000000) >> 56 + | (val & 0x00FF000000000000) >> 40 + | (val & 0x0000FF0000000000) >> 24 + | (val & 0x000000FF00000000) >> 8 + | (val & 0x00000000FF000000) << 8 + | (val & 0x0000000000FF0000) << 24 + | (val & 0x000000000000FF00) << 40 + | (val & 0x00000000000000FF) << 56; +} + +fastfloat_really_inline uint64_t read_u64(const char *chars) { + uint64_t val; + ::memcpy(&val, chars, sizeof(uint64_t)); +#if FASTFLOAT_IS_BIG_ENDIAN == 1 + // Need to read as-if the number was in little-endian order. + val = byteswap(val); +#endif + return val; +} + +fastfloat_really_inline void write_u64(uint8_t *chars, uint64_t val) { +#if FASTFLOAT_IS_BIG_ENDIAN == 1 + // Need to read as-if the number was in little-endian order. + val = byteswap(val); +#endif + ::memcpy(chars, &val, sizeof(uint64_t)); +} + // credit @aqrit fastfloat_really_inline uint32_t parse_eight_digits_unrolled(uint64_t val) { const uint64_t mask = 0x000000FF000000FF; @@ -55,17 +55,17 @@ fastfloat_really_inline uint32_t parse_eight_digits_unrolled(uint64_t val) { } fastfloat_really_inline uint32_t parse_eight_digits_unrolled(const char *chars) noexcept { - return parse_eight_digits_unrolled(read_u64(chars)); + return parse_eight_digits_unrolled(read_u64(chars)); } // credit @aqrit fastfloat_really_inline bool is_made_of_eight_digits_fast(uint64_t val) noexcept { return !((((val + 0x4646464646464646) | (val - 0x3030303030303030)) & - 0x8080808080808080)); + 0x8080808080808080)); } fastfloat_really_inline bool is_made_of_eight_digits_fast(const char *chars) noexcept { - return is_made_of_eight_digits_fast(read_u64(chars)); + return is_made_of_eight_digits_fast(read_u64(chars)); } typedef span<const char> byte_span; @@ -85,20 +85,20 @@ struct parsed_number_string { // Assuming that you use no more than 19 digits, this will // parse an ASCII string. fastfloat_really_inline -parsed_number_string parse_number_string(const char *p, const char *pend, parse_options options) noexcept { - const chars_format fmt = options.format; - const char decimal_point = options.decimal_point; - +parsed_number_string parse_number_string(const char *p, const char *pend, parse_options options) noexcept { + const chars_format fmt = options.format; + const char decimal_point = options.decimal_point; + parsed_number_string answer; answer.valid = false; - answer.too_many_digits = false; + answer.too_many_digits = false; answer.negative = (*p == '-'); - if (*p == '-') { // C++17 20.19.3.(7.1) explicitly forbids '+' sign here + if (*p == '-') { // C++17 20.19.3.(7.1) explicitly forbids '+' sign here ++p; if (p == pend) { return answer; } - if (!is_integer(*p) && (*p != decimal_point)) { // a sign must be followed by an integer or the dot + if (!is_integer(*p) && (*p != decimal_point)) { // a sign must be followed by an integer or the dot return answer; } } @@ -117,11 +117,11 @@ parsed_number_string parse_number_string(const char *p, const char *pend, parse_ uint64_t(*p - '0'); // might overflow, we will handle the overflow later ++p; } - const char *const end_of_integer_part = p; - int64_t digit_count = int64_t(end_of_integer_part - start_digits); + const char *const end_of_integer_part = p; + int64_t digit_count = int64_t(end_of_integer_part - start_digits); answer.integer = byte_span(start_digits, size_t(digit_count)); int64_t exponent = 0; - if ((p != pend) && (*p == decimal_point)) { + if ((p != pend) && (*p == decimal_point)) { ++p; const char* before = p; // can occur at most twice without overflowing, but let it occur more, since @@ -137,13 +137,13 @@ parsed_number_string parse_number_string(const char *p, const char *pend, parse_ } exponent = before - p; answer.fraction = byte_span(before, size_t(p - before)); - digit_count -= exponent; + digit_count -= exponent; } // we must have encountered at least one integer! - if (digit_count == 0) { + if (digit_count == 0) { return answer; } - int64_t exp_number = 0; // explicit exponential part + int64_t exp_number = 0; // explicit exponential part if ((fmt & chars_format::scientific) && (p != pend) && (('e' == *p) || ('E' == *p))) { const char * location_of_e = p; ++p; @@ -151,7 +151,7 @@ parsed_number_string parse_number_string(const char *p, const char *pend, parse_ if ((p != pend) && ('-' == *p)) { neg_exp = true; ++p; - } else if ((p != pend) && ('+' == *p)) { // '+' on exponent is allowed by C++17 20.19.3.(7.1) + } else if ((p != pend) && ('+' == *p)) { // '+' on exponent is allowed by C++17 20.19.3.(7.1) ++p; } if ((p == pend) || !is_integer(*p)) { @@ -169,8 +169,8 @@ parsed_number_string parse_number_string(const char *p, const char *pend, parse_ } ++p; } - if(neg_exp) { exp_number = - exp_number; } - exponent += exp_number; + if(neg_exp) { exp_number = - exp_number; } + exponent += exp_number; } } else { // If it scientific and not fixed, we have to bail out. @@ -182,43 +182,43 @@ parsed_number_string parse_number_string(const char *p, const char *pend, parse_ // If we frequently had to deal with long strings of digits, // we could extend our code by using a 128-bit integer instead // of a 64-bit integer. However, this is uncommon. - // - // We can deal with up to 19 digits. - if (digit_count > 19) { // this is uncommon + // + // We can deal with up to 19 digits. + if (digit_count > 19) { // this is uncommon // It is possible that the integer had an overflow. // We have to handle the case where we have 0.0000somenumber. - // We need to be mindful of the case where we only have zeroes... - // E.g., 0.000000000...000. + // We need to be mindful of the case where we only have zeroes... + // E.g., 0.000000000...000. const char *start = start_digits; - while ((start != pend) && (*start == '0' || *start == decimal_point)) { - if(*start == '0') { digit_count --; } + while ((start != pend) && (*start == '0' || *start == decimal_point)) { + if(*start == '0') { digit_count --; } start++; } - if (digit_count > 19) { + if (digit_count > 19) { answer.too_many_digits = true; - // Let us start again, this time, avoiding overflows. + // Let us start again, this time, avoiding overflows. // We don't need to check if is_integer, since we use the // pre-tokenized spans from above. - i = 0; + i = 0; p = answer.integer.ptr; const char* int_end = p + answer.integer.len(); - const uint64_t minimal_nineteen_digit_integer{1000000000000000000}; + const uint64_t minimal_nineteen_digit_integer{1000000000000000000}; while((i < minimal_nineteen_digit_integer) && (p != int_end)) { - i = i * 10 + uint64_t(*p - '0'); - ++p; - } - if (i >= minimal_nineteen_digit_integer) { // We have a big integers - exponent = end_of_integer_part - p + exp_number; - } else { // We have a value with a fractional component. + i = i * 10 + uint64_t(*p - '0'); + ++p; + } + if (i >= minimal_nineteen_digit_integer) { // We have a big integers + exponent = end_of_integer_part - p + exp_number; + } else { // We have a value with a fractional component. p = answer.fraction.ptr; const char* frac_end = p + answer.fraction.len(); while((i < minimal_nineteen_digit_integer) && (p != frac_end)) { - i = i * 10 + uint64_t(*p - '0'); - ++p; - } + i = i * 10 + uint64_t(*p - '0'); + ++p; + } exponent = answer.fraction.ptr - p + exp_number; - } - // We have now corrected both exponent and i, to a truncated value + } + // We have now corrected both exponent and i, to a truncated value } } answer.exponent = exponent; diff --git a/contrib/restricted/fast_float/include/fast_float/decimal_to_binary.h b/contrib/restricted/fast_float/include/fast_float/decimal_to_binary.h index 6da6c66a3a..adcc5bee0a 100644 --- a/contrib/restricted/fast_float/include/fast_float/decimal_to_binary.h +++ b/contrib/restricted/fast_float/include/fast_float/decimal_to_binary.h @@ -19,18 +19,18 @@ namespace fast_float { template <int bit_precision> fastfloat_really_inline value128 compute_product_approximation(int64_t q, uint64_t w) { - const int index = 2 * int(q - powers::smallest_power_of_five); + const int index = 2 * int(q - powers::smallest_power_of_five); // For small values of q, e.g., q in [0,27], the answer is always exact because // The line value128 firstproduct = full_multiplication(w, power_of_five_128[index]); // gives the exact answer. - value128 firstproduct = full_multiplication(w, powers::power_of_five_128[index]); + value128 firstproduct = full_multiplication(w, powers::power_of_five_128[index]); static_assert((bit_precision >= 0) && (bit_precision <= 64), " precision should be in (0,64]"); constexpr uint64_t precision_mask = (bit_precision < 64) ? (uint64_t(0xFFFFFFFFFFFFFFFF) >> bit_precision) : uint64_t(0xFFFFFFFFFFFFFFFF); if((firstproduct.high & precision_mask) == precision_mask) { // could further guard with (lower + w < lower) // regarding the second product, we only need secondproduct.high, but our expectation is that the compiler will optimize this extra work away if needed. - value128 secondproduct = full_multiplication(w, powers::power_of_five_128[index + 1]); + value128 secondproduct = full_multiplication(w, powers::power_of_five_128[index + 1]); firstproduct.low += secondproduct.high; if(secondproduct.high > firstproduct.low) { firstproduct.high++; @@ -39,7 +39,7 @@ value128 compute_product_approximation(int64_t q, uint64_t w) { return firstproduct; } -namespace detail { +namespace detail { /** * For q in (0,350), we have that * f = (((152170 + 65536) * q ) >> 16); @@ -58,7 +58,7 @@ namespace detail { constexpr fastfloat_really_inline int32_t power(int32_t q) noexcept { return (((152170 + 65536) * q) >> 16) + 63; } -} // namespace detail +} // namespace detail // create an adjusted mantissa, biased by the invalid power2 // for significant digits already multiplied by 10 ** q. @@ -105,7 +105,7 @@ adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept { answer.mantissa = 0; return answer; } - // At this point in time q is in [powers::smallest_power_of_five, powers::largest_power_of_five]. + // At this point in time q is in [powers::smallest_power_of_five, powers::largest_power_of_five]. // We want the most significant bit of i to be 1. Shift if needed. int lz = leading_zeroes(w); diff --git a/contrib/restricted/fast_float/include/fast_float/fast_float.h b/contrib/restricted/fast_float/include/fast_float/fast_float.h index 3c483803af..294d68e5c1 100644 --- a/contrib/restricted/fast_float/include/fast_float/fast_float.h +++ b/contrib/restricted/fast_float/include/fast_float/fast_float.h @@ -17,17 +17,17 @@ struct from_chars_result { std::errc ec; }; -struct parse_options { +struct parse_options { constexpr explicit parse_options(chars_format fmt = chars_format::general, - char dot = '.') - : format(fmt), decimal_point(dot) {} - - /** Which number formats are accepted */ - chars_format format; - /** The character used as decimal point */ - char decimal_point; -}; - + char dot = '.') + : format(fmt), decimal_point(dot) {} + + /** Which number formats are accepted */ + chars_format format; + /** The character used as decimal point */ + char decimal_point; +}; + /** * This function parses the character sequence [first,last) for a number. It parses floating-point numbers expecting * a locale-indepent format equivalent to what is used by std::strtod in the default ("C") locale. @@ -51,13 +51,13 @@ template<typename T> from_chars_result from_chars(const char *first, const char *last, T &value, chars_format fmt = chars_format::general) noexcept; -/** - * Like from_chars, but accepts an `options` argument to govern number parsing. - */ -template<typename T> -from_chars_result from_chars_advanced(const char *first, const char *last, - T &value, parse_options options) noexcept; - +/** + * Like from_chars, but accepts an `options` argument to govern number parsing. + */ +template<typename T> +from_chars_result from_chars_advanced(const char *first, const char *last, + T &value, parse_options options) noexcept; + } #include "parse_number.h" -#endif // FASTFLOAT_FAST_FLOAT_H +#endif // FASTFLOAT_FAST_FLOAT_H diff --git a/contrib/restricted/fast_float/include/fast_float/fast_table.h b/contrib/restricted/fast_float/include/fast_float/fast_table.h index 5766274ca4..945046c67d 100644 --- a/contrib/restricted/fast_float/include/fast_float/fast_table.h +++ b/contrib/restricted/fast_float/include/fast_float/fast_table.h @@ -29,18 +29,18 @@ namespace fast_float { * infinite in binary64 so we never need to worry about powers * of 5 greater than 308. */ -template <class unused = void> -struct powers_template { - -constexpr static int smallest_power_of_five = binary_format<double>::smallest_power_of_ten(); -constexpr static int largest_power_of_five = binary_format<double>::largest_power_of_ten(); -constexpr static int number_of_entries = 2 * (largest_power_of_five - smallest_power_of_five + 1); +template <class unused = void> +struct powers_template { + +constexpr static int smallest_power_of_five = binary_format<double>::smallest_power_of_ten(); +constexpr static int largest_power_of_five = binary_format<double>::largest_power_of_ten(); +constexpr static int number_of_entries = 2 * (largest_power_of_five - smallest_power_of_five + 1); // Powers of five from 5^-342 all the way to 5^308 rounded toward one. -static const uint64_t power_of_five_128[number_of_entries]; -}; - -template <class unused> -const uint64_t powers_template<unused>::power_of_five_128[number_of_entries] = { +static const uint64_t power_of_five_128[number_of_entries]; +}; + +template <class unused> +const uint64_t powers_template<unused>::power_of_five_128[number_of_entries] = { 0xeef453d6923bd65a,0x113faa2906a13b3f, 0x9558b4661b6565f8,0x4ac7ca59a424c507, 0xbaaee17fa23ebf76,0x5d79bcf00d2df649, @@ -692,7 +692,7 @@ const uint64_t powers_template<unused>::power_of_five_128[number_of_entries] = { 0xb6472e511c81471d,0xe0133fe4adf8e952, 0xe3d8f9e563a198e5,0x58180fddd97723a6, 0x8e679c2f5e44ff8f,0x570f09eaa7ea7648,}; -using powers = powers_template<>; +using powers = powers_template<>; } diff --git a/contrib/restricted/fast_float/include/fast_float/float_common.h b/contrib/restricted/fast_float/include/fast_float/float_common.h index 9374cdffd4..8adc68e1c8 100644 --- a/contrib/restricted/fast_float/include/fast_float/float_common.h +++ b/contrib/restricted/fast_float/include/fast_float/float_common.h @@ -7,30 +7,30 @@ #include <cstring> #include <type_traits> -#if (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) \ +#if (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) \ || defined(__amd64) || defined(__aarch64__) || defined(_M_ARM64) \ || defined(__MINGW64__) \ || defined(__s390x__) \ - || (defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__)) \ - || defined(__EMSCRIPTEN__)) + || (defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__)) \ + || defined(__EMSCRIPTEN__)) #define FASTFLOAT_64BIT -#elif (defined(__i386) || defined(__i386__) || defined(_M_IX86) \ - || defined(__arm__) || defined(_M_ARM) \ - || defined(__MINGW32__)) -#define FASTFLOAT_32BIT +#elif (defined(__i386) || defined(__i386__) || defined(_M_IX86) \ + || defined(__arm__) || defined(_M_ARM) \ + || defined(__MINGW32__)) +#define FASTFLOAT_32BIT #else - // Need to check incrementally, since SIZE_MAX is a size_t, avoid overflow. - // We can never tell the register width, but the SIZE_MAX is a good approximation. - // UINTPTR_MAX and INTPTR_MAX are optional, so avoid them for max portability. - #if SIZE_MAX == 0xffff - #error Unknown platform (16-bit, unsupported) - #elif SIZE_MAX == 0xffffffff - #define FASTFLOAT_32BIT - #elif SIZE_MAX == 0xffffffffffffffff - #define FASTFLOAT_64BIT - #else - #error Unknown platform (not 32-bit, not 64-bit?) - #endif + // Need to check incrementally, since SIZE_MAX is a size_t, avoid overflow. + // We can never tell the register width, but the SIZE_MAX is a good approximation. + // UINTPTR_MAX and INTPTR_MAX are optional, so avoid them for max portability. + #if SIZE_MAX == 0xffff + #error Unknown platform (16-bit, unsupported) + #elif SIZE_MAX == 0xffffffff + #define FASTFLOAT_32BIT + #elif SIZE_MAX == 0xffffffffffffffff + #define FASTFLOAT_64BIT + #else + #error Unknown platform (not 32-bit, not 64-bit?) + #endif #endif #if ((defined(_WIN32) || defined(_WIN64)) && !defined(__clang__)) @@ -46,8 +46,8 @@ #else #if defined(__APPLE__) || defined(__FreeBSD__) #include <machine/endian.h> -#elif defined(sun) || defined(__sun) -#include <sys/byteorder.h> +#elif defined(sun) || defined(__sun) +#include <sys/byteorder.h> #else #include <endian.h> #endif @@ -156,7 +156,7 @@ fastfloat_really_inline int leading_zeroes(uint64_t input_num) { #ifdef FASTFLOAT_32BIT // slow emulation routine for 32-bit -fastfloat_really_inline uint64_t emulu(uint32_t x, uint32_t y) { +fastfloat_really_inline uint64_t emulu(uint32_t x, uint32_t y) { return x * (uint64_t)y; } @@ -164,12 +164,12 @@ fastfloat_really_inline uint64_t emulu(uint32_t x, uint32_t y) { #if !defined(__MINGW64__) fastfloat_really_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) { - uint64_t ad = emulu((uint32_t)(ab >> 32), (uint32_t)cd); - uint64_t bd = emulu((uint32_t)ab, (uint32_t)cd); - uint64_t adbc = ad + emulu((uint32_t)ab, (uint32_t)(cd >> 32)); + uint64_t ad = emulu((uint32_t)(ab >> 32), (uint32_t)cd); + uint64_t bd = emulu((uint32_t)ab, (uint32_t)cd); + uint64_t adbc = ad + emulu((uint32_t)ab, (uint32_t)(cd >> 32)); uint64_t adbc_carry = !!(adbc < ad); uint64_t lo = bd + (adbc << 32); - *hi = emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + + *hi = emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + (adbc_carry << 32) + !!(lo < bd); return lo; } @@ -186,7 +186,7 @@ fastfloat_really_inline value128 full_multiplication(uint64_t a, // ARM64 has native support for 64-bit multiplications, no need to emulate answer.high = __umulh(a, b); answer.low = a * b; -#elif defined(FASTFLOAT_32BIT) || (defined(_WIN64) && !defined(__clang__)) +#elif defined(FASTFLOAT_32BIT) || (defined(_WIN64) && !defined(__clang__)) answer.low = _umul128(a, b, &answer.high); // _umul128 not available on ARM64 #elif defined(FASTFLOAT_64BIT) __uint128_t r = ((__uint128_t)a) * b; @@ -205,9 +205,9 @@ struct adjusted_mantissa { bool operator==(const adjusted_mantissa &o) const { return mantissa == o.mantissa && power2 == o.power2; } - bool operator!=(const adjusted_mantissa &o) const { - return mantissa != o.mantissa || power2 != o.power2; - } + bool operator!=(const adjusted_mantissa &o) const { + return mantissa != o.mantissa || power2 != o.power2; + } }; // Bias so we can get the real exponent with an invalid adjusted_mantissa. @@ -222,72 +222,72 @@ constexpr static float powers_of_ten_float[] = {1e0, 1e1, 1e2, 1e3, 1e4, 1e5, template <typename T> struct binary_format { using equiv_uint = typename std::conditional<sizeof(T) == 4, uint32_t, uint64_t>::type; - static inline constexpr int mantissa_explicit_bits(); - static inline constexpr int minimum_exponent(); - static inline constexpr int infinite_power(); - static inline constexpr int sign_index(); - static inline constexpr int min_exponent_fast_path(); - static inline constexpr int max_exponent_fast_path(); - static inline constexpr int max_exponent_round_to_even(); - static inline constexpr int min_exponent_round_to_even(); - static inline constexpr uint64_t max_mantissa_fast_path(); - static inline constexpr int largest_power_of_ten(); - static inline constexpr int smallest_power_of_ten(); - static inline constexpr T exact_power_of_ten(int64_t power); + static inline constexpr int mantissa_explicit_bits(); + static inline constexpr int minimum_exponent(); + static inline constexpr int infinite_power(); + static inline constexpr int sign_index(); + static inline constexpr int min_exponent_fast_path(); + static inline constexpr int max_exponent_fast_path(); + static inline constexpr int max_exponent_round_to_even(); + static inline constexpr int min_exponent_round_to_even(); + static inline constexpr uint64_t max_mantissa_fast_path(); + static inline constexpr int largest_power_of_ten(); + static inline constexpr int smallest_power_of_ten(); + static inline constexpr T exact_power_of_ten(int64_t power); static inline constexpr size_t max_digits(); static inline constexpr equiv_uint exponent_mask(); static inline constexpr equiv_uint mantissa_mask(); static inline constexpr equiv_uint hidden_bit_mask(); }; -template <> inline constexpr int binary_format<double>::mantissa_explicit_bits() { +template <> inline constexpr int binary_format<double>::mantissa_explicit_bits() { return 52; } -template <> inline constexpr int binary_format<float>::mantissa_explicit_bits() { +template <> inline constexpr int binary_format<float>::mantissa_explicit_bits() { return 23; } -template <> inline constexpr int binary_format<double>::max_exponent_round_to_even() { +template <> inline constexpr int binary_format<double>::max_exponent_round_to_even() { return 23; } -template <> inline constexpr int binary_format<float>::max_exponent_round_to_even() { +template <> inline constexpr int binary_format<float>::max_exponent_round_to_even() { return 10; } -template <> inline constexpr int binary_format<double>::min_exponent_round_to_even() { +template <> inline constexpr int binary_format<double>::min_exponent_round_to_even() { return -4; } -template <> inline constexpr int binary_format<float>::min_exponent_round_to_even() { +template <> inline constexpr int binary_format<float>::min_exponent_round_to_even() { return -17; } -template <> inline constexpr int binary_format<double>::minimum_exponent() { +template <> inline constexpr int binary_format<double>::minimum_exponent() { return -1023; } -template <> inline constexpr int binary_format<float>::minimum_exponent() { +template <> inline constexpr int binary_format<float>::minimum_exponent() { return -127; } -template <> inline constexpr int binary_format<double>::infinite_power() { +template <> inline constexpr int binary_format<double>::infinite_power() { return 0x7FF; } -template <> inline constexpr int binary_format<float>::infinite_power() { +template <> inline constexpr int binary_format<float>::infinite_power() { return 0xFF; } -template <> inline constexpr int binary_format<double>::sign_index() { return 63; } -template <> inline constexpr int binary_format<float>::sign_index() { return 31; } +template <> inline constexpr int binary_format<double>::sign_index() { return 63; } +template <> inline constexpr int binary_format<float>::sign_index() { return 31; } -template <> inline constexpr int binary_format<double>::min_exponent_fast_path() { +template <> inline constexpr int binary_format<double>::min_exponent_fast_path() { #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) return 0; #else return -22; #endif } -template <> inline constexpr int binary_format<float>::min_exponent_fast_path() { +template <> inline constexpr int binary_format<float>::min_exponent_fast_path() { #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) return 0; #else @@ -295,46 +295,46 @@ template <> inline constexpr int binary_format<float>::min_exponent_fast_path() #endif } -template <> inline constexpr int binary_format<double>::max_exponent_fast_path() { +template <> inline constexpr int binary_format<double>::max_exponent_fast_path() { return 22; } -template <> inline constexpr int binary_format<float>::max_exponent_fast_path() { +template <> inline constexpr int binary_format<float>::max_exponent_fast_path() { return 10; } -template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path() { +template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path() { return uint64_t(2) << mantissa_explicit_bits(); } -template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path() { +template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path() { return uint64_t(2) << mantissa_explicit_bits(); } template <> -inline constexpr double binary_format<double>::exact_power_of_ten(int64_t power) { +inline constexpr double binary_format<double>::exact_power_of_ten(int64_t power) { return powers_of_ten_double[power]; } template <> -inline constexpr float binary_format<float>::exact_power_of_ten(int64_t power) { +inline constexpr float binary_format<float>::exact_power_of_ten(int64_t power) { return powers_of_ten_float[power]; } template <> -inline constexpr int binary_format<double>::largest_power_of_ten() { +inline constexpr int binary_format<double>::largest_power_of_ten() { return 308; } template <> -inline constexpr int binary_format<float>::largest_power_of_ten() { +inline constexpr int binary_format<float>::largest_power_of_ten() { return 38; } template <> -inline constexpr int binary_format<double>::smallest_power_of_ten() { +inline constexpr int binary_format<double>::smallest_power_of_ten() { return -342; } template <> -inline constexpr int binary_format<float>::smallest_power_of_ten() { +inline constexpr int binary_format<float>::smallest_power_of_ten() { return -65; } @@ -387,7 +387,7 @@ fastfloat_really_inline void to_float(bool negative, adjusted_mantissa am, T &va #else // For little-endian systems: ::memcpy(&value, &word, sizeof(T)); -#endif +#endif } } // namespace fast_float diff --git a/contrib/restricted/fast_float/include/fast_float/parse_number.h b/contrib/restricted/fast_float/include/fast_float/parse_number.h index 62ae3b039e..2215e2915c 100644 --- a/contrib/restricted/fast_float/include/fast_float/parse_number.h +++ b/contrib/restricted/fast_float/include/fast_float/parse_number.h @@ -13,7 +13,7 @@ namespace fast_float { -namespace detail { +namespace detail { /** * Special case +inf, -inf, nan, infinity, -infinity. * The case comparisons could be made much faster given that we know that the @@ -22,37 +22,37 @@ namespace detail { template <typename T> from_chars_result parse_infnan(const char *first, const char *last, T &value) noexcept { from_chars_result answer; - answer.ptr = first; + answer.ptr = first; answer.ec = std::errc(); // be optimistic - bool minusSign = false; - if (*first == '-') { // assume first < last, so dereference without checks; C++17 20.19.3.(7.1) explicitly forbids '+' here - minusSign = true; - ++first; - } + bool minusSign = false; + if (*first == '-') { // assume first < last, so dereference without checks; C++17 20.19.3.(7.1) explicitly forbids '+' here + minusSign = true; + ++first; + } if (last - first >= 3) { if (fastfloat_strncasecmp(first, "nan", 3)) { - answer.ptr = (first += 3); - value = minusSign ? -std::numeric_limits<T>::quiet_NaN() : std::numeric_limits<T>::quiet_NaN(); - // Check for possible nan(n-char-seq-opt), C++17 20.19.3.7, C11 7.20.1.3.3. At least MSVC produces nan(ind) and nan(snan). - if(first != last && *first == '(') { - for(const char* ptr = first + 1; ptr != last; ++ptr) { - if (*ptr == ')') { - answer.ptr = ptr + 1; // valid nan(n-char-seq-opt) - break; - } - else if(!(('a' <= *ptr && *ptr <= 'z') || ('A' <= *ptr && *ptr <= 'Z') || ('0' <= *ptr && *ptr <= '9') || *ptr == '_')) - break; // forbidden char, not nan(n-char-seq-opt) - } - } + answer.ptr = (first += 3); + value = minusSign ? -std::numeric_limits<T>::quiet_NaN() : std::numeric_limits<T>::quiet_NaN(); + // Check for possible nan(n-char-seq-opt), C++17 20.19.3.7, C11 7.20.1.3.3. At least MSVC produces nan(ind) and nan(snan). + if(first != last && *first == '(') { + for(const char* ptr = first + 1; ptr != last; ++ptr) { + if (*ptr == ')') { + answer.ptr = ptr + 1; // valid nan(n-char-seq-opt) + break; + } + else if(!(('a' <= *ptr && *ptr <= 'z') || ('A' <= *ptr && *ptr <= 'Z') || ('0' <= *ptr && *ptr <= '9') || *ptr == '_')) + break; // forbidden char, not nan(n-char-seq-opt) + } + } return answer; } if (fastfloat_strncasecmp(first, "inf", 3)) { - if ((last - first >= 8) && fastfloat_strncasecmp(first + 3, "inity", 5)) { + if ((last - first >= 8) && fastfloat_strncasecmp(first + 3, "inity", 5)) { answer.ptr = first + 8; } else { answer.ptr = first + 3; } - value = minusSign ? -std::numeric_limits<T>::infinity() : std::numeric_limits<T>::infinity(); + value = minusSign ? -std::numeric_limits<T>::infinity() : std::numeric_limits<T>::infinity(); return answer; } } @@ -60,18 +60,18 @@ from_chars_result parse_infnan(const char *first, const char *last, T &value) n return answer; } -} // namespace detail +} // namespace detail template<typename T> from_chars_result from_chars(const char *first, const char *last, T &value, chars_format fmt /*= chars_format::general*/) noexcept { - return from_chars_advanced(first, last, value, parse_options{fmt}); -} - -template<typename T> -from_chars_result from_chars_advanced(const char *first, const char *last, - T &value, parse_options options) noexcept { - + return from_chars_advanced(first, last, value, parse_options{fmt}); +} + +template<typename T> +from_chars_result from_chars_advanced(const char *first, const char *last, + T &value, parse_options options) noexcept { + static_assert (std::is_same<T, double>::value || std::is_same<T, float>::value, "only float and double are supported"); @@ -81,26 +81,26 @@ from_chars_result from_chars_advanced(const char *first, const char *last, answer.ptr = first; return answer; } - parsed_number_string pns = parse_number_string(first, last, options); + parsed_number_string pns = parse_number_string(first, last, options); if (!pns.valid) { - return detail::parse_infnan(first, last, value); + return detail::parse_infnan(first, last, value); } answer.ec = std::errc(); // be optimistic answer.ptr = pns.lastmatch; // Next is Clinger's fast path. - if (binary_format<T>::min_exponent_fast_path() <= pns.exponent && pns.exponent <= binary_format<T>::max_exponent_fast_path() && pns.mantissa <=binary_format<T>::max_mantissa_fast_path() && !pns.too_many_digits) { + if (binary_format<T>::min_exponent_fast_path() <= pns.exponent && pns.exponent <= binary_format<T>::max_exponent_fast_path() && pns.mantissa <=binary_format<T>::max_mantissa_fast_path() && !pns.too_many_digits) { value = T(pns.mantissa); if (pns.exponent < 0) { value = value / binary_format<T>::exact_power_of_ten(-pns.exponent); } else { value = value * binary_format<T>::exact_power_of_ten(pns.exponent); } if (pns.negative) { value = -value; } return answer; } - adjusted_mantissa am = compute_float<binary_format<T>>(pns.exponent, pns.mantissa); + adjusted_mantissa am = compute_float<binary_format<T>>(pns.exponent, pns.mantissa); if(pns.too_many_digits && am.power2 >= 0) { - if(am != compute_float<binary_format<T>>(pns.exponent, pns.mantissa + 1)) { + if(am != compute_float<binary_format<T>>(pns.exponent, pns.mantissa + 1)) { am = compute_error<binary_format<T>>(pns.exponent, pns.mantissa); - } - } + } + } // If we called compute_float<binary_format<T>>(pns.exponent, pns.mantissa) and we have an invalid power (am.power2 < 0), // then we need to go the long way around again. This is very uncommon. if(am.power2 < 0) { am = digit_comp<T>(pns, am); } diff --git a/contrib/restricted/fast_float/include/fast_float/simple_decimal_conversion.h b/contrib/restricted/fast_float/include/fast_float/simple_decimal_conversion.h index e87801480b..f3b66b0b10 100644 --- a/contrib/restricted/fast_float/include/fast_float/simple_decimal_conversion.h +++ b/contrib/restricted/fast_float/include/fast_float/simple_decimal_conversion.h @@ -19,7 +19,7 @@ namespace fast_float { -namespace detail { +namespace detail { // remove all final zeroes inline void trim(decimal &h) { @@ -30,7 +30,7 @@ inline void trim(decimal &h) { -inline uint32_t number_of_digits_decimal_left_shift(const decimal &h, uint32_t shift) { +inline uint32_t number_of_digits_decimal_left_shift(const decimal &h, uint32_t shift) { shift &= 63; constexpr uint16_t number_of_digits_decimal_left_shift_table[65] = { 0x0000, 0x0800, 0x0801, 0x0803, 0x1006, 0x1009, 0x100D, 0x1812, 0x1817, @@ -123,7 +123,7 @@ inline uint32_t number_of_digits_decimal_left_shift(const decimal &h, uint32_t s return num_new_digits; } -inline uint64_t round(decimal &h) { +inline uint64_t round(decimal &h) { if ((h.num_digits == 0) || (h.decimal_point < 0)) { return 0; } else if (h.decimal_point > 18) { @@ -150,7 +150,7 @@ inline uint64_t round(decimal &h) { } // computes h * 2^-shift -inline void decimal_left_shift(decimal &h, uint32_t shift) { +inline void decimal_left_shift(decimal &h, uint32_t shift) { if (h.num_digits == 0) { return; } @@ -192,7 +192,7 @@ inline void decimal_left_shift(decimal &h, uint32_t shift) { } // computes h * 2^shift -inline void decimal_right_shift(decimal &h, uint32_t shift) { +inline void decimal_right_shift(decimal &h, uint32_t shift) { uint32_t read_index = 0; uint32_t write_index = 0; @@ -238,7 +238,7 @@ inline void decimal_right_shift(decimal &h, uint32_t shift) { trim(h); } -} // namespace detail +} // namespace detail template <typename binary> adjusted_mantissa compute_float(decimal &d) { @@ -280,8 +280,8 @@ adjusted_mantissa compute_float(decimal &d) { int32_t exp2 = 0; while (d.decimal_point > 0) { uint32_t n = uint32_t(d.decimal_point); - uint32_t shift = (n < num_powers) ? decimal_powers[n] : max_shift; - detail::decimal_right_shift(d, shift); + uint32_t shift = (n < num_powers) ? decimal_powers[n] : max_shift; + detail::decimal_right_shift(d, shift); if (d.decimal_point < -decimal_point_range) { // should be zero answer.power2 = 0; @@ -300,12 +300,12 @@ adjusted_mantissa compute_float(decimal &d) { shift = (d.digits[0] < 2) ? 2 : 1; } else { uint32_t n = uint32_t(-d.decimal_point); - shift = (n < num_powers) ? decimal_powers[n] : max_shift; + shift = (n < num_powers) ? decimal_powers[n] : max_shift; } - detail::decimal_left_shift(d, shift); + detail::decimal_left_shift(d, shift); if (d.decimal_point > decimal_point_range) { // we want to get infinity: - answer.power2 = binary::infinite_power(); + answer.power2 = binary::infinite_power(); answer.mantissa = 0; return answer; } @@ -319,7 +319,7 @@ adjusted_mantissa compute_float(decimal &d) { if (n > max_shift) { n = max_shift; } - detail::decimal_right_shift(d, n); + detail::decimal_right_shift(d, n); exp2 += int32_t(n); } if ((exp2 - minimum_exponent) >= binary::infinite_power()) { @@ -329,15 +329,15 @@ adjusted_mantissa compute_float(decimal &d) { } const int mantissa_size_in_bits = binary::mantissa_explicit_bits() + 1; - detail::decimal_left_shift(d, mantissa_size_in_bits); + detail::decimal_left_shift(d, mantissa_size_in_bits); - uint64_t mantissa = detail::round(d); + uint64_t mantissa = detail::round(d); // It is possible that we have an overflow, in which case we need // to shift back. if(mantissa >= (uint64_t(1) << mantissa_size_in_bits)) { - detail::decimal_right_shift(d, 1); + detail::decimal_right_shift(d, 1); exp2 += 1; - mantissa = detail::round(d); + mantissa = detail::round(d); if ((exp2 - minimum_exponent) >= binary::infinite_power()) { answer.power2 = binary::infinite_power(); answer.mantissa = 0; @@ -351,8 +351,8 @@ adjusted_mantissa compute_float(decimal &d) { } template <typename binary> -adjusted_mantissa parse_long_mantissa(const char *first, const char* last, parse_options options) { - decimal d = parse_decimal(first, last, options); +adjusted_mantissa parse_long_mantissa(const char *first, const char* last, parse_options options) { + decimal d = parse_decimal(first, last, options); return compute_float<binary>(d); } diff --git a/contrib/restricted/fast_float/ya.make b/contrib/restricted/fast_float/ya.make index dd331096b3..b3e87bb472 100644 --- a/contrib/restricted/fast_float/ya.make +++ b/contrib/restricted/fast_float/ya.make @@ -1,6 +1,6 @@ # Generated by devtools/yamaker from nixpkgs 21.11. -LIBRARY() +LIBRARY() LICENSE( Apache-2.0 AND @@ -21,8 +21,8 @@ ORIGINAL_SOURCE(https://github.com/fastfloat/fast_float/archive/v3.4.0.tar.gz) NO_COMPILER_WARNINGS() -NO_RUNTIME() +NO_RUNTIME() -NO_UTIL() +NO_UTIL() END() diff --git a/contrib/restricted/googletest/googletest/include/gtest/gtest-printers.h b/contrib/restricted/googletest/googletest/include/gtest/gtest-printers.h index 5a155d2141..410e8b7ad5 100644 --- a/contrib/restricted/googletest/googletest/include/gtest/gtest-printers.h +++ b/contrib/restricted/googletest/googletest/include/gtest/gtest-printers.h @@ -394,7 +394,7 @@ GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char32_t); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string); -#ifdef __cpp_lib_char8_t +#ifdef __cpp_lib_char8_t GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char8_t, ::std::u8string); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char8_t, ::std::u8string); #endif diff --git a/contrib/restricted/thrift/thrift/VirtualProfiling.cpp b/contrib/restricted/thrift/thrift/VirtualProfiling.cpp index fa0a1d88a2..334e38b7aa 100644 --- a/contrib/restricted/thrift/thrift/VirtualProfiling.cpp +++ b/contrib/restricted/thrift/thrift/VirtualProfiling.cpp @@ -37,7 +37,7 @@ #include <thrift/concurrency/Mutex.h> -#error include <ext/hash_map> +#error include <ext/hash_map> #include <execinfo.h> #include <stdio.h> diff --git a/contrib/restricted/uriparser/config.h b/contrib/restricted/uriparser/config.h index ebb62f778d..b9a9cf7c8b 100644 --- a/contrib/restricted/uriparser/config.h +++ b/contrib/restricted/uriparser/config.h @@ -44,7 +44,7 @@ #define PACKAGE_VERSION "0.9.6" #define HAVE_WPRINTF -#define HAVE_REALLOCARRAY +#define HAVE_REALLOCARRAY diff --git a/contrib/restricted/uriparser/test/MemoryManagerSuite.cpp b/contrib/restricted/uriparser/test/MemoryManagerSuite.cpp index 0abc263bca..ecf3bc0f8d 100644 --- a/contrib/restricted/uriparser/test/MemoryManagerSuite.cpp +++ b/contrib/restricted/uriparser/test/MemoryManagerSuite.cpp @@ -207,7 +207,7 @@ TEST(MemoryManagerCompletenessSuite, MallocAndFreeRequiredOnly) { -TEST(MemoryManagerTestingSuite, DISABLED_DefaultMemoryManager) { +TEST(MemoryManagerTestingSuite, DISABLED_DefaultMemoryManager) { ASSERT_EQ(uriTestMemoryManager(&defaultMemoryManager), URI_SUCCESS); } @@ -229,7 +229,7 @@ TEST(MemoryManagerTestingSuite, CompleteMemoryManager) { -TEST(MemoryManagerTestingSuite, DISABLED_EmulateCalloc) { +TEST(MemoryManagerTestingSuite, DISABLED_EmulateCalloc) { UriMemoryManager partialEmulationMemoryManager; memcpy(&partialEmulationMemoryManager, &defaultMemoryManager, sizeof(UriMemoryManager)); diff --git a/contrib/restricted/uriparser/test/ya.make b/contrib/restricted/uriparser/test/ya.make index ae8a32a932..7e576940ef 100644 --- a/contrib/restricted/uriparser/test/ya.make +++ b/contrib/restricted/uriparser/test/ya.make @@ -17,7 +17,7 @@ LICENSE( LICENSE_TEXTS(.yandex_meta/licenses.list.txt) PEERDIR( - contrib/restricted/uriparser + contrib/restricted/uriparser ) ADDINCL( @@ -29,10 +29,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() SRCS( - FourSuite.cpp - MemoryManagerSuite.cpp - VersionSuite.cpp - test.cpp + FourSuite.cpp + MemoryManagerSuite.cpp + VersionSuite.cpp + test.cpp ) END() diff --git a/contrib/restricted/uriparser/tool/ya.make b/contrib/restricted/uriparser/tool/ya.make index 3692ca78e5..961fbd4bf1 100644 --- a/contrib/restricted/uriparser/tool/ya.make +++ b/contrib/restricted/uriparser/tool/ya.make @@ -14,7 +14,7 @@ LICENSE(BSD-3-Clause) LICENSE_TEXTS(.yandex_meta/licenses.list.txt) PEERDIR( - contrib/restricted/uriparser + contrib/restricted/uriparser ) ADDINCL( diff --git a/contrib/restricted/uriparser/ya.make b/contrib/restricted/uriparser/ya.make index a2b64f8229..c6715c21e1 100644 --- a/contrib/restricted/uriparser/ya.make +++ b/contrib/restricted/uriparser/ya.make @@ -17,13 +17,13 @@ LICENSE(BSD-3-Clause) LICENSE_TEXTS(.yandex_meta/licenses.list.txt) -PEERDIR( - contrib/libs/libc_compat -) - +PEERDIR( + contrib/libs/libc_compat +) + ADDINCL( - GLOBAL contrib/restricted/uriparser/include - contrib/restricted/uriparser + GLOBAL contrib/restricted/uriparser/include + contrib/restricted/uriparser ) NO_COMPILER_WARNINGS() diff --git a/contrib/restricted/ya.make b/contrib/restricted/ya.make index b52a206733..14a5103ccd 100644 --- a/contrib/restricted/ya.make +++ b/contrib/restricted/ya.make @@ -13,12 +13,12 @@ RECURSE( boost cityhash-1.0.2 cmph - cpuinfo - exiv2 - expected-lite + cpuinfo + exiv2 + expected-lite fast_float dragonbox - gemmlowp + gemmlowp glib glib-networking glibmm @@ -28,7 +28,7 @@ RECURSE( gst-plugins-base gst-plugins-good gstreamer - http-parser + http-parser keyutils libelf libffi @@ -37,12 +37,12 @@ RECURSE( librseq libsigcxx libsoup - libtorrent + libtorrent liburcu - libxsmm + libxsmm llhttp mpg123 - murmurhash + murmurhash nfs_ganesha noc openal-soft @@ -53,11 +53,11 @@ RECURSE( range-v3 rnnoise rubberband - spdlog + spdlog thrift thrift/compiler - turbo_base64 - uriparser + turbo_base64 + uriparser ) IF(OS_LINUX OR OS_DARWIN) |