aboutsummaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorAlexander Smirnov <alex@ydb.tech>2025-02-19 00:51:42 +0000
committerAlexander Smirnov <alex@ydb.tech>2025-02-19 00:51:42 +0000
commit95b254219eb0d087aadae07ff41ee597718fbbfd (patch)
tree21da0cb51a0ab8c1360b8adc4718beda1f023cf8 /contrib
parent0402fc0225de7587fb71303b66a54f2716820e96 (diff)
parentafe5f174d1537a99ec81b46bd61861bc7f1a29ee (diff)
downloadydb-95b254219eb0d087aadae07ff41ee597718fbbfd.tar.gz
Merge branch 'rightlib' into merge-libs-250219-0050
Diffstat (limited to 'contrib')
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__config_site1
-rw-r--r--contrib/libs/protobuf_old/protoherobora.py195
-rw-r--r--contrib/libs/protobuf_old/ya.make2
-rw-r--r--contrib/restricted/abseil-cpp/.yandex_meta/__init__.py2
-rw-r--r--contrib/restricted/abseil-cpp/.yandex_meta/devtools.copyrights.report6
-rw-r--r--contrib/restricted/abseil-cpp/.yandex_meta/devtools.licenses.report4
-rw-r--r--contrib/restricted/abseil-cpp/.yandex_meta/override.nix4
-rw-r--r--contrib/restricted/abseil-cpp/absl/algorithm/algorithm.h4
-rw-r--r--contrib/restricted/abseil-cpp/absl/algorithm/container.h127
-rw-r--r--contrib/restricted/abseil-cpp/absl/algorithm/ya.make4
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/attributes.h82
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/call_once.h13
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/config.h8
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/internal/nullability_impl.h73
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/internal/raw_logging.cc2
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/internal/sysinfo.cc14
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/internal/thread_identity.h6
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/internal/tracing.cc39
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/internal/tracing.h81
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.cc10
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.h12
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/macros.h39
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/nullability.h88
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/optimization.h20
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/options.h7
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/policy_checks.h2
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/ya.make3
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/btree_map.h4
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/btree_set.h4
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/fixed_array.h3
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/flat_hash_map.h20
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/flat_hash_set.h20
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/inlined_vector.h3
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/internal/common_policy_traits.h9
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/internal/container_memory.h1
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/internal/inlined_vector.h6
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/internal/layout.h2
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set.cc256
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set.h622
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/node_hash_map.h29
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/node_hash_set.h29
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/ya.make2
-rw-r--r--contrib/restricted/abseil-cpp/absl/crc/internal/cpu_detect.cc56
-rw-r--r--contrib/restricted/abseil-cpp/absl/crc/internal/non_temporal_memcpy.h28
-rw-r--r--contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.cc37
-rw-r--r--contrib/restricted/abseil-cpp/absl/debugging/internal/elf_mem_image.h2
-rw-r--r--contrib/restricted/abseil-cpp/absl/debugging/internal/stack_consumption.h2
-rw-r--r--contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc16
-rw-r--r--contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_config.h7
-rw-r--r--contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc15
-rw-r--r--contrib/restricted/abseil-cpp/absl/debugging/leak_check.cc6
-rw-r--r--contrib/restricted/abseil-cpp/absl/debugging/symbolize.cc5
-rw-r--r--contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc57
-rw-r--r--contrib/restricted/abseil-cpp/absl/debugging/ya.make2
-rw-r--r--contrib/restricted/abseil-cpp/absl/flags/commandlineflag.cc1
-rw-r--r--contrib/restricted/abseil-cpp/absl/flags/commandlineflag.h7
-rw-r--r--contrib/restricted/abseil-cpp/absl/flags/flag.h26
-rw-r--r--contrib/restricted/abseil-cpp/absl/flags/internal/flag.cc16
-rw-r--r--contrib/restricted/abseil-cpp/absl/flags/internal/flag.h21
-rw-r--r--contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor.cc4
-rw-r--r--contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor.h3
-rw-r--r--contrib/restricted/abseil-cpp/absl/flags/internal/program_name.cc25
-rw-r--r--contrib/restricted/abseil-cpp/absl/flags/internal/usage.cc27
-rw-r--r--contrib/restricted/abseil-cpp/absl/flags/parse.cc25
-rw-r--r--contrib/restricted/abseil-cpp/absl/flags/usage_config.cc13
-rw-r--r--contrib/restricted/abseil-cpp/absl/flags/ya.make2
-rw-r--r--contrib/restricted/abseil-cpp/absl/functional/ya.make4
-rw-r--r--contrib/restricted/abseil-cpp/absl/hash/hash.h28
-rw-r--r--contrib/restricted/abseil-cpp/absl/hash/hash_testing.h16
-rw-r--r--contrib/restricted/abseil-cpp/absl/hash/internal/hash.cc34
-rw-r--r--contrib/restricted/abseil-cpp/absl/hash/internal/hash.h287
-rw-r--r--contrib/restricted/abseil-cpp/absl/hash/internal/low_level_hash.cc6
-rw-r--r--contrib/restricted/abseil-cpp/absl/hash/internal/spy_hash_state.h8
-rw-r--r--contrib/restricted/abseil-cpp/absl/hash/ya.make2
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/absl_vlog_is_on.h2
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/internal/check_op.cc49
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/internal/check_op.h182
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/internal/log_message.cc128
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/internal/log_message.h128
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/internal/proto.cc3
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/internal/proto.h40
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/internal/structured.h110
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/internal/structured_proto.cc115
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/internal/structured_proto.h107
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/internal/vlog_config.cc9
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/log_sink_registry.h7
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/scoped_mock_log.h4
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/structured.h7
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/vlog_is_on.h2
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/ya.make3
-rw-r--r--contrib/restricted/abseil-cpp/absl/memory/ya.make4
-rw-r--r--contrib/restricted/abseil-cpp/absl/meta/type_traits.h22
-rw-r--r--contrib/restricted/abseil-cpp/absl/meta/ya.make4
-rw-r--r--contrib/restricted/abseil-cpp/absl/numeric/int128.h18
-rw-r--r--contrib/restricted/abseil-cpp/absl/numeric/int128_have_intrinsic.inc10
-rw-r--r--contrib/restricted/abseil-cpp/absl/numeric/int128_no_intrinsic.inc9
-rw-r--r--contrib/restricted/abseil-cpp/absl/numeric/ya.make2
-rw-r--r--contrib/restricted/abseil-cpp/absl/profiling/ya.make2
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/bernoulli_distribution.h4
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/beta_distribution.h4
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/bit_gen_ref.h3
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/discrete_distribution.cc10
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/discrete_distribution.h6
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/exponential_distribution.h1
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.h3
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/chi_square.cc9
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/distribution_caller.h4
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.h6
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/iostream_state_saver.h7
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/mock_overload_set.h12
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/platform.h24
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.cc61
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/randen_engine.h3
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/uniform_helper.h4
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/wide_multiply.h1
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/log_uniform_int_distribution.h5
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/mock_distributions.h4
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/mocking_bit_gen.h119
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/poisson_distribution.h7
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.cc5
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/seed_sequences.h3
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/uniform_int_distribution.h3
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/uniform_real_distribution.h2
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/ya.make2
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/zipf_distribution.h9
-rw-r--r--contrib/restricted/abseil-cpp/absl/status/internal/status_internal.cc12
-rw-r--r--contrib/restricted/abseil-cpp/absl/status/internal/status_internal.h2
-rw-r--r--contrib/restricted/abseil-cpp/absl/status/status.h2
-rw-r--r--contrib/restricted/abseil-cpp/absl/status/ya.make2
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/ascii.cc67
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/ascii.h56
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/charconv.cc11
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/charset.h7
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/cord.h24
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/escaping.cc104
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/internal/charconv_bigint.h2
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.h63
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc5
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/internal/str_split_internal.h35
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/match.h32
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/numbers.cc3
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/str_cat.h11
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/str_split.h19
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/string_view.h39
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/strip.h19
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/ya.make2
-rw-r--r--contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.cc26
-rw-r--r--contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.h6
-rw-r--r--contrib/restricted/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc6
-rw-r--r--contrib/restricted/abseil-cpp/absl/synchronization/mutex.cc50
-rw-r--r--contrib/restricted/abseil-cpp/absl/synchronization/notification.cc12
-rw-r--r--contrib/restricted/abseil-cpp/absl/synchronization/notification.h12
-rw-r--r--contrib/restricted/abseil-cpp/absl/synchronization/ya.make2
-rw-r--r--contrib/restricted/abseil-cpp/absl/time/duration.cc57
-rw-r--r--contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc2
-rw-r--r--contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc2
-rw-r--r--contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.cc6
-rw-r--r--contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc4
-rw-r--r--contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.h4
-rw-r--r--contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc6
-rw-r--r--contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.h4
-rw-r--r--contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc2
-rw-r--r--contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.h2
-rw-r--r--contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc5
-rw-r--r--contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc2
-rw-r--r--contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/tzfile.h10
-rw-r--r--contrib/restricted/abseil-cpp/absl/time/time.h105
-rw-r--r--contrib/restricted/abseil-cpp/absl/time/ya.make2
-rw-r--r--contrib/restricted/abseil-cpp/absl/types/internal/span.h5
-rw-r--r--contrib/restricted/abseil-cpp/absl/types/optional.h6
-rw-r--r--contrib/restricted/abseil-cpp/absl/types/span.h128
-rw-r--r--contrib/restricted/abseil-cpp/absl/types/ya.make2
-rw-r--r--contrib/restricted/abseil-cpp/absl/utility/ya.make4
-rw-r--r--contrib/restricted/abseil-cpp/patches/pr1728-fix-ndk-r25.patch87
-rw-r--r--contrib/restricted/abseil-cpp/ya.make4
175 files changed, 3422 insertions, 1592 deletions
diff --git a/contrib/libs/cxxsupp/libcxx/include/__config_site b/contrib/libs/cxxsupp/libcxx/include/__config_site
index 9c748b346a..41a3962dd4 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__config_site
+++ b/contrib/libs/cxxsupp/libcxx/include/__config_site
@@ -3,7 +3,6 @@
#define _LIBCPP_ABI_VERSION 1
#define _LIBCPP_ABI_NAMESPACE __y1
-#define _LIBCPP_DISABLE_NODISCARD_EXT
#define _LIBCPP_PSTL_CPU_BACKEND_THREAD
#ifndef _YNDX_LIBCPP_ENABLE_EXTENSIONS
diff --git a/contrib/libs/protobuf_old/protoherobora.py b/contrib/libs/protobuf_old/protoherobora.py
new file mode 100644
index 0000000000..9b85a204bc
--- /dev/null
+++ b/contrib/libs/protobuf_old/protoherobora.py
@@ -0,0 +1,195 @@
+#!/usr/bin/env python3
+
+import subprocess
+import os
+import sys
+import json
+
+
+# TODO: dedup
+def is_cmdfile_arg(arg):
+ # type: (str) -> bool
+ return arg.startswith('@')
+
+
+def cmdfile_path(arg):
+ # type: (str) -> str
+ return arg[1:]
+
+
+def read_from_command_file(arg):
+ # type: (str) -> list[str]
+ with open(arg) as afile:
+ return afile.read().splitlines()
+
+
+def skip_markers(args):
+ # type: (list[str]) -> list[str]
+ res = []
+ for arg in args:
+ if arg == '--ya-start-command-file' or arg == '--ya-end-command-file':
+ continue
+ res.append(arg)
+ return res
+
+
+def iter_args(
+ args, # type: list[str]
+ ):
+ for arg in args:
+ if not is_cmdfile_arg(arg):
+ if arg == '--ya-start-command-file' or arg == '--ya-end-command-file':
+ continue
+ yield arg
+ else:
+ for cmdfile_arg in read_from_command_file(cmdfile_path(arg)):
+ yield cmdfile_arg
+
+
+def get_args(args):
+ # type: (list[str]) -> list[str]
+ return list(iter_args(args))
+# end TODO
+
+
+def run(*args):
+ return subprocess.check_output(list(args), shell=False).strip()
+
+
+def gen_renames_1(d):
+ for l in d.split('\n'):
+ l = l.strip()
+
+ if ' ' in l:
+ yield l.split(' ')[-1]
+
+
+def gen_renames_2(p, d):
+ for s in gen_renames_1(d):
+ """
+ Since clang-17, the option -fsanitize-address-globals-dead-stripping
+ has been enabled by default. Due to this, we have broken optimization
+ that merges calls to the `asan.module_ctor` function, as we are renaming
+ symbols with a prefix of 'py2_'. When this flag is enabled, and
+ the functions are not merged, false-positive ODR (One Definition Rule)
+ violations occur on objects such as `typeinfo std::exception`, because
+ the runtime is trying to handle global objects that have already been handled.
+ """
+ if 'asan_globals' in s:
+ continue
+ yield s + ' ' + p + s
+
+
+def gen_renames(p, d):
+ return '\n'.join(gen_renames_2(p, d)).strip() + '\n'
+
+
+def rename_syms(where, ret, libs):
+ p = 'py2_'
+
+ # join libs
+ run(where + 'llvm-ar', 'qcL', ret, *libs)
+
+ # find symbols to rename
+ syms = run(where + 'llvm-nm', '--extern-only', '--defined-only', '-A', ret)
+
+ # prepare rename plan
+ renames = gen_renames(p, syms)
+
+ with open('syms', 'w') as f:
+ f.write(renames)
+
+ # rename symbols
+ run(where + 'llvm-objcopy', '--redefine-syms=syms', ret)
+
+ # back-rename some symbols
+ args = [
+ where + 'llvm-objcopy',
+ '--redefine-sym',
+ p + 'init_api_implementation=init6google8protobuf8internal19_api_implementation',
+ '--redefine-sym',
+ p + 'init_message=init6google8protobuf5pyext8_message',
+ '--redefine-sym',
+ p + 'init6google8protobuf8internal19_api_implementation=init6google8protobuf8internal19_api_implementation',
+ '--redefine-sym',
+ p + 'init6google8protobuf5pyext8_message=init6google8protobuf5pyext8_message',
+ '--redefine-sym',
+ p + '_init6google8protobuf8internal19_api_implementation=_init6google8protobuf8internal19_api_implementation',
+ '--redefine-sym',
+ p + '_init6google8protobuf5pyext8_message=_init6google8protobuf5pyext8_message',
+ ret,
+ ]
+
+ run(*args)
+ return ret
+
+
+def find_lld(args):
+ for x in args:
+ if 'lld-link' in x:
+ return x
+
+ raise IndexError()
+
+
+def fix_py2(cmd, have_comand_files=False, prefix='lib', suffix='a'):
+ args = cmd
+
+ if have_comand_files:
+ args = get_args(cmd)
+
+ if 'protobuf_old' not in str(args):
+ return cmd
+
+ py2_libs = [prefix + 'contrib-libs-protobuf_old.' + suffix, prefix + 'pypython-protobuf-py2.' + suffix]
+
+ def need_rename(x):
+ for v in py2_libs:
+ if v in x:
+ return True
+
+ return False
+
+ old = []
+ lib = []
+
+ try:
+ where = os.path.dirname(cmd[cmd.index('--objcopy-exe') + 1]) + '/'
+ except ValueError:
+ where = os.path.dirname(find_lld(cmd)) + '/'
+
+ for x in args:
+ if need_rename(x):
+ lib.append(x)
+ else:
+ old.append(x)
+
+ name = rename_syms(where, 'libprotoherobora.' + suffix, lib)
+
+ if not have_comand_files:
+ return old + [name]
+
+ for file in cmd:
+ if is_cmdfile_arg(file):
+ cmd_file_path = cmdfile_path(file)
+ args = read_from_command_file(cmd_file_path)
+ if not 'protobuf_old' in str(args):
+ continue
+ with open(cmd_file_path, 'w') as afile:
+ for arg in args:
+ if not need_rename(arg):
+ afile.write(arg + '\n')
+ afile.write(name)
+
+ return cmd
+
+
+if __name__ == '__main__':
+ args = sys.argv[1:]
+
+ if 'lld-link' in str(args):
+ cmd = fix_py2(args, have_comand_files=True, prefix='', suffix='lib')
+ else:
+ cmd = fix_py2(args)
+
+ sys.stdout.write(json.dumps(cmd))
diff --git a/contrib/libs/protobuf_old/ya.make b/contrib/libs/protobuf_old/ya.make
index 50a3d8cd79..39f6a558a8 100644
--- a/contrib/libs/protobuf_old/ya.make
+++ b/contrib/libs/protobuf_old/ya.make
@@ -2,6 +2,8 @@
LIBRARY()
+LD_PLUGIN(protoherobora.py)
+
LICENSE(
BSD-3-Clause AND
Protobuf-License
diff --git a/contrib/restricted/abseil-cpp/.yandex_meta/__init__.py b/contrib/restricted/abseil-cpp/.yandex_meta/__init__.py
index 8ffd340d62..489e4e6d66 100644
--- a/contrib/restricted/abseil-cpp/.yandex_meta/__init__.py
+++ b/contrib/restricted/abseil-cpp/.yandex_meta/__init__.py
@@ -160,6 +160,7 @@ abseil_cpp = CMakeNinjaNixProject(
"absl_spinlock_wait",
"absl_strerror",
"absl_throw_delegate",
+ "absl_tracing_internal",
],
"absl_debugging_internal": [
"absl_decode_rust_punycode",
@@ -202,6 +203,7 @@ abseil_cpp = CMakeNinjaNixProject(
"absl_log_internal_message",
"absl_log_internal_nullguard",
"absl_log_internal_proto",
+ "absl_log_internal_structured_proto",
"absl_log_sink",
"absl_vlog_config_internal",
],
diff --git a/contrib/restricted/abseil-cpp/.yandex_meta/devtools.copyrights.report b/contrib/restricted/abseil-cpp/.yandex_meta/devtools.copyrights.report
index 1d1da6829f..1197f5fb7b 100644
--- a/contrib/restricted/abseil-cpp/.yandex_meta/devtools.copyrights.report
+++ b/contrib/restricted/abseil-cpp/.yandex_meta/devtools.copyrights.report
@@ -602,6 +602,8 @@ BELONGS absl/strings/ya.make
Files with this license:
absl/base/internal/poison.cc [1:1]
absl/base/internal/poison.h [1:1]
+ absl/base/internal/tracing.cc [1:1]
+ absl/base/internal/tracing.h [1:1]
absl/container/hash_container_defaults.h [1:1]
absl/debugging/internal/bounded_utf8_length_sequence.h [1:1]
absl/debugging/internal/decode_rust_punycode.cc [1:1]
@@ -610,11 +612,13 @@ BELONGS absl/strings/ya.make
absl/debugging/internal/demangle_rust.h [1:1]
absl/debugging/internal/utf8_for_code_point.cc [1:1]
absl/debugging/internal/utf8_for_code_point.h [1:1]
+ absl/log/internal/structured_proto.cc [2:2]
+ absl/log/internal/structured_proto.h [1:1]
absl/random/internal/mock_validators.h [1:1]
absl/status/internal/status_matchers.h [1:1]
Belongs difference:
+ absl/strings/ya.make
- - absl/base/ya.make absl/container/ya.make absl/debugging/ya.make absl/random/ya.make absl/status/ya.make
+ - absl/base/ya.make absl/container/ya.make absl/debugging/ya.make absl/log/ya.make absl/random/ya.make absl/status/ya.make
KEEP COPYRIGHT_SERVICE_LABEL 9fd4860fdb6776c0e8deab1d14ff7b1b
BELONGS absl/debugging/ya.make
diff --git a/contrib/restricted/abseil-cpp/.yandex_meta/devtools.licenses.report b/contrib/restricted/abseil-cpp/.yandex_meta/devtools.licenses.report
index 7797dd2f87..3767fa892e 100644
--- a/contrib/restricted/abseil-cpp/.yandex_meta/devtools.licenses.report
+++ b/contrib/restricted/abseil-cpp/.yandex_meta/devtools.licenses.report
@@ -41,6 +41,8 @@ BELONGS absl/base/ya.make absl/debugging/ya.make absl/hash/ya.make absl/log/ya.m
absl/base/internal/cycleclock_config.h [3:13]
absl/base/internal/poison.cc [3:13]
absl/base/internal/poison.h [3:13]
+ absl/base/internal/tracing.cc [3:13]
+ absl/base/internal/tracing.h [3:13]
absl/base/internal/unscaledcycleclock_config.h [3:13]
absl/base/prefetch.h [3:13]
absl/container/hash_container_defaults.h [3:13]
@@ -402,6 +404,8 @@ BELONGS absl/algorithm/ya.make absl/base/ya.make absl/container/ya.make absl/deb
absl/log/internal/proto.h [3:13]
absl/log/internal/strip.h [3:13]
absl/log/internal/structured.h [3:13]
+ absl/log/internal/structured_proto.cc [4:14]
+ absl/log/internal/structured_proto.h [3:13]
absl/log/internal/test_actions.h [3:13]
absl/log/internal/test_helpers.h [3:13]
absl/log/internal/test_matchers.h [3:13]
diff --git a/contrib/restricted/abseil-cpp/.yandex_meta/override.nix b/contrib/restricted/abseil-cpp/.yandex_meta/override.nix
index 8935fabf1e..67be2bdadc 100644
--- a/contrib/restricted/abseil-cpp/.yandex_meta/override.nix
+++ b/contrib/restricted/abseil-cpp/.yandex_meta/override.nix
@@ -1,11 +1,11 @@
self: super: with self; rec {
- version = "20240722.1";
+ version = "20250127.0";
src = fetchFromGitHub {
owner = "abseil";
repo = "abseil-cpp";
rev = version;
- hash = "sha256-ir4hG2VIPv3se7JfWqCM/siLqFEFkmhMW/IGCocy6Pc=";
+ hash = "sha256-Tt4F0VT7koEARWNjL/L2E8jrPZbSsPb/Y32Kn86sb+k=";
};
patches = [];
diff --git a/contrib/restricted/abseil-cpp/absl/algorithm/algorithm.h b/contrib/restricted/abseil-cpp/absl/algorithm/algorithm.h
index 59aeed7d26..48f59504d2 100644
--- a/contrib/restricted/abseil-cpp/absl/algorithm/algorithm.h
+++ b/contrib/restricted/abseil-cpp/absl/algorithm/algorithm.h
@@ -53,8 +53,8 @@ using std::rotate;
// n = (`last` - `first`) comparisons. A linear search over short containers
// may be faster than a binary search, even when the container is sorted.
template <typename InputIterator, typename EqualityComparable>
-bool linear_search(InputIterator first, InputIterator last,
- const EqualityComparable& value) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool linear_search(
+ InputIterator first, InputIterator last, const EqualityComparable& value) {
return std::find(first, last, value) != last;
}
diff --git a/contrib/restricted/abseil-cpp/absl/algorithm/container.h b/contrib/restricted/abseil-cpp/absl/algorithm/container.h
index 6bbe3b5adf..3193656f88 100644
--- a/contrib/restricted/abseil-cpp/absl/algorithm/container.h
+++ b/contrib/restricted/abseil-cpp/absl/algorithm/container.h
@@ -131,11 +131,14 @@ struct IsUnorderedContainer<std::unordered_set<Key, Hash, KeyEqual, Allocator>>
//
// Container-based version of absl::linear_search() for performing a linear
// search within a container.
+//
+// For a generalization that uses a predicate, see absl::c_any_of().
template <typename C, typename EqualityComparable>
-bool c_linear_search(const C& c, EqualityComparable&& value) {
- return linear_search(container_algorithm_internal::c_begin(c),
- container_algorithm_internal::c_end(c),
- std::forward<EqualityComparable>(value));
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool c_linear_search(
+ const C& c, EqualityComparable&& value) {
+ return absl::linear_search(container_algorithm_internal::c_begin(c),
+ container_algorithm_internal::c_end(c),
+ std::forward<EqualityComparable>(value));
}
//------------------------------------------------------------------------------
@@ -163,7 +166,7 @@ ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17
// Container-based version of the <algorithm> `std::all_of()` function to
// test if all elements within a container satisfy a condition.
template <typename C, typename Pred>
-bool c_all_of(const C& c, Pred&& pred) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool c_all_of(const C& c, Pred&& pred) {
return std::all_of(container_algorithm_internal::c_begin(c),
container_algorithm_internal::c_end(c),
std::forward<Pred>(pred));
@@ -174,7 +177,7 @@ bool c_all_of(const C& c, Pred&& pred) {
// Container-based version of the <algorithm> `std::any_of()` function to
// test if any element in a container fulfills a condition.
template <typename C, typename Pred>
-bool c_any_of(const C& c, Pred&& pred) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool c_any_of(const C& c, Pred&& pred) {
return std::any_of(container_algorithm_internal::c_begin(c),
container_algorithm_internal::c_end(c),
std::forward<Pred>(pred));
@@ -185,7 +188,7 @@ bool c_any_of(const C& c, Pred&& pred) {
// Container-based version of the <algorithm> `std::none_of()` function to
// test if no elements in a container fulfill a condition.
template <typename C, typename Pred>
-bool c_none_of(const C& c, Pred&& pred) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool c_none_of(const C& c, Pred&& pred) {
return std::none_of(container_algorithm_internal::c_begin(c),
container_algorithm_internal::c_end(c),
std::forward<Pred>(pred));
@@ -196,7 +199,8 @@ bool c_none_of(const C& c, Pred&& pred) {
// Container-based version of the <algorithm> `std::for_each()` function to
// apply a function to a container's elements.
template <typename C, typename Function>
-decay_t<Function> c_for_each(C&& c, Function&& f) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 decay_t<Function> c_for_each(C&& c,
+ Function&& f) {
return std::for_each(container_algorithm_internal::c_begin(c),
container_algorithm_internal::c_end(c),
std::forward<Function>(f));
@@ -207,7 +211,9 @@ decay_t<Function> c_for_each(C&& c, Function&& f) {
// Container-based version of the <algorithm> `std::find()` function to find
// the first element containing the passed value within a container value.
template <typename C, typename T>
-container_algorithm_internal::ContainerIter<C> c_find(C& c, T&& value) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20
+ container_algorithm_internal::ContainerIter<C>
+ c_find(C& c, T&& value) {
return std::find(container_algorithm_internal::c_begin(c),
container_algorithm_internal::c_end(c),
std::forward<T>(value));
@@ -218,7 +224,8 @@ container_algorithm_internal::ContainerIter<C> c_find(C& c, T&& value) {
// Container-based version of the <algorithm> `std::ranges::contains()` C++23
// function to search a container for a value.
template <typename Sequence, typename T>
-bool c_contains(const Sequence& sequence, T&& value) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool c_contains(const Sequence& sequence,
+ T&& value) {
return absl::c_find(sequence, std::forward<T>(value)) !=
container_algorithm_internal::c_end(sequence);
}
@@ -228,7 +235,9 @@ bool c_contains(const Sequence& sequence, T&& value) {
// Container-based version of the <algorithm> `std::find_if()` function to find
// the first element in a container matching the given condition.
template <typename C, typename Pred>
-container_algorithm_internal::ContainerIter<C> c_find_if(C& c, Pred&& pred) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20
+ container_algorithm_internal::ContainerIter<C>
+ c_find_if(C& c, Pred&& pred) {
return std::find_if(container_algorithm_internal::c_begin(c),
container_algorithm_internal::c_end(c),
std::forward<Pred>(pred));
@@ -239,8 +248,9 @@ container_algorithm_internal::ContainerIter<C> c_find_if(C& c, Pred&& pred) {
// Container-based version of the <algorithm> `std::find_if_not()` function to
// find the first element in a container not matching the given condition.
template <typename C, typename Pred>
-container_algorithm_internal::ContainerIter<C> c_find_if_not(C& c,
- Pred&& pred) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20
+ container_algorithm_internal::ContainerIter<C>
+ c_find_if_not(C& c, Pred&& pred) {
return std::find_if_not(container_algorithm_internal::c_begin(c),
container_algorithm_internal::c_end(c),
std::forward<Pred>(pred));
@@ -251,8 +261,9 @@ container_algorithm_internal::ContainerIter<C> c_find_if_not(C& c,
// Container-based version of the <algorithm> `std::find_end()` function to
// find the last subsequence within a container.
template <typename Sequence1, typename Sequence2>
-container_algorithm_internal::ContainerIter<Sequence1> c_find_end(
- Sequence1& sequence, Sequence2& subsequence) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20
+ container_algorithm_internal::ContainerIter<Sequence1>
+ c_find_end(Sequence1& sequence, Sequence2& subsequence) {
return std::find_end(container_algorithm_internal::c_begin(sequence),
container_algorithm_internal::c_end(sequence),
container_algorithm_internal::c_begin(subsequence),
@@ -262,8 +273,10 @@ container_algorithm_internal::ContainerIter<Sequence1> c_find_end(
// Overload of c_find_end() for using a predicate evaluation other than `==` as
// the function's test condition.
template <typename Sequence1, typename Sequence2, typename BinaryPredicate>
-container_algorithm_internal::ContainerIter<Sequence1> c_find_end(
- Sequence1& sequence, Sequence2& subsequence, BinaryPredicate&& pred) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20
+ container_algorithm_internal::ContainerIter<Sequence1>
+ c_find_end(Sequence1& sequence, Sequence2& subsequence,
+ BinaryPredicate&& pred) {
return std::find_end(container_algorithm_internal::c_begin(sequence),
container_algorithm_internal::c_end(sequence),
container_algorithm_internal::c_begin(subsequence),
@@ -277,8 +290,9 @@ container_algorithm_internal::ContainerIter<Sequence1> c_find_end(
// find the first element within the container that is also within the options
// container.
template <typename C1, typename C2>
-container_algorithm_internal::ContainerIter<C1> c_find_first_of(C1& container,
- C2& options) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20
+ container_algorithm_internal::ContainerIter<C1>
+ c_find_first_of(C1& container, const C2& options) {
return std::find_first_of(container_algorithm_internal::c_begin(container),
container_algorithm_internal::c_end(container),
container_algorithm_internal::c_begin(options),
@@ -288,8 +302,9 @@ container_algorithm_internal::ContainerIter<C1> c_find_first_of(C1& container,
// Overload of c_find_first_of() for using a predicate evaluation other than
// `==` as the function's test condition.
template <typename C1, typename C2, typename BinaryPredicate>
-container_algorithm_internal::ContainerIter<C1> c_find_first_of(
- C1& container, C2& options, BinaryPredicate&& pred) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20
+ container_algorithm_internal::ContainerIter<C1>
+ c_find_first_of(C1& container, const C2& options, BinaryPredicate&& pred) {
return std::find_first_of(container_algorithm_internal::c_begin(container),
container_algorithm_internal::c_end(container),
container_algorithm_internal::c_begin(options),
@@ -302,8 +317,9 @@ container_algorithm_internal::ContainerIter<C1> c_find_first_of(
// Container-based version of the <algorithm> `std::adjacent_find()` function to
// find equal adjacent elements within a container.
template <typename Sequence>
-container_algorithm_internal::ContainerIter<Sequence> c_adjacent_find(
- Sequence& sequence) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20
+ container_algorithm_internal::ContainerIter<Sequence>
+ c_adjacent_find(Sequence& sequence) {
return std::adjacent_find(container_algorithm_internal::c_begin(sequence),
container_algorithm_internal::c_end(sequence));
}
@@ -311,8 +327,9 @@ container_algorithm_internal::ContainerIter<Sequence> c_adjacent_find(
// Overload of c_adjacent_find() for using a predicate evaluation other than
// `==` as the function's test condition.
template <typename Sequence, typename BinaryPredicate>
-container_algorithm_internal::ContainerIter<Sequence> c_adjacent_find(
- Sequence& sequence, BinaryPredicate&& pred) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20
+ container_algorithm_internal::ContainerIter<Sequence>
+ c_adjacent_find(Sequence& sequence, BinaryPredicate&& pred) {
return std::adjacent_find(container_algorithm_internal::c_begin(sequence),
container_algorithm_internal::c_end(sequence),
std::forward<BinaryPredicate>(pred));
@@ -323,8 +340,9 @@ container_algorithm_internal::ContainerIter<Sequence> c_adjacent_find(
// Container-based version of the <algorithm> `std::count()` function to count
// values that match within a container.
template <typename C, typename T>
-container_algorithm_internal::ContainerDifferenceType<const C> c_count(
- const C& c, T&& value) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20
+ container_algorithm_internal::ContainerDifferenceType<const C>
+ c_count(const C& c, T&& value) {
return std::count(container_algorithm_internal::c_begin(c),
container_algorithm_internal::c_end(c),
std::forward<T>(value));
@@ -335,8 +353,9 @@ container_algorithm_internal::ContainerDifferenceType<const C> c_count(
// Container-based version of the <algorithm> `std::count_if()` function to
// count values matching a condition within a container.
template <typename C, typename Pred>
-container_algorithm_internal::ContainerDifferenceType<const C> c_count_if(
- const C& c, Pred&& pred) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20
+ container_algorithm_internal::ContainerDifferenceType<const C>
+ c_count_if(const C& c, Pred&& pred) {
return std::count_if(container_algorithm_internal::c_begin(c),
container_algorithm_internal::c_end(c),
std::forward<Pred>(pred));
@@ -348,8 +367,9 @@ container_algorithm_internal::ContainerDifferenceType<const C> c_count_if(
// return the first element where two ordered containers differ. Applies `==` to
// the first N elements of `c1` and `c2`, where N = min(size(c1), size(c2)).
template <typename C1, typename C2>
-container_algorithm_internal::ContainerIterPairType<C1, C2> c_mismatch(C1& c1,
- C2& c2) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20
+ container_algorithm_internal::ContainerIterPairType<C1, C2>
+ c_mismatch(C1& c1, C2& c2) {
return std::mismatch(container_algorithm_internal::c_begin(c1),
container_algorithm_internal::c_end(c1),
container_algorithm_internal::c_begin(c2),
@@ -360,8 +380,9 @@ container_algorithm_internal::ContainerIterPairType<C1, C2> c_mismatch(C1& c1,
// the function's test condition. Applies `pred`to the first N elements of `c1`
// and `c2`, where N = min(size(c1), size(c2)).
template <typename C1, typename C2, typename BinaryPredicate>
-container_algorithm_internal::ContainerIterPairType<C1, C2> c_mismatch(
- C1& c1, C2& c2, BinaryPredicate pred) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20
+ container_algorithm_internal::ContainerIterPairType<C1, C2>
+ c_mismatch(C1& c1, C2& c2, BinaryPredicate pred) {
return std::mismatch(container_algorithm_internal::c_begin(c1),
container_algorithm_internal::c_end(c1),
container_algorithm_internal::c_begin(c2),
@@ -373,7 +394,7 @@ container_algorithm_internal::ContainerIterPairType<C1, C2> c_mismatch(
// Container-based version of the <algorithm> `std::equal()` function to
// test whether two containers are equal.
template <typename C1, typename C2>
-bool c_equal(const C1& c1, const C2& c2) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool c_equal(const C1& c1, const C2& c2) {
return std::equal(container_algorithm_internal::c_begin(c1),
container_algorithm_internal::c_end(c1),
container_algorithm_internal::c_begin(c2),
@@ -383,7 +404,8 @@ bool c_equal(const C1& c1, const C2& c2) {
// Overload of c_equal() for using a predicate evaluation other than `==` as
// the function's test condition.
template <typename C1, typename C2, typename BinaryPredicate>
-bool c_equal(const C1& c1, const C2& c2, BinaryPredicate&& pred) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool c_equal(const C1& c1, const C2& c2,
+ BinaryPredicate&& pred) {
return std::equal(container_algorithm_internal::c_begin(c1),
container_algorithm_internal::c_end(c1),
container_algorithm_internal::c_begin(c2),
@@ -396,7 +418,8 @@ bool c_equal(const C1& c1, const C2& c2, BinaryPredicate&& pred) {
// Container-based version of the <algorithm> `std::is_permutation()` function
// to test whether a container is a permutation of another.
template <typename C1, typename C2>
-bool c_is_permutation(const C1& c1, const C2& c2) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool c_is_permutation(const C1& c1,
+ const C2& c2) {
return std::is_permutation(container_algorithm_internal::c_begin(c1),
container_algorithm_internal::c_end(c1),
container_algorithm_internal::c_begin(c2),
@@ -406,7 +429,8 @@ bool c_is_permutation(const C1& c1, const C2& c2) {
// Overload of c_is_permutation() for using a predicate evaluation other than
// `==` as the function's test condition.
template <typename C1, typename C2, typename BinaryPredicate>
-bool c_is_permutation(const C1& c1, const C2& c2, BinaryPredicate&& pred) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool c_is_permutation(
+ const C1& c1, const C2& c2, BinaryPredicate&& pred) {
return std::is_permutation(container_algorithm_internal::c_begin(c1),
container_algorithm_internal::c_end(c1),
container_algorithm_internal::c_begin(c2),
@@ -419,8 +443,9 @@ bool c_is_permutation(const C1& c1, const C2& c2, BinaryPredicate&& pred) {
// Container-based version of the <algorithm> `std::search()` function to search
// a container for a subsequence.
template <typename Sequence1, typename Sequence2>
-container_algorithm_internal::ContainerIter<Sequence1> c_search(
- Sequence1& sequence, Sequence2& subsequence) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20
+ container_algorithm_internal::ContainerIter<Sequence1>
+ c_search(Sequence1& sequence, Sequence2& subsequence) {
return std::search(container_algorithm_internal::c_begin(sequence),
container_algorithm_internal::c_end(sequence),
container_algorithm_internal::c_begin(subsequence),
@@ -430,8 +455,10 @@ container_algorithm_internal::ContainerIter<Sequence1> c_search(
// Overload of c_search() for using a predicate evaluation other than
// `==` as the function's test condition.
template <typename Sequence1, typename Sequence2, typename BinaryPredicate>
-container_algorithm_internal::ContainerIter<Sequence1> c_search(
- Sequence1& sequence, Sequence2& subsequence, BinaryPredicate&& pred) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20
+ container_algorithm_internal::ContainerIter<Sequence1>
+ c_search(Sequence1& sequence, Sequence2& subsequence,
+ BinaryPredicate&& pred) {
return std::search(container_algorithm_internal::c_begin(sequence),
container_algorithm_internal::c_end(sequence),
container_algorithm_internal::c_begin(subsequence),
@@ -444,7 +471,8 @@ container_algorithm_internal::ContainerIter<Sequence1> c_search(
// Container-based version of the <algorithm> `std::ranges::contains_subrange()`
// C++23 function to search a container for a subsequence.
template <typename Sequence1, typename Sequence2>
-bool c_contains_subrange(Sequence1& sequence, Sequence2& subsequence) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool c_contains_subrange(
+ Sequence1& sequence, Sequence2& subsequence) {
return absl::c_search(sequence, subsequence) !=
container_algorithm_internal::c_end(sequence);
}
@@ -452,8 +480,8 @@ bool c_contains_subrange(Sequence1& sequence, Sequence2& subsequence) {
// Overload of c_contains_subrange() for using a predicate evaluation other than
// `==` as the function's test condition.
template <typename Sequence1, typename Sequence2, typename BinaryPredicate>
-bool c_contains_subrange(Sequence1& sequence, Sequence2& subsequence,
- BinaryPredicate&& pred) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool c_contains_subrange(
+ Sequence1& sequence, Sequence2& subsequence, BinaryPredicate&& pred) {
return absl::c_search(sequence, subsequence,
std::forward<BinaryPredicate>(pred)) !=
container_algorithm_internal::c_end(sequence);
@@ -464,8 +492,9 @@ bool c_contains_subrange(Sequence1& sequence, Sequence2& subsequence,
// Container-based version of the <algorithm> `std::search_n()` function to
// search a container for the first sequence of N elements.
template <typename Sequence, typename Size, typename T>
-container_algorithm_internal::ContainerIter<Sequence> c_search_n(
- Sequence& sequence, Size count, T&& value) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20
+ container_algorithm_internal::ContainerIter<Sequence>
+ c_search_n(Sequence& sequence, Size count, T&& value) {
return std::search_n(container_algorithm_internal::c_begin(sequence),
container_algorithm_internal::c_end(sequence), count,
std::forward<T>(value));
@@ -475,8 +504,10 @@ container_algorithm_internal::ContainerIter<Sequence> c_search_n(
// `==` as the function's test condition.
template <typename Sequence, typename Size, typename T,
typename BinaryPredicate>
-container_algorithm_internal::ContainerIter<Sequence> c_search_n(
- Sequence& sequence, Size count, T&& value, BinaryPredicate&& pred) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20
+ container_algorithm_internal::ContainerIter<Sequence>
+ c_search_n(Sequence& sequence, Size count, T&& value,
+ BinaryPredicate&& pred) {
return std::search_n(container_algorithm_internal::c_begin(sequence),
container_algorithm_internal::c_end(sequence), count,
std::forward<T>(value),
diff --git a/contrib/restricted/abseil-cpp/absl/algorithm/ya.make b/contrib/restricted/abseil-cpp/absl/algorithm/ya.make
index 4e3328995c..2deef3b2a7 100644
--- a/contrib/restricted/abseil-cpp/absl/algorithm/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/algorithm/ya.make
@@ -6,9 +6,9 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20240722.1)
+VERSION(20250127.0)
-ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20240722.1.tar.gz)
+ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20250127.0.tar.gz)
NO_RUNTIME()
diff --git a/contrib/restricted/abseil-cpp/absl/base/attributes.h b/contrib/restricted/abseil-cpp/absl/base/attributes.h
index 5ea5ee3ef8..95b102e52b 100644
--- a/contrib/restricted/abseil-cpp/absl/base/attributes.h
+++ b/contrib/restricted/abseil-cpp/absl/base/attributes.h
@@ -31,6 +31,8 @@
// `__has_attribute()` first. If the check fails, we check if we are on GCC and
// assume the attribute exists on GCC (which is verified on GCC 4.7).
+// SKIP_ABSL_INLINE_NAMESPACE_CHECK
+
#ifndef ABSL_BASE_ATTRIBUTES_H_
#define ABSL_BASE_ATTRIBUTES_H_
@@ -133,12 +135,14 @@
// 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
-// for further information.
+// for further information. Weak attributes do not work across DLL boundary.
// 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) || (defined(__clang__) && __clang_major__ >= 9)) && \
+#if (ABSL_HAVE_ATTRIBUTE(weak) || \
+ (defined(__GNUC__) && !defined(__clang__))) && \
+ (!defined(_WIN32) || \
+ (defined(__clang__) && __clang_major__ >= 9 && \
+ !defined(ABSL_BUILD_DLL) && !defined(ABSL_CONSUME_DLL))) && \
!defined(__MINGW32__)
#undef ABSL_ATTRIBUTE_WEAK
#define ABSL_ATTRIBUTE_WEAK __attribute__((weak))
@@ -827,30 +831,76 @@
#define ABSL_ATTRIBUTE_LIFETIME_BOUND
#endif
-// ABSL_INTERNAL_ATTRIBUTE_VIEW indicates that a type acts like a view i.e. a
-// raw (non-owning) pointer. This enables diagnoses similar to those enabled by
-// ABSL_ATTRIBUTE_LIFETIME_BOUND.
+// Internal attribute; name and documentation TBD.
+//
+// See the upstream documentation:
+// https://clang.llvm.org/docs/AttributeReference.html#lifetime_capture_by
+#if ABSL_HAVE_CPP_ATTRIBUTE(clang::lifetime_capture_by)
+#define ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(Owner) \
+ [[clang::lifetime_capture_by(Owner)]]
+#else
+#define ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(Owner)
+#endif
+
+// ABSL_ATTRIBUTE_VIEW indicates that a type is solely a "view" of data that it
+// points to, similarly to a span, string_view, or other non-owning reference
+// type.
+// This enables diagnosing certain lifetime issues similar to those enabled by
+// ABSL_ATTRIBUTE_LIFETIME_BOUND, such as:
+//
+// struct ABSL_ATTRIBUTE_VIEW StringView {
+// template<class R>
+// StringView(const R&);
+// };
+//
+// StringView f(std::string s) {
+// return s; // warning: address of stack memory returned
+// }
+//
+// We disable this on Clang versions < 13 because of the following
+// false-positive:
+//
+// absl::string_view f(absl::optional<absl::string_view> sv) { return *sv; }
//
// See the following links for details:
// https://reviews.llvm.org/D64448
// https://lists.llvm.org/pipermail/cfe-dev/2018-November/060355.html
-#if ABSL_HAVE_CPP_ATTRIBUTE(gsl::Pointer)
-#define ABSL_INTERNAL_ATTRIBUTE_VIEW [[gsl::Pointer]]
+#if ABSL_HAVE_CPP_ATTRIBUTE(gsl::Pointer) && \
+ (!defined(__clang_major__) || __clang_major__ >= 13)
+#define ABSL_ATTRIBUTE_VIEW [[gsl::Pointer]]
#else
-#define ABSL_INTERNAL_ATTRIBUTE_VIEW
+#define ABSL_ATTRIBUTE_VIEW
#endif
-// ABSL_INTERNAL_ATTRIBUTE_OWNER indicates that a type acts like a smart
-// (owning) pointer. This enables diagnoses similar to those enabled by
-// ABSL_ATTRIBUTE_LIFETIME_BOUND.
+// ABSL_ATTRIBUTE_OWNER indicates that a type is a container, smart pointer, or
+// similar class that owns all the data that it points to.
+// This enables diagnosing certain lifetime issues similar to those enabled by
+// ABSL_ATTRIBUTE_LIFETIME_BOUND, such as:
+//
+// struct ABSL_ATTRIBUTE_VIEW StringView {
+// template<class R>
+// StringView(const R&);
+// };
+//
+// struct ABSL_ATTRIBUTE_OWNER String {};
+//
+// StringView f(String s) {
+// return s; // warning: address of stack memory returned
+// }
+//
+// We disable this on Clang versions < 13 because of the following
+// false-positive:
+//
+// absl::string_view f(absl::optional<absl::string_view> sv) { return *sv; }
//
// See the following links for details:
// https://reviews.llvm.org/D64448
// https://lists.llvm.org/pipermail/cfe-dev/2018-November/060355.html
-#if ABSL_HAVE_CPP_ATTRIBUTE(gsl::Owner)
-#define ABSL_INTERNAL_ATTRIBUTE_OWNER [[gsl::Owner]]
+#if ABSL_HAVE_CPP_ATTRIBUTE(gsl::Owner) && \
+ (!defined(__clang_major__) || __clang_major__ >= 13)
+#define ABSL_ATTRIBUTE_OWNER [[gsl::Owner]]
#else
-#define ABSL_INTERNAL_ATTRIBUTE_OWNER
+#define ABSL_ATTRIBUTE_OWNER
#endif
// ABSL_ATTRIBUTE_TRIVIAL_ABI
diff --git a/contrib/restricted/abseil-cpp/absl/base/call_once.h b/contrib/restricted/abseil-cpp/absl/base/call_once.h
index 7b0e69ccd5..b666d36f0e 100644
--- a/contrib/restricted/abseil-cpp/absl/base/call_once.h
+++ b/contrib/restricted/abseil-cpp/absl/base/call_once.h
@@ -31,6 +31,8 @@
#include <type_traits>
#include <utility>
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/internal/invoke.h"
#include "absl/base/internal/low_level_scheduling.h"
#include "absl/base/internal/raw_logging.h"
@@ -147,10 +149,10 @@ enum {
};
template <typename Callable, typename... Args>
-ABSL_ATTRIBUTE_NOINLINE void CallOnceImpl(
- absl::Nonnull<std::atomic<uint32_t>*> control,
- base_internal::SchedulingMode scheduling_mode, Callable&& fn,
- Args&&... args) {
+ void
+ CallOnceImpl(absl::Nonnull<std::atomic<uint32_t>*> control,
+ base_internal::SchedulingMode scheduling_mode, Callable&& fn,
+ Args&&... args) {
#ifndef NDEBUG
{
uint32_t old_control = control->load(std::memory_order_relaxed);
@@ -209,7 +211,8 @@ void LowLevelCallOnce(absl::Nonnull<absl::once_flag*> flag, Callable&& fn,
} // namespace base_internal
template <typename Callable, typename... Args>
-void call_once(absl::once_flag& flag, Callable&& fn, Args&&... args) {
+ void
+ call_once(absl::once_flag& flag, Callable&& fn, Args&&... args) {
std::atomic<uint32_t>* once = base_internal::ControlWord(&flag);
uint32_t s = once->load(std::memory_order_acquire);
if (ABSL_PREDICT_FALSE(s != base_internal::kOnceDone)) {
diff --git a/contrib/restricted/abseil-cpp/absl/base/config.h b/contrib/restricted/abseil-cpp/absl/base/config.h
index 46e6fbcb9b..0b24865153 100644
--- a/contrib/restricted/abseil-cpp/absl/base/config.h
+++ b/contrib/restricted/abseil-cpp/absl/base/config.h
@@ -117,8 +117,8 @@
//
// LTS releases can be obtained from
// https://github.com/abseil/abseil-cpp/releases.
-#define ABSL_LTS_RELEASE_VERSION 20240722
-#define ABSL_LTS_RELEASE_PATCH_LEVEL 1
+#define ABSL_LTS_RELEASE_VERSION 20250127
+#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
@@ -380,7 +380,7 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
defined(__asmjs__) || defined(__EMSCRIPTEN__) || defined(__Fuchsia__) || \
defined(__sun) || defined(__myriad2__) || defined(__HAIKU__) || \
defined(__OpenBSD__) || defined(__NetBSD__) || defined(__QNX__) || \
- defined(__VXWORKS__) || defined(__hexagon__)
+ defined(__VXWORKS__) || defined(__hexagon__) || defined(__XTENSA__)
#define ABSL_HAVE_MMAP 1
#endif
@@ -926,7 +926,7 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
// https://llvm.org/docs/CompileCudaWithLLVM.html#detecting-clang-vs-nvcc-from-code
#ifdef ABSL_INTERNAL_HAVE_ARM_NEON
#error ABSL_INTERNAL_HAVE_ARM_NEON cannot be directly set
-#elif defined(__ARM_NEON) && !defined(__CUDA_ARCH__)
+#elif defined(__ARM_NEON) && !(defined(__NVCC__) && defined(__CUDACC__))
#define ABSL_INTERNAL_HAVE_ARM_NEON 1
#endif
diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/nullability_impl.h b/contrib/restricted/abseil-cpp/absl/base/internal/nullability_impl.h
index 03fa2434ce..b601fc4ce9 100644
--- a/contrib/restricted/abseil-cpp/absl/base/internal/nullability_impl.h
+++ b/contrib/restricted/abseil-cpp/absl/base/internal/nullability_impl.h
@@ -26,80 +26,41 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
namespace nullability_internal {
-// `IsNullabilityCompatible` checks whether its first argument is a class
-// explicitly tagged as supporting nullability annotations. The tag is the type
-// declaration `absl_nullability_compatible`.
-template <typename, typename = void>
-struct IsNullabilityCompatible : std::false_type {};
-
-template <typename T>
-struct IsNullabilityCompatible<
- T, absl::void_t<typename T::absl_nullability_compatible>> : std::true_type {
-};
-
-template <typename T>
-constexpr bool IsSupportedType = IsNullabilityCompatible<T>::value;
-
-template <typename T>
-constexpr bool IsSupportedType<T*> = true;
-
-template <typename T, typename U>
-constexpr bool IsSupportedType<T U::*> = true;
-
-template <typename T, typename... Deleter>
-constexpr bool IsSupportedType<std::unique_ptr<T, Deleter...>> = true;
-
-template <typename T>
-constexpr bool IsSupportedType<std::shared_ptr<T>> = true;
-
template <typename T>
-struct EnableNullable {
- static_assert(nullability_internal::IsSupportedType<std::remove_cv_t<T>>,
- "Template argument must be a raw or supported smart pointer "
- "type. See absl/base/nullability.h.");
- using type = T;
-};
-
-template <typename T>
-struct EnableNonnull {
- static_assert(nullability_internal::IsSupportedType<std::remove_cv_t<T>>,
- "Template argument must be a raw or supported smart pointer "
- "type. See absl/base/nullability.h.");
- using type = T;
-};
-
-template <typename T>
-struct EnableNullabilityUnknown {
- static_assert(nullability_internal::IsSupportedType<std::remove_cv_t<T>>,
- "Template argument must be a raw or supported smart pointer "
- "type. See absl/base/nullability.h.");
- using type = T;
-};
-
-// Note: we do not apply Clang nullability attributes (e.g. _Nullable). These
-// only support raw pointers, and conditionally enabling them only for raw
-// pointers inhibits template arg deduction. Ideally, they would support all
-// pointer-like types.
-template <typename T, typename = typename EnableNullable<T>::type>
using NullableImpl
#if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate)
[[clang::annotate("Nullable")]]
#endif
+// Don't add the _Nullable attribute in Objective-C compiles. Many Objective-C
+// projects enable the `-Wnullable-to-nonnull-conversion warning`, which is
+// liable to produce false positives.
+#if ABSL_HAVE_FEATURE(nullability_on_classes) && !defined(__OBJC__)
+ = T _Nullable;
+#else
= T;
+#endif
-template <typename T, typename = typename EnableNonnull<T>::type>
+template <typename T>
using NonnullImpl
#if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate)
[[clang::annotate("Nonnull")]]
#endif
+#if ABSL_HAVE_FEATURE(nullability_on_classes) && !defined(__OBJC__)
+ = T _Nonnull;
+#else
= T;
+#endif
-template <typename T, typename = typename EnableNullabilityUnknown<T>::type>
+template <typename T>
using NullabilityUnknownImpl
#if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate)
[[clang::annotate("Nullability_Unspecified")]]
#endif
+#if ABSL_HAVE_FEATURE(nullability_on_classes) && !defined(__OBJC__)
+ = T _Null_unspecified;
+#else
= T;
+#endif
} // namespace nullability_internal
ABSL_NAMESPACE_END
diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging.cc b/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging.cc
index d32b40a8bb..35a08f0ac0 100644
--- a/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging.cc
+++ b/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging.cc
@@ -175,7 +175,7 @@ void RawLogVA(absl::LogSeverity severity, const char* file, int line,
} else {
DoRawLog(&buf, &size, "%s", kTruncated);
}
- AsyncSignalSafeWriteError(buffer, strlen(buffer));
+ AsyncSignalSafeWriteError(buffer, static_cast<size_t>(buf - buffer));
}
#else
static_cast<void>(format);
diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/sysinfo.cc b/contrib/restricted/abseil-cpp/absl/base/internal/sysinfo.cc
index b86667cb08..62880330ac 100644
--- a/contrib/restricted/abseil-cpp/absl/base/internal/sysinfo.cc
+++ b/contrib/restricted/abseil-cpp/absl/base/internal/sysinfo.cc
@@ -46,6 +46,10 @@
#error #include <rtems.h>
#endif
+#if defined(__Fuchsia__)
+#include <zircon/process.h>
+#endif
+
#include <string.h>
#include <cassert>
@@ -461,6 +465,16 @@ pid_t GetTID() {
return reinterpret_cast<pid_t>(thread);
}
+#elif defined(__Fuchsia__)
+
+pid_t GetTID() {
+ // Use our thread handle as the TID, which should be unique within this
+ // process (but may not be globally unique). The handle value was chosen over
+ // a kernel object ID (KOID) because zx_handle_t (32-bits) can be cast to a
+ // pid_t type without loss of precision, but a zx_koid_t (64-bits) cannot.
+ return static_cast<pid_t>(zx_thread_self());
+}
+
#else
// Fallback implementation of `GetTID` using `pthread_self`.
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 b6e917ce80..acfc15a8f6 100644
--- a/contrib/restricted/abseil-cpp/absl/base/internal/thread_identity.h
+++ b/contrib/restricted/abseil-cpp/absl/base/internal/thread_identity.h
@@ -130,7 +130,11 @@ struct PerThreadSynch {
};
// The instances of this class are allocated in NewThreadIdentity() with an
-// alignment of PerThreadSynch::kAlignment.
+// alignment of PerThreadSynch::kAlignment and never destroyed. Initialization
+// should happen in OneTimeInitThreadIdentity().
+//
+// Instances may be reused by new threads - fields should be reset in
+// ResetThreadIdentityBetweenReuse().
//
// NOTE: The layout of fields in this structure is critical, please do not
// add, remove, or modify the field placements without fully auditing the
diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/tracing.cc b/contrib/restricted/abseil-cpp/absl/base/internal/tracing.cc
new file mode 100644
index 0000000000..d304e6a29a
--- /dev/null
+++ b/contrib/restricted/abseil-cpp/absl/base/internal/tracing.cc
@@ -0,0 +1,39 @@
+// Copyright 2024 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/internal/tracing.h"
+
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace base_internal {
+
+extern "C" {
+
+ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalTraceWait)(
+ const void*, ObjectKind) {}
+ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalTraceContinue)(
+ const void*, ObjectKind) {}
+ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalTraceSignal)(
+ const void*, ObjectKind) {}
+ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalTraceObserved)(
+ const void*, ObjectKind) {}
+
+} // extern "C"
+
+} // namespace base_internal
+ABSL_NAMESPACE_END
+} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/tracing.h b/contrib/restricted/abseil-cpp/absl/base/internal/tracing.h
new file mode 100644
index 0000000000..e7ab7758fe
--- /dev/null
+++ b/contrib/restricted/abseil-cpp/absl/base/internal/tracing.h
@@ -0,0 +1,81 @@
+// Copyright 2024 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_BASE_INTERNAL_TRACING_H_
+#define ABSL_BASE_INTERNAL_TRACING_H_
+
+#include "absl/base/config.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace base_internal {
+
+// Well known Abseil object types that have causality.
+enum class ObjectKind { kUnknown, kBlockingCounter, kNotification };
+
+// `TraceWait` and `TraceContinue` record the start and end of a potentially
+// blocking wait operation on `object`. `object` typically represents a higher
+// level synchronization object such as `absl::Notification`.
+void TraceWait(const void* object, ObjectKind kind);
+void TraceContinue(const void* object, ObjectKind kind);
+
+// `TraceSignal` records a signal on `object`.
+void TraceSignal(const void* object, ObjectKind kind);
+
+// `TraceObserved` records the non-blocking observation of a signaled object.
+void TraceObserved(const void* object, ObjectKind kind);
+
+// ---------------------------------------------------------------------------
+// Weak implementation detail:
+//
+// We define the weak API as extern "C": in some build configurations we pass
+// `--detect-odr-violations` to the gold linker. This causes it to flag weak
+// symbol overrides as ODR violations. Because ODR only applies to C++ and not
+// C, `--detect-odr-violations` ignores symbols not mangled with C++ names.
+// By changing our extension points to be extern "C", we dodge this check.
+// ---------------------------------------------------------------------------
+extern "C" {
+
+ void ABSL_INTERNAL_C_SYMBOL(AbslInternalTraceWait)(const void* object,
+ ObjectKind kind);
+ void ABSL_INTERNAL_C_SYMBOL(AbslInternalTraceContinue)(const void* object,
+ ObjectKind kind);
+ void ABSL_INTERNAL_C_SYMBOL(AbslInternalTraceSignal)(const void* object,
+ ObjectKind kind);
+ void ABSL_INTERNAL_C_SYMBOL(AbslInternalTraceObserved)(const void* object,
+ ObjectKind kind);
+
+} // extern "C"
+
+inline void TraceWait(const void* object, ObjectKind kind) {
+ ABSL_INTERNAL_C_SYMBOL(AbslInternalTraceWait)(object, kind);
+}
+
+inline void TraceContinue(const void* object, ObjectKind kind) {
+ ABSL_INTERNAL_C_SYMBOL(AbslInternalTraceContinue)(object, kind);
+}
+
+inline void TraceSignal(const void* object, ObjectKind kind) {
+ ABSL_INTERNAL_C_SYMBOL(AbslInternalTraceSignal)(object, kind);
+}
+
+inline void TraceObserved(const void* object, ObjectKind kind) {
+ ABSL_INTERNAL_C_SYMBOL(AbslInternalTraceObserved)(object, kind);
+}
+
+} // namespace base_internal
+ABSL_NAMESPACE_END
+} // namespace absl
+
+#endif // ABSL_BASE_INTERNAL_TRACING_H_
diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.cc b/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.cc
index a0bf3a65f7..68f92730a8 100644
--- a/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.cc
+++ b/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.cc
@@ -105,16 +105,6 @@ double UnscaledCycleClock::Frequency() {
#elif defined(__aarch64__)
-// System timer of ARMv8 runs at a different frequency than the CPU's.
-// The frequency is fixed, typically in the range 1-50MHz. It can be
-// read at CNTFRQ special register. We assume the OS has set up
-// the virtual timer properly.
-int64_t UnscaledCycleClock::Now() {
- int64_t virtual_timer_value;
- asm volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value));
- return virtual_timer_value;
-}
-
double UnscaledCycleClock::Frequency() {
uint64_t aarch64_timer_frequency;
asm volatile("mrs %0, cntfrq_el0" : "=r"(aarch64_timer_frequency));
diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.h b/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.h
index cc1276ba08..965c42de4e 100644
--- a/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.h
+++ b/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.h
@@ -85,6 +85,18 @@ inline int64_t UnscaledCycleClock::Now() {
return static_cast<int64_t>((high << 32) | low);
}
+#elif defined(__aarch64__)
+
+// System timer of ARMv8 runs at a different frequency than the CPU's.
+// The frequency is fixed, typically in the range 1-50MHz. It can be
+// read at CNTFRQ special register. We assume the OS has set up
+// the virtual timer properly.
+inline int64_t UnscaledCycleClock::Now() {
+ int64_t virtual_timer_value;
+ asm volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value));
+ return virtual_timer_value;
+}
+
#endif
} // namespace base_internal
diff --git a/contrib/restricted/abseil-cpp/absl/base/macros.h b/contrib/restricted/abseil-cpp/absl/base/macros.h
index b318f11664..ff89944ae4 100644
--- a/contrib/restricted/abseil-cpp/absl/base/macros.h
+++ b/contrib/restricted/abseil-cpp/absl/base/macros.h
@@ -34,6 +34,7 @@
#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/optimization.h"
+#include "absl/base/options.h"
#include "absl/base/port.h"
// ABSL_ARRAYSIZE()
@@ -81,8 +82,9 @@ ABSL_NAMESPACE_END
// ABSL_ASSERT()
//
// In C++11, `assert` can't be used portably within constexpr functions.
+// `assert` also generates spurious unused-symbol warnings.
// ABSL_ASSERT functions as a runtime assert but works in C++11 constexpr
-// functions. Example:
+// functions, and maintains references to symbols. Example:
//
// constexpr double Divide(double a, double b) {
// return ABSL_ASSERT(b != 0), a / b;
@@ -91,8 +93,18 @@ ABSL_NAMESPACE_END
// This macro is inspired by
// https://akrzemi1.wordpress.com/2017/05/18/asserts-in-constexpr-functions/
#if defined(NDEBUG)
-#define ABSL_ASSERT(expr) \
- (false ? static_cast<void>(expr) : static_cast<void>(0))
+#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+// We use `decltype` here to avoid generating unnecessary code that the
+// optimizer then has to optimize away.
+// This not only improves compilation performance by reducing codegen bloat
+// and optimization work, but also guarantees fast run-time performance without
+// having to rely on the optimizer.
+#define ABSL_ASSERT(expr) (decltype((expr) ? void() : void())())
+#else
+// Pre-C++20, lambdas can't be inside unevaluated operands, so we're forced to
+// rely on the optimizer.
+#define ABSL_ASSERT(expr) (false ? ((expr) ? void() : void()) : void())
+#endif
#else
#define ABSL_ASSERT(expr) \
(ABSL_PREDICT_TRUE((expr)) ? static_cast<void>(0) \
@@ -120,7 +132,7 @@ ABSL_NAMESPACE_END
//
// See `ABSL_OPTION_HARDENED` in `absl/base/options.h` for more information on
// hardened mode.
-#if ABSL_OPTION_HARDENED == 1 && defined(NDEBUG)
+#if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
#define ABSL_HARDENING_ASSERT(expr) \
(ABSL_PREDICT_TRUE((expr)) ? static_cast<void>(0) \
: [] { ABSL_INTERNAL_HARDENING_ABORT(); }())
@@ -128,6 +140,25 @@ ABSL_NAMESPACE_END
#define ABSL_HARDENING_ASSERT(expr) ABSL_ASSERT(expr)
#endif
+// ABSL_HARDENING_ASSERT_SLOW()
+//
+// `ABSL_HARDENING_ASSERT()` is like `ABSL_HARDENING_ASSERT()`,
+// but specifically for assertions whose predicates are too slow
+// to be enabled in many applications.
+//
+// When `NDEBUG` is not defined, `ABSL_HARDENING_ASSERT_SLOW()` is identical to
+// `ABSL_ASSERT()`.
+//
+// See `ABSL_OPTION_HARDENED` in `absl/base/options.h` for more information on
+// hardened mode.
+#if ABSL_OPTION_HARDENED == 1 && defined(NDEBUG)
+#define ABSL_HARDENING_ASSERT_SLOW(expr) \
+ (ABSL_PREDICT_TRUE((expr)) ? static_cast<void>(0) \
+ : [] { ABSL_INTERNAL_HARDENING_ABORT(); }())
+#else
+#define ABSL_HARDENING_ASSERT_SLOW(expr) ABSL_ASSERT(expr)
+#endif
+
#ifdef ABSL_HAVE_EXCEPTIONS
#define ABSL_INTERNAL_TRY try
#define ABSL_INTERNAL_CATCH_ANY catch (...)
diff --git a/contrib/restricted/abseil-cpp/absl/base/nullability.h b/contrib/restricted/abseil-cpp/absl/base/nullability.h
index 34dc083a4e..241c65ac25 100644
--- a/contrib/restricted/abseil-cpp/absl/base/nullability.h
+++ b/contrib/restricted/abseil-cpp/absl/base/nullability.h
@@ -135,17 +135,9 @@
// ...
// };
//
-// Note: For the time being, nullability-compatible classes should additionally
-// be marked with an `absl_nullability_compatible` nested type (this will soon
-// be deprecated). The actual definition of this inner type is not relevant as
-// it is used merely as a marker. It is common to use a using declaration of
-// `absl_nullability_compatible` set to void.
-//
-// // Example:
-// struct MyPtr {
-// using absl_nullability_compatible = void;
-// ...
-// };
+// Note: Compilers that don't support the `nullability_on_classes` feature will
+// allow nullability annotations to be applied to any type, not just ones
+// marked with `ABSL_NULLABILITY_COMPATIBLE`.
//
// DISCLAIMER:
// ===========================================================================
@@ -161,10 +153,47 @@
#include "absl/base/config.h"
#include "absl/base/internal/nullability_impl.h"
+// ABSL_POINTERS_DEFAULT_NONNULL
+//
+// This macro specifies that all unannotated pointer types within the given
+// file are designated as nonnull (instead of the default "unknown"). This macro
+// exists as a standalone statement and applies default nonnull behavior to all
+// subsequent pointers; as a result, place this macro as the first non-comment,
+// non-`#include` line in a file.
+//
+// Example:
+//
+// #include "absl/base/nullability.h"
+//
+// ABSL_POINTERS_DEFAULT_NONNULL
+//
+// void FillMessage(Message *m); // implicitly non-null
+// absl::Nullable<T*> GetNullablePtr(); // explicitly nullable
+// absl::NullabilityUnknown<T*> GetUnknownPtr(); // explicitly unknown
+//
+// The macro can be safely used in header files -- it will not affect any files
+// that include it.
+//
+// In files with the macro, plain `T*` syntax means `absl::Nonnull<T*>`, and the
+// exceptions (`Nullable` and `NullabilityUnknown`) must be marked
+// explicitly. The same holds, correspondingly, for smart pointer types.
+//
+// For comparison, without the macro, all unannotated pointers would default to
+// unknown, and otherwise require explicit annotations to change this behavior:
+//
+// #include "absl/base/nullability.h"
+//
+// void FillMessage(absl::Nonnull<Message*> m); // explicitly non-null
+// absl::Nullable<T*> GetNullablePtr(); // explicitly nullable
+// T* GetUnknownPtr(); // implicitly unknown
+//
+// No-op except for being a human readable signal.
+#define ABSL_POINTERS_DEFAULT_NONNULL
+
namespace absl {
ABSL_NAMESPACE_BEGIN
-// absl::Nonnull
+// absl::Nonnull (default with `ABSL_POINTERS_DEFAULT_NONNULL`)
//
// The indicated pointer is never null. It is the responsibility of the provider
// of this pointer across an API boundary to ensure that the pointer is never
@@ -197,7 +226,7 @@ using Nonnull = nullability_internal::NonnullImpl<T>;
template <typename T>
using Nullable = nullability_internal::NullableImpl<T>;
-// absl::NullabilityUnknown (default)
+// absl::NullabilityUnknown (default without `ABSL_POINTERS_DEFAULT_NONNULL`)
//
// The indicated pointer has not yet been determined to be definitively
// "non-null" or "nullable." Providers of such pointers across API boundaries
@@ -208,9 +237,10 @@ using Nullable = nullability_internal::NullableImpl<T>;
// migrated into one of the above two nullability states: `Nonnull<T>` or
// `Nullable<T>`.
//
-// NOTE: Because this annotation is the global default state, unannotated
-// pointers are assumed to have "unknown" semantics. This assumption is designed
-// to minimize churn and reduce clutter within the codebase.
+// NOTE: For files that do not specify `ABSL_POINTERS_DEFAULT_NONNULL`,
+// because this annotation is the global default state, unannotated pointers are
+// are assumed to have "unknown" semantics. This assumption is designed to
+// minimize churn and reduce clutter within the codebase.
//
// Example:
//
@@ -241,10 +271,36 @@ ABSL_NAMESPACE_END
// struct ABSL_NULLABILITY_COMPATIBLE MyPtr {
// ...
// };
+//
+// Note: Compilers that don't support the `nullability_on_classes` feature will
+// allow nullability annotations to be applied to any type, not just ones marked
+// with `ABSL_NULLABILITY_COMPATIBLE`.
#if ABSL_HAVE_FEATURE(nullability_on_classes)
#define ABSL_NULLABILITY_COMPATIBLE _Nullable
#else
#define ABSL_NULLABILITY_COMPATIBLE
#endif
+// ABSL_NONNULL
+// ABSL_NULLABLE
+// ABSL_NULLABILITY_UNKNOWN
+//
+// These macros are analogues of the alias template nullability annotations
+// above.
+//
+// Example:
+// int* ABSL_NULLABLE foo;
+// Is equivalent to:
+// absl::Nullable<int*> foo;
+#if defined(__clang__) && !defined(__OBJC__) && \
+ ABSL_HAVE_FEATURE(nullability_on_classes)
+#define ABSL_NONNULL _Nonnull
+#define ABSL_NULLABLE _Nullable
+#define ABSL_NULLABILITY_UNKNOWN _Null_unspecified
+#else
+#define ABSL_NONNULL
+#define ABSL_NULLABLE
+#define ABSL_NULLABILITY_UNKNOWN
+#endif
+
#endif // ABSL_BASE_NULLABILITY_H_
diff --git a/contrib/restricted/abseil-cpp/absl/base/optimization.h b/contrib/restricted/abseil-cpp/absl/base/optimization.h
index 3aa66e1c7d..429ea9ce79 100644
--- a/contrib/restricted/abseil-cpp/absl/base/optimization.h
+++ b/contrib/restricted/abseil-cpp/absl/base/optimization.h
@@ -25,6 +25,8 @@
// new code that requires C compatibility or assume C compatibility will remain
// indefinitely.
+// SKIP_ABSL_INLINE_NAMESPACE_CHECK
+
#ifndef ABSL_BASE_OPTIMIZATION_H_
#define ABSL_BASE_OPTIMIZATION_H_
@@ -271,20 +273,14 @@
#elif defined(_MSC_VER)
#define ABSL_ASSUME(cond) __assume(cond)
#elif defined(__cpp_lib_unreachable) && __cpp_lib_unreachable >= 202202L
-#define ABSL_ASSUME(cond) \
- do { \
- if (!(cond)) std::unreachable(); \
- } while (false)
+#define ABSL_ASSUME(cond) ((cond) ? void() : std::unreachable())
#elif defined(__GNUC__) || ABSL_HAVE_BUILTIN(__builtin_unreachable)
-#define ABSL_ASSUME(cond) \
- do { \
- if (!(cond)) __builtin_unreachable(); \
- } while (false)
+#define ABSL_ASSUME(cond) ((cond) ? void() : __builtin_unreachable())
+#elif ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+// Unimplemented. Uses the same definition as ABSL_ASSERT in the NDEBUG case.
+#define ABSL_ASSUME(expr) (decltype((expr) ? void() : void())())
#else
-#define ABSL_ASSUME(cond) \
- do { \
- static_cast<void>(false && (cond)); \
- } while (false)
+#define ABSL_ASSUME(expr) (false ? ((expr) ? void() : void()) : void())
#endif
// ABSL_INTERNAL_UNIQUE_SMALL_NAME(cond)
diff --git a/contrib/restricted/abseil-cpp/absl/base/options.h b/contrib/restricted/abseil-cpp/absl/base/options.h
index 61a996b6c8..5caa58f6e3 100644
--- a/contrib/restricted/abseil-cpp/absl/base/options.h
+++ b/contrib/restricted/abseil-cpp/absl/base/options.h
@@ -226,7 +226,7 @@
// allowed.
#define ABSL_OPTION_USE_INLINE_NAMESPACE 1
-#define ABSL_OPTION_INLINE_NAMESPACE_NAME lts_20240722
+#define ABSL_OPTION_INLINE_NAMESPACE_NAME lts_20250127
// ABSL_OPTION_HARDENED
//
@@ -235,7 +235,10 @@
//
// A value of 0 means that "hardened" mode is not enabled.
//
-// A value of 1 means that "hardened" mode is enabled.
+// A value of 1 means that "hardened" mode is enabled with all checks.
+//
+// A value of 2 means that "hardened" mode is partially enabled, with
+// only a subset of checks chosen to minimize performance impact.
//
// Hardened builds have additional security checks enabled when `NDEBUG` is
// defined. Defining `NDEBUG` is normally used to turn `assert()` macro into a
diff --git a/contrib/restricted/abseil-cpp/absl/base/policy_checks.h b/contrib/restricted/abseil-cpp/absl/base/policy_checks.h
index 372e848d8c..7538166bed 100644
--- a/contrib/restricted/abseil-cpp/absl/base/policy_checks.h
+++ b/contrib/restricted/abseil-cpp/absl/base/policy_checks.h
@@ -21,6 +21,8 @@
// reported with `#error`. This enforcement is best effort, so successfully
// compiling this header does not guarantee a supported configuration.
+// SKIP_ABSL_INLINE_NAMESPACE_CHECK
+
#ifndef ABSL_BASE_POLICY_CHECKS_H_
#define ABSL_BASE_POLICY_CHECKS_H_
diff --git a/contrib/restricted/abseil-cpp/absl/base/ya.make b/contrib/restricted/abseil-cpp/absl/base/ya.make
index c887180740..f31517630e 100644
--- a/contrib/restricted/abseil-cpp/absl/base/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/base/ya.make
@@ -6,7 +6,7 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20240722.1)
+VERSION(20250127.0)
PEERDIR(
library/cpp/sanitizer/include
@@ -32,6 +32,7 @@ SRCS(
internal/sysinfo.cc
internal/thread_identity.cc
internal/throw_delegate.cc
+ internal/tracing.cc
internal/unscaledcycleclock.cc
log_severity.cc
)
diff --git a/contrib/restricted/abseil-cpp/absl/container/btree_map.h b/contrib/restricted/abseil-cpp/absl/container/btree_map.h
index b959b674ee..470de2a199 100644
--- a/contrib/restricted/abseil-cpp/absl/container/btree_map.h
+++ b/contrib/restricted/abseil-cpp/absl/container/btree_map.h
@@ -87,7 +87,7 @@ struct map_params;
//
template <typename Key, typename Value, typename Compare = std::less<Key>,
typename Alloc = std::allocator<std::pair<const Key, Value>>>
-class ABSL_INTERNAL_ATTRIBUTE_OWNER btree_map
+class ABSL_ATTRIBUTE_OWNER btree_map
: public container_internal::btree_map_container<
container_internal::btree<container_internal::map_params<
Key, Value, Compare, Alloc, /*TargetNodeSize=*/256,
@@ -525,7 +525,7 @@ typename btree_map<K, V, C, A>::size_type erase_if(
//
template <typename Key, typename Value, typename Compare = std::less<Key>,
typename Alloc = std::allocator<std::pair<const Key, Value>>>
-class ABSL_INTERNAL_ATTRIBUTE_OWNER btree_multimap
+class ABSL_ATTRIBUTE_OWNER btree_multimap
: public container_internal::btree_multimap_container<
container_internal::btree<container_internal::map_params<
Key, Value, Compare, Alloc, /*TargetNodeSize=*/256,
diff --git a/contrib/restricted/abseil-cpp/absl/container/btree_set.h b/contrib/restricted/abseil-cpp/absl/container/btree_set.h
index 986d27da6f..e57d6d9b68 100644
--- a/contrib/restricted/abseil-cpp/absl/container/btree_set.h
+++ b/contrib/restricted/abseil-cpp/absl/container/btree_set.h
@@ -89,7 +89,7 @@ struct set_params;
//
template <typename Key, typename Compare = std::less<Key>,
typename Alloc = std::allocator<Key>>
-class ABSL_INTERNAL_ATTRIBUTE_OWNER btree_set
+class ABSL_ATTRIBUTE_OWNER btree_set
: public container_internal::btree_set_container<
container_internal::btree<container_internal::set_params<
Key, Compare, Alloc, /*TargetNodeSize=*/256,
@@ -445,7 +445,7 @@ typename btree_set<K, C, A>::size_type erase_if(btree_set<K, C, A> &set,
//
template <typename Key, typename Compare = std::less<Key>,
typename Alloc = std::allocator<Key>>
-class ABSL_INTERNAL_ATTRIBUTE_OWNER btree_multiset
+class ABSL_ATTRIBUTE_OWNER btree_multiset
: public container_internal::btree_multiset_container<
container_internal::btree<container_internal::set_params<
Key, Compare, Alloc, /*TargetNodeSize=*/256,
diff --git a/contrib/restricted/abseil-cpp/absl/container/fixed_array.h b/contrib/restricted/abseil-cpp/absl/container/fixed_array.h
index 9f1c813dca..95abb0a59d 100644
--- a/contrib/restricted/abseil-cpp/absl/container/fixed_array.h
+++ b/contrib/restricted/abseil-cpp/absl/container/fixed_array.h
@@ -41,6 +41,7 @@
#include <type_traits>
#include "absl/algorithm/algorithm.h"
+#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/dynamic_annotations.h"
#include "absl/base/internal/throw_delegate.h"
@@ -74,7 +75,7 @@ constexpr static auto kFixedArrayUseDefault = static_cast<size_t>(-1);
// `std::vector`.
template <typename T, size_t N = kFixedArrayUseDefault,
typename A = std::allocator<T>>
-class FixedArray {
+class ABSL_ATTRIBUTE_WARN_UNUSED FixedArray {
static_assert(!std::is_array<T>::value || std::extent<T>::value > 0,
"Arrays with unknown bounds cannot be used with FixedArray.");
diff --git a/contrib/restricted/abseil-cpp/absl/container/flat_hash_map.h b/contrib/restricted/abseil-cpp/absl/container/flat_hash_map.h
index ebd9ed6756..735ee3424d 100644
--- a/contrib/restricted/abseil-cpp/absl/container/flat_hash_map.h
+++ b/contrib/restricted/abseil-cpp/absl/container/flat_hash_map.h
@@ -125,7 +125,7 @@ struct FlatHashMapPolicy;
template <class K, class V, class Hash = DefaultHashContainerHash<K>,
class Eq = DefaultHashContainerEq<K>,
class Allocator = std::allocator<std::pair<const K, V>>>
-class ABSL_INTERNAL_ATTRIBUTE_OWNER flat_hash_map
+class ABSL_ATTRIBUTE_OWNER flat_hash_map
: public absl::container_internal::raw_hash_map<
absl::container_internal::FlatHashMapPolicy<K, V>, Hash, Eq,
Allocator> {
@@ -426,8 +426,7 @@ class ABSL_INTERNAL_ATTRIBUTE_OWNER flat_hash_map
// flat_hash_map::swap(flat_hash_map& other)
//
// Exchanges the contents of this `flat_hash_map` with those of the `other`
- // flat hash map, avoiding invocation of any move, copy, or swap operations on
- // individual elements.
+ // flat hash map.
//
// All iterators and references on the `flat_hash_map` remain valid, excepting
// for the past-the-end iterator, which is invalidated.
@@ -574,6 +573,21 @@ typename flat_hash_map<K, V, H, E, A>::size_type erase_if(
return container_internal::EraseIf(pred, &c);
}
+// swap(flat_hash_map<>, flat_hash_map<>)
+//
+// Swaps the contents of two `flat_hash_map` containers.
+//
+// NOTE: we need to define this function template in order for
+// `flat_hash_set::swap` to be called instead of `std::swap`. Even though we
+// have `swap(raw_hash_set&, raw_hash_set&)` defined, that function requires a
+// derived-to-base conversion, whereas `std::swap` is a function template so
+// `std::swap` will be preferred by compiler.
+template <typename K, typename V, typename H, typename E, typename A>
+void swap(flat_hash_map<K, V, H, E, A>& x,
+ flat_hash_map<K, V, H, E, A>& y) noexcept(noexcept(x.swap(y))) {
+ x.swap(y);
+}
+
namespace container_internal {
// c_for_each_fast(flat_hash_map<>, Function)
diff --git a/contrib/restricted/abseil-cpp/absl/container/flat_hash_set.h b/contrib/restricted/abseil-cpp/absl/container/flat_hash_set.h
index a3e36e05e3..b5d0f7f955 100644
--- a/contrib/restricted/abseil-cpp/absl/container/flat_hash_set.h
+++ b/contrib/restricted/abseil-cpp/absl/container/flat_hash_set.h
@@ -122,7 +122,7 @@ struct FlatHashSetPolicy;
template <class T, class Hash = DefaultHashContainerHash<T>,
class Eq = DefaultHashContainerEq<T>,
class Allocator = std::allocator<T>>
-class ABSL_INTERNAL_ATTRIBUTE_OWNER flat_hash_set
+class ABSL_ATTRIBUTE_OWNER flat_hash_set
: public absl::container_internal::raw_hash_set<
absl::container_internal::FlatHashSetPolicy<T>, Hash, Eq, Allocator> {
using Base = typename flat_hash_set::raw_hash_set;
@@ -360,8 +360,7 @@ class ABSL_INTERNAL_ATTRIBUTE_OWNER flat_hash_set
// flat_hash_set::swap(flat_hash_set& other)
//
// Exchanges the contents of this `flat_hash_set` with those of the `other`
- // flat hash set, avoiding invocation of any move, copy, or swap operations on
- // individual elements.
+ // flat hash set.
//
// All iterators and references on the `flat_hash_set` remain valid, excepting
// for the past-the-end iterator, which is invalidated.
@@ -478,6 +477,21 @@ typename flat_hash_set<T, H, E, A>::size_type erase_if(
return container_internal::EraseIf(pred, &c);
}
+// swap(flat_hash_set<>, flat_hash_set<>)
+//
+// Swaps the contents of two `flat_hash_set` containers.
+//
+// NOTE: we need to define this function template in order for
+// `flat_hash_set::swap` to be called instead of `std::swap`. Even though we
+// have `swap(raw_hash_set&, raw_hash_set&)` defined, that function requires a
+// derived-to-base conversion, whereas `std::swap` is a function template so
+// `std::swap` will be preferred by compiler.
+template <typename T, typename H, typename E, typename A>
+void swap(flat_hash_set<T, H, E, A>& x,
+ flat_hash_set<T, H, E, A>& y) noexcept(noexcept(x.swap(y))) {
+ return x.swap(y);
+}
+
namespace container_internal {
// c_for_each_fast(flat_hash_set<>, Function)
diff --git a/contrib/restricted/abseil-cpp/absl/container/inlined_vector.h b/contrib/restricted/abseil-cpp/absl/container/inlined_vector.h
index 974b6521a0..cbf8bc2c1f 100644
--- a/contrib/restricted/abseil-cpp/absl/container/inlined_vector.h
+++ b/contrib/restricted/abseil-cpp/absl/container/inlined_vector.h
@@ -46,6 +46,7 @@
#include <utility>
#include "absl/algorithm/algorithm.h"
+#include "absl/base/attributes.h"
#include "absl/base/internal/throw_delegate.h"
#include "absl/base/macros.h"
#include "absl/base/optimization.h"
@@ -67,7 +68,7 @@ ABSL_NAMESPACE_BEGIN
// as a `std::vector`. The API of the `absl::InlinedVector` within this file is
// designed to cover the same API footprint as covered by `std::vector`.
template <typename T, size_t N, typename A = std::allocator<T>>
-class InlinedVector {
+class ABSL_ATTRIBUTE_WARN_UNUSED InlinedVector {
static_assert(N > 0, "`absl::InlinedVector` requires an inlined capacity.");
using Storage = inlined_vector_internal::Storage<T, N, A>;
diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/common_policy_traits.h b/contrib/restricted/abseil-cpp/absl/container/internal/common_policy_traits.h
index c521f6122e..bbf54750f9 100644
--- a/contrib/restricted/abseil-cpp/absl/container/internal/common_policy_traits.h
+++ b/contrib/restricted/abseil-cpp/absl/container/internal/common_policy_traits.h
@@ -28,6 +28,15 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
namespace container_internal {
+template <class Policy, class = void>
+struct policy_trait_element_is_owner : std::false_type {};
+
+template <class Policy>
+struct policy_trait_element_is_owner<
+ Policy,
+ std::enable_if_t<!std::is_void<typename Policy::element_is_owner>::value>>
+ : Policy::element_is_owner {};
+
// Defines how slots are initialized/destroyed/moved.
template <class Policy, class = void>
struct common_policy_traits {
diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/container_memory.h b/contrib/restricted/abseil-cpp/absl/container/internal/container_memory.h
index ba8e08a2d2..e703179701 100644
--- a/contrib/restricted/abseil-cpp/absl/container/internal/container_memory.h
+++ b/contrib/restricted/abseil-cpp/absl/container/internal/container_memory.h
@@ -17,6 +17,7 @@
#include <cassert>
#include <cstddef>
+#include <cstdint>
#include <cstring>
#include <memory>
#include <new>
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 2f24e4616f..0bd0a1c4a4 100644
--- a/contrib/restricted/abseil-cpp/absl/container/internal/inlined_vector.h
+++ b/contrib/restricted/abseil-cpp/absl/container/internal/inlined_vector.h
@@ -83,8 +83,10 @@ using IsMoveAssignOk = std::is_move_assignable<ValueType<A>>;
template <typename A>
using IsSwapOk = absl::type_traits_internal::IsSwappable<ValueType<A>>;
-template <typename A, bool IsTriviallyDestructible =
- absl::is_trivially_destructible<ValueType<A>>::value>
+template <typename A,
+ bool IsTriviallyDestructible =
+ absl::is_trivially_destructible<ValueType<A>>::value &&
+ std::is_same<A, std::allocator<ValueType<A>>>::value>
struct DestroyAdapter;
template <typename A>
diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/layout.h b/contrib/restricted/abseil-cpp/absl/container/internal/layout.h
index 384929af49..f8b425c577 100644
--- a/contrib/restricted/abseil-cpp/absl/container/internal/layout.h
+++ b/contrib/restricted/abseil-cpp/absl/container/internal/layout.h
@@ -306,7 +306,7 @@ constexpr size_t Max(size_t a, size_t b, Ts... rest) {
template <class T>
std::string TypeName() {
std::string out;
-#if ABSL_INTERNAL_HAS_RTTI
+#ifdef ABSL_INTERNAL_HAS_RTTI
absl::StrAppend(&out, "<",
absl::debugging_internal::DemangleString(typeid(T).name()),
">");
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 1cae03819d..8911aa3dc8 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
@@ -24,10 +24,12 @@
#include "absl/base/config.h"
#include "absl/base/dynamic_annotations.h"
#include "absl/base/internal/endian.h"
+#include "absl/base/internal/raw_logging.h"
#include "absl/base/optimization.h"
#include "absl/container/internal/container_memory.h"
#include "absl/container/internal/hashtablez_sampler.h"
#include "absl/hash/hash.h"
+#include "absl/numeric/bits.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -96,6 +98,16 @@ bool ShouldRehashForBugDetection(const ctrl_t* ctrl, size_t capacity) {
RehashProbabilityConstant();
}
+// Find a non-deterministic hash for single group table.
+// Last two bits are used to find a position for a newly inserted element after
+// resize.
+// This function is mixing all bits of hash and control pointer to maximize
+// entropy.
+size_t SingleGroupTableH1(size_t hash, ctrl_t* control) {
+ return static_cast<size_t>(absl::popcount(
+ hash ^ static_cast<size_t>(reinterpret_cast<uintptr_t>(control))));
+}
+
} // namespace
GenerationType* EmptyGeneration() {
@@ -135,7 +147,7 @@ size_t PrepareInsertAfterSoo(size_t hash, size_t slot_size,
// index 1 occupied, so we need to insert either at index 0 or index 2.
assert(HashSetResizeHelper::SooSlotIndex() == 1);
PrepareInsertCommon(common);
- const size_t offset = H1(hash, common.control()) & 2;
+ const size_t offset = SingleGroupTableH1(hash, common.control()) & 2;
common.growth_info().OverwriteEmptyAsFull();
SetCtrlInSingleGroupTable(common, offset, H2(hash), slot_size);
common.infoz().RecordInsert(hash, /*distance_from_desired=*/0);
@@ -338,7 +350,7 @@ void ClearBackingArray(CommonFields& c, const PolicyFunctions& policy,
c.infoz().RecordClearedReservation();
c.infoz().RecordStorageChanged(0, soo_enabled ? SooCapacity() : 0);
(*policy.dealloc)(c, policy);
- c = soo_enabled ? CommonFields{soo_tag_t{}} : CommonFields{};
+ c = soo_enabled ? CommonFields{soo_tag_t{}} : CommonFields{non_soo_tag_t{}};
}
}
@@ -346,124 +358,124 @@ void HashSetResizeHelper::GrowIntoSingleGroupShuffleControlBytes(
ctrl_t* __restrict new_ctrl, size_t new_capacity) const {
assert(is_single_group(new_capacity));
constexpr size_t kHalfWidth = Group::kWidth / 2;
- constexpr size_t kQuarterWidth = Group::kWidth / 4;
- assert(old_capacity_ < kHalfWidth);
- static_assert(sizeof(uint64_t) >= kHalfWidth,
- "Group size is too large. The ctrl bytes for half a group must "
- "fit into a uint64_t for this implementation.");
- static_assert(sizeof(uint64_t) <= Group::kWidth,
- "Group size is too small. The ctrl bytes for a group must "
- "cover a uint64_t for this implementation.");
-
- const size_t half_old_capacity = old_capacity_ / 2;
-
- // NOTE: operations are done with compile time known size = kHalfWidth.
+ ABSL_ASSUME(old_capacity_ < kHalfWidth);
+ ABSL_ASSUME(old_capacity_ > 0);
+ static_assert(Group::kWidth == 8 || Group::kWidth == 16,
+ "Group size is not supported.");
+
+ // NOTE: operations are done with compile time known size = 8.
// Compiler optimizes that into single ASM operation.
- // Load the bytes from half_old_capacity + 1. This contains the last half of
- // old_ctrl bytes, followed by the sentinel byte, and then the first half of
- // the cloned bytes. This effectively shuffles the control bytes.
- uint64_t copied_bytes = 0;
- copied_bytes =
- absl::little_endian::Load64(old_ctrl() + half_old_capacity + 1);
+ // Load the bytes from old_capacity. This contains
+ // - the sentinel byte
+ // - all the old control bytes
+ // - the rest is filled with kEmpty bytes
+ // Example:
+ // old_ctrl = 012S012EEEEEEEEE...
+ // copied_bytes = S012EEEE
+ uint64_t copied_bytes =
+ absl::little_endian::Load64(old_ctrl() + old_capacity_);
// We change the sentinel byte to kEmpty before storing to both the start of
// the new_ctrl, and past the end of the new_ctrl later for the new cloned
// bytes. Note that this is faster than setting the sentinel byte to kEmpty
// after the copy directly in new_ctrl because we are limited on store
// bandwidth.
- constexpr uint64_t kEmptyXorSentinel =
+ static constexpr uint64_t kEmptyXorSentinel =
static_cast<uint8_t>(ctrl_t::kEmpty) ^
static_cast<uint8_t>(ctrl_t::kSentinel);
- const uint64_t mask_convert_old_sentinel_to_empty =
- kEmptyXorSentinel << (half_old_capacity * 8);
- copied_bytes ^= mask_convert_old_sentinel_to_empty;
-
- // Copy second half of bytes to the beginning. This correctly sets the bytes
- // [0, old_capacity]. We potentially copy more bytes in order to have compile
- // time known size. Mirrored bytes from the old_ctrl() will also be copied. In
- // case of old_capacity_ == 3, we will copy 1st element twice.
- // Examples:
- // (old capacity = 1)
- // old_ctrl = 0S0EEEEEEE...
- // new_ctrl = E0EEEEEE??...
- //
- // (old capacity = 3)
- // old_ctrl = 012S012EEEEE...
- // new_ctrl = 12E012EE????...
- //
- // (old capacity = 7)
- // old_ctrl = 0123456S0123456EE...
- // new_ctrl = 456E0123?????????...
- absl::little_endian::Store64(new_ctrl, copied_bytes);
- // Set the space [old_capacity + 1, new_capacity] to empty as these bytes will
- // not be written again. This is safe because
- // NumControlBytes = new_capacity + kWidth and new_capacity >=
- // old_capacity+1.
- // Examples:
- // (old_capacity = 3, new_capacity = 15)
- // new_ctrl = 12E012EE?????????????...??
- // *new_ctrl = 12E0EEEEEEEEEEEEEEEE?...??
- // position / S
- //
- // (old_capacity = 7, new_capacity = 15)
- // new_ctrl = 456E0123?????????????????...??
- // *new_ctrl = 456E0123EEEEEEEEEEEEEEEE?...??
- // position / S
- std::memset(new_ctrl + old_capacity_ + 1, static_cast<int8_t>(ctrl_t::kEmpty),
- Group::kWidth);
-
- // Set the last kHalfWidth bytes to empty, to ensure the bytes all the way to
- // the end are initialized.
- // Examples:
- // new_ctrl = 12E0EEEEEEEEEEEEEEEE?...???????
- // *new_ctrl = 12E0EEEEEEEEEEEEEEEE???EEEEEEEE
- // position S /
- //
- // new_ctrl = 456E0123EEEEEEEEEEEEEEEE???????
- // *new_ctrl = 456E0123EEEEEEEEEEEEEEEEEEEEEEE
- // position S /
- std::memset(new_ctrl + NumControlBytes(new_capacity) - kHalfWidth,
- static_cast<int8_t>(ctrl_t::kEmpty), kHalfWidth);
+ // Replace the first byte kSentinel with kEmpty.
+ // Resulting bytes will be shifted by one byte old control blocks.
+ // Example:
+ // old_ctrl = 012S012EEEEEEEEE...
+ // before = S012EEEE
+ // after = E012EEEE
+ copied_bytes ^= kEmptyXorSentinel;
+
+ if (Group::kWidth == 8) {
+ // With group size 8, we can grow with two write operations.
+ assert(old_capacity_ < 8 && "old_capacity_ is too large for group size 8");
+ absl::little_endian::Store64(new_ctrl, copied_bytes);
+
+ static constexpr uint64_t kSentinal64 =
+ static_cast<uint8_t>(ctrl_t::kSentinel);
+
+ // Prepend kSentinel byte to the beginning of copied_bytes.
+ // We have maximum 3 non-empty bytes at the beginning of copied_bytes for
+ // group size 8.
+ // Example:
+ // old_ctrl = 012S012EEEE
+ // before = E012EEEE
+ // after = SE012EEE
+ copied_bytes = (copied_bytes << 8) ^ kSentinal64;
+ absl::little_endian::Store64(new_ctrl + new_capacity, copied_bytes);
+ // Example for capacity 3:
+ // old_ctrl = 012S012EEEE
+ // After the first store:
+ // >!
+ // new_ctrl = E012EEEE???????
+ // After the second store:
+ // >!
+ // new_ctrl = E012EEESE012EEE
+ return;
+ }
- // Copy the first bytes to the end (starting at new_capacity +1) to set the
- // cloned bytes. Note that we use the already copied bytes from old_ctrl here
- // rather than copying from new_ctrl to avoid a Read-after-Write hazard, since
- // new_ctrl was just written to. The first old_capacity-1 bytes are set
- // correctly. Then there may be up to old_capacity bytes that need to be
- // overwritten, and any remaining bytes will be correctly set to empty. This
- // sets [new_capacity + 1, new_capacity +1 + old_capacity] correctly.
- // Examples:
- // new_ctrl = 12E0EEEEEEEEEEEEEEEE?...???????
- // *new_ctrl = 12E0EEEEEEEEEEEE12E012EEEEEEEEE
- // position S/
- //
- // new_ctrl = 456E0123EEEEEEEE?...???EEEEEEEE
- // *new_ctrl = 456E0123EEEEEEEE456E0123EEEEEEE
- // position S/
- absl::little_endian::Store64(new_ctrl + new_capacity + 1, copied_bytes);
+ assert(Group::kWidth == 16);
- // Set The remaining bytes at the end past the cloned bytes to empty. The
- // incorrectly set bytes are [new_capacity + old_capacity + 2,
- // min(new_capacity + 1 + kHalfWidth, new_capacity + old_capacity + 2 +
- // half_old_capacity)]. Taking the difference, we need to set min(kHalfWidth -
- // (old_capacity + 1), half_old_capacity)]. Since old_capacity < kHalfWidth,
- // half_old_capacity < kQuarterWidth, so we set kQuarterWidth beginning at
- // new_capacity + old_capacity + 2 to kEmpty.
- // Examples:
- // new_ctrl = 12E0EEEEEEEEEEEE12E012EEEEEEEEE
- // *new_ctrl = 12E0EEEEEEEEEEEE12E0EEEEEEEEEEE
- // position S /
- //
- // new_ctrl = 456E0123EEEEEEEE456E0123EEEEEEE
- // *new_ctrl = 456E0123EEEEEEEE456E0123EEEEEEE (no change)
- // position S /
- std::memset(new_ctrl + new_capacity + old_capacity_ + 2,
- static_cast<int8_t>(ctrl_t::kEmpty), kQuarterWidth);
-
- // Finally, we set the new sentinel byte.
+ // Fill the second half of the main control bytes with kEmpty.
+ // For small capacity that may write into mirrored control bytes.
+ // It is fine as we will overwrite all the bytes later.
+ std::memset(new_ctrl + kHalfWidth, static_cast<int8_t>(ctrl_t::kEmpty),
+ kHalfWidth);
+ // Fill the second half of the mirrored control bytes with kEmpty.
+ std::memset(new_ctrl + new_capacity + kHalfWidth,
+ static_cast<int8_t>(ctrl_t::kEmpty), kHalfWidth);
+ // Copy the first half of the non-mirrored control bytes.
+ absl::little_endian::Store64(new_ctrl, copied_bytes);
new_ctrl[new_capacity] = ctrl_t::kSentinel;
+ // Copy the first half of the mirrored control bytes.
+ absl::little_endian::Store64(new_ctrl + new_capacity + 1, copied_bytes);
+
+ // Example for growth capacity 1->3:
+ // old_ctrl = 0S0EEEEEEEEEEEEEE
+ // new_ctrl at the end = E0ESE0EEEEEEEEEEEEE
+ // >!
+ // new_ctrl after 1st memset = ????????EEEEEEEE???
+ // >!
+ // new_ctrl after 2nd memset = ????????EEEEEEEEEEE
+ // >!
+ // new_ctrl after 1st store = E0EEEEEEEEEEEEEEEEE
+ // new_ctrl after kSentinel = E0ESEEEEEEEEEEEEEEE
+ // >!
+ // new_ctrl after 2nd store = E0ESE0EEEEEEEEEEEEE
+
+ // Example for growth capacity 3->7:
+ // old_ctrl = 012S012EEEEEEEEEEEE
+ // new_ctrl at the end = E012EEESE012EEEEEEEEEEE
+ // >!
+ // new_ctrl after 1st memset = ????????EEEEEEEE???????
+ // >!
+ // new_ctrl after 2nd memset = ????????EEEEEEEEEEEEEEE
+ // >!
+ // new_ctrl after 1st store = E012EEEEEEEEEEEEEEEEEEE
+ // new_ctrl after kSentinel = E012EEESEEEEEEEEEEEEEEE
+ // >!
+ // new_ctrl after 2nd store = E012EEESE012EEEEEEEEEEE
+
+
+ // Example for growth capacity 7->15:
+ // old_ctrl = 0123456S0123456EEEEEEEE
+ // new_ctrl at the end = E0123456EEEEEEESE0123456EEEEEEE
+ // >!
+ // new_ctrl after 1st memset = ????????EEEEEEEE???????????????
+ // >!
+ // new_ctrl after 2nd memset = ????????EEEEEEEE???????EEEEEEEE
+ // >!
+ // new_ctrl after 1st store = E0123456EEEEEEEE???????EEEEEEEE
+ // new_ctrl after kSentinel = E0123456EEEEEEES???????EEEEEEEE
+ // >!
+ // new_ctrl after 2nd store = E0123456EEEEEEESE0123456EEEEEEE
}
void HashSetResizeHelper::InitControlBytesAfterSoo(ctrl_t* new_ctrl, ctrl_t h2,
@@ -480,15 +492,10 @@ void HashSetResizeHelper::InitControlBytesAfterSoo(ctrl_t* new_ctrl, ctrl_t h2,
void HashSetResizeHelper::GrowIntoSingleGroupShuffleTransferableSlots(
void* new_slots, size_t slot_size) const {
- assert(old_capacity_ > 0);
- const size_t half_old_capacity = old_capacity_ / 2;
-
+ ABSL_ASSUME(old_capacity_ > 0);
SanitizerUnpoisonMemoryRegion(old_slots(), slot_size * old_capacity_);
- std::memcpy(new_slots,
- SlotAddress(old_slots(), half_old_capacity + 1, slot_size),
- slot_size * half_old_capacity);
- std::memcpy(SlotAddress(new_slots, half_old_capacity + 1, slot_size),
- old_slots(), slot_size * (half_old_capacity + 1));
+ std::memcpy(SlotAddress(new_slots, 1, slot_size), old_slots(),
+ slot_size * old_capacity_);
}
void HashSetResizeHelper::GrowSizeIntoSingleGroupTransferable(
@@ -588,6 +595,23 @@ const void* GetHashRefForEmptyHasher(const CommonFields& common) {
return &common;
}
+FindInfo HashSetResizeHelper::FindFirstNonFullAfterResize(const CommonFields& c,
+ size_t old_capacity,
+ size_t hash) {
+ size_t new_capacity = c.capacity();
+ if (!IsGrowingIntoSingleGroupApplicable(old_capacity, new_capacity)) {
+ return find_first_non_full(c, hash);
+ }
+
+ // We put the new element either at the beginning or at the end of the table
+ // with approximately equal probability.
+ size_t offset =
+ SingleGroupTableH1(hash, c.control()) & 1 ? 0 : new_capacity - 1;
+
+ assert(IsEmpty(c.control()[offset]));
+ return FindInfo{offset, 0};
+}
+
size_t PrepareInsertNonSoo(CommonFields& common, size_t hash, FindInfo target,
const PolicyFunctions& policy) {
// When there are no deleted slots in the table
@@ -638,6 +662,10 @@ size_t PrepareInsertNonSoo(CommonFields& common, size_t hash, FindInfo target,
return target.offset;
}
+void HashTableSizeOverflow() {
+ ABSL_RAW_LOG(FATAL, "Hash table size overflow");
+}
+
} // namespace container_internal
ABSL_NAMESPACE_END
} // namespace absl
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 7934b88c3e..79ccb596b7 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
@@ -41,12 +41,6 @@
// When heterogeneous lookup is disabled, only the explicit `key_type` overloads
// exist.
//
-// find() also supports passing the hash explicitly:
-//
-// iterator find(const key_type& key, size_t hash);
-// template <class U>
-// iterator find(const U& key, size_t hash);
-//
// In addition the pointer to element and iterator stability guarantees are
// weaker: all iterators and pointers are invalidated after a new element is
// inserted.
@@ -190,6 +184,7 @@
#include <cstddef>
#include <cstdint>
#include <cstring>
+#include <functional>
#include <initializer_list>
#include <iterator>
#include <limits>
@@ -208,11 +203,14 @@
#include "absl/base/port.h"
#include "absl/base/prefetch.h"
#include "absl/container/internal/common.h" // IWYU pragma: export // for node_handle
+#include "absl/container/internal/common_policy_traits.h"
#include "absl/container/internal/compressed_tuple.h"
#include "absl/container/internal/container_memory.h"
+#include "absl/container/internal/hash_function_defaults.h"
#include "absl/container/internal/hash_policy_traits.h"
#include "absl/container/internal/hashtable_debug_hooks.h"
#include "absl/container/internal/hashtablez_sampler.h"
+#include "absl/hash/hash.h"
#include "absl/memory/memory.h"
#include "absl/meta/type_traits.h"
#include "absl/numeric/bits.h"
@@ -252,6 +250,15 @@ namespace container_internal {
#define ABSL_SWISSTABLE_ENABLE_GENERATIONS
#endif
+#ifdef ABSL_SWISSTABLE_ASSERT
+#error ABSL_SWISSTABLE_ASSERT cannot be directly set
+#else
+// We use this macro for assertions that users may see when the table is in an
+// invalid state that sanitizers may help diagnose.
+#define ABSL_SWISSTABLE_ASSERT(CONDITION) \
+ assert((CONDITION) && "Try enabling sanitizers.")
+#endif
+
// We use uint8_t so we don't need to worry about padding.
using GenerationType = uint8_t;
@@ -322,7 +329,7 @@ class probe_seq {
// sequence and `mask` (usually the capacity of the table) as the mask to
// apply to each value in the progression.
probe_seq(size_t hash, size_t mask) {
- assert(((mask + 1) & mask) == 0 && "not a mask");
+ ABSL_SWISSTABLE_ASSERT(((mask + 1) & mask) == 0 && "not a mask");
mask_ = mask;
offset_ = hash & mask_;
}
@@ -452,7 +459,7 @@ class BitMask : public NonIterableBitMask<T, SignificantBits, Shift> {
public:
explicit BitMask(T mask) : Base(mask) {
if (Shift == 3 && !NullifyBitsOnIteration) {
- assert(this->mask_ == (this->mask_ & kMsbs8Bytes));
+ ABSL_SWISSTABLE_ASSERT(this->mask_ == (this->mask_ & kMsbs8Bytes));
}
}
// BitMask is an iterator over the indices of its abstract bits.
@@ -536,6 +543,18 @@ static_assert(ctrl_t::kDeleted == static_cast<ctrl_t>(-2),
// See definition comment for why this is size 32.
ABSL_DLL extern const ctrl_t kEmptyGroup[32];
+// We use these sentinel capacity values in debug mode to indicate different
+// classes of bugs.
+enum InvalidCapacity : size_t {
+ kAboveMaxValidCapacity = ~size_t{} - 100,
+ kReentrance,
+ kDestroyed,
+
+ // These two must be last because we use `>= kMovedFrom` to mean moved-from.
+ kMovedFrom,
+ kSelfMovedFrom,
+};
+
// Returns a pointer to a control byte group that can be used by empty tables.
inline ctrl_t* EmptyGroup() {
// Const must be cast away here; no uses of this function will actually write
@@ -687,10 +706,8 @@ struct GroupSse2Impl {
// Returns a bitmask representing the positions of slots that match hash.
BitMask<uint16_t, kWidth> Match(h2_t hash) const {
auto match = _mm_set1_epi8(static_cast<char>(hash));
- BitMask<uint16_t, kWidth> result = BitMask<uint16_t, kWidth>(0);
- result = BitMask<uint16_t, kWidth>(
+ return BitMask<uint16_t, kWidth>(
static_cast<uint16_t>(_mm_movemask_epi8(_mm_cmpeq_epi8(match, ctrl))));
- return result;
}
// Returns a bitmask representing the positions of empty slots.
@@ -1105,19 +1122,20 @@ class GrowthInfo {
// Overwrites single empty slot with a full slot.
void OverwriteEmptyAsFull() {
- assert(GetGrowthLeft() > 0);
+ ABSL_SWISSTABLE_ASSERT(GetGrowthLeft() > 0);
--growth_left_info_;
}
// Overwrites several empty slots with full slots.
void OverwriteManyEmptyAsFull(size_t cnt) {
- assert(GetGrowthLeft() >= cnt);
+ ABSL_SWISSTABLE_ASSERT(GetGrowthLeft() >= cnt);
growth_left_info_ -= cnt;
}
// Overwrites specified control element with full slot.
void OverwriteControlAsFull(ctrl_t ctrl) {
- assert(GetGrowthLeft() >= static_cast<size_t>(IsEmpty(ctrl)));
+ ABSL_SWISSTABLE_ASSERT(GetGrowthLeft() >=
+ static_cast<size_t>(IsEmpty(ctrl)));
growth_left_info_ -= static_cast<size_t>(IsEmpty(ctrl));
}
@@ -1187,7 +1205,7 @@ class RawHashSetLayout {
slot_offset_(
(generation_offset_ + NumGenerationBytes() + slot_align - 1) &
(~slot_align + 1)) {
- assert(IsValidCapacity(capacity));
+ ABSL_SWISSTABLE_ASSERT(IsValidCapacity(capacity));
}
// Returns the capacity of a table.
@@ -1208,7 +1226,7 @@ class RawHashSetLayout {
// Given the capacity of a table, computes the total size of the backing
// array.
size_t alloc_size(size_t slot_size) const {
- ABSL_HARDENING_ASSERT(
+ ABSL_SWISSTABLE_ASSERT(
slot_size <=
((std::numeric_limits<size_t>::max)() - slot_offset_) / capacity_);
return slot_offset_ + capacity_ * slot_size;
@@ -1235,6 +1253,10 @@ constexpr size_t SooCapacity() { return 1; }
struct soo_tag_t {};
// Sentinel type to indicate SOO CommonFields construction with full size.
struct full_soo_tag_t {};
+// Sentinel type to indicate non-SOO CommonFields construction.
+struct non_soo_tag_t {};
+// Sentinel value to indicate an uninitialized CommonFields for use in swapping.
+struct uninitialized_tag_t {};
// Suppress erroneous uninitialized memory errors on GCC. For example, GCC
// thinks that the call to slot_array() in find_or_prepare_insert() is reading
@@ -1316,10 +1338,13 @@ union HeapOrSoo {
// of this state to helper functions as a single argument.
class CommonFields : public CommonFieldsGenerationInfo {
public:
- CommonFields() : capacity_(0), size_(0), heap_or_soo_(EmptyGroup()) {}
explicit CommonFields(soo_tag_t) : capacity_(SooCapacity()), size_(0) {}
explicit CommonFields(full_soo_tag_t)
: capacity_(SooCapacity()), size_(size_t{1} << HasInfozShift()) {}
+ explicit CommonFields(non_soo_tag_t)
+ : capacity_(0), size_(0), heap_or_soo_(EmptyGroup()) {}
+ // For use in swapping.
+ explicit CommonFields(uninitialized_tag_t) {}
// Not copyable
CommonFields(const CommonFields&) = delete;
@@ -1331,7 +1356,8 @@ class CommonFields : public CommonFieldsGenerationInfo {
template <bool kSooEnabled>
static CommonFields CreateDefault() {
- return kSooEnabled ? CommonFields{soo_tag_t{}} : CommonFields{};
+ return kSooEnabled ? CommonFields{soo_tag_t{}}
+ : CommonFields{non_soo_tag_t{}};
}
// The inline data for SOO is written on top of control_/slots_.
@@ -1345,7 +1371,8 @@ class CommonFields : public CommonFieldsGenerationInfo {
void set_control(ctrl_t* c) { heap_or_soo_.control() = c; }
void* backing_array_start() const {
// growth_info (and maybe infoz) is stored before control bytes.
- assert(reinterpret_cast<uintptr_t>(control()) % alignof(size_t) == 0);
+ ABSL_SWISSTABLE_ASSERT(
+ reinterpret_cast<uintptr_t>(control()) % alignof(size_t) == 0);
return control() - ControlOffset(has_infoz());
}
@@ -1368,18 +1395,20 @@ class CommonFields : public CommonFieldsGenerationInfo {
size_ = size_t{1} << HasInfozShift();
}
void increment_size() {
- assert(size() < capacity());
+ ABSL_SWISSTABLE_ASSERT(size() < capacity());
size_ += size_t{1} << HasInfozShift();
}
void decrement_size() {
- assert(size() > 0);
+ ABSL_SWISSTABLE_ASSERT(size() > 0);
size_ -= size_t{1} << HasInfozShift();
}
// The total number of available slots.
size_t capacity() const { return capacity_; }
void set_capacity(size_t c) {
- assert(c == 0 || IsValidCapacity(c));
+ // We allow setting above the max valid capacity for debugging purposes.
+ ABSL_SWISSTABLE_ASSERT(c == 0 || IsValidCapacity(c) ||
+ c > kAboveMaxValidCapacity);
capacity_ = c;
}
@@ -1391,7 +1420,8 @@ class CommonFields : public CommonFieldsGenerationInfo {
GrowthInfo& growth_info() {
auto* gl_ptr = reinterpret_cast<GrowthInfo*>(control()) - 1;
- assert(reinterpret_cast<uintptr_t>(gl_ptr) % alignof(GrowthInfo) == 0);
+ ABSL_SWISSTABLE_ASSERT(
+ reinterpret_cast<uintptr_t>(gl_ptr) % alignof(GrowthInfo) == 0);
return *gl_ptr;
}
GrowthInfo growth_info() const {
@@ -1411,7 +1441,7 @@ class CommonFields : public CommonFieldsGenerationInfo {
: HashtablezInfoHandle();
}
void set_infoz(HashtablezInfoHandle infoz) {
- assert(has_infoz());
+ ABSL_SWISSTABLE_ASSERT(has_infoz());
*reinterpret_cast<HashtablezInfoHandle*>(backing_array_start()) = infoz;
}
@@ -1447,6 +1477,20 @@ class CommonFields : public CommonFieldsGenerationInfo {
std::count(control(), control() + capacity(), ctrl_t::kDeleted));
}
+ // Helper to enable sanitizer mode validation to protect against reentrant
+ // calls during element constructor/destructor.
+ template <typename F>
+ void RunWithReentrancyGuard(F f) {
+#ifdef NDEBUG
+ f();
+ return;
+#endif
+ const size_t cap = capacity();
+ set_capacity(InvalidCapacity::kReentrance);
+ f();
+ set_capacity(cap);
+ }
+
private:
// We store the has_infoz bit in the lowest bit of size_.
static constexpr size_t HasInfozShift() { return 1; }
@@ -1457,8 +1501,8 @@ class CommonFields : public CommonFieldsGenerationInfo {
// We can't assert that SOO is enabled because we don't have SooEnabled(), but
// we assert what we can.
void AssertInSooMode() const {
- assert(capacity() == SooCapacity());
- assert(!has_infoz());
+ ABSL_SWISSTABLE_ASSERT(capacity() == SooCapacity());
+ ABSL_SWISSTABLE_ASSERT(!has_infoz());
}
// The number of slots in the backing array. This is always 2^N-1 for an
@@ -1484,7 +1528,7 @@ class raw_hash_set;
// Returns the next valid capacity after `n`.
inline size_t NextCapacity(size_t n) {
- assert(IsValidCapacity(n) || n == 0);
+ ABSL_SWISSTABLE_ASSERT(IsValidCapacity(n) || n == 0);
return n * 2 + 1;
}
@@ -1509,6 +1553,9 @@ size_t MaxValidCapacity() {
kSlotSize);
}
+// Use a non-inlined function to avoid code bloat.
+[[noreturn]] void HashTableSizeOverflow();
+
// General notes on capacity/growth methods below:
// - We use 7/8th as maximum load factor. For 16-wide groups, that gives an
// average of two empty slots per group.
@@ -1520,7 +1567,7 @@ size_t MaxValidCapacity() {
// Given `capacity`, applies the load factor; i.e., it returns the maximum
// number of values we should put into the table before a resizing rehash.
inline size_t CapacityToGrowth(size_t capacity) {
- assert(IsValidCapacity(capacity));
+ ABSL_SWISSTABLE_ASSERT(IsValidCapacity(capacity));
// `capacity*7/8`
if (Group::kWidth == 8 && capacity == 7) {
// x-x/8 does not work when x==7.
@@ -1712,7 +1759,7 @@ inline void AssertSameContainer(const ctrl_t* ctrl_a, const ctrl_t* ctrl_b,
"hashtable.");
fail_if(true, "Comparing non-end() iterators from different hashtables.");
} else {
- ABSL_HARDENING_ASSERT(
+ ABSL_HARDENING_ASSERT_SLOW(
AreItersFromSameContainer(ctrl_a, ctrl_b, slot_a, slot_b) &&
"Invalid iterator comparison. The iterators may be from different "
"containers or the container might have rehashed or moved. Consider "
@@ -1778,7 +1825,7 @@ inline FindInfo find_first_non_full(const CommonFields& common, size_t hash) {
seq.index()};
}
seq.next();
- assert(seq.index() <= common.capacity() && "full table!");
+ ABSL_SWISSTABLE_ASSERT(seq.index() <= common.capacity() && "full table!");
}
}
@@ -1810,7 +1857,7 @@ inline void ResetCtrl(CommonFields& common, size_t slot_size) {
// Sets sanitizer poisoning for slot corresponding to control byte being set.
inline void DoSanitizeOnSetCtrl(const CommonFields& c, size_t i, ctrl_t h,
size_t slot_size) {
- assert(i < c.capacity());
+ ABSL_SWISSTABLE_ASSERT(i < c.capacity());
auto* slot_i = static_cast<const char*>(c.slot_array()) + i * slot_size;
if (IsFull(h)) {
SanitizerUnpoisonMemoryRegion(slot_i, slot_size);
@@ -1840,7 +1887,7 @@ inline void SetCtrl(const CommonFields& c, size_t i, h2_t h, size_t slot_size) {
// setting the cloned control byte.
inline void SetCtrlInSingleGroupTable(const CommonFields& c, size_t i, ctrl_t h,
size_t slot_size) {
- assert(is_single_group(c.capacity()));
+ ABSL_SWISSTABLE_ASSERT(is_single_group(c.capacity()));
DoSanitizeOnSetCtrl(c, i, h, slot_size);
ctrl_t* ctrl = c.control();
ctrl[i] = h;
@@ -1880,8 +1927,8 @@ ABSL_ATTRIBUTE_ALWAYS_INLINE inline void IterateOverFullSlots(
// Small tables capacity fits into portable group, where
// GroupPortableImpl::MaskFull is more efficient for the
// capacity <= GroupPortableImpl::kWidth.
- assert(cap <= GroupPortableImpl::kWidth &&
- "unexpectedly large small capacity");
+ ABSL_SWISSTABLE_ASSERT(cap <= GroupPortableImpl::kWidth &&
+ "unexpectedly large small capacity");
static_assert(Group::kWidth >= GroupPortableImpl::kWidth,
"unexpected group width");
// Group starts from kSentinel slot, so indices in the mask will
@@ -1898,19 +1945,21 @@ ABSL_ATTRIBUTE_ALWAYS_INLINE inline void IterateOverFullSlots(
ABSL_ATTRIBUTE_UNUSED const size_t original_size_for_assert = remaining;
while (remaining != 0) {
for (uint32_t i : GroupFullEmptyOrDeleted(ctrl).MaskFull()) {
- assert(IsFull(ctrl[i]) && "hash table was modified unexpectedly");
+ ABSL_SWISSTABLE_ASSERT(IsFull(ctrl[i]) &&
+ "hash table was modified unexpectedly");
cb(ctrl + i, slot + i);
--remaining;
}
ctrl += Group::kWidth;
slot += Group::kWidth;
- assert((remaining == 0 || *(ctrl - 1) != ctrl_t::kSentinel) &&
- "hash table was modified unexpectedly");
+ ABSL_SWISSTABLE_ASSERT(
+ (remaining == 0 || *(ctrl - 1) != ctrl_t::kSentinel) &&
+ "hash table was modified unexpectedly");
}
// NOTE: erasure of the current element is allowed in callback for
// absl::erase_if specialization. So we use `>=`.
- assert(original_size_for_assert >= c.size() &&
- "hash table was modified unexpectedly");
+ ABSL_SWISSTABLE_ASSERT(original_size_for_assert >= c.size() &&
+ "hash table was modified unexpectedly");
}
template <typename CharAlloc>
@@ -1965,34 +2014,16 @@ class HashSetResizeHelper {
// `GrowSizeIntoSingleGroup*` in case `IsGrowingIntoSingleGroupApplicable`.
// Falls back to `find_first_non_full` in case of big groups.
static FindInfo FindFirstNonFullAfterResize(const CommonFields& c,
- size_t old_capacity,
- size_t hash) {
- if (!IsGrowingIntoSingleGroupApplicable(old_capacity, c.capacity())) {
- return find_first_non_full(c, hash);
- }
- // Find a location for the new element non-deterministically.
- // Note that any position is correct.
- // It will located at `half_old_capacity` or one of the other
- // empty slots with approximately 50% probability each.
- size_t offset = probe(c, hash).offset();
-
- // Note that we intentionally use unsigned int underflow.
- if (offset - (old_capacity + 1) >= old_capacity) {
- // Offset fall on kSentinel or into the mostly occupied first half.
- offset = old_capacity / 2;
- }
- assert(IsEmpty(c.control()[offset]));
- return FindInfo{offset, 0};
- }
+ size_t old_capacity, size_t hash);
HeapOrSoo& old_heap_or_soo() { return old_heap_or_soo_; }
void* old_soo_data() { return old_heap_or_soo_.get_soo_data(); }
ctrl_t* old_ctrl() const {
- assert(!was_soo_);
+ ABSL_SWISSTABLE_ASSERT(!was_soo_);
return old_heap_or_soo_.control();
}
void* old_slots() const {
- assert(!was_soo_);
+ ABSL_SWISSTABLE_ASSERT(!was_soo_);
return old_heap_or_soo_.slot_array().get();
}
size_t old_capacity() const { return old_capacity_; }
@@ -2043,7 +2074,7 @@ class HashSetResizeHelper {
ctrl_t soo_slot_h2,
size_t key_size,
size_t value_size) {
- assert(c.capacity());
+ ABSL_SWISSTABLE_ASSERT(c.capacity());
HashtablezInfoHandle infoz =
ShouldSampleHashtablezInfo<Alloc>()
? SampleHashtablezInfo<SooEnabled>(SizeOfSlot, key_size, value_size,
@@ -2100,21 +2131,20 @@ class HashSetResizeHelper {
// 1. GrowIntoSingleGroupShuffleControlBytes was already called.
template <class PolicyTraits, class Alloc>
void GrowSizeIntoSingleGroup(CommonFields& c, Alloc& alloc_ref) {
- assert(old_capacity_ < Group::kWidth / 2);
- assert(IsGrowingIntoSingleGroupApplicable(old_capacity_, c.capacity()));
+ ABSL_SWISSTABLE_ASSERT(old_capacity_ < Group::kWidth / 2);
+ ABSL_SWISSTABLE_ASSERT(
+ IsGrowingIntoSingleGroupApplicable(old_capacity_, c.capacity()));
using slot_type = typename PolicyTraits::slot_type;
- assert(is_single_group(c.capacity()));
+ ABSL_SWISSTABLE_ASSERT(is_single_group(c.capacity()));
- auto* new_slots = static_cast<slot_type*>(c.slot_array());
+ auto* new_slots = static_cast<slot_type*>(c.slot_array()) + 1;
auto* old_slots_ptr = static_cast<slot_type*>(old_slots());
+ auto* old_ctrl_ptr = old_ctrl();
- size_t shuffle_bit = old_capacity_ / 2 + 1;
- for (size_t i = 0; i < old_capacity_; ++i) {
- if (IsFull(old_ctrl()[i])) {
- size_t new_i = i ^ shuffle_bit;
- SanitizerUnpoisonMemoryRegion(new_slots + new_i, sizeof(slot_type));
- PolicyTraits::transfer(&alloc_ref, new_slots + new_i,
- old_slots_ptr + i);
+ for (size_t i = 0; i < old_capacity_; ++i, ++new_slots) {
+ if (IsFull(old_ctrl_ptr[i])) {
+ SanitizerUnpoisonMemoryRegion(new_slots, sizeof(slot_type));
+ PolicyTraits::transfer(&alloc_ref, new_slots, old_slots_ptr + i);
}
}
PoisonSingleGroupEmptySlots(c, sizeof(slot_type));
@@ -2156,27 +2186,25 @@ class HashSetResizeHelper {
// 1. new_ctrl is allocated for new_capacity,
// but not initialized.
// 2. new_capacity is a single group.
+ // 3. old_capacity > 0.
//
// All elements are transferred into the first `old_capacity + 1` positions
- // of the new_ctrl. Elements are rotated by `old_capacity_ / 2 + 1` positions
- // in order to change an order and keep it non deterministic.
- // Although rotation itself deterministic, position of the new added element
- // will be based on `H1` and is not deterministic.
+ // of the new_ctrl. Elements are shifted by 1 in order to keep a space at the
+ // beginning for the new element.
+ // Position of the new added element will be based on `H1` and is not
+ // deterministic.
//
// Examples:
// S = kSentinel, E = kEmpty
//
- // old_ctrl = SEEEEEEEE...
- // new_ctrl = ESEEEEEEE...
- //
// old_ctrl = 0SEEEEEEE...
// new_ctrl = E0ESE0EEE...
//
// old_ctrl = 012S012EEEEEEEEE...
- // new_ctrl = 2E01EEES2E01EEE...
+ // new_ctrl = E012EEESE012EEE...
//
// old_ctrl = 0123456S0123456EEEEEEEEEEE...
- // new_ctrl = 456E0123EEEEEES456E0123EEE...
+ // new_ctrl = E0123456EEEEEESE0123456EEE...
void GrowIntoSingleGroupShuffleControlBytes(ctrl_t* new_ctrl,
size_t new_capacity) const;
@@ -2385,6 +2413,10 @@ class raw_hash_set {
alignof(slot_type) <= alignof(HeapOrSoo);
}
+ constexpr static size_t DefaultCapacity() {
+ return SooEnabled() ? SooCapacity() : 0;
+ }
+
// Whether `size` fits in the SOO capacity of this table.
bool fits_in_soo(size_t size) const {
return SooEnabled() && size <= SooCapacity();
@@ -2411,23 +2443,14 @@ class raw_hash_set {
static_assert(std::is_lvalue_reference<reference>::value,
"Policy::element() must return a reference");
- template <typename T>
- struct SameAsElementReference
- : std::is_same<typename std::remove_cv<
- typename std::remove_reference<reference>::type>::type,
- typename std::remove_cv<
- typename std::remove_reference<T>::type>::type> {};
-
// An enabler for insert(T&&): T must be convertible to init_type or be the
// same as [cv] value_type [ref].
- // Note: we separate SameAsElementReference into its own type to avoid using
- // reference unless we need to. MSVC doesn't seem to like it in some
- // cases.
template <class T>
- using RequiresInsertable = typename std::enable_if<
- absl::disjunction<std::is_convertible<T, init_type>,
- SameAsElementReference<T>>::value,
- int>::type;
+ using Insertable = absl::disjunction<
+ std::is_same<absl::remove_cvref_t<reference>, absl::remove_cvref_t<T>>,
+ std::is_convertible<T, init_type>>;
+ template <class T>
+ using IsNotBitField = std::is_pointer<T*>;
// RequiresNotInit is a workaround for gcc prior to 7.1.
// See https://godbolt.org/g/Y4xsUh.
@@ -2438,6 +2461,17 @@ class raw_hash_set {
template <class... Ts>
using IsDecomposable = IsDecomposable<void, PolicyTraits, Hash, Eq, Ts...>;
+ template <class T>
+ using IsDecomposableAndInsertable =
+ IsDecomposable<std::enable_if_t<Insertable<T>::value, T>>;
+
+ // Evaluates to true if an assignment from the given type would require the
+ // source object to remain alive for the life of the element.
+ template <class U>
+ using IsLifetimeBoundAssignmentFrom = std::conditional_t<
+ policy_trait_element_is_owner<Policy>::value, std::false_type,
+ type_traits_internal::IsLifetimeBoundAssignment<init_type, U>>;
+
public:
static_assert(std::is_same<pointer, value_type*>::value,
"Allocators with custom pointer types are not supported");
@@ -2622,9 +2656,11 @@ class raw_hash_set {
const allocator_type& alloc = allocator_type())
: settings_(CommonFields::CreateDefault<SooEnabled()>(), hash, eq,
alloc) {
- if (bucket_count > (SooEnabled() ? SooCapacity() : 0)) {
- ABSL_RAW_CHECK(bucket_count <= MaxValidCapacity<sizeof(slot_type)>(),
- "Hash table size overflow");
+ if (bucket_count > DefaultCapacity()) {
+ if (ABSL_PREDICT_FALSE(bucket_count >
+ MaxValidCapacity<sizeof(slot_type)>())) {
+ HashTableSizeOverflow();
+ }
resize(NormalizeCapacity(bucket_count));
}
}
@@ -2683,7 +2719,8 @@ class raw_hash_set {
// absl::flat_hash_set<int> a, b{a};
//
// RequiresNotInit<T> is a workaround for gcc prior to 7.1.
- template <class T, RequiresNotInit<T> = 0, RequiresInsertable<T> = 0>
+ template <class T, RequiresNotInit<T> = 0,
+ std::enable_if_t<Insertable<T>::value, int> = 0>
raw_hash_set(std::initializer_list<T> init, size_t bucket_count = 0,
const hasher& hash = hasher(), const key_equal& eq = key_equal(),
const allocator_type& alloc = allocator_type())
@@ -2694,7 +2731,8 @@ class raw_hash_set {
const allocator_type& alloc = allocator_type())
: raw_hash_set(init.begin(), init.end(), bucket_count, hash, eq, alloc) {}
- template <class T, RequiresNotInit<T> = 0, RequiresInsertable<T> = 0>
+ template <class T, RequiresNotInit<T> = 0,
+ std::enable_if_t<Insertable<T>::value, int> = 0>
raw_hash_set(std::initializer_list<T> init, size_t bucket_count,
const hasher& hash, const allocator_type& alloc)
: raw_hash_set(init, bucket_count, hash, key_equal(), alloc) {}
@@ -2703,7 +2741,8 @@ class raw_hash_set {
const hasher& hash, const allocator_type& alloc)
: raw_hash_set(init, bucket_count, hash, key_equal(), alloc) {}
- template <class T, RequiresNotInit<T> = 0, RequiresInsertable<T> = 0>
+ template <class T, RequiresNotInit<T> = 0,
+ std::enable_if_t<Insertable<T>::value, int> = 0>
raw_hash_set(std::initializer_list<T> init, size_t bucket_count,
const allocator_type& alloc)
: raw_hash_set(init, bucket_count, hasher(), key_equal(), alloc) {}
@@ -2712,7 +2751,8 @@ class raw_hash_set {
const allocator_type& alloc)
: raw_hash_set(init, bucket_count, hasher(), key_equal(), alloc) {}
- template <class T, RequiresNotInit<T> = 0, RequiresInsertable<T> = 0>
+ template <class T, RequiresNotInit<T> = 0,
+ std::enable_if_t<Insertable<T>::value, int> = 0>
raw_hash_set(std::initializer_list<T> init, const allocator_type& alloc)
: raw_hash_set(init, 0, hasher(), key_equal(), alloc) {}
@@ -2727,6 +2767,7 @@ class raw_hash_set {
raw_hash_set(const raw_hash_set& that, const allocator_type& a)
: raw_hash_set(GrowthToLowerboundCapacity(that.size()), that.hash_ref(),
that.eq_ref(), a) {
+ that.AssertNotDebugCapacity();
const size_t size = that.size();
if (size == 0) {
return;
@@ -2734,14 +2775,14 @@ class raw_hash_set {
// We don't use `that.is_soo()` here because `that` can have non-SOO
// capacity but have a size that fits into SOO capacity.
if (fits_in_soo(size)) {
- assert(size == 1);
+ ABSL_SWISSTABLE_ASSERT(size == 1);
common().set_full_soo();
emplace_at(soo_iterator(), *that.begin());
const HashtablezInfoHandle infoz = try_sample_soo();
if (infoz.IsSampled()) resize_with_soo_infoz(infoz);
return;
}
- assert(!that.is_soo());
+ ABSL_SWISSTABLE_ASSERT(!that.is_soo());
const size_t cap = capacity();
// Note about single group tables:
// 1. It is correct to have any order of elements.
@@ -2773,7 +2814,8 @@ class raw_hash_set {
offset = (offset + shift) & cap;
}
const h2_t h2 = static_cast<h2_t>(*that_ctrl);
- assert( // We rely that hash is not changed for small tables.
+ ABSL_SWISSTABLE_ASSERT( // We rely that hash is not changed for small
+ // tables.
H2(PolicyTraits::apply(HashElement{hash_ref()},
PolicyTraits::element(that_slot))) == h2 &&
"hash function value changed unexpectedly during the copy");
@@ -2797,7 +2839,6 @@ class raw_hash_set {
: // Hash, equality and allocator are copied instead of moved because
// `that` must be left valid. If Hash is std::function<Key>, moving it
// would create a nullptr functor that cannot be called.
- // TODO(b/296061262): move instead of copying hash/eq/alloc.
// Note: we avoid using exchange for better generated code.
settings_(PolicyTraits::transfer_uses_memcpy() || !that.is_full_soo()
? std::move(that.common())
@@ -2807,7 +2848,7 @@ class raw_hash_set {
transfer(soo_slot(), that.soo_slot());
}
that.common() = CommonFields::CreateDefault<SooEnabled()>();
- maybe_increment_generation_or_rehash_on_move();
+ annotate_for_bug_detection_on_move(that);
}
raw_hash_set(raw_hash_set&& that, const allocator_type& a)
@@ -2815,13 +2856,14 @@ class raw_hash_set {
that.eq_ref(), a) {
if (a == that.alloc_ref()) {
swap_common(that);
- maybe_increment_generation_or_rehash_on_move();
+ annotate_for_bug_detection_on_move(that);
} else {
move_elements_allocs_unequal(std::move(that));
}
}
raw_hash_set& operator=(const raw_hash_set& that) {
+ that.AssertNotDebugCapacity();
if (ABSL_PREDICT_FALSE(this == &that)) return *this;
constexpr bool propagate_alloc =
AllocTraits::propagate_on_container_copy_assignment::value;
@@ -2846,7 +2888,12 @@ class raw_hash_set {
typename AllocTraits::propagate_on_container_move_assignment());
}
- ~raw_hash_set() { destructor_impl(); }
+ ~raw_hash_set() {
+ destructor_impl();
+#ifndef NDEBUG
+ common().set_capacity(InvalidCapacity::kDestroyed);
+#endif
+ }
iterator begin() ABSL_ATTRIBUTE_LIFETIME_BOUND {
if (ABSL_PREDICT_FALSE(empty())) return end();
@@ -2854,10 +2901,11 @@ class raw_hash_set {
iterator it = {control(), common().slots_union(),
common().generation_ptr()};
it.skip_empty_or_deleted();
- assert(IsFull(*it.control()));
+ ABSL_SWISSTABLE_ASSERT(IsFull(*it.control()));
return it;
}
iterator end() ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ AssertNotDebugCapacity();
return iterator(common().generation_ptr());
}
@@ -2865,7 +2913,7 @@ class raw_hash_set {
return const_cast<raw_hash_set*>(this)->begin();
}
const_iterator end() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
- return iterator(common().generation_ptr());
+ return const_cast<raw_hash_set*>(this)->end();
}
const_iterator cbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
return begin();
@@ -2873,13 +2921,16 @@ class raw_hash_set {
const_iterator cend() const ABSL_ATTRIBUTE_LIFETIME_BOUND { return end(); }
bool empty() const { return !size(); }
- size_t size() const { return common().size(); }
+ size_t size() const {
+ AssertNotDebugCapacity();
+ return common().size();
+ }
size_t capacity() const {
const size_t cap = common().capacity();
- // Compiler complains when using functions in assume so use local variables.
- ABSL_ATTRIBUTE_UNUSED static constexpr bool kEnabled = SooEnabled();
- ABSL_ATTRIBUTE_UNUSED static constexpr size_t kCapacity = SooCapacity();
- ABSL_ASSUME(!kEnabled || cap >= kCapacity);
+ // Compiler complains when using functions in ASSUME so use local variable.
+ ABSL_ATTRIBUTE_UNUSED static constexpr size_t kDefaultCapacity =
+ DefaultCapacity();
+ ABSL_ASSUME(cap >= kDefaultCapacity);
return cap;
}
size_t max_size() const {
@@ -2887,6 +2938,11 @@ class raw_hash_set {
}
ABSL_ATTRIBUTE_REINITIALIZES void clear() {
+ if (SwisstableGenerationsEnabled() &&
+ capacity() >= InvalidCapacity::kMovedFrom) {
+ common().set_capacity(DefaultCapacity());
+ }
+ AssertNotDebugCapacity();
// Iterating over this container is O(bucket_count()). When bucket_count()
// is much greater than size(), iteration becomes prohibitively expensive.
// For clear() it is more important to reuse the allocated array when the
@@ -2914,15 +2970,26 @@ class raw_hash_set {
//
// flat_hash_map<std::string, int> m;
// m.insert(std::make_pair("abc", 42));
- // TODO(cheshire): A type alias T2 is introduced as a workaround for the nvcc
- // bug.
- template <class T, RequiresInsertable<T> = 0, class T2 = T,
- typename std::enable_if<IsDecomposable<T2>::value, int>::type = 0,
- T* = nullptr>
+ template <class T,
+ std::enable_if_t<IsDecomposableAndInsertable<T>::value &&
+ IsNotBitField<T>::value &&
+ !IsLifetimeBoundAssignmentFrom<T>::value,
+ int> = 0>
std::pair<iterator, bool> insert(T&& value) ABSL_ATTRIBUTE_LIFETIME_BOUND {
return emplace(std::forward<T>(value));
}
+ template <class T,
+ std::enable_if_t<IsDecomposableAndInsertable<T>::value &&
+ IsNotBitField<T>::value &&
+ IsLifetimeBoundAssignmentFrom<T>::value,
+ int> = 0>
+ std::pair<iterator, bool> insert(
+ T&& value ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this))
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ return emplace(std::forward<T>(value));
+ }
+
// This overload kicks in when the argument is a bitfield or an lvalue of
// insertable and decomposable type.
//
@@ -2934,13 +3001,23 @@ class raw_hash_set {
// const char* p = "hello";
// s.insert(p);
//
- template <
- class T, RequiresInsertable<const T&> = 0,
- typename std::enable_if<IsDecomposable<const T&>::value, int>::type = 0>
+ template <class T, std::enable_if_t<
+ IsDecomposableAndInsertable<const T&>::value &&
+ !IsLifetimeBoundAssignmentFrom<const T&>::value,
+ int> = 0>
std::pair<iterator, bool> insert(const T& value)
ABSL_ATTRIBUTE_LIFETIME_BOUND {
return emplace(value);
}
+ template <class T,
+ std::enable_if_t<IsDecomposableAndInsertable<const T&>::value &&
+ IsLifetimeBoundAssignmentFrom<const T&>::value,
+ int> = 0>
+ std::pair<iterator, bool> insert(
+ const T& value ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this))
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ return emplace(value);
+ }
// This overload kicks in when the argument is an rvalue of init_type. Its
// purpose is to handle brace-init-list arguments.
@@ -2948,22 +3025,43 @@ class raw_hash_set {
// flat_hash_map<std::string, int> s;
// s.insert({"abc", 42});
std::pair<iterator, bool> insert(init_type&& value)
- ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ ABSL_ATTRIBUTE_LIFETIME_BOUND
+#if __cplusplus >= 202002L
+ requires(!IsLifetimeBoundAssignmentFrom<init_type>::value)
+#endif
+ {
+ return emplace(std::move(value));
+ }
+#if __cplusplus >= 202002L
+ std::pair<iterator, bool> insert(
+ init_type&& value ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this))
+ ABSL_ATTRIBUTE_LIFETIME_BOUND
+ requires(IsLifetimeBoundAssignmentFrom<init_type>::value)
+ {
return emplace(std::move(value));
}
+#endif
- // TODO(cheshire): A type alias T2 is introduced as a workaround for the nvcc
- // bug.
- template <class T, RequiresInsertable<T> = 0, class T2 = T,
- typename std::enable_if<IsDecomposable<T2>::value, int>::type = 0,
- T* = nullptr>
+ template <class T,
+ std::enable_if_t<IsDecomposableAndInsertable<T>::value &&
+ IsNotBitField<T>::value &&
+ !IsLifetimeBoundAssignmentFrom<T>::value,
+ int> = 0>
iterator insert(const_iterator, T&& value) ABSL_ATTRIBUTE_LIFETIME_BOUND {
return insert(std::forward<T>(value)).first;
}
+ template <class T,
+ std::enable_if_t<IsDecomposableAndInsertable<T>::value &&
+ IsNotBitField<T>::value &&
+ IsLifetimeBoundAssignmentFrom<T>::value,
+ int> = 0>
+ iterator insert(const_iterator, T&& value ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(
+ this)) ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ return insert(std::forward<T>(value)).first;
+ }
- template <
- class T, RequiresInsertable<const T&> = 0,
- typename std::enable_if<IsDecomposable<const T&>::value, int>::type = 0>
+ template <class T, std::enable_if_t<
+ IsDecomposableAndInsertable<const T&>::value, int> = 0>
iterator insert(const_iterator,
const T& value) ABSL_ATTRIBUTE_LIFETIME_BOUND {
return insert(value).first;
@@ -2979,7 +3077,8 @@ class raw_hash_set {
for (; first != last; ++first) emplace(*first);
}
- template <class T, RequiresNotInit<T> = 0, RequiresInsertable<const T&> = 0>
+ template <class T, RequiresNotInit<T> = 0,
+ std::enable_if_t<Insertable<const T&>::value, int> = 0>
void insert(std::initializer_list<T> ilist) {
insert(ilist.begin(), ilist.end());
}
@@ -3018,8 +3117,8 @@ class raw_hash_set {
// flat_hash_map<std::string, std::string> m = {{"abc", "def"}};
// // Creates no std::string copies and makes no heap allocations.
// m.emplace("abc", "xyz");
- template <class... Args, typename std::enable_if<
- IsDecomposable<Args...>::value, int>::type = 0>
+ template <class... Args,
+ std::enable_if_t<IsDecomposable<Args...>::value, int> = 0>
std::pair<iterator, bool> emplace(Args&&... args)
ABSL_ATTRIBUTE_LIFETIME_BOUND {
return PolicyTraits::apply(EmplaceDecomposable{*this},
@@ -3029,8 +3128,8 @@ class raw_hash_set {
// This overload kicks in if we cannot deduce the key from args. It constructs
// value_type unconditionally and then either moves it into the table or
// destroys.
- template <class... Args, typename std::enable_if<
- !IsDecomposable<Args...>::value, int>::type = 0>
+ template <class... Args,
+ std::enable_if_t<!IsDecomposable<Args...>::value, int> = 0>
std::pair<iterator, bool> emplace(Args&&... args)
ABSL_ATTRIBUTE_LIFETIME_BOUND {
alignas(slot_type) unsigned char raw[sizeof(slot_type)];
@@ -3081,7 +3180,7 @@ class raw_hash_set {
public:
template <class... Args>
void operator()(Args&&... args) const {
- assert(*slot_);
+ ABSL_SWISSTABLE_ASSERT(*slot_);
PolicyTraits::construct(alloc_, *slot_, std::forward<Args>(args)...);
*slot_ = nullptr;
}
@@ -3100,7 +3199,7 @@ class raw_hash_set {
if (res.second) {
slot_type* slot = res.first.slot();
std::forward<F>(f)(constructor(&alloc_ref(), &slot));
- assert(!slot);
+ ABSL_SWISSTABLE_ASSERT(!slot);
}
return res.first;
}
@@ -3122,24 +3221,16 @@ class raw_hash_set {
return 1;
}
- // Erases the element pointed to by `it`. Unlike `std::unordered_set::erase`,
- // this method returns void to reduce algorithmic complexity to O(1). The
- // iterator is invalidated, so any increment should be done before calling
- // erase. In order to erase while iterating across a map, use the following
- // idiom (which also works for some standard containers):
- //
- // for (auto it = m.begin(), end = m.end(); it != end;) {
- // // `erase()` will invalidate `it`, so advance `it` first.
- // auto copy_it = it++;
- // if (<pred>) {
- // m.erase(copy_it);
- // }
- // }
+ // Erases the element pointed to by `it`. Unlike `std::unordered_set::erase`,
+ // this method returns void to reduce algorithmic complexity to O(1). The
+ // iterator is invalidated so any increment should be done before calling
+ // erase (e.g. `erase(it++)`).
void erase(const_iterator cit) { erase(cit.inner_); }
// This overload is necessary because otherwise erase<K>(const K&) would be
// a better match if non-const iterator is passed as an argument.
void erase(iterator it) {
+ AssertNotDebugCapacity();
AssertIsFull(it.control(), it.generation(), it.generation_ptr(), "erase()");
destroy(it.slot());
if (is_soo()) {
@@ -3151,6 +3242,7 @@ class raw_hash_set {
iterator erase(const_iterator first,
const_iterator last) ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ AssertNotDebugCapacity();
// We check for empty first because ClearBackingArray requires that
// capacity() > 0 as a precondition.
if (empty()) return end();
@@ -3180,6 +3272,8 @@ class raw_hash_set {
// If the element already exists in `this`, it is left unmodified in `src`.
template <typename H, typename E>
void merge(raw_hash_set<Policy, H, E, Alloc>& src) { // NOLINT
+ AssertNotDebugCapacity();
+ src.AssertNotDebugCapacity();
assert(this != &src);
// Returns whether insertion took place.
const auto insert_slot = [this](slot_type* src_slot) {
@@ -3206,6 +3300,7 @@ class raw_hash_set {
}
node_type extract(const_iterator position) {
+ AssertNotDebugCapacity();
AssertIsFull(position.control(), position.inner_.generation(),
position.inner_.generation_ptr(), "extract()");
auto node = CommonAccess::Transfer<node_type>(alloc_ref(), position.slot());
@@ -3217,9 +3312,8 @@ class raw_hash_set {
return node;
}
- template <
- class K = key_type,
- typename std::enable_if<!std::is_same<K, iterator>::value, int>::type = 0>
+ template <class K = key_type,
+ std::enable_if_t<!std::is_same<K, iterator>::value, int> = 0>
node_type extract(const key_arg<K>& key) {
auto it = find(key);
return it == end() ? node_type() : extract(const_iterator{it});
@@ -3229,6 +3323,8 @@ class raw_hash_set {
IsNoThrowSwappable<hasher>() && IsNoThrowSwappable<key_equal>() &&
IsNoThrowSwappable<allocator_type>(
typename AllocTraits::propagate_on_container_swap{})) {
+ AssertNotDebugCapacity();
+ that.AssertNotDebugCapacity();
using std::swap;
swap_common(that);
swap(hash_ref(), that.hash_ref());
@@ -3254,7 +3350,7 @@ class raw_hash_set {
resize(kInitialSampledCapacity);
}
// This asserts that we didn't lose sampling coverage in `resize`.
- assert(infoz().IsSampled());
+ ABSL_SWISSTABLE_ASSERT(infoz().IsSampled());
return;
}
alignas(slot_type) unsigned char slot_space[sizeof(slot_type)];
@@ -3273,8 +3369,9 @@ class raw_hash_set {
auto m = NormalizeCapacity(n | GrowthToLowerboundCapacity(size()));
// n == 0 unconditionally rehashes as per the standard.
if (n == 0 || m > cap) {
- ABSL_RAW_CHECK(m <= MaxValidCapacity<sizeof(slot_type)>(),
- "Hash table size overflow");
+ if (ABSL_PREDICT_FALSE(m > MaxValidCapacity<sizeof(slot_type)>())) {
+ HashTableSizeOverflow();
+ }
resize(m);
// This is after resize, to ensure that we have completed the allocation
@@ -3287,7 +3384,9 @@ class raw_hash_set {
const size_t max_size_before_growth =
is_soo() ? SooCapacity() : size() + growth_left();
if (n > max_size_before_growth) {
- ABSL_RAW_CHECK(n <= max_size(), "Hash table size overflow");
+ if (ABSL_PREDICT_FALSE(n > max_size())) {
+ HashTableSizeOverflow();
+ }
size_t m = GrowthToLowerboundCapacity(n);
resize(NormalizeCapacity(m));
@@ -3320,7 +3419,7 @@ class raw_hash_set {
// specific benchmarks indicating its importance.
template <class K = key_type>
void prefetch(const key_arg<K>& key) const {
- if (SooEnabled() ? is_soo() : capacity() == 0) return;
+ if (capacity() == DefaultCapacity()) return;
(void)key;
// Avoid probing if we won't be able to prefetch the addresses received.
#ifdef ABSL_HAVE_PREFETCH
@@ -3331,32 +3430,27 @@ class raw_hash_set {
#endif // ABSL_HAVE_PREFETCH
}
- // The API of find() has two extensions.
- //
- // 1. The hash can be passed by the user. It must be equal to the hash of the
- // key.
- //
- // 2. The type of the key argument doesn't have to be key_type. This is so
- // called heterogeneous key support.
template <class K = key_type>
+ ABSL_DEPRECATE_AND_INLINE()
iterator find(const key_arg<K>& key,
- size_t hash) ABSL_ATTRIBUTE_LIFETIME_BOUND {
- AssertHashEqConsistent(key);
- if (is_soo()) return find_soo(key);
- return find_non_soo(key, hash);
+ size_t) ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ return find(key);
}
+ // The API of find() has one extension: the type of the key argument doesn't
+ // have to be key_type. This is so called heterogeneous key support.
template <class K = key_type>
iterator find(const key_arg<K>& key) ABSL_ATTRIBUTE_LIFETIME_BOUND {
- AssertHashEqConsistent(key);
+ AssertOnFind(key);
if (is_soo()) return find_soo(key);
prefetch_heap_block();
return find_non_soo(key, hash_ref()(key));
}
template <class K = key_type>
+ ABSL_DEPRECATE_AND_INLINE()
const_iterator find(const key_arg<K>& key,
- size_t hash) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
- return const_cast<raw_hash_set*>(this)->find(key, hash);
+ size_t) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ return find(key);
}
template <class K = key_type>
const_iterator find(const key_arg<K>& key) const
@@ -3408,7 +3502,16 @@ class raw_hash_set {
if (outer->capacity() > inner->capacity()) std::swap(outer, inner);
for (const value_type& elem : *outer) {
auto it = PolicyTraits::apply(FindElement{*inner}, elem);
- if (it == inner->end() || !(*it == elem)) return false;
+ if (it == inner->end()) return false;
+ // Note: we used key_equal to check for key equality in FindElement, but
+ // we may need to do an additional comparison using
+ // value_type::operator==. E.g. the keys could be equal and the
+ // mapped_types could be unequal in a map or even in a set, key_equal
+ // could ignore some fields that aren't ignored by operator==.
+ static constexpr bool kKeyEqIsValueEq =
+ std::is_same<key_type, value_type>::value &&
+ std::is_same<key_equal, hash_default_eq<key_type>>::value;
+ if (!kKeyEqIsValueEq && !(*it == elem)) return false;
}
return true;
}
@@ -3492,23 +3595,26 @@ class raw_hash_set {
slot_type&& slot;
};
- // TODO(b/303305702): re-enable reentrant validation.
template <typename... Args>
inline void construct(slot_type* slot, Args&&... args) {
- PolicyTraits::construct(&alloc_ref(), slot, std::forward<Args>(args)...);
+ common().RunWithReentrancyGuard([&] {
+ PolicyTraits::construct(&alloc_ref(), slot, std::forward<Args>(args)...);
+ });
}
inline void destroy(slot_type* slot) {
- PolicyTraits::destroy(&alloc_ref(), slot);
+ common().RunWithReentrancyGuard(
+ [&] { PolicyTraits::destroy(&alloc_ref(), slot); });
}
inline void transfer(slot_type* to, slot_type* from) {
- PolicyTraits::transfer(&alloc_ref(), to, from);
+ common().RunWithReentrancyGuard(
+ [&] { PolicyTraits::transfer(&alloc_ref(), to, from); });
}
// TODO(b/289225379): consider having a helper class that has the impls for
// SOO functionality.
template <class K = key_type>
iterator find_soo(const key_arg<K>& key) {
- assert(is_soo());
+ ABSL_SWISSTABLE_ASSERT(is_soo());
return empty() || !PolicyTraits::apply(EqualElement<K>{key, eq_ref()},
PolicyTraits::element(soo_slot()))
? end()
@@ -3517,7 +3623,7 @@ class raw_hash_set {
template <class K = key_type>
iterator find_non_soo(const key_arg<K>& key, size_t hash) {
- assert(!is_soo());
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
auto seq = probe(common(), hash);
const ctrl_t* ctrl = control();
while (true) {
@@ -3530,7 +3636,7 @@ class raw_hash_set {
}
if (ABSL_PREDICT_TRUE(g.MaskEmpty())) return end();
seq.next();
- assert(seq.index() <= capacity() && "full table!");
+ ABSL_SWISSTABLE_ASSERT(seq.index() <= capacity() && "full table!");
}
}
@@ -3538,14 +3644,14 @@ class raw_hash_set {
// insertion into an empty SOO table and in copy construction when the size
// can fit in SOO capacity.
inline HashtablezInfoHandle try_sample_soo() {
- assert(is_soo());
+ ABSL_SWISSTABLE_ASSERT(is_soo());
if (!ShouldSampleHashtablezInfo<CharAlloc>()) return HashtablezInfoHandle{};
return Sample(sizeof(slot_type), sizeof(key_type), sizeof(value_type),
SooCapacity());
}
inline void destroy_slots() {
- assert(!is_soo());
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
if (PolicyTraits::template destroy_is_trivial<Alloc>()) return;
IterateOverFullSlots(
common(), slot_array(),
@@ -3554,7 +3660,7 @@ class raw_hash_set {
}
inline void dealloc() {
- assert(capacity() != 0);
+ ABSL_SWISSTABLE_ASSERT(capacity() != 0);
// Unpoison before returning the memory to the allocator.
SanitizerUnpoisonMemoryRegion(slot_array(), sizeof(slot_type) * capacity());
infoz().Unregister();
@@ -3564,6 +3670,10 @@ class raw_hash_set {
}
inline void destructor_impl() {
+ if (SwisstableGenerationsEnabled() &&
+ capacity() >= InvalidCapacity::kMovedFrom) {
+ return;
+ }
if (capacity() == 0) return;
if (is_soo()) {
if (!empty()) {
@@ -3580,7 +3690,7 @@ class raw_hash_set {
// This merely updates the pertinent control byte. This can be used in
// conjunction with Policy::transfer to move the object to another place.
void erase_meta_only(const_iterator it) {
- assert(!is_soo());
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
EraseMetaOnly(common(), static_cast<size_t>(it.control() - control()),
sizeof(slot_type));
}
@@ -3606,7 +3716,7 @@ class raw_hash_set {
// SOO tables, since they need to switch from SOO to heap in order to
// store the infoz.
void resize_with_soo_infoz(HashtablezInfoHandle forced_infoz) {
- assert(forced_infoz.IsSampled());
+ ABSL_SWISSTABLE_ASSERT(forced_infoz.IsSampled());
raw_hash_set::resize_impl(common(), NextCapacity(SooCapacity()),
forced_infoz);
}
@@ -3617,8 +3727,8 @@ class raw_hash_set {
CommonFields& common, size_t new_capacity,
HashtablezInfoHandle forced_infoz) {
raw_hash_set* set = reinterpret_cast<raw_hash_set*>(&common);
- assert(IsValidCapacity(new_capacity));
- assert(!set->fits_in_soo(new_capacity));
+ ABSL_SWISSTABLE_ASSERT(IsValidCapacity(new_capacity));
+ ABSL_SWISSTABLE_ASSERT(!set->fits_in_soo(new_capacity));
const bool was_soo = set->is_soo();
const bool had_soo_slot = was_soo && !set->empty();
const ctrl_t soo_slot_h2 =
@@ -3653,7 +3763,7 @@ class raw_hash_set {
// InitializeSlots did all the work including infoz().RecordRehash().
return;
}
- assert(resize_helper.old_capacity() > 0);
+ ABSL_SWISSTABLE_ASSERT(resize_helper.old_capacity() > 0);
// Nothing more to do in this case.
if (was_soo && !had_soo_slot) return;
@@ -3706,15 +3816,18 @@ class raw_hash_set {
static slot_type* to_slot(void* buf) { return static_cast<slot_type*>(buf); }
// Requires that lhs does not have a full SOO slot.
- static void move_common(bool that_is_full_soo, allocator_type& rhs_alloc,
+ static void move_common(bool rhs_is_full_soo, allocator_type& rhs_alloc,
CommonFields& lhs, CommonFields&& rhs) {
- if (PolicyTraits::transfer_uses_memcpy() || !that_is_full_soo) {
+ if (PolicyTraits::transfer_uses_memcpy() || !rhs_is_full_soo) {
lhs = std::move(rhs);
} else {
lhs.move_non_heap_or_soo_fields(rhs);
- // TODO(b/303305702): add reentrancy guard.
- PolicyTraits::transfer(&rhs_alloc, to_slot(lhs.soo_data()),
- to_slot(rhs.soo_data()));
+ rhs.RunWithReentrancyGuard([&] {
+ lhs.RunWithReentrancyGuard([&] {
+ PolicyTraits::transfer(&rhs_alloc, to_slot(lhs.soo_data()),
+ to_slot(rhs.soo_data()));
+ });
+ });
}
}
@@ -3726,7 +3839,7 @@ class raw_hash_set {
swap(common(), that.common());
return;
}
- CommonFields tmp = CommonFields::CreateDefault<SooEnabled()>();
+ CommonFields tmp = CommonFields(uninitialized_tag_t{});
const bool that_is_full_soo = that.is_full_soo();
move_common(that_is_full_soo, that.alloc_ref(), tmp,
std::move(that.common()));
@@ -3734,8 +3847,17 @@ class raw_hash_set {
move_common(that_is_full_soo, that.alloc_ref(), common(), std::move(tmp));
}
- void maybe_increment_generation_or_rehash_on_move() {
- if (!SwisstableGenerationsEnabled() || capacity() == 0 || is_soo()) {
+ void annotate_for_bug_detection_on_move(
+ ABSL_ATTRIBUTE_UNUSED raw_hash_set& that) {
+ // We only enable moved-from validation when generations are enabled (rather
+ // than using NDEBUG) to avoid issues in which NDEBUG is enabled in some
+ // translation units but not in others.
+ if (SwisstableGenerationsEnabled()) {
+ that.common().set_capacity(this == &that ? InvalidCapacity::kSelfMovedFrom
+ : InvalidCapacity::kMovedFrom);
+ }
+ if (!SwisstableGenerationsEnabled() || capacity() == DefaultCapacity() ||
+ capacity() > kAboveMaxValidCapacity) {
return;
}
common().increment_generation();
@@ -3751,13 +3873,12 @@ class raw_hash_set {
destructor_impl();
move_common(that.is_full_soo(), that.alloc_ref(), common(),
std::move(that.common()));
- // TODO(b/296061262): move instead of copying hash/eq/alloc.
hash_ref() = that.hash_ref();
eq_ref() = that.eq_ref();
CopyAlloc(alloc_ref(), that.alloc_ref(),
std::integral_constant<bool, propagate_alloc>());
that.common() = CommonFields::CreateDefault<SooEnabled()>();
- maybe_increment_generation_or_rehash_on_move();
+ annotate_for_bug_detection_on_move(that);
return *this;
}
@@ -3771,7 +3892,7 @@ class raw_hash_set {
}
if (!that.is_soo()) that.dealloc();
that.common() = CommonFields::CreateDefault<SooEnabled()>();
- maybe_increment_generation_or_rehash_on_move();
+ annotate_for_bug_detection_on_move(that);
return *this;
}
@@ -3790,7 +3911,6 @@ class raw_hash_set {
// We can't take over that's memory so we need to move each element.
// While moving elements, this should have that's hash/eq so copy hash/eq
// before moving elements.
- // TODO(b/296061262): move instead of copying hash/eq.
hash_ref() = that.hash_ref();
eq_ref() = that.eq_ref();
return move_elements_allocs_unequal(std::move(that));
@@ -3819,7 +3939,7 @@ class raw_hash_set {
template <class K>
std::pair<iterator, bool> find_or_prepare_insert_non_soo(const K& key) {
- assert(!is_soo());
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
prefetch_heap_block();
auto hash = hash_ref()(key);
auto seq = probe(common(), hash);
@@ -3842,16 +3962,57 @@ class raw_hash_set {
true};
}
seq.next();
- assert(seq.index() <= capacity() && "full table!");
+ ABSL_SWISSTABLE_ASSERT(seq.index() <= capacity() && "full table!");
}
}
protected:
+ // Asserts for correctness that we run on find/find_or_prepare_insert.
+ template <class K>
+ void AssertOnFind(ABSL_ATTRIBUTE_UNUSED const K& key) {
+ AssertHashEqConsistent(key);
+ AssertNotDebugCapacity();
+ }
+
+ // Asserts that the capacity is not a sentinel invalid value.
+ void AssertNotDebugCapacity() const {
+ if (ABSL_PREDICT_TRUE(capacity() <
+ InvalidCapacity::kAboveMaxValidCapacity)) {
+ return;
+ }
+ assert(capacity() != InvalidCapacity::kReentrance &&
+ "Reentrant container access during element construction/destruction "
+ "is not allowed.");
+ assert(capacity() != InvalidCapacity::kDestroyed &&
+ "Use of destroyed hash table.");
+ if (SwisstableGenerationsEnabled() &&
+ ABSL_PREDICT_FALSE(capacity() >= InvalidCapacity::kMovedFrom)) {
+ if (capacity() == InvalidCapacity::kSelfMovedFrom) {
+ // If this log triggers, then a hash table was move-assigned to itself
+ // and then used again later without being reinitialized.
+ ABSL_RAW_LOG(FATAL, "Use of self-move-assigned hash table.");
+ }
+ ABSL_RAW_LOG(FATAL, "Use of moved-from hash table.");
+ }
+ }
+
// Asserts that hash and equal functors provided by the user are consistent,
// meaning that `eq(k1, k2)` implies `hash(k1)==hash(k2)`.
template <class K>
- void AssertHashEqConsistent(ABSL_ATTRIBUTE_UNUSED const K& key) {
-#ifndef NDEBUG
+ void AssertHashEqConsistent(const K& key) {
+#ifdef NDEBUG
+ return;
+#endif
+ // If the hash/eq functors are known to be consistent, then skip validation.
+ if (std::is_same<hasher, absl::container_internal::StringHash>::value &&
+ std::is_same<key_equal, absl::container_internal::StringEq>::value) {
+ return;
+ }
+ if (std::is_scalar<key_type>::value &&
+ std::is_same<hasher, absl::Hash<key_type>>::value &&
+ std::is_same<key_equal, std::equal_to<key_type>>::value) {
+ return;
+ }
if (empty()) return;
const size_t hash_of_arg = hash_ref()(key);
@@ -3863,21 +4024,8 @@ class raw_hash_set {
const size_t hash_of_slot =
PolicyTraits::apply(HashElement{hash_ref()}, element);
- const bool is_hash_equal = hash_of_arg == hash_of_slot;
- if (!is_hash_equal) {
- // In this case, we're going to crash. Do a couple of other checks for
- // idempotence issues. Recalculating hash/eq here is also convenient for
- // debugging with gdb/lldb.
- const size_t once_more_hash_arg = hash_ref()(key);
- assert(hash_of_arg == once_more_hash_arg && "hash is not idempotent.");
- const size_t once_more_hash_slot =
- PolicyTraits::apply(HashElement{hash_ref()}, element);
- assert(hash_of_slot == once_more_hash_slot &&
- "hash is not idempotent.");
- const bool once_more_eq =
- PolicyTraits::apply(EqualElement<K>{key, eq_ref()}, element);
- assert(is_key_equal == once_more_eq && "equality is not idempotent.");
- }
+ ABSL_ATTRIBUTE_UNUSED const bool is_hash_equal =
+ hash_of_arg == hash_of_slot;
assert((!is_key_equal || is_hash_equal) &&
"eq(k1, k2) must imply that hash(k1) == hash(k2). "
"hash/eq functors are inconsistent.");
@@ -3890,7 +4038,6 @@ class raw_hash_set {
// We only do validation for small tables so that it's constant time.
if (capacity() > 16) return;
IterateOverFullSlots(common(), slot_array(), assert_consistent);
-#endif
}
// Attempts to find `key` in the table; if it isn't found, returns an iterator
@@ -3898,7 +4045,7 @@ class raw_hash_set {
// `key`'s H2. Returns a bool indicating whether an insertion can take place.
template <class K>
std::pair<iterator, bool> find_or_prepare_insert(const K& key) {
- AssertHashEqConsistent(key);
+ AssertOnFind(key);
if (is_soo()) return find_or_prepare_insert_soo(key);
return find_or_prepare_insert_non_soo(key);
}
@@ -3942,16 +4089,16 @@ class raw_hash_set {
//
// See `CapacityToGrowth()`.
size_t growth_left() const {
- assert(!is_soo());
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
return common().growth_left();
}
GrowthInfo& growth_info() {
- assert(!is_soo());
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
return common().growth_info();
}
GrowthInfo growth_info() const {
- assert(!is_soo());
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
return common().growth_info();
}
@@ -3959,7 +4106,7 @@ class raw_hash_set {
// cache misses. This is intended to overlap with execution of calculating the
// hash for a key.
void prefetch_heap_block() const {
- assert(!is_soo());
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
#if ABSL_HAVE_BUILTIN(__builtin_prefetch) || defined(__GNUC__)
__builtin_prefetch(control(), 0, 1);
#endif
@@ -3969,15 +4116,15 @@ class raw_hash_set {
const CommonFields& common() const { return settings_.template get<0>(); }
ctrl_t* control() const {
- assert(!is_soo());
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
return common().control();
}
slot_type* slot_array() const {
- assert(!is_soo());
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
return static_cast<slot_type*>(common().slot_array());
}
slot_type* soo_slot() {
- assert(is_soo());
+ ABSL_SWISSTABLE_ASSERT(is_soo());
return static_cast<slot_type*>(common().soo_data());
}
const slot_type* soo_slot() const {
@@ -3990,7 +4137,7 @@ class raw_hash_set {
return const_cast<raw_hash_set*>(this)->soo_iterator();
}
HashtablezInfoHandle infoz() {
- assert(!is_soo());
+ ABSL_SWISSTABLE_ASSERT(!is_soo());
return common().infoz();
}
@@ -4039,7 +4186,7 @@ class raw_hash_set {
(std::is_same<SlotAlloc, std::allocator<slot_type>>::value
? &DeallocateStandard<alignof(slot_type)>
: &raw_hash_set::dealloc_fn),
- &raw_hash_set::resize_impl,
+ &raw_hash_set::resize_impl
};
return value;
}
@@ -4063,7 +4210,8 @@ struct HashtableFreeFunctionsAccess {
if (c->is_soo()) {
auto it = c->soo_iterator();
if (!pred(*it)) {
- assert(c->size() == 1 && "hash table was modified unexpectedly");
+ ABSL_SWISSTABLE_ASSERT(c->size() == 1 &&
+ "hash table was modified unexpectedly");
return 0;
}
c->destroy(it.slot());
@@ -4083,8 +4231,9 @@ struct HashtableFreeFunctionsAccess {
});
// NOTE: IterateOverFullSlots allow removal of the current element, so we
// verify the size additionally here.
- assert(original_size_for_assert - num_deleted == c->size() &&
- "hash table was modified unexpectedly");
+ ABSL_SWISSTABLE_ASSERT(original_size_for_assert - num_deleted ==
+ c->size() &&
+ "hash table was modified unexpectedly");
return num_deleted;
}
@@ -4178,5 +4327,6 @@ ABSL_NAMESPACE_END
#undef ABSL_SWISSTABLE_ENABLE_GENERATIONS
#undef ABSL_SWISSTABLE_IGNORE_UNINITIALIZED
#undef ABSL_SWISSTABLE_IGNORE_UNINITIALIZED_RETURN
+#undef ABSL_SWISSTABLE_ASSERT
#endif // ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_
diff --git a/contrib/restricted/abseil-cpp/absl/container/node_hash_map.h b/contrib/restricted/abseil-cpp/absl/container/node_hash_map.h
index 5615e4966b..127c893739 100644
--- a/contrib/restricted/abseil-cpp/absl/container/node_hash_map.h
+++ b/contrib/restricted/abseil-cpp/absl/container/node_hash_map.h
@@ -120,7 +120,7 @@ class NodeHashMapPolicy;
template <class Key, class Value, class Hash = DefaultHashContainerHash<Key>,
class Eq = DefaultHashContainerEq<Key>,
class Alloc = std::allocator<std::pair<const Key, Value>>>
-class ABSL_INTERNAL_ATTRIBUTE_OWNER node_hash_map
+class ABSL_ATTRIBUTE_OWNER node_hash_map
: public absl::container_internal::raw_hash_map<
absl::container_internal::NodeHashMapPolicy<Key, Value>, Hash, Eq,
Alloc> {
@@ -236,8 +236,13 @@ class ABSL_INTERNAL_ATTRIBUTE_OWNER node_hash_map
// Erases the element at `position` of the `node_hash_map`, returning
// `void`.
//
- // NOTE: this return behavior is different than that of STL containers in
- // general and `std::unordered_map` in particular.
+ // NOTE: Returning `void` in this case is different than that of STL
+ // containers in general and `std::unordered_map` in particular (which
+ // return an iterator to the element following the erased element). If that
+ // iterator is needed, simply post increment the iterator:
+ //
+ // map.erase(it++);
+ //
//
// iterator erase(const_iterator first, const_iterator last):
//
@@ -417,8 +422,7 @@ class ABSL_INTERNAL_ATTRIBUTE_OWNER node_hash_map
// node_hash_map::swap(node_hash_map& other)
//
// Exchanges the contents of this `node_hash_map` with those of the `other`
- // node hash map, avoiding invocation of any move, copy, or swap operations on
- // individual elements.
+ // node hash map.
//
// All iterators and references on the `node_hash_map` remain valid, excepting
// for the past-the-end iterator, which is invalidated.
@@ -558,6 +562,21 @@ typename node_hash_map<K, V, H, E, A>::size_type erase_if(
return container_internal::EraseIf(pred, &c);
}
+// swap(node_hash_map<>, node_hash_map<>)
+//
+// Swaps the contents of two `node_hash_map` containers.
+//
+// NOTE: we need to define this function template in order for
+// `flat_hash_set::swap` to be called instead of `std::swap`. Even though we
+// have `swap(raw_hash_set&, raw_hash_set&)` defined, that function requires a
+// derived-to-base conversion, whereas `std::swap` is a function template so
+// `std::swap` will be preferred by compiler.
+template <typename K, typename V, typename H, typename E, typename A>
+void swap(node_hash_map<K, V, H, E, A>& x,
+ node_hash_map<K, V, H, E, A>& y) noexcept(noexcept(x.swap(y))) {
+ return x.swap(y);
+}
+
namespace container_internal {
// c_for_each_fast(node_hash_map<>, Function)
diff --git a/contrib/restricted/abseil-cpp/absl/container/node_hash_set.h b/contrib/restricted/abseil-cpp/absl/container/node_hash_set.h
index 53435ae630..cffa50ec77 100644
--- a/contrib/restricted/abseil-cpp/absl/container/node_hash_set.h
+++ b/contrib/restricted/abseil-cpp/absl/container/node_hash_set.h
@@ -115,7 +115,7 @@ struct NodeHashSetPolicy;
// }
template <class T, class Hash = DefaultHashContainerHash<T>,
class Eq = DefaultHashContainerEq<T>, class Alloc = std::allocator<T>>
-class ABSL_INTERNAL_ATTRIBUTE_OWNER node_hash_set
+class ABSL_ATTRIBUTE_OWNER node_hash_set
: public absl::container_internal::raw_hash_set<
absl::container_internal::NodeHashSetPolicy<T>, Hash, Eq, Alloc> {
using Base = typename node_hash_set::raw_hash_set;
@@ -230,8 +230,13 @@ class ABSL_INTERNAL_ATTRIBUTE_OWNER node_hash_set
// Erases the element at `position` of the `node_hash_set`, returning
// `void`.
//
- // NOTE: this return behavior is different than that of STL containers in
- // general and `std::unordered_set` in particular.
+ // NOTE: Returning `void` in this case is different than that of STL
+ // containers in general and `std::unordered_map` in particular (which
+ // return an iterator to the element following the erased element). If that
+ // iterator is needed, simply post increment the iterator:
+ //
+ // map.erase(it++);
+ //
//
// iterator erase(const_iterator first, const_iterator last):
//
@@ -349,8 +354,7 @@ class ABSL_INTERNAL_ATTRIBUTE_OWNER node_hash_set
// node_hash_set::swap(node_hash_set& other)
//
// Exchanges the contents of this `node_hash_set` with those of the `other`
- // node hash set, avoiding invocation of any move, copy, or swap operations on
- // individual elements.
+ // node hash set.
//
// All iterators and references on the `node_hash_set` remain valid, excepting
// for the past-the-end iterator, which is invalidated.
@@ -467,6 +471,21 @@ typename node_hash_set<T, H, E, A>::size_type erase_if(
return container_internal::EraseIf(pred, &c);
}
+// swap(node_hash_set<>, node_hash_set<>)
+//
+// Swaps the contents of two `node_hash_set` containers.
+//
+// NOTE: we need to define this function template in order for
+// `flat_hash_set::swap` to be called instead of `std::swap`. Even though we
+// have `swap(raw_hash_set&, raw_hash_set&)` defined, that function requires a
+// derived-to-base conversion, whereas `std::swap` is a function template so
+// `std::swap` will be preferred by compiler.
+template <typename T, typename H, typename E, typename A>
+void swap(node_hash_set<T, H, E, A>& x,
+ node_hash_set<T, H, E, A>& y) noexcept(noexcept(x.swap(y))) {
+ return x.swap(y);
+}
+
namespace container_internal {
// c_for_each_fast(node_hash_set<>, Function)
diff --git a/contrib/restricted/abseil-cpp/absl/container/ya.make b/contrib/restricted/abseil-cpp/absl/container/ya.make
index 3d7b557c1b..f56079a755 100644
--- a/contrib/restricted/abseil-cpp/absl/container/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/container/ya.make
@@ -6,7 +6,7 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20240722.1)
+VERSION(20250127.0)
PEERDIR(
contrib/restricted/abseil-cpp/absl/base
diff --git a/contrib/restricted/abseil-cpp/absl/crc/internal/cpu_detect.cc b/contrib/restricted/abseil-cpp/absl/crc/internal/cpu_detect.cc
index d7eedd1ca4..c59f773ea3 100644
--- a/contrib/restricted/abseil-cpp/absl/crc/internal/cpu_detect.cc
+++ b/contrib/restricted/abseil-cpp/absl/crc/internal/cpu_detect.cc
@@ -18,12 +18,21 @@
#include <string>
#include "absl/base/config.h"
+#include "absl/types/optional.h" // IWYU pragma: keep
#if defined(__aarch64__) && defined(__linux__)
#include <asm/hwcap.h>
#include <sys/auxv.h>
#endif
+#if defined(__aarch64__) && defined(__APPLE__)
+#if defined(__has_include) && __has_include(<arm/cpu_capabilities_public.h>)
+#include <arm/cpu_capabilities_public.h>
+#endif
+#include <sys/sysctl.h>
+#include <sys/types.h>
+#endif
+
#if defined(_WIN32) || defined(_WIN64)
#include <intrin.h>
#endif
@@ -269,8 +278,55 @@ CpuType GetCpuType() {
}
bool SupportsArmCRC32PMULL() {
+#if defined(HWCAP_CRC32) && defined(HWCAP_PMULL)
uint64_t hwcaps = getauxval(AT_HWCAP);
return (hwcaps & HWCAP_CRC32) && (hwcaps & HWCAP_PMULL);
+#else
+ return false;
+#endif
+}
+
+#elif defined(__aarch64__) && defined(__APPLE__)
+
+CpuType GetCpuType() { return CpuType::kUnknown; }
+
+template <typename T>
+static absl::optional<T> ReadSysctlByName(const char* name) {
+ T val;
+ size_t val_size = sizeof(T);
+ int ret = sysctlbyname(name, &val, &val_size, nullptr, 0);
+ if (ret == -1) {
+ return absl::nullopt;
+ }
+ return val;
+}
+
+bool SupportsArmCRC32PMULL() {
+ // Newer XNU kernels support querying all capabilities in a single
+ // sysctlbyname.
+#if defined(CAP_BIT_CRC32) && defined(CAP_BIT_FEAT_PMULL)
+ static const absl::optional<uint64_t> caps =
+ ReadSysctlByName<uint64_t>("hw.optional.arm.caps");
+ if (caps.has_value()) {
+ constexpr uint64_t kCrc32AndPmullCaps =
+ (uint64_t{1} << CAP_BIT_CRC32) | (uint64_t{1} << CAP_BIT_FEAT_PMULL);
+ return (*caps & kCrc32AndPmullCaps) == kCrc32AndPmullCaps;
+ }
+#endif
+
+ // https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics#3915619
+ static const absl::optional<int> armv8_crc32 =
+ ReadSysctlByName<int>("hw.optional.armv8_crc32");
+ if (armv8_crc32.value_or(0) == 0) {
+ return false;
+ }
+ // https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics#3918855
+ static const absl::optional<int> feat_pmull =
+ ReadSysctlByName<int>("hw.optional.arm.FEAT_PMULL");
+ if (feat_pmull.value_or(0) == 0) {
+ return false;
+ }
+ return true;
}
#else
diff --git a/contrib/restricted/abseil-cpp/absl/crc/internal/non_temporal_memcpy.h b/contrib/restricted/abseil-cpp/absl/crc/internal/non_temporal_memcpy.h
index 7ae83bdcbd..5d3e4e3ff1 100644
--- a/contrib/restricted/abseil-cpp/absl/crc/internal/non_temporal_memcpy.h
+++ b/contrib/restricted/abseil-cpp/absl/crc/internal/non_temporal_memcpy.h
@@ -111,20 +111,31 @@ inline void *non_temporal_store_memcpy(void *__restrict dst,
#endif // __SSE3__ || __aarch64__ || (_MSC_VER && __AVX__)
}
+// We try to force non_temporal_store_memcpy_avx to use AVX instructions
+// so that we can select it at runtime when AVX is available.
+// Clang on Windows has gnu::target but does not make AVX types like __m256i
+// available when trying to force specific functions to use AVX compiles.
+#if ABSL_HAVE_CPP_ATTRIBUTE(gnu::target) && !defined(_MSC_VER) && \
+ (defined(__x86_64__) || defined(__i386__))
+#define ABSL_INTERNAL_CAN_FORCE_AVX 1
+#endif
+
// If the objects overlap, the behavior is undefined. Uses regular memcpy
// instead of non-temporal memcpy if the required CPU intrinsics are unavailable
// at compile time.
-#if ABSL_HAVE_CPP_ATTRIBUTE(gnu::target) && \
- (defined(__x86_64__) || defined(__i386__))
+#ifdef ABSL_INTERNAL_CAN_FORCE_AVX
[[gnu::target("avx")]]
#endif
inline void *non_temporal_store_memcpy_avx(void *__restrict dst,
const void *__restrict src,
size_t len) {
- // This function requires AVX. For clang and gcc we compile it with AVX even
- // if the translation unit isn't built with AVX support. This works because we
- // only select this implementation at runtime if the CPU supports AVX.
-#if defined(__SSE3__) || (defined(_MSC_VER) && defined(__AVX__))
+ // This function requires AVX. If possible we compile it with AVX even if the
+ // translation unit isn't built with AVX support. This works because we only
+ // select this implementation at runtime if the CPU supports AVX.
+ // MSVC AVX support implies SSE3 support.
+#if ((defined(__AVX__) || defined(ABSL_INTERNAL_CAN_FORCE_AVX)) && \
+ defined(__SSE3__)) || \
+ (defined(_MSC_VER) && defined(__AVX__))
uint8_t *d = reinterpret_cast<uint8_t *>(dst);
const uint8_t *s = reinterpret_cast<const uint8_t *>(src);
@@ -170,10 +181,13 @@ inline void *non_temporal_store_memcpy_avx(void *__restrict dst,
}
return dst;
#else
+ // Fallback to regular memcpy so that this function compiles.
return memcpy(dst, src, len);
-#endif // __SSE3__ || (_MSC_VER && __AVX__)
+#endif
}
+#undef ABSL_INTERNAL_CAN_FORCE_AVX
+
} // namespace crc_internal
ABSL_NAMESPACE_END
} // namespace absl
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 570d1e504d..d31f5a1f4e 100644
--- a/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.cc
+++ b/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.cc
@@ -21,6 +21,7 @@
#ifdef _WIN32
#include <windows.h>
#else
+#include <pthread.h>
#include <sched.h>
#include <unistd.h>
#endif
@@ -65,6 +66,23 @@
#endif
#endif
+// ABSL_HAVE_PTHREAD_CPU_NUMBER_NP
+//
+// Checks whether pthread_cpu_number_np is available.
+#ifdef ABSL_HAVE_PTHREAD_CPU_NUMBER_NP
+#error ABSL_HAVE_PTHREAD_CPU_NUMBER_NP cannot be directly set
+#elif defined(__APPLE__) && defined(__has_include) && \
+ ((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
+ __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 110000) || \
+ (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \
+ __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 140200) || \
+ (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && \
+ __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ >= 70100) || \
+ (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && \
+ __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ >= 140200))
+#define ABSL_HAVE_PTHREAD_CPU_NUMBER_NP 1
+#endif
+
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -330,6 +348,20 @@ static void ImmediateAbortSignalHandler(int) { RaiseToDefaultHandler(SIGABRT); }
using GetTidType = decltype(absl::base_internal::GetTID());
ABSL_CONST_INIT static std::atomic<GetTidType> failed_tid(0);
+static int GetCpuNumber() {
+#ifdef ABSL_HAVE_SCHED_GETCPU
+ return sched_getcpu();
+#elif defined(ABSL_HAVE_PTHREAD_CPU_NUMBER_NP)
+ size_t cpu_num;
+ if (pthread_cpu_number_np(&cpu_num) == 0) {
+ return static_cast<int>(cpu_num);
+ }
+ return -1;
+#else
+ return -1;
+#endif
+}
+
#ifndef ABSL_HAVE_SIGACTION
static void AbslFailureSignalHandler(int signo) {
void* ucontext = nullptr;
@@ -360,10 +392,7 @@ static void AbslFailureSignalHandler(int signo, siginfo_t*, void* ucontext) {
// Increase the chance that the CPU we report was the same CPU on which the
// signal was received by doing this as early as possible, i.e. after
// verifying that this is not a recursive signal handler invocation.
- int my_cpu = -1;
-#ifdef ABSL_HAVE_SCHED_GETCPU
- my_cpu = sched_getcpu();
-#endif
+ int my_cpu = GetCpuNumber();
#ifdef ABSL_HAVE_ALARM
// Set an alarm to abort the program in case this code hangs or deadlocks.
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 19c4952e2f..1fac29c52b 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
@@ -35,7 +35,7 @@
#if defined(__ELF__) && !defined(__OpenBSD__) && !defined(__QNX__) && \
!defined(__native_client__) && !defined(__asmjs__) && \
!defined(__wasm__) && !defined(__HAIKU__) && !defined(__sun) && \
- !defined(__VXWORKS__) && !defined(__hexagon__)
+ !defined(__VXWORKS__) && !defined(__hexagon__) && !defined(__XTENSA__)
#define ABSL_HAVE_ELF_MEM_IMAGE 1
#endif
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..f5ba5575d1 100644
--- a/contrib/restricted/abseil-cpp/absl/debugging/internal/stack_consumption.h
+++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/stack_consumption.h
@@ -24,7 +24,7 @@
// Use this feature test macro to detect its availability.
#ifdef ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION
#error ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION cannot be set directly
-#elif !defined(__APPLE__) && !defined(_WIN32) && \
+#elif !defined(__APPLE__) && !defined(_WIN32) && !defined(__Fuchsia__) && \
(defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || \
defined(__aarch64__) || defined(__riscv))
#define ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION 1
diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc
index b123479b1a..4490c4e13c 100644
--- a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc
+++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc
@@ -178,6 +178,20 @@ static void **NextStackFrame(void **old_frame_pointer, const void *uc,
return new_frame_pointer;
}
+// When PAC-RET (-mbranch-protection=pac-ret) is enabled, return addresses
+// stored on the stack will be signed, which means that pointer bits outside of
+// the VA range are potentially set. Since the stacktrace code is expected to
+// return normal code pointers, this function clears those bits.
+inline void* ClearPacBits(void* ptr) {
+ register void* x30 __asm__("x30") = ptr;
+ // The normal instruction for clearing PAC bits is XPACI, but for
+ // compatibility with ARM platforms that do not support pointer
+ // authentication, we use the hint space instruction XPACLRI instead. Hint
+ // space instructions behave as NOPs on unsupported platforms.
+ asm("xpaclri" : "+r"(x30));
+ return x30;
+}
+
template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT>
// We count on the bottom frame being this one. See the comment
// at prev_return_address
@@ -219,7 +233,7 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count,
if (skip_count > 0) {
skip_count--;
} else {
- result[n] = prev_return_address;
+ result[n] = ClearPacBits(prev_return_address);
if (IS_STACK_FRAMES) {
sizes[n] = static_cast<int>(
ComputeStackFrameSize(prev_frame_pointer, frame_pointer));
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 3929b1b734..88949fe974 100644
--- a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_config.h
+++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_config.h
@@ -42,6 +42,13 @@
#define ABSL_STACKTRACE_INL_HEADER \
"absl/debugging/internal/stacktrace_emscripten-inl.inc"
+#elif defined(__ANDROID__) && __ANDROID_API__ >= 33
+
+// Use the generic implementation for Android 33+ (Android T+). This is the
+// first version of Android for which <execinfo.h> implements backtrace().
+#define ABSL_STACKTRACE_INL_HEADER \
+ "absl/debugging/internal/stacktrace_generic-inl.inc"
+
#elif defined(__linux__) && !defined(__ANDROID__)
#if defined(NO_FRAME_POINTER) && \
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 20183fa321..3f9e12407a 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
@@ -36,15 +36,16 @@
#include "absl/base/attributes.h"
#include "absl/debugging/stacktrace.h"
-static const uintptr_t kUnknownFrameSize = 0;
+static constexpr ptrdiff_t kUnknownFrameSize = 0;
// 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) {
+static inline ptrdiff_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;
+ return low < high ? static_cast<ptrdiff_t>(high_char_ptr - low_char_ptr)
+ : kUnknownFrameSize;
}
// Given a pointer to a stack frame, locate and return the calling stackframe,
@@ -93,8 +94,8 @@ static void ** NextStackFrame(void **old_frame_pointer, const void *uc,
// 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.
- const uintptr_t max_size = STRICT_UNWINDING ? 100000 : 1000000;
- const uintptr_t frame_size =
+ const ptrdiff_t max_size = STRICT_UNWINDING ? 100000 : 1000000;
+ const ptrdiff_t frame_size =
ComputeStackFrameSize(old_frame_pointer, new_frame_pointer);
if (frame_size == kUnknownFrameSize) {
if (STRICT_UNWINDING)
@@ -151,7 +152,9 @@ static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count,
} else {
result[n] = return_address;
if (IS_STACK_FRAMES) {
- sizes[n] = ComputeStackFrameSize(frame_pointer, next_frame_pointer);
+ // NextStackFrame() has already checked that frame size fits to int
+ sizes[n] = static_cast<int>(ComputeStackFrameSize(frame_pointer,
+ next_frame_pointer));
}
n++;
}
diff --git a/contrib/restricted/abseil-cpp/absl/debugging/leak_check.cc b/contrib/restricted/abseil-cpp/absl/debugging/leak_check.cc
index fdb8798b81..1370bcc455 100644
--- a/contrib/restricted/abseil-cpp/absl/debugging/leak_check.cc
+++ b/contrib/restricted/abseil-cpp/absl/debugging/leak_check.cc
@@ -28,7 +28,7 @@
#include <sanitizer/lsan_interface.h>
#if ABSL_HAVE_ATTRIBUTE_WEAK
-extern "C" ABSL_ATTRIBUTE_WEAK int __lsan_is_turned_off();
+extern "C" ABSL_ATTRIBUTE_WEAK int __lsan_is_turned_off() { return 0; }
#endif
namespace absl {
@@ -37,13 +37,13 @@ bool HaveLeakSanitizer() { return true; }
#if ABSL_HAVE_ATTRIBUTE_WEAK
bool LeakCheckerIsActive() {
- return !(&__lsan_is_turned_off && __lsan_is_turned_off());
+ return __lsan_is_turned_off() == 0;
}
#else
bool LeakCheckerIsActive() { return true; }
#endif
-bool FindAndReportLeaks() { return __lsan_do_recoverable_leak_check(); }
+bool FindAndReportLeaks() { return __lsan_do_recoverable_leak_check() != 0; }
void DoIgnoreLeak(const void* ptr) { __lsan_ignore_object(ptr); }
void RegisterLivePointers(const void* ptr, size_t size) {
__lsan_register_root_region(ptr, size);
diff --git a/contrib/restricted/abseil-cpp/absl/debugging/symbolize.cc b/contrib/restricted/abseil-cpp/absl/debugging/symbolize.cc
index 638d3954ae..344436f9d1 100644
--- a/contrib/restricted/abseil-cpp/absl/debugging/symbolize.cc
+++ b/contrib/restricted/abseil-cpp/absl/debugging/symbolize.cc
@@ -12,12 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+// SKIP_ABSL_INLINE_NAMESPACE_CHECK
+
#include "absl/debugging/symbolize.h"
#ifdef _WIN32
#include <winapifamily.h>
-#if !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)) || \
- WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
// UWP doesn't have access to win32 APIs.
#define ABSL_INTERNAL_HAVE_SYMBOLIZE_WIN32
#endif
diff --git a/contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc b/contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc
index ae75cd4153..a98ca81d17 100644
--- a/contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc
+++ b/contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc
@@ -52,6 +52,7 @@
#include <elf.h>
#include <fcntl.h>
#include <link.h> // For ElfW() macro.
+#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
@@ -376,6 +377,46 @@ class Symbolizer {
SymbolCacheLine symbol_cache_[SYMBOL_CACHE_LINES];
};
+// Protect against client code closing low-valued file descriptors it doesn't
+// actually own.
+int OpenReadOnlyWithHighFD(const char *fname) {
+ static int high_fd = [] {
+ struct rlimit rlim{};
+ const int rc = getrlimit(RLIMIT_NOFILE, &rlim);
+ if (rc == 0 && rlim.rlim_cur >= 2000) {
+ const int max_fd = static_cast<int>(rlim.rlim_cur);
+
+ // This will return 2000 on reasonably-configured systems.
+ return std::min<int>(2000, max_fd - 1000);
+ }
+ ABSL_RAW_LOG(WARNING, "Unable to get high fd: rc=%d, limit=%ld", //
+ rc, static_cast<long>(rlim.rlim_cur));
+ return -1;
+ }();
+ constexpr int kOpenFlags = O_RDONLY | O_CLOEXEC;
+ if (high_fd >= 1000) {
+ const int fd = open(fname, kOpenFlags);
+ if (fd != -1 && fd < high_fd) {
+ // Try to relocate fd to high range.
+ static_assert(kOpenFlags & O_CLOEXEC,
+ "F_DUPFD_CLOEXEC assumes O_CLOEXEC");
+ const int fd2 = fcntl(fd, F_DUPFD_CLOEXEC, high_fd);
+ if (fd2 != -1) {
+ // Successfully obtained high fd. Use it.
+ close(fd);
+ return fd2;
+ } else {
+ ABSL_RAW_LOG(WARNING, "Unable to dup fd=%d above %d, errno=%d", fd,
+ high_fd, errno);
+ }
+ }
+ // Either open failed and fd==-1, or fd is already above high_fd, or fcntl
+ // failed and fd is valid (but low).
+ return fd;
+ }
+ return open(fname, kOpenFlags);
+}
+
static std::atomic<Symbolizer *> g_cached_symbolizer;
} // namespace
@@ -541,11 +582,9 @@ static ABSL_ATTRIBUTE_NOINLINE bool GetSectionHeaderByType(
(buf_bytes > num_bytes_left) ? num_bytes_left : buf_bytes;
const off_t offset = sh_offset + static_cast<off_t>(i * sizeof(buf[0]));
const ssize_t len = file->ReadFromOffset(buf, num_bytes_to_read, offset);
- if (len < 0) {
- ABSL_RAW_LOG(
- WARNING,
- "Reading %zu bytes from offset %ju returned %zd which is negative.",
- num_bytes_to_read, static_cast<intmax_t>(offset), len);
+ if (len <= 0) {
+ ABSL_RAW_LOG(WARNING, "Reading %zu bytes from offset %ju returned %zd.",
+ num_bytes_to_read, static_cast<intmax_t>(offset), len);
return false;
}
if (static_cast<size_t>(len) % sizeof(buf[0]) != 0) {
@@ -1066,7 +1105,7 @@ static ABSL_ATTRIBUTE_NOINLINE bool ReadAddrMap(
snprintf(maps_path, sizeof(maps_path), "/proc/self/task/%d/maps", getpid());
int maps_fd;
- NO_INTR(maps_fd = open(maps_path, O_RDONLY));
+ NO_INTR(maps_fd = OpenReadOnlyWithHighFD(maps_path));
FileDescriptor wrapped_maps_fd(maps_fd);
if (wrapped_maps_fd.get() < 0) {
ABSL_RAW_LOG(WARNING, "%s: errno=%d", maps_path, errno);
@@ -1340,7 +1379,7 @@ static void MaybeOpenFdFromSelfExe(ObjFile *obj) {
if (memcmp(obj->start_addr, ELFMAG, SELFMAG) != 0) {
return;
}
- int fd = open("/proc/self/exe", O_RDONLY);
+ int fd = OpenReadOnlyWithHighFD("/proc/self/exe");
if (fd == -1) {
return;
}
@@ -1364,7 +1403,7 @@ static void MaybeOpenFdFromSelfExe(ObjFile *obj) {
static bool MaybeInitializeObjFile(ObjFile *obj) {
if (obj->fd < 0) {
- obj->fd = open(obj->filename, O_RDONLY);
+ obj->fd = OpenReadOnlyWithHighFD(obj->filename);
if (obj->fd < 0) {
// Getting /proc/self/exe here means that we were hinted.
@@ -1372,7 +1411,7 @@ static bool MaybeInitializeObjFile(ObjFile *obj) {
// /proc/self/exe may be inaccessible (due to setuid, etc.), so try
// accessing the binary via argv0.
if (argv0_value != nullptr) {
- obj->fd = open(argv0_value, O_RDONLY);
+ obj->fd = OpenReadOnlyWithHighFD(argv0_value);
}
} else {
MaybeOpenFdFromSelfExe(obj);
diff --git a/contrib/restricted/abseil-cpp/absl/debugging/ya.make b/contrib/restricted/abseil-cpp/absl/debugging/ya.make
index 3c3aa2d8bc..cff58f5fc8 100644
--- a/contrib/restricted/abseil-cpp/absl/debugging/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/debugging/ya.make
@@ -6,7 +6,7 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20240722.1)
+VERSION(20250127.0)
PEERDIR(
contrib/restricted/abseil-cpp/absl/base
diff --git a/contrib/restricted/abseil-cpp/absl/flags/commandlineflag.cc b/contrib/restricted/abseil-cpp/absl/flags/commandlineflag.cc
index 9f3b4a5a28..4140230651 100644
--- a/contrib/restricted/abseil-cpp/absl/flags/commandlineflag.cc
+++ b/contrib/restricted/abseil-cpp/absl/flags/commandlineflag.cc
@@ -24,6 +24,7 @@
namespace absl {
ABSL_NAMESPACE_BEGIN
+absl::string_view CommandLineFlag::TypeName() const { return ""; }
bool CommandLineFlag::IsRetired() const { return false; }
bool CommandLineFlag::ParseFrom(absl::string_view value, std::string* error) {
return ParseFrom(value, flags_internal::SET_FLAGS_VALUE,
diff --git a/contrib/restricted/abseil-cpp/absl/flags/commandlineflag.h b/contrib/restricted/abseil-cpp/absl/flags/commandlineflag.h
index 26ec0e7d84..a9ffd02084 100644
--- a/contrib/restricted/abseil-cpp/absl/flags/commandlineflag.h
+++ b/contrib/restricted/abseil-cpp/absl/flags/commandlineflag.h
@@ -200,6 +200,13 @@ class CommandLineFlag {
// Checks that flags default value can be converted to string and back to the
// flag's value type.
virtual void CheckDefaultValueParsingRoundtrip() const = 0;
+
+ // absl::CommandLineFlag::TypeName()
+ //
+ // Returns string representation of the type of this flag
+ // (the way it is spelled in the ABSL_FLAG macro).
+ // The default implementation returns the empty string.
+ virtual absl::string_view TypeName() const;
};
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
diff --git a/contrib/restricted/abseil-cpp/absl/flags/flag.h b/contrib/restricted/abseil-cpp/absl/flags/flag.h
index a8e0e93299..19d0ef992f 100644
--- a/contrib/restricted/abseil-cpp/absl/flags/flag.h
+++ b/contrib/restricted/abseil-cpp/absl/flags/flag.h
@@ -204,12 +204,14 @@ ABSL_NAMESPACE_END
#if ABSL_FLAGS_STRIP_NAMES
#define ABSL_FLAG_IMPL_FLAGNAME(txt) ""
+#define ABSL_FLAG_IMPL_TYPENAME(txt) ""
#define ABSL_FLAG_IMPL_FILENAME() ""
#define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \
absl::flags_internal::FlagRegistrar<T, false>(ABSL_FLAG_IMPL_FLAG_PTR(flag), \
nullptr)
#else
#define ABSL_FLAG_IMPL_FLAGNAME(txt) txt
+#define ABSL_FLAG_IMPL_TYPENAME(txt) txt
#define ABSL_FLAG_IMPL_FILENAME() __FILE__
#define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \
absl::flags_internal::FlagRegistrar<T, true>(ABSL_FLAG_IMPL_FLAG_PTR(flag), \
@@ -261,16 +263,17 @@ ABSL_NAMESPACE_END
// Note: Name of registrar object is not arbitrary. It is used to "grab"
// global name for FLAGS_no<flag_name> symbol, thus preventing the possibility
// of defining two flags with names foo and nofoo.
-#define ABSL_FLAG_IMPL(Type, name, default_value, help) \
- extern ::absl::Flag<Type> FLAGS_##name; \
- namespace absl /* block flags in namespaces */ {} \
- ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value) \
- ABSL_FLAG_IMPL_DECLARE_HELP_WRAPPER(name, help) \
- ABSL_CONST_INIT absl::Flag<Type> FLAGS_##name{ \
- ABSL_FLAG_IMPL_FLAGNAME(#name), ABSL_FLAG_IMPL_FILENAME(), \
- ABSL_FLAG_IMPL_HELP_ARG(name), ABSL_FLAG_IMPL_DEFAULT_ARG(Type, name)}; \
- extern absl::flags_internal::FlagRegistrarEmpty FLAGS_no##name; \
- absl::flags_internal::FlagRegistrarEmpty FLAGS_no##name = \
+#define ABSL_FLAG_IMPL(Type, name, default_value, help) \
+ extern ::absl::Flag<Type> FLAGS_##name; \
+ namespace absl /* block flags in namespaces */ {} \
+ ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value) \
+ ABSL_FLAG_IMPL_DECLARE_HELP_WRAPPER(name, help) \
+ ABSL_CONST_INIT absl::Flag<Type> FLAGS_##name{ \
+ ABSL_FLAG_IMPL_FLAGNAME(#name), ABSL_FLAG_IMPL_TYPENAME(#Type), \
+ ABSL_FLAG_IMPL_FILENAME(), ABSL_FLAG_IMPL_HELP_ARG(name), \
+ ABSL_FLAG_IMPL_DEFAULT_ARG(Type, name)}; \
+ extern absl::flags_internal::FlagRegistrarEmpty FLAGS_no##name; \
+ absl::flags_internal::FlagRegistrarEmpty FLAGS_no##name = \
ABSL_FLAG_IMPL_REGISTRAR(Type, FLAGS_##name)
// ABSL_RETIRED_FLAG
@@ -290,8 +293,7 @@ ABSL_NAMESPACE_END
// arguments unchanged (unless of course you actually want to retire the flag
// type at this time as well).
//
-// `default_value` is only used as a double check on the type. `explanation` is
-// unused.
+// `default_value` and `explanation` are unused.
// TODO(rogeeff): replace RETIRED_FLAGS with FLAGS once forward declarations of
// retired flags are cleaned up.
#define ABSL_RETIRED_FLAG(type, name, default_value, explanation) \
diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/flag.cc b/contrib/restricted/abseil-cpp/absl/flags/internal/flag.cc
index 981f19fdb8..ccd26670cf 100644
--- a/contrib/restricted/abseil-cpp/absl/flags/internal/flag.cc
+++ b/contrib/restricted/abseil-cpp/absl/flags/internal/flag.cc
@@ -34,7 +34,9 @@
#include "absl/base/config.h"
#include "absl/base/const_init.h"
#include "absl/base/dynamic_annotations.h"
+#include "absl/base/no_destructor.h"
#include "absl/base/optimization.h"
+#include "absl/base/thread_annotations.h"
#include "absl/flags/config.h"
#include "absl/flags/internal/commandlineflag.h"
#include "absl/flags/usage_config.h"
@@ -85,11 +87,15 @@ class MutexRelock {
// we move the memory to the freelist where it lives indefinitely, so it can
// still be safely accessed. This also prevents leak checkers from complaining
// about the leaked memory that can no longer be accessed through any pointer.
-ABSL_CONST_INIT absl::Mutex s_freelist_guard(absl::kConstInit);
-ABSL_CONST_INIT std::vector<void*>* s_freelist = nullptr;
+absl::Mutex* FreelistMutex() {
+ static absl::NoDestructor<absl::Mutex> mutex;
+ return mutex.get();
+}
+ABSL_CONST_INIT std::vector<void*>* s_freelist ABSL_GUARDED_BY(FreelistMutex())
+ ABSL_PT_GUARDED_BY(FreelistMutex()) = nullptr;
void AddToFreelist(void* p) {
- absl::MutexLock l(&s_freelist_guard);
+ absl::MutexLock l(FreelistMutex());
if (!s_freelist) {
s_freelist = new std::vector<void*>;
}
@@ -101,7 +107,7 @@ void AddToFreelist(void* p) {
///////////////////////////////////////////////////////////////////////////////
uint64_t NumLeakedFlagValues() {
- absl::MutexLock l(&s_freelist_guard);
+ absl::MutexLock l(FreelistMutex());
return s_freelist == nullptr ? 0u : s_freelist->size();
}
@@ -336,6 +342,8 @@ void FlagImpl::StoreValue(const void* src, ValueSource source) {
absl::string_view FlagImpl::Name() const { return name_; }
+absl::string_view FlagImpl::TypeName() const { return type_name_; }
+
std::string FlagImpl::Filename() const {
return flags_internal::GetUsageConfig().normalize_filename(filename_);
}
diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/flag.h b/contrib/restricted/abseil-cpp/absl/flags/internal/flag.h
index a0be31d93a..a6e7986f96 100644
--- a/contrib/restricted/abseil-cpp/absl/flags/internal/flag.h
+++ b/contrib/restricted/abseil-cpp/absl/flags/internal/flag.h
@@ -373,9 +373,13 @@ class MaskedPointer {
static constexpr int RequiredAlignment() { return 4; }
+ constexpr MaskedPointer() : ptr_(nullptr) {}
constexpr explicit MaskedPointer(ptr_t rhs) : ptr_(rhs) {}
MaskedPointer(ptr_t rhs, bool is_candidate);
+ MaskedPointer(const MaskedPointer& rhs) = default;
+ MaskedPointer& operator=(const MaskedPointer& rhs) = default;
+
void* Ptr() const {
return reinterpret_cast<void*>(reinterpret_cast<mask_t>(ptr_) &
kPtrValueMask);
@@ -578,10 +582,12 @@ class FlagState;
#endif
class FlagImpl final : public CommandLineFlag {
public:
- constexpr FlagImpl(const char* name, const char* filename, FlagOpFn op,
- FlagHelpArg help, FlagValueStorageKind value_kind,
+ constexpr FlagImpl(const char* name, const char* type_name,
+ const char* filename, FlagOpFn op, FlagHelpArg help,
+ FlagValueStorageKind value_kind,
FlagDefaultArg default_arg)
: name_(name),
+ type_name_(type_name),
filename_(filename),
op_(op),
help_(help.source),
@@ -694,6 +700,7 @@ class FlagImpl final : public CommandLineFlag {
// CommandLineFlag interface implementation
absl::string_view Name() const override;
+ absl::string_view TypeName() const override;
std::string Filename() const override;
std::string Help() const override;
FlagFastTypeId TypeId() const override;
@@ -727,6 +734,10 @@ class FlagImpl final : public CommandLineFlag {
// Flags name passed to ABSL_FLAG as second arg.
const char* const name_;
+
+ // Flags type passed to ABSL_FLAG as first arg.
+ const char* const type_name_;
+
// The file name where ABSL_FLAG resides.
const char* const filename_;
// Type-specific operations vtable.
@@ -785,9 +796,9 @@ class FlagImpl final : public CommandLineFlag {
template <typename T>
class Flag {
public:
- constexpr Flag(const char* name, const char* filename, FlagHelpArg help,
- const FlagDefaultArg default_arg)
- : impl_(name, filename, &FlagOps<T>, help,
+ constexpr Flag(const char* name, const char* type_name, const char* filename,
+ FlagHelpArg help, const FlagDefaultArg default_arg)
+ : impl_(name, type_name, filename, &FlagOps<T>, help,
flags_internal::StorageKind<T>(), default_arg),
value_() {}
diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor.cc b/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor.cc
index a7eb58b6d4..610d1ffdf7 100644
--- a/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor.cc
+++ b/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor.cc
@@ -59,6 +59,10 @@ bool PrivateHandleAccessor::ParseFrom(CommandLineFlag& flag,
return flag.ParseFrom(value, set_mode, source, error);
}
+absl::string_view PrivateHandleAccessor::TypeName(const CommandLineFlag& flag) {
+ return flag.TypeName();
+}
+
} // namespace flags_internal
ABSL_NAMESPACE_END
} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor.h b/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor.h
index c64435cd61..bf4154c5a5 100644
--- a/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor.h
+++ b/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor.h
@@ -52,6 +52,9 @@ class PrivateHandleAccessor {
static bool ParseFrom(CommandLineFlag& flag, absl::string_view value,
flags_internal::FlagSettingMode set_mode,
flags_internal::ValueSource source, std::string& error);
+
+ // Access to CommandLineFlag::TypeName.
+ static absl::string_view TypeName(const CommandLineFlag& flag);
};
} // namespace flags_internal
diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/program_name.cc b/contrib/restricted/abseil-cpp/absl/flags/internal/program_name.cc
index 51d698da8b..fb06643df5 100644
--- a/contrib/restricted/abseil-cpp/absl/flags/internal/program_name.cc
+++ b/contrib/restricted/abseil-cpp/absl/flags/internal/program_name.cc
@@ -19,7 +19,7 @@
#include "absl/base/attributes.h"
#include "absl/base/config.h"
-#include "absl/base/const_init.h"
+#include "absl/base/no_destructor.h"
#include "absl/base/thread_annotations.h"
#include "absl/flags/internal/path_util.h"
#include "absl/strings/string_view.h"
@@ -29,30 +29,31 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
namespace flags_internal {
-ABSL_CONST_INIT static absl::Mutex program_name_guard(absl::kConstInit);
-ABSL_CONST_INIT static std::string* program_name
- ABSL_GUARDED_BY(program_name_guard) = nullptr;
+static absl::Mutex* ProgramNameMutex() {
+ static absl::NoDestructor<absl::Mutex> mutex;
+ return mutex.get();
+}
+ABSL_CONST_INIT static std::string* program_name ABSL_GUARDED_BY(
+ ProgramNameMutex()) ABSL_PT_GUARDED_BY(ProgramNameMutex()) = nullptr;
std::string ProgramInvocationName() {
- absl::MutexLock l(&program_name_guard);
-
+ absl::MutexLock l(ProgramNameMutex());
return program_name ? *program_name : "UNKNOWN";
}
std::string ShortProgramInvocationName() {
- absl::MutexLock l(&program_name_guard);
-
+ absl::MutexLock l(ProgramNameMutex());
return program_name ? std::string(flags_internal::Basename(*program_name))
: "UNKNOWN";
}
void SetProgramInvocationName(absl::string_view prog_name_str) {
- absl::MutexLock l(&program_name_guard);
-
- if (!program_name)
+ absl::MutexLock l(ProgramNameMutex());
+ if (!program_name) {
program_name = new std::string(prog_name_str);
- else
+ } else {
program_name->assign(prog_name_str.data(), prog_name_str.size());
+ }
}
} // namespace flags_internal
diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/usage.cc b/contrib/restricted/abseil-cpp/absl/flags/internal/usage.cc
index 8b169bcdc2..fc68b03db2 100644
--- a/contrib/restricted/abseil-cpp/absl/flags/internal/usage.cc
+++ b/contrib/restricted/abseil-cpp/absl/flags/internal/usage.cc
@@ -29,7 +29,7 @@
#include "absl/base/attributes.h"
#include "absl/base/config.h"
-#include "absl/base/const_init.h"
+#include "absl/base/no_destructor.h"
#include "absl/base/thread_annotations.h"
#include "absl/flags/commandlineflag.h"
#include "absl/flags/flag.h"
@@ -434,45 +434,48 @@ HelpMode HandleUsageFlags(std::ostream& out,
namespace {
-ABSL_CONST_INIT absl::Mutex help_attributes_guard(absl::kConstInit);
-ABSL_CONST_INIT std::string* match_substr
- ABSL_GUARDED_BY(help_attributes_guard) = nullptr;
-ABSL_CONST_INIT HelpMode help_mode ABSL_GUARDED_BY(help_attributes_guard) =
+absl::Mutex* HelpAttributesMutex() {
+ static absl::NoDestructor<absl::Mutex> mutex;
+ return mutex.get();
+}
+ABSL_CONST_INIT std::string* match_substr ABSL_GUARDED_BY(HelpAttributesMutex())
+ ABSL_PT_GUARDED_BY(HelpAttributesMutex()) = nullptr;
+ABSL_CONST_INIT HelpMode help_mode ABSL_GUARDED_BY(HelpAttributesMutex()) =
HelpMode::kNone;
-ABSL_CONST_INIT HelpFormat help_format ABSL_GUARDED_BY(help_attributes_guard) =
+ABSL_CONST_INIT HelpFormat help_format ABSL_GUARDED_BY(HelpAttributesMutex()) =
HelpFormat::kHumanReadable;
} // namespace
std::string GetFlagsHelpMatchSubstr() {
- absl::MutexLock l(&help_attributes_guard);
+ absl::MutexLock l(HelpAttributesMutex());
if (match_substr == nullptr) return "";
return *match_substr;
}
void SetFlagsHelpMatchSubstr(absl::string_view substr) {
- absl::MutexLock l(&help_attributes_guard);
+ absl::MutexLock l(HelpAttributesMutex());
if (match_substr == nullptr) match_substr = new std::string;
match_substr->assign(substr.data(), substr.size());
}
HelpMode GetFlagsHelpMode() {
- absl::MutexLock l(&help_attributes_guard);
+ absl::MutexLock l(HelpAttributesMutex());
return help_mode;
}
void SetFlagsHelpMode(HelpMode mode) {
- absl::MutexLock l(&help_attributes_guard);
+ absl::MutexLock l(HelpAttributesMutex());
help_mode = mode;
}
HelpFormat GetFlagsHelpFormat() {
- absl::MutexLock l(&help_attributes_guard);
+ absl::MutexLock l(HelpAttributesMutex());
return help_format;
}
void SetFlagsHelpFormat(HelpFormat format) {
- absl::MutexLock l(&help_attributes_guard);
+ absl::MutexLock l(HelpAttributesMutex());
help_format = format;
}
diff --git a/contrib/restricted/abseil-cpp/absl/flags/parse.cc b/contrib/restricted/abseil-cpp/absl/flags/parse.cc
index 526b61d1d1..8be2016fd6 100644
--- a/contrib/restricted/abseil-cpp/absl/flags/parse.cc
+++ b/contrib/restricted/abseil-cpp/absl/flags/parse.cc
@@ -35,7 +35,7 @@
#include "absl/algorithm/container.h"
#include "absl/base/attributes.h"
#include "absl/base/config.h"
-#include "absl/base/const_init.h"
+#include "absl/base/no_destructor.h"
#include "absl/base/thread_annotations.h"
#include "absl/flags/commandlineflag.h"
#include "absl/flags/config.h"
@@ -64,14 +64,17 @@ ABSL_NAMESPACE_BEGIN
namespace flags_internal {
namespace {
-ABSL_CONST_INIT absl::Mutex processing_checks_guard(absl::kConstInit);
+absl::Mutex* ProcessingChecksMutex() {
+ static absl::NoDestructor<absl::Mutex> mutex;
+ return mutex.get();
+}
ABSL_CONST_INIT bool flagfile_needs_processing
- ABSL_GUARDED_BY(processing_checks_guard) = false;
+ ABSL_GUARDED_BY(ProcessingChecksMutex()) = false;
ABSL_CONST_INIT bool fromenv_needs_processing
- ABSL_GUARDED_BY(processing_checks_guard) = false;
+ ABSL_GUARDED_BY(ProcessingChecksMutex()) = false;
ABSL_CONST_INIT bool tryfromenv_needs_processing
- ABSL_GUARDED_BY(processing_checks_guard) = false;
+ ABSL_GUARDED_BY(ProcessingChecksMutex()) = false;
ABSL_CONST_INIT absl::Mutex specified_flags_guard(absl::kConstInit);
ABSL_CONST_INIT std::vector<const CommandLineFlag*>* specified_flags
@@ -106,7 +109,7 @@ ABSL_FLAG(std::vector<std::string>, flagfile, {},
.OnUpdate([]() {
if (absl::GetFlag(FLAGS_flagfile).empty()) return;
- absl::MutexLock l(&absl::flags_internal::processing_checks_guard);
+ absl::MutexLock l(absl::flags_internal::ProcessingChecksMutex());
// Setting this flag twice before it is handled most likely an internal
// error and should be reviewed by developers.
@@ -122,7 +125,7 @@ ABSL_FLAG(std::vector<std::string>, fromenv, {},
.OnUpdate([]() {
if (absl::GetFlag(FLAGS_fromenv).empty()) return;
- absl::MutexLock l(&absl::flags_internal::processing_checks_guard);
+ absl::MutexLock l(absl::flags_internal::ProcessingChecksMutex());
// Setting this flag twice before it is handled most likely an internal
// error and should be reviewed by developers.
@@ -138,7 +141,7 @@ ABSL_FLAG(std::vector<std::string>, tryfromenv, {},
.OnUpdate([]() {
if (absl::GetFlag(FLAGS_tryfromenv).empty()) return;
- absl::MutexLock l(&absl::flags_internal::processing_checks_guard);
+ absl::MutexLock l(absl::flags_internal::ProcessingChecksMutex());
// Setting this flag twice before it is handled most likely an internal
// error and should be reviewed by developers.
@@ -415,7 +418,7 @@ bool HandleGeneratorFlags(std::vector<ArgsList>& input_args,
std::vector<std::string>& flagfile_value) {
bool success = true;
- absl::MutexLock l(&flags_internal::processing_checks_guard);
+ absl::MutexLock l(flags_internal::ProcessingChecksMutex());
// flagfile could have been set either on a command line or
// programmatically before invoking ParseCommandLine. Note that we do not
@@ -478,7 +481,7 @@ void ResetGeneratorFlags(const std::vector<std::string>& flagfile_value) {
// going to be {"f1", "f2"}
if (!flagfile_value.empty()) {
absl::SetFlag(&FLAGS_flagfile, flagfile_value);
- absl::MutexLock l(&flags_internal::processing_checks_guard);
+ absl::MutexLock l(flags_internal::ProcessingChecksMutex());
flags_internal::flagfile_needs_processing = false;
}
@@ -490,7 +493,7 @@ void ResetGeneratorFlags(const std::vector<std::string>& flagfile_value) {
absl::SetFlag(&FLAGS_tryfromenv, {});
}
- absl::MutexLock l(&flags_internal::processing_checks_guard);
+ absl::MutexLock l(flags_internal::ProcessingChecksMutex());
flags_internal::fromenv_needs_processing = false;
flags_internal::tryfromenv_needs_processing = false;
}
diff --git a/contrib/restricted/abseil-cpp/absl/flags/usage_config.cc b/contrib/restricted/abseil-cpp/absl/flags/usage_config.cc
index 5d7426db31..5922c5e20f 100644
--- a/contrib/restricted/abseil-cpp/absl/flags/usage_config.cc
+++ b/contrib/restricted/abseil-cpp/absl/flags/usage_config.cc
@@ -22,6 +22,7 @@
#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/const_init.h"
+#include "absl/base/no_destructor.h"
#include "absl/base/thread_annotations.h"
#include "absl/flags/internal/path_util.h"
#include "absl/flags/internal/program_name.h"
@@ -104,14 +105,18 @@ std::string NormalizeFilename(absl::string_view filename) {
// --------------------------------------------------------------------
-ABSL_CONST_INIT absl::Mutex custom_usage_config_guard(absl::kConstInit);
+absl::Mutex* CustomUsageConfigMutex() {
+ static absl::NoDestructor<absl::Mutex> mutex;
+ return mutex.get();
+}
ABSL_CONST_INIT FlagsUsageConfig* custom_usage_config
- ABSL_GUARDED_BY(custom_usage_config_guard) = nullptr;
+ ABSL_GUARDED_BY(CustomUsageConfigMutex())
+ ABSL_PT_GUARDED_BY(CustomUsageConfigMutex()) = nullptr;
} // namespace
FlagsUsageConfig GetUsageConfig() {
- absl::MutexLock l(&custom_usage_config_guard);
+ absl::MutexLock l(CustomUsageConfigMutex());
if (custom_usage_config) return *custom_usage_config;
@@ -136,7 +141,7 @@ void ReportUsageError(absl::string_view msg, bool is_fatal) {
} // namespace flags_internal
void SetFlagsUsageConfig(FlagsUsageConfig usage_config) {
- absl::MutexLock l(&flags_internal::custom_usage_config_guard);
+ absl::MutexLock l(flags_internal::CustomUsageConfigMutex());
if (!usage_config.contains_helpshort_flags)
usage_config.contains_helpshort_flags =
diff --git a/contrib/restricted/abseil-cpp/absl/flags/ya.make b/contrib/restricted/abseil-cpp/absl/flags/ya.make
index 6cdd7fa292..309a6f39d9 100644
--- a/contrib/restricted/abseil-cpp/absl/flags/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/flags/ya.make
@@ -6,7 +6,7 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20240722.1)
+VERSION(20250127.0)
PEERDIR(
contrib/restricted/abseil-cpp/absl/base
diff --git a/contrib/restricted/abseil-cpp/absl/functional/ya.make b/contrib/restricted/abseil-cpp/absl/functional/ya.make
index 4e3328995c..2deef3b2a7 100644
--- a/contrib/restricted/abseil-cpp/absl/functional/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/functional/ya.make
@@ -6,9 +6,9 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20240722.1)
+VERSION(20250127.0)
-ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20240722.1.tar.gz)
+ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20250127.0.tar.gz)
NO_RUNTIME()
diff --git a/contrib/restricted/abseil-cpp/absl/hash/hash.h b/contrib/restricted/abseil-cpp/absl/hash/hash.h
index 470cca4837..479b17b7b1 100644
--- a/contrib/restricted/abseil-cpp/absl/hash/hash.h
+++ b/contrib/restricted/abseil-cpp/absl/hash/hash.h
@@ -78,11 +78,16 @@
#ifndef ABSL_HASH_HASH_H_
#define ABSL_HASH_HASH_H_
+#include <cstddef>
+#include <cstdint>
#include <tuple>
+#include <type_traits>
#include <utility>
+#include "absl/base/config.h"
#include "absl/functional/function_ref.h"
#include "absl/hash/internal/hash.h"
+#include "absl/meta/type_traits.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -319,8 +324,12 @@ class HashState : public hash_internal::HashStateBase<HashState> {
// Create a new `HashState` instance that wraps `state`. All calls to
// `combine()` and `combine_contiguous()` on the new instance will be
// redirected to the original `state` object. The `state` object must outlive
- // the `HashState` instance.
- template <typename T>
+ // the `HashState` instance. `T` must be a subclass of `HashStateBase<T>` -
+ // users should not define their own HashState types.
+ template <
+ typename T,
+ absl::enable_if_t<
+ std::is_base_of<hash_internal::HashStateBase<T>, T>::value, int> = 0>
static HashState Create(T* state) {
HashState s;
s.Init(state);
@@ -353,6 +362,7 @@ class HashState : public hash_internal::HashStateBase<HashState> {
HashState() = default;
friend class HashState::HashStateBase;
+ friend struct hash_internal::CombineRaw;
template <typename T>
static void CombineContiguousImpl(void* p, const unsigned char* first,
@@ -361,10 +371,22 @@ class HashState : public hash_internal::HashStateBase<HashState> {
state = T::combine_contiguous(std::move(state), first, size);
}
+ static HashState combine_raw(HashState hash_state, uint64_t value) {
+ hash_state.combine_raw_(hash_state.state_, value);
+ return hash_state;
+ }
+
+ template <typename T>
+ static void CombineRawImpl(void* p, uint64_t value) {
+ T& state = *static_cast<T*>(p);
+ state = hash_internal::CombineRaw()(std::move(state), value);
+ }
+
template <typename T>
void Init(T* state) {
state_ = state;
combine_contiguous_ = &CombineContiguousImpl<T>;
+ combine_raw_ = &CombineRawImpl<T>;
run_combine_unordered_ = &RunCombineUnorderedImpl<T>;
}
@@ -403,6 +425,7 @@ class HashState : public hash_internal::HashStateBase<HashState> {
void Init(HashState* state) {
state_ = state->state_;
combine_contiguous_ = state->combine_contiguous_;
+ combine_raw_ = state->combine_raw_;
run_combine_unordered_ = state->run_combine_unordered_;
}
@@ -413,6 +436,7 @@ class HashState : public hash_internal::HashStateBase<HashState> {
void* state_;
void (*combine_contiguous_)(void*, const unsigned char*, size_t);
+ void (*combine_raw_)(void*, uint64_t);
HashState (*run_combine_unordered_)(
HashState state,
absl::FunctionRef<void(HashState, absl::FunctionRef<void(HashState&)>)>);
diff --git a/contrib/restricted/abseil-cpp/absl/hash/hash_testing.h b/contrib/restricted/abseil-cpp/absl/hash/hash_testing.h
index 1e1c574149..673366deef 100644
--- a/contrib/restricted/abseil-cpp/absl/hash/hash_testing.h
+++ b/contrib/restricted/abseil-cpp/absl/hash/hash_testing.h
@@ -244,7 +244,8 @@ VerifyTypeImplementsAbslHashCorrectly(const Container& values, Eq equals) {
if (v.expand() != expected) {
return testing::AssertionFailure()
<< "Values " << c[0].ToString() << " and " << v.ToString()
- << " evaluate as equal but have an unequal hash expansion.";
+ << " evaluate as equal but have unequal hash expansions ("
+ << expected << " vs. " << v.expand() << ").";
}
}
@@ -256,17 +257,18 @@ VerifyTypeImplementsAbslHashCorrectly(const Container& values, Eq equals) {
case SpyHashState::CompareResult::kEqual:
return testing::AssertionFailure()
<< "Values " << c[0].ToString() << " and " << c2[0].ToString()
- << " evaluate as unequal but have an equal hash expansion.";
+ << " evaluate as unequal but have an equal hash expansion:"
+ << c2_hash << ".";
case SpyHashState::CompareResult::kBSuffixA:
return testing::AssertionFailure()
- << "Hash expansion of " << c2[0].ToString()
+ << "Hash expansion of " << c2[0].ToString() << ";" << c2_hash
<< " is a suffix of the hash expansion of " << c[0].ToString()
- << ".";
+ << ";" << expected << ".";
case SpyHashState::CompareResult::kASuffixB:
return testing::AssertionFailure()
- << "Hash expansion of " << c[0].ToString()
- << " is a suffix of the hash expansion of " << c2[0].ToString()
- << ".";
+ << "Hash expansion of " << c[0].ToString() << ";"
+ << expected << " is a suffix of the hash expansion of "
+ << c2[0].ToString() << ";" << c2_hash << ".";
case SpyHashState::CompareResult::kUnequal:
break;
}
diff --git a/contrib/restricted/abseil-cpp/absl/hash/internal/hash.cc b/contrib/restricted/abseil-cpp/absl/hash/internal/hash.cc
index 93906ef872..e0a8ea9974 100644
--- a/contrib/restricted/abseil-cpp/absl/hash/internal/hash.cc
+++ b/contrib/restricted/abseil-cpp/absl/hash/internal/hash.cc
@@ -14,6 +14,14 @@
#include "absl/hash/internal/hash.h"
+#include <cstddef>
+#include <cstdint>
+#include <type_traits>
+
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/hash/internal/low_level_hash.h"
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace hash_internal {
@@ -21,9 +29,10 @@ namespace hash_internal {
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()),
+ kMul);
len -= PiecewiseChunkSize();
first += PiecewiseChunkSize();
}
@@ -35,7 +44,7 @@ uint64_t MixingHashState::CombineLargeContiguousImpl32(
uint64_t MixingHashState::CombineLargeContiguousImpl64(
uint64_t state, const unsigned char* first, size_t len) {
while (len >= PiecewiseChunkSize()) {
- state = Mix(state, Hash64(first, PiecewiseChunkSize()));
+ state = Mix(state ^ Hash64(first, PiecewiseChunkSize()), kMul);
len -= PiecewiseChunkSize();
first += PiecewiseChunkSize();
}
@@ -46,22 +55,13 @@ uint64_t MixingHashState::CombineLargeContiguousImpl64(
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.
-//
-// 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] = {
- uint64_t{0x243F6A8885A308D3}, uint64_t{0x13198A2E03707344},
- uint64_t{0xA4093822299F31D0}, uint64_t{0x082EFA98EC4E6C89},
- uint64_t{0x452821E638D01377},
-};
+#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
+constexpr uint64_t MixingHashState::kStaticRandomData[];
+#endif
uint64_t MixingHashState::LowLevelHashImpl(const unsigned char* data,
size_t len) {
- return LowLevelHashLenGt16(data, len, Seed(), kHashSalt);
+ return LowLevelHashLenGt16(data, len, Seed(), &kStaticRandomData[0]);
}
} // 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 03bf183905..f4a0d7857c 100644
--- a/contrib/restricted/abseil-cpp/absl/hash/internal/hash.h
+++ b/contrib/restricted/abseil-cpp/absl/hash/internal/hash.h
@@ -36,8 +36,10 @@
#include <algorithm>
#include <array>
#include <bitset>
+#include <cassert>
#include <cmath>
#include <cstddef>
+#include <cstdint>
#include <cstring>
#include <deque>
#include <forward_list>
@@ -56,7 +58,10 @@
#include <utility>
#include <vector>
+#include "absl/base/attributes.h"
+#include "absl/base/internal/endian.h"
#include "absl/base/internal/unaligned_access.h"
+#include "absl/base/optimization.h"
#include "absl/base/port.h"
#include "absl/container/fixed_array.h"
#include "absl/hash/internal/city.h"
@@ -69,8 +74,7 @@
#include "absl/types/variant.h"
#include "absl/utility/utility.h"
-#if defined(__cpp_lib_filesystem) && __cpp_lib_filesystem >= 201703L && \
- !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
+#if defined(__cpp_lib_filesystem) && __cpp_lib_filesystem >= 201703L
#include <filesystem> // NOLINT
#endif
@@ -78,6 +82,10 @@
#include <string_view>
#endif
+#ifdef __ARM_ACLE
+#include <arm_acle.h>
+#endif
+
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -340,11 +348,47 @@ struct is_uniquely_represented<
template <>
struct is_uniquely_represented<bool> : std::false_type {};
+#ifdef ABSL_HAVE_INTRINSIC_INT128
+// Specialize the trait for GNU extension types.
+template <>
+struct is_uniquely_represented<__int128> : std::true_type {};
+template <>
+struct is_uniquely_represented<unsigned __int128> : std::true_type {};
+#endif // ABSL_HAVE_INTRINSIC_INT128
+
+template <typename T>
+struct FitsIn64Bits : std::integral_constant<bool, sizeof(T) <= 8> {};
+
+struct CombineRaw {
+ template <typename H>
+ H operator()(H state, uint64_t value) const {
+ return H::combine_raw(std::move(state), value);
+ }
+};
+
// hash_bytes()
//
// Convenience function that combines `hash_state` with the byte representation
// of `value`.
-template <typename H, typename T>
+template <typename H, typename T,
+ absl::enable_if_t<FitsIn64Bits<T>::value, int> = 0>
+H hash_bytes(H hash_state, const T& value) {
+ const unsigned char* start = reinterpret_cast<const unsigned char*>(&value);
+ uint64_t v;
+ if (sizeof(T) == 1) {
+ v = *start;
+ } else if (sizeof(T) == 2) {
+ v = absl::base_internal::UnalignedLoad16(start);
+ } else if (sizeof(T) == 4) {
+ v = absl::base_internal::UnalignedLoad32(start);
+ } else {
+ assert(sizeof(T) == 8);
+ v = absl::base_internal::UnalignedLoad64(start);
+ }
+ return CombineRaw()(std::move(hash_state), v);
+}
+template <typename H, typename T,
+ absl::enable_if_t<!FitsIn64Bits<T>::value, int> = 0>
H hash_bytes(H hash_state, const T& value) {
const unsigned char* start = reinterpret_cast<const unsigned char*>(&value);
return H::combine_contiguous(std::move(hash_state), start, sizeof(value));
@@ -446,9 +490,9 @@ std::enable_if_t<std::is_pointer<T>::value, H> AbslHashValue(H hash_state,
T ptr) {
auto v = reinterpret_cast<uintptr_t>(ptr);
// Due to alignment, pointers tend to have low bits as zero, and the next few
- // bits follow a pattern since they are also multiples of some base value.
- // Mixing the pointer twice helps prevent stuck low bits for certain alignment
- // values.
+ // bits follow a pattern since they are also multiples of some base value. The
+ // byte swap in WeakMix helps ensure we still have good entropy in low bits.
+ // Mix pointers twice to ensure we have good entropy in low bits.
return H::combine(std::move(hash_state), v, v);
}
@@ -597,7 +641,6 @@ H AbslHashValue(H hash_state, std::basic_string_view<Char> str) {
#endif // ABSL_HAVE_STD_STRING_VIEW
#if defined(__cpp_lib_filesystem) && __cpp_lib_filesystem >= 201703L && \
- !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY) && \
(!defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) || \
__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 130000) && \
(!defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) || \
@@ -929,6 +972,7 @@ struct HashSelect {
static State combine_contiguous(State hash_state, const unsigned char*,
size_t);
using State::HashStateBase::combine_contiguous;
+ static State combine_raw(State state, uint64_t value);
};
struct UniquelyRepresentedProbe {
@@ -1011,13 +1055,21 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> {
using uint128 = absl::uint128;
#endif // ABSL_HAVE_INTRINSIC_INT128
+ // Random data taken from the hexadecimal digits of Pi's fractional component.
+ // https://en.wikipedia.org/wiki/Nothing-up-my-sleeve_number
+ ABSL_CACHELINE_ALIGNED static constexpr uint64_t kStaticRandomData[] = {
+ 0x243f'6a88'85a3'08d3, 0x1319'8a2e'0370'7344, 0xa409'3822'299f'31d0,
+ 0x082e'fa98'ec4e'6c89, 0x4528'21e6'38d0'1377,
+ };
+
static constexpr uint64_t kMul =
sizeof(size_t) == 4 ? uint64_t{0xcc9e2d51}
- : uint64_t{0x9ddfea08eb382d69};
+ : uint64_t{0xdcb22ca68cb134ed};
template <typename T>
using IntegralFastPath =
- conjunction<std::is_integral<T>, is_uniquely_represented<T>>;
+ conjunction<std::is_integral<T>, is_uniquely_represented<T>,
+ FitsIn64Bits<T>>;
public:
// Move only
@@ -1047,7 +1099,7 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> {
template <typename T, absl::enable_if_t<IntegralFastPath<T>::value, int> = 0>
static size_t hash(T value) {
return static_cast<size_t>(
- Mix(Seed(), static_cast<std::make_unsigned_t<T>>(value)));
+ WeakMix(Seed() ^ static_cast<std::make_unsigned_t<T>>(value)));
}
// Overload of MixingHashState::hash()
@@ -1085,6 +1137,7 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> {
// Allow the HashState type-erasure implementation to invoke
// RunCombinedUnordered() directly.
friend class absl::HashState;
+ friend struct CombineRaw;
// Workaround for MSVC bug.
// We make the type copyable to fix the calling convention, even though we
@@ -1094,6 +1147,14 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> {
explicit MixingHashState(uint64_t state) : state_(state) {}
+ // Combines a raw value from e.g. integrals/floats/pointers/etc. This allows
+ // us to be consistent with IntegralFastPath when combining raw types, but
+ // optimize Read1To3 and Read4To8 differently for the string case.
+ static MixingHashState combine_raw(MixingHashState hash_state,
+ uint64_t value) {
+ return MixingHashState(WeakMix(hash_state.state_ ^ value));
+ }
+
// Implementation of the base case for combine_contiguous where we actually
// mix the bytes into the state.
// Dispatch to different implementations of the combine_contiguous depending
@@ -1107,6 +1168,49 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> {
std::integral_constant<int, 8>
/* sizeof_size_t */);
+ ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t CombineSmallContiguousImpl(
+ uint64_t state, const unsigned char* first, size_t len) {
+ ABSL_ASSUME(len <= 8);
+ uint64_t v;
+ if (len >= 4) {
+ v = Read4To8(first, len);
+ } else if (len > 0) {
+ v = Read1To3(first, len);
+ } else {
+ // Empty ranges have no effect.
+ return state;
+ }
+ return WeakMix(state ^ v);
+ }
+
+ ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t CombineContiguousImpl9to16(
+ uint64_t state, const unsigned char* first, size_t len) {
+ ABSL_ASSUME(len >= 9);
+ ABSL_ASSUME(len <= 16);
+ // Note: any time one half of the mix function becomes zero it will fail to
+ // incorporate any bits from the other half. However, there is exactly 1 in
+ // 2^64 values for each side that achieve this, and only when the size is
+ // exactly 16 -- for smaller sizes there is an overlapping byte that makes
+ // this impossible unless the seed is *also* incredibly unlucky.
+ auto p = Read9To16(first, len);
+ return Mix(state ^ p.first, kMul ^ p.second);
+ }
+
+ ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t CombineContiguousImpl17to32(
+ uint64_t state, const unsigned char* first, size_t len) {
+ ABSL_ASSUME(len >= 17);
+ ABSL_ASSUME(len <= 32);
+ // Do two mixes of overlapping 16-byte ranges in parallel to minimize
+ // latency.
+ const uint64_t m0 =
+ Mix(Read8(first) ^ kStaticRandomData[1], Read8(first + 8) ^ state);
+
+ const unsigned char* tail_16b_ptr = first + (len - 16);
+ const uint64_t m1 = Mix(Read8(tail_16b_ptr) ^ kStaticRandomData[3],
+ Read8(tail_16b_ptr + 8) ^ state);
+ return m0 ^ m1;
+ }
+
// Slow dispatch path for calls to CombineContiguousImpl with a size argument
// larger than PiecewiseChunkSize(). Has the same effect as calling
// CombineContiguousImpl() repeatedly with the chunk stride size.
@@ -1122,8 +1226,8 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> {
// are in .second.
static std::pair<uint64_t, uint64_t> Read9To16(const unsigned char* p,
size_t len) {
- uint64_t low_mem = absl::base_internal::UnalignedLoad64(p);
- uint64_t high_mem = absl::base_internal::UnalignedLoad64(p + len - 8);
+ uint64_t low_mem = Read8(p);
+ uint64_t high_mem = Read8(p + len - 8);
#ifdef ABSL_IS_LITTLE_ENDIAN
uint64_t most_significant = high_mem;
uint64_t least_significant = low_mem;
@@ -1134,55 +1238,81 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> {
return {least_significant, most_significant};
}
+ // Reads 8 bytes from p.
+ static uint64_t Read8(const unsigned char* p) {
+ // Suppress erroneous array bounds errors on GCC.
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Warray-bounds"
+#endif
+ return absl::base_internal::UnalignedLoad64(p);
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+ }
+
// Reads 4 to 8 bytes from p. Zero pads to fill uint64_t.
+ // TODO(b/384509507): consider optimizing this by not requiring the output to
+ // be equivalent to an integer load for 4/8 bytes. Currently, we rely on this
+ // behavior for the HashConsistentAcrossIntTypes test case. Ditto for
+ // Read1To3.
static uint64_t Read4To8(const unsigned char* p, size_t len) {
- uint32_t low_mem = absl::base_internal::UnalignedLoad32(p);
- uint32_t high_mem = absl::base_internal::UnalignedLoad32(p + len - 4);
-#ifdef ABSL_IS_LITTLE_ENDIAN
- uint32_t most_significant = high_mem;
- uint32_t least_significant = low_mem;
-#else
- uint32_t most_significant = low_mem;
- uint32_t least_significant = high_mem;
-#endif
- return (static_cast<uint64_t>(most_significant) << (len - 4) * 8) |
- least_significant;
+ // If `len < 8`, we duplicate bytes in the middle.
+ // E.g.:
+ // `ABCD` will be read as `ABCDABCD`.
+ // `ABCDE` will be read as `ABCDBCDE`.
+ // `ABCDEF` will be read as `ABCDCDEF`.
+ // `ABCDEFG` will be read as `ABCDDEFG`.
+ // We also do not care about endianness. On big-endian platforms, bytes will
+ // be shuffled (it's fine). We always shift low memory by 32, because that
+ // can be pipelined earlier. Reading high memory requires computing
+ // `p + len - 4`.
+ uint64_t most_significant =
+ static_cast<uint64_t>(absl::base_internal::UnalignedLoad32(p)) << 32;
+ uint64_t least_significant =
+ absl::base_internal::UnalignedLoad32(p + len - 4);
+ return most_significant | least_significant;
}
// Reads 1 to 3 bytes from p. Zero pads to fill uint32_t.
static uint32_t Read1To3(const unsigned char* p, size_t len) {
- // The trick used by this implementation is to avoid branches if possible.
- unsigned char mem0 = p[0];
- unsigned char mem1 = p[len / 2];
- unsigned char mem2 = p[len - 1];
-#ifdef ABSL_IS_LITTLE_ENDIAN
- unsigned char significant2 = mem2;
- unsigned char significant1 = mem1;
- unsigned char significant0 = mem0;
-#else
- unsigned char significant2 = mem0;
- unsigned char significant1 = len == 2 ? mem0 : mem1;
- unsigned char significant0 = mem2;
-#endif
- return static_cast<uint32_t>(significant0 | //
- (significant1 << (len / 2 * 8)) | //
- (significant2 << ((len - 1) * 8)));
+ // The trick used by this implementation is to avoid branches.
+ // We always read three bytes by duplicating.
+ // E.g.,
+ // `A` is read as `AAA`.
+ // `AB` is read as `ABB`.
+ // `ABC` is read as `ABC`.
+ // We always shift `p[0]` so that it can be pipelined better.
+ // Other bytes require extra computation to find indices.
+ uint32_t mem0 = (static_cast<uint32_t>(p[0]) << 16) | p[len - 1];
+ uint32_t mem1 = static_cast<uint32_t>(p[len / 2]) << 8;
+ return mem0 | mem1;
}
- ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t Mix(uint64_t state, uint64_t v) {
+ ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t Mix(uint64_t lhs, uint64_t rhs) {
// Though the 128-bit product on AArch64 needs two instructions, it is
// still a good balance between speed and hash quality.
using MultType =
absl::conditional_t<sizeof(size_t) == 4, uint64_t, uint128>;
- // 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
- // multiplications instead of one.
- MultType m = state + v;
- m *= kMul;
+ MultType m = lhs;
+ m *= rhs;
return static_cast<uint64_t>(m ^ (m >> (sizeof(m) * 8 / 2)));
}
+ // Slightly lower latency than Mix, but with lower quality. The byte swap
+ // helps ensure that low bits still have high quality.
+ ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t WeakMix(uint64_t n) {
+ // WeakMix doesn't work well on 32-bit platforms so just use Mix.
+ if (sizeof(size_t) < 8) return Mix(n, kMul);
+#ifdef __ARM_ACLE
+ // gbswap_64 compiles to `rev` on ARM, but `rbit` is better because it
+ // reverses bits rather than reversing bytes.
+ return __rbitll(n * kMul);
+#else
+ return absl::gbswap_64(n * kMul);
+#endif
+ }
+
// 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);
@@ -1234,21 +1364,15 @@ inline uint64_t MixingHashState::CombineContiguousImpl(
std::integral_constant<int, 4> /* sizeof_size_t */) {
// For large values we use CityHash, for small ones we just use a
// multiplicative hash.
- uint64_t v;
- if (len > 8) {
- if (ABSL_PREDICT_FALSE(len > PiecewiseChunkSize())) {
- return CombineLargeContiguousImpl32(state, first, len);
- }
- v = hash_internal::CityHash32(reinterpret_cast<const char*>(first), len);
- } else if (len >= 4) {
- v = Read4To8(first, len);
- } else if (len > 0) {
- v = Read1To3(first, len);
- } else {
- // Empty ranges have no effect.
- return state;
+ if (len <= 8) {
+ return CombineSmallContiguousImpl(state, first, len);
}
- return Mix(state, v);
+ if (ABSL_PREDICT_TRUE(len <= PiecewiseChunkSize())) {
+ return Mix(state ^ hash_internal::CityHash32(
+ reinterpret_cast<const char*>(first), len),
+ kMul);
+ }
+ return CombineLargeContiguousImpl32(state, first, len);
}
// Overload of MixingHashState::CombineContiguousImpl()
@@ -1257,38 +1381,19 @@ inline uint64_t MixingHashState::CombineContiguousImpl(
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.
- uint64_t v;
- if (len > 16) {
- if (ABSL_PREDICT_FALSE(len > PiecewiseChunkSize())) {
- return CombineLargeContiguousImpl64(state, first, len);
- }
- v = Hash64(first, len);
- } else if (len > 8) {
- // This hash function was constructed by the ML-driven algorithm discovery
- // using reinforcement learning. We fed the agent lots of inputs from
- // microbenchmarks, SMHasher, low hamming distance from generated inputs and
- // picked up the one that was good on micro and macrobenchmarks.
- auto p = Read9To16(first, len);
- uint64_t lo = p.first;
- uint64_t hi = p.second;
- // Rotation by 53 was found to be most often useful when discovering these
- // hashing algorithms with ML techniques.
- lo = absl::rotr(lo, 53);
- state += kMul;
- lo += state;
- state ^= hi;
- uint128 m = state;
- m *= lo;
- return static_cast<uint64_t>(m ^ (m >> 64));
- } else if (len >= 4) {
- v = Read4To8(first, len);
- } else if (len > 0) {
- v = Read1To3(first, len);
- } else {
- // Empty ranges have no effect.
- return state;
+ if (len <= 8) {
+ return CombineSmallContiguousImpl(state, first, len);
+ }
+ if (len <= 16) {
+ return CombineContiguousImpl9to16(state, first, len);
+ }
+ if (len <= 32) {
+ return CombineContiguousImpl17to32(state, first, len);
+ }
+ if (ABSL_PREDICT_TRUE(len <= PiecewiseChunkSize())) {
+ return Mix(state ^ Hash64(first, len), kMul);
}
- return Mix(state, v);
+ return CombineLargeContiguousImpl64(state, first, len);
}
struct AggregateBarrier {};
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 6dc71cf7cd..ec02d7e7c5 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
@@ -33,8 +33,6 @@ static uint64_t Mix(uint64_t v0, uint64_t v1) {
uint64_t LowLevelHashLenGt16(const void* data, size_t len, uint64_t seed,
const uint64_t salt[5]) {
- // Prefetch the cacheline that data resides in.
- PrefetchToLocalCache(data);
const uint8_t* ptr = static_cast<const uint8_t*>(data);
uint64_t starting_length = static_cast<uint64_t>(len);
const uint8_t* last_16_ptr = ptr + starting_length - 16;
@@ -42,8 +40,8 @@ uint64_t LowLevelHashLenGt16(const void* data, size_t len, uint64_t seed,
if (len > 64) {
// If we have more than 64 bytes, we're going to handle chunks of 64
- // bytes at a time. We're going to build up two separate hash states
- // which we will then hash together.
+ // bytes at a time. We're going to build up four separate hash states
+ // which we will then hash together. This avoids short dependency chains.
uint64_t duplicated_state0 = current_state;
uint64_t duplicated_state1 = current_state;
uint64_t duplicated_state2 = current_state;
diff --git a/contrib/restricted/abseil-cpp/absl/hash/internal/spy_hash_state.h b/contrib/restricted/abseil-cpp/absl/hash/internal/spy_hash_state.h
index 357c301c4a..92490b1a21 100644
--- a/contrib/restricted/abseil-cpp/absl/hash/internal/spy_hash_state.h
+++ b/contrib/restricted/abseil-cpp/absl/hash/internal/spy_hash_state.h
@@ -16,6 +16,7 @@
#define ABSL_HASH_INTERNAL_SPY_HASH_STATE_H_
#include <algorithm>
+#include <cstdint>
#include <ostream>
#include <string>
#include <vector>
@@ -196,6 +197,7 @@ class SpyHashStateImpl : public HashStateBase<SpyHashStateImpl<T>> {
private:
template <typename U>
friend class SpyHashStateImpl;
+ friend struct CombineRaw;
struct UnorderedCombinerCallback {
std::vector<std::string> element_hash_representations;
@@ -213,6 +215,12 @@ class SpyHashStateImpl : public HashStateBase<SpyHashStateImpl<T>> {
}
};
+ // Combines raw data from e.g. integrals/floats/pointers/etc.
+ static SpyHashStateImpl combine_raw(SpyHashStateImpl state, uint64_t value) {
+ const unsigned char* data = reinterpret_cast<const unsigned char*>(&value);
+ return SpyHashStateImpl::combine_contiguous(std::move(state), data, 8);
+ }
+
// This is true if SpyHashStateImpl<T> has been passed to a call of
// AbslHashValue with the wrong type. This detects that the user called
// AbslHashValue directly (because the hash state type does not match).
diff --git a/contrib/restricted/abseil-cpp/absl/hash/ya.make b/contrib/restricted/abseil-cpp/absl/hash/ya.make
index aeef6cea71..4281424c58 100644
--- a/contrib/restricted/abseil-cpp/absl/hash/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/hash/ya.make
@@ -6,7 +6,7 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20240722.1)
+VERSION(20250127.0)
PEERDIR(
contrib/restricted/abseil-cpp/absl/base
diff --git a/contrib/restricted/abseil-cpp/absl/log/absl_vlog_is_on.h b/contrib/restricted/abseil-cpp/absl/log/absl_vlog_is_on.h
index 6bf6c41339..e4ec86db52 100644
--- a/contrib/restricted/abseil-cpp/absl/log/absl_vlog_is_on.h
+++ b/contrib/restricted/abseil-cpp/absl/log/absl_vlog_is_on.h
@@ -40,6 +40,8 @@
// last . and everything after it) is stripped from each filename prior to
// matching, as is the special suffix "-inl".
//
+// Example: --vmodule=module_a=1,module_b=2
+//
// Files are matched against globs in `--vmodule` in order, and the first match
// determines the verbosity level.
//
diff --git a/contrib/restricted/abseil-cpp/absl/log/internal/check_op.cc b/contrib/restricted/abseil-cpp/absl/log/internal/check_op.cc
index 23c4a3b205..cec94218ec 100644
--- a/contrib/restricted/abseil-cpp/absl/log/internal/check_op.cc
+++ b/contrib/restricted/abseil-cpp/absl/log/internal/check_op.cc
@@ -14,10 +14,15 @@
#include "absl/log/internal/check_op.h"
-#include <string.h>
-
+#include <cstring>
#include <ostream>
+#include <string>
+#include <utility>
+#include "absl/base/config.h"
+#include "absl/base/nullability.h"
+#include "absl/debugging/leak_check.h"
+#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#ifdef _MSC_VER
@@ -26,18 +31,13 @@
#include <strings.h> // for strcasecmp, but msvc does not have this header
#endif
-#include <sstream>
-#include <string>
-
-#include "absl/base/config.h"
-#include "absl/strings/str_cat.h"
-
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace log_internal {
#define ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(x) \
- template std::string* MakeCheckOpString(x, x, const char*)
+ template absl::Nonnull<const char*> MakeCheckOpString( \
+ x, x, absl::Nonnull<const char*>)
ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(bool);
ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(int64_t);
ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(uint64_t);
@@ -53,7 +53,8 @@ ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const unsigned char*);
ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const void*);
#undef ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING
-CheckOpMessageBuilder::CheckOpMessageBuilder(const char* exprtext) {
+CheckOpMessageBuilder::CheckOpMessageBuilder(
+ absl::Nonnull<const char*> exprtext) {
stream_ << exprtext << " (";
}
@@ -62,9 +63,10 @@ std::ostream& CheckOpMessageBuilder::ForVar2() {
return stream_;
}
-std::string* CheckOpMessageBuilder::NewString() {
+absl::Nonnull<const char*> CheckOpMessageBuilder::NewString() {
stream_ << ")";
- return new std::string(stream_.str());
+ // There's no need to free this string since the process is crashing.
+ return absl::IgnoreLeak(new std::string(std::move(stream_).str()))->c_str();
}
void MakeCheckOpValueString(std::ostream& os, const char v) {
@@ -100,16 +102,19 @@ void MakeCheckOpValueString(std::ostream& os, const void* p) {
}
// Helper functions for string comparisons.
-#define DEFINE_CHECK_STROP_IMPL(name, func, expected) \
- std::string* Check##func##expected##Impl(const char* s1, const char* s2, \
- const char* exprtext) { \
- bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \
- if (equal == expected) { \
- return nullptr; \
- } else { \
- return new std::string( \
- absl::StrCat(exprtext, " (", s1, " vs. ", s2, ")")); \
- } \
+#define DEFINE_CHECK_STROP_IMPL(name, func, expected) \
+ absl::Nullable<const char*> Check##func##expected##Impl( \
+ absl::Nullable<const char*> s1, absl::Nullable<const char*> s2, \
+ absl::Nonnull<const char*> exprtext) { \
+ bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \
+ if (equal == expected) { \
+ return nullptr; \
+ } else { \
+ /* There's no need to free this string since the process is crashing. */ \
+ return absl::IgnoreLeak(new std::string(absl::StrCat(exprtext, " (", s1, \
+ " vs. ", s2, ")"))) \
+ ->c_str(); \
+ } \
}
DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true)
DEFINE_CHECK_STROP_IMPL(CHECK_STRNE, strcmp, false)
diff --git a/contrib/restricted/abseil-cpp/absl/log/internal/check_op.h b/contrib/restricted/abseil-cpp/absl/log/internal/check_op.h
index 215922079c..d56aa3130e 100644
--- a/contrib/restricted/abseil-cpp/absl/log/internal/check_op.h
+++ b/contrib/restricted/abseil-cpp/absl/log/internal/check_op.h
@@ -32,7 +32,9 @@
#include <utility>
#include "absl/base/attributes.h"
+#include "absl/base/casts.h"
#include "absl/base/config.h"
+#include "absl/base/nullability.h"
#include "absl/base/optimization.h"
#include "absl/log/internal/nullguard.h"
#include "absl/log/internal/nullstream.h"
@@ -62,7 +64,7 @@
#endif
#define ABSL_LOG_INTERNAL_CHECK_OP(name, op, val1, val1_text, val2, val2_text) \
- while (::std::string* absl_log_internal_check_op_result \
+ while (absl::Nullable<const char*> absl_log_internal_check_op_result \
ABSL_LOG_INTERNAL_ATTRIBUTE_UNUSED_IF_STRIP_LOG = \
::absl::log_internal::name##Impl( \
::absl::log_internal::GetReferenceableValue(val1), \
@@ -70,37 +72,44 @@
ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL( \
val1_text " " #op " " val2_text))) \
ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, true) \
- ABSL_LOG_INTERNAL_CHECK(*absl_log_internal_check_op_result).InternalStream()
-#define ABSL_LOG_INTERNAL_QCHECK_OP(name, op, val1, val1_text, val2, \
- val2_text) \
- while (::std::string* absl_log_internal_qcheck_op_result = \
- ::absl::log_internal::name##Impl( \
- ::absl::log_internal::GetReferenceableValue(val1), \
- ::absl::log_internal::GetReferenceableValue(val2), \
- ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL( \
- val1_text " " #op " " val2_text))) \
- ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, true) \
- ABSL_LOG_INTERNAL_QCHECK(*absl_log_internal_qcheck_op_result).InternalStream()
+ ABSL_LOG_INTERNAL_CHECK(absl::implicit_cast<absl::Nonnull<const char*>>( \
+ absl_log_internal_check_op_result)) \
+ .InternalStream()
+#define ABSL_LOG_INTERNAL_QCHECK_OP(name, op, val1, val1_text, val2, \
+ val2_text) \
+ while (absl::Nullable<const char*> absl_log_internal_qcheck_op_result = \
+ ::absl::log_internal::name##Impl( \
+ ::absl::log_internal::GetReferenceableValue(val1), \
+ ::absl::log_internal::GetReferenceableValue(val2), \
+ ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL( \
+ val1_text " " #op " " val2_text))) \
+ ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, true) \
+ ABSL_LOG_INTERNAL_QCHECK(absl::implicit_cast<absl::Nonnull<const char*>>( \
+ absl_log_internal_qcheck_op_result)) \
+ .InternalStream()
#define ABSL_LOG_INTERNAL_CHECK_STROP(func, op, expected, s1, s1_text, s2, \
s2_text) \
- while (::std::string* absl_log_internal_check_strop_result = \
+ while (absl::Nullable<const char*> absl_log_internal_check_strop_result = \
::absl::log_internal::Check##func##expected##Impl( \
(s1), (s2), \
ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(s1_text " " #op \
" " s2_text))) \
ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, true) \
- ABSL_LOG_INTERNAL_CHECK(*absl_log_internal_check_strop_result) \
+ ABSL_LOG_INTERNAL_CHECK(absl::implicit_cast<absl::Nonnull<const char*>>( \
+ absl_log_internal_check_strop_result)) \
.InternalStream()
#define ABSL_LOG_INTERNAL_QCHECK_STROP(func, op, expected, s1, s1_text, s2, \
s2_text) \
- while (::std::string* absl_log_internal_qcheck_strop_result = \
+ while (absl::Nullable<const char*> absl_log_internal_qcheck_strop_result = \
::absl::log_internal::Check##func##expected##Impl( \
(s1), (s2), \
ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(s1_text " " #op \
" " s2_text))) \
ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, true) \
- ABSL_LOG_INTERNAL_QCHECK(*absl_log_internal_qcheck_strop_result) \
+ ABSL_LOG_INTERNAL_QCHECK(absl::implicit_cast<absl::Nonnull<const char*>>( \
+ absl_log_internal_qcheck_strop_result)) \
.InternalStream()
+
// This one is tricky:
// * We must evaluate `val` exactly once, yet we need to do two things with it:
// evaluate `.ok()` and (sometimes) `.ToString()`.
@@ -125,37 +134,41 @@
// string literal and abort without doing any streaming. We don't need to
// strip the call to stringify the non-ok `Status` as long as we don't log it;
// dropping the `Status`'s message text is out of scope.
-#define ABSL_LOG_INTERNAL_CHECK_OK(val, val_text) \
- for (::std::pair<const ::absl::Status*, ::std::string*> \
- absl_log_internal_check_ok_goo; \
- absl_log_internal_check_ok_goo.first = \
- ::absl::log_internal::AsStatus(val), \
- absl_log_internal_check_ok_goo.second = \
- ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok()) \
- ? nullptr \
- : ::absl::status_internal::MakeCheckFailString( \
- absl_log_internal_check_ok_goo.first, \
- ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(val_text \
- " is OK")), \
- !ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok());) \
- ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, true) \
- ABSL_LOG_INTERNAL_CHECK(*absl_log_internal_check_ok_goo.second) \
+#define ABSL_LOG_INTERNAL_CHECK_OK(val, val_text) \
+ for (::std::pair<absl::Nonnull<const ::absl::Status*>, \
+ absl::Nullable<const char*>> \
+ absl_log_internal_check_ok_goo; \
+ absl_log_internal_check_ok_goo.first = \
+ ::absl::log_internal::AsStatus(val), \
+ absl_log_internal_check_ok_goo.second = \
+ ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok()) \
+ ? nullptr \
+ : ::absl::status_internal::MakeCheckFailString( \
+ absl_log_internal_check_ok_goo.first, \
+ ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(val_text \
+ " is OK")), \
+ !ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok());) \
+ ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, true) \
+ ABSL_LOG_INTERNAL_CHECK(absl::implicit_cast<absl::Nonnull<const char*>>( \
+ absl_log_internal_check_ok_goo.second)) \
.InternalStream()
-#define ABSL_LOG_INTERNAL_QCHECK_OK(val, val_text) \
- for (::std::pair<const ::absl::Status*, ::std::string*> \
- absl_log_internal_qcheck_ok_goo; \
- absl_log_internal_qcheck_ok_goo.first = \
- ::absl::log_internal::AsStatus(val), \
- absl_log_internal_qcheck_ok_goo.second = \
- ABSL_PREDICT_TRUE(absl_log_internal_qcheck_ok_goo.first->ok()) \
- ? nullptr \
- : ::absl::status_internal::MakeCheckFailString( \
- absl_log_internal_qcheck_ok_goo.first, \
- ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(val_text \
- " is OK")), \
- !ABSL_PREDICT_TRUE(absl_log_internal_qcheck_ok_goo.first->ok());) \
- ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, true) \
- ABSL_LOG_INTERNAL_QCHECK(*absl_log_internal_qcheck_ok_goo.second) \
+#define ABSL_LOG_INTERNAL_QCHECK_OK(val, val_text) \
+ for (::std::pair<absl::Nonnull<const ::absl::Status*>, \
+ absl::Nullable<const char*>> \
+ absl_log_internal_qcheck_ok_goo; \
+ absl_log_internal_qcheck_ok_goo.first = \
+ ::absl::log_internal::AsStatus(val), \
+ absl_log_internal_qcheck_ok_goo.second = \
+ ABSL_PREDICT_TRUE(absl_log_internal_qcheck_ok_goo.first->ok()) \
+ ? nullptr \
+ : ::absl::status_internal::MakeCheckFailString( \
+ absl_log_internal_qcheck_ok_goo.first, \
+ ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(val_text \
+ " is OK")), \
+ !ABSL_PREDICT_TRUE(absl_log_internal_qcheck_ok_goo.first->ok());) \
+ ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, true) \
+ ABSL_LOG_INTERNAL_QCHECK(absl::implicit_cast<absl::Nonnull<const char*>>( \
+ absl_log_internal_qcheck_ok_goo.second)) \
.InternalStream()
namespace absl {
@@ -166,8 +179,9 @@ template <typename T>
class StatusOr;
namespace status_internal {
-ABSL_ATTRIBUTE_PURE_FUNCTION std::string* MakeCheckFailString(
- const absl::Status* status, const char* prefix);
+ABSL_ATTRIBUTE_PURE_FUNCTION absl::Nonnull<const char*> MakeCheckFailString(
+ absl::Nonnull<const absl::Status*> status,
+ absl::Nonnull<const char*> prefix);
} // namespace status_internal
namespace log_internal {
@@ -175,9 +189,11 @@ namespace log_internal {
// Convert a Status or a StatusOr to its underlying status value.
//
// (This implementation does not require a dep on absl::Status to work.)
-inline const absl::Status* AsStatus(const absl::Status& s) { return &s; }
+inline absl::Nonnull<const absl::Status*> AsStatus(const absl::Status& s) {
+ return &s;
+}
template <typename T>
-const absl::Status* AsStatus(const absl::StatusOr<T>& s) {
+absl::Nonnull<const absl::Status*> AsStatus(const absl::StatusOr<T>& s) {
return &s.status();
}
@@ -186,14 +202,14 @@ const absl::Status* AsStatus(const absl::StatusOr<T>& s) {
class CheckOpMessageBuilder final {
public:
// Inserts `exprtext` and ` (` to the stream.
- explicit CheckOpMessageBuilder(const char* exprtext);
+ explicit CheckOpMessageBuilder(absl::Nonnull<const char*> exprtext);
~CheckOpMessageBuilder() = default;
// For inserting the first variable.
std::ostream& ForVar1() { return stream_; }
// For inserting the second variable (adds an intermediate ` vs. `).
std::ostream& ForVar2();
// Get the result (inserts the closing `)`).
- std::string* NewString();
+ absl::Nonnull<const char*> NewString();
private:
std::ostringstream stream_;
@@ -336,11 +352,12 @@ using CheckOpStreamType = decltype(detect_specialization::Detect<T>(0));
// Build the error message string. Specify no inlining for code size.
template <typename T1, typename T2>
-ABSL_ATTRIBUTE_RETURNS_NONNULL std::string* MakeCheckOpString(
- T1 v1, T2 v2, const char* exprtext) ABSL_ATTRIBUTE_NOINLINE;
+ABSL_ATTRIBUTE_RETURNS_NONNULL absl::Nonnull<const char*> MakeCheckOpString(
+ T1 v1, T2 v2, absl::Nonnull<const char*> exprtext) ABSL_ATTRIBUTE_NOINLINE;
template <typename T1, typename T2>
-std::string* MakeCheckOpString(T1 v1, T2 v2, const char* exprtext) {
+absl::Nonnull<const char*> MakeCheckOpString(
+ T1 v1, T2 v2, absl::Nonnull<const char*> exprtext) {
CheckOpMessageBuilder comb(exprtext);
MakeCheckOpValueString(comb.ForVar1(), v1);
MakeCheckOpValueString(comb.ForVar2(), v2);
@@ -350,7 +367,8 @@ std::string* MakeCheckOpString(T1 v1, T2 v2, const char* exprtext) {
// Add a few commonly used instantiations as extern to reduce size of objects
// files.
#define ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(x) \
- extern template std::string* MakeCheckOpString(x, x, const char*)
+ extern template absl::Nonnull<const char*> MakeCheckOpString( \
+ x, x, absl::Nonnull<const char*>)
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(bool);
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(int64_t);
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(uint64_t);
@@ -374,7 +392,7 @@ ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const void*);
((::absl::LogSeverity::kFatal >= \
static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL)) \
? MakeCheckOpString<U1, U2>(v1, v2, exprtext) \
- : new std::string())
+ : "")
#else
#define ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT(U1, U2, v1, v2, exprtext) \
MakeCheckOpString<U1, U2>(v1, v2, exprtext)
@@ -386,8 +404,8 @@ ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const void*);
// type.
#define ABSL_LOG_INTERNAL_CHECK_OP_IMPL(name, op) \
template <typename T1, typename T2> \
- inline constexpr ::std::string* name##Impl(const T1& v1, const T2& v2, \
- const char* exprtext) { \
+ inline constexpr absl::Nullable<const char*> name##Impl( \
+ const T1& v1, const T2& v2, absl::Nonnull<const char*> exprtext) { \
using U1 = CheckOpStreamType<T1>; \
using U2 = CheckOpStreamType<T2>; \
return ABSL_PREDICT_TRUE(v1 op v2) \
@@ -395,8 +413,8 @@ ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const void*);
: ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT(U1, U2, U1(v1), \
U2(v2), exprtext); \
} \
- inline constexpr ::std::string* name##Impl(int v1, int v2, \
- const char* exprtext) { \
+ inline constexpr absl::Nullable<const char*> name##Impl( \
+ int v1, int v2, absl::Nonnull<const char*> exprtext) { \
return name##Impl<int, int>(v1, v2, exprtext); \
}
@@ -409,14 +427,18 @@ ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_GT, >)
#undef ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT
#undef ABSL_LOG_INTERNAL_CHECK_OP_IMPL
-std::string* CheckstrcmptrueImpl(const char* s1, const char* s2,
- const char* exprtext);
-std::string* CheckstrcmpfalseImpl(const char* s1, const char* s2,
- const char* exprtext);
-std::string* CheckstrcasecmptrueImpl(const char* s1, const char* s2,
- const char* exprtext);
-std::string* CheckstrcasecmpfalseImpl(const char* s1, const char* s2,
- const char* exprtext);
+absl::Nullable<const char*> CheckstrcmptrueImpl(
+ absl::Nullable<const char*> s1, absl::Nullable<const char*> s2,
+ absl::Nonnull<const char*> exprtext);
+absl::Nullable<const char*> CheckstrcmpfalseImpl(
+ absl::Nullable<const char*> s1, absl::Nullable<const char*> s2,
+ absl::Nonnull<const char*> exprtext);
+absl::Nullable<const char*> CheckstrcasecmptrueImpl(
+ absl::Nullable<const char*> s1, absl::Nullable<const char*> s2,
+ absl::Nonnull<const char*> exprtext);
+absl::Nullable<const char*> CheckstrcasecmpfalseImpl(
+ absl::Nullable<const char*> s1, absl::Nullable<const char*> s2,
+ absl::Nonnull<const char*> exprtext);
// `CHECK_EQ` and friends want to pass their arguments by reference, however
// this winds up exposing lots of cases where people have defined and
@@ -424,6 +446,8 @@ std::string* CheckstrcasecmpfalseImpl(const char* s1, const char* s2,
// file), meaning they are not referenceable. This function avoids that problem
// for integers (the most common cases) by overloading for every primitive
// integer type, even the ones we discourage, and returning them by value.
+// NOLINTBEGIN(runtime/int)
+// NOLINTBEGIN(google-runtime-int)
template <typename T>
inline constexpr const T& GetReferenceableValue(const T& t) {
return t;
@@ -433,27 +457,25 @@ inline constexpr unsigned char GetReferenceableValue(unsigned char t) {
return t;
}
inline constexpr signed char GetReferenceableValue(signed char t) { return t; }
-inline constexpr short GetReferenceableValue(short t) { return t; } // NOLINT
-inline constexpr unsigned short GetReferenceableValue( // NOLINT
- unsigned short t) { // NOLINT
+inline constexpr short GetReferenceableValue(short t) { return t; }
+inline constexpr unsigned short GetReferenceableValue(unsigned short t) {
return t;
}
inline constexpr int GetReferenceableValue(int t) { return t; }
inline constexpr unsigned int GetReferenceableValue(unsigned int t) {
return t;
}
-inline constexpr long GetReferenceableValue(long t) { return t; } // NOLINT
-inline constexpr unsigned long GetReferenceableValue( // NOLINT
- unsigned long t) { // NOLINT
- return t;
-}
-inline constexpr long long GetReferenceableValue(long long t) { // NOLINT
+inline constexpr long GetReferenceableValue(long t) { return t; }
+inline constexpr unsigned long GetReferenceableValue(unsigned long t) {
return t;
}
-inline constexpr unsigned long long GetReferenceableValue( // NOLINT
- unsigned long long t) { // NOLINT
+inline constexpr long long GetReferenceableValue(long long t) { return t; }
+inline constexpr unsigned long long GetReferenceableValue(
+ unsigned long long t) {
return t;
}
+// NOLINTEND(google-runtime-int)
+// NOLINTEND(runtime/int)
} // namespace log_internal
ABSL_NAMESPACE_END
diff --git a/contrib/restricted/abseil-cpp/absl/log/internal/log_message.cc b/contrib/restricted/abseil-cpp/absl/log/internal/log_message.cc
index 4e9b08af64..9e7722dac0 100644
--- a/contrib/restricted/abseil-cpp/absl/log/internal/log_message.cc
+++ b/contrib/restricted/abseil-cpp/absl/log/internal/log_message.cc
@@ -39,6 +39,7 @@
#include "absl/base/internal/strerror.h"
#include "absl/base/internal/sysinfo.h"
#include "absl/base/log_severity.h"
+#include "absl/base/nullability.h"
#include "absl/container/inlined_vector.h"
#include "absl/debugging/internal/examine_stack.h"
#include "absl/log/globals.h"
@@ -47,6 +48,7 @@
#include "absl/log/internal/log_format.h"
#include "absl/log/internal/log_sink_set.h"
#include "absl/log/internal/proto.h"
+#include "absl/log/internal/structured_proto.h"
#include "absl/log/log_entry.h"
#include "absl/log/log_sink.h"
#include "absl/log/log_sink_registry.h"
@@ -145,8 +147,8 @@ void WriteToStream(const char* data, void* os) {
} // namespace
struct LogMessage::LogMessageData final {
- LogMessageData(const char* file, int line, absl::LogSeverity severity,
- absl::Time timestamp);
+ LogMessageData(absl::Nonnull<const char*> file, int line,
+ absl::LogSeverity severity, absl::Time timestamp);
LogMessageData(const LogMessageData&) = delete;
LogMessageData& operator=(const LogMessageData&) = delete;
@@ -161,7 +163,7 @@ struct LogMessage::LogMessageData final {
bool is_perror;
// Extra `LogSink`s to log to, in addition to `global_sinks`.
- absl::InlinedVector<absl::LogSink*, 16> extra_sinks;
+ absl::InlinedVector<absl::Nonnull<absl::LogSink*>, 16> extra_sinks;
// If true, log to `extra_sinks` but not to `global_sinks` or hardcoded
// non-sink targets (e.g. stderr, log files).
bool extra_sinks_only;
@@ -197,8 +199,8 @@ struct LogMessage::LogMessageData final {
void FinalizeEncodingAndFormat();
};
-LogMessage::LogMessageData::LogMessageData(const char* file, int line,
- absl::LogSeverity severity,
+LogMessage::LogMessageData::LogMessageData(absl::Nonnull<const char*> file,
+ int line, absl::LogSeverity severity,
absl::Time timestamp)
: extra_sinks_only(false), manipulated(nullptr) {
// Legacy defaults for LOG's ostream:
@@ -268,7 +270,8 @@ void LogMessage::LogMessageData::FinalizeEncodingAndFormat() {
absl::MakeSpan(string_buf).subspan(0, chars_written);
}
-LogMessage::LogMessage(const char* file, int line, absl::LogSeverity severity)
+LogMessage::LogMessage(absl::Nonnull<const char*> file, int line,
+ absl::LogSeverity severity)
: data_(absl::make_unique<LogMessageData>(file, line, severity,
absl::Now())) {
data_->first_fatal = false;
@@ -281,11 +284,11 @@ LogMessage::LogMessage(const char* file, int line, absl::LogSeverity severity)
LogBacktraceIfNeeded();
}
-LogMessage::LogMessage(const char* file, int line, InfoTag)
+LogMessage::LogMessage(absl::Nonnull<const char*> file, int line, InfoTag)
: LogMessage(file, line, absl::LogSeverity::kInfo) {}
-LogMessage::LogMessage(const char* file, int line, WarningTag)
+LogMessage::LogMessage(absl::Nonnull<const char*> file, int line, WarningTag)
: LogMessage(file, line, absl::LogSeverity::kWarning) {}
-LogMessage::LogMessage(const char* file, int line, ErrorTag)
+LogMessage::LogMessage(absl::Nonnull<const char*> file, int line, ErrorTag)
: LogMessage(file, line, absl::LogSeverity::kError) {}
LogMessage::~LogMessage() {
@@ -348,13 +351,13 @@ LogMessage& LogMessage::WithPerror() {
return *this;
}
-LogMessage& LogMessage::ToSinkAlso(absl::LogSink* sink) {
+LogMessage& LogMessage::ToSinkAlso(absl::Nonnull<absl::LogSink*> sink) {
ABSL_INTERNAL_CHECK(sink, "null LogSink*");
data_->extra_sinks.push_back(sink);
return *this;
}
-LogMessage& LogMessage::ToSinkOnly(absl::LogSink* sink) {
+LogMessage& LogMessage::ToSinkOnly(absl::Nonnull<absl::LogSink*> sink) {
ABSL_INTERNAL_CHECK(sink, "null LogSink*");
data_->extra_sinks.clear();
data_->extra_sinks.push_back(sink);
@@ -418,23 +421,26 @@ LogMessage& LogMessage::operator<<(std::ios_base& (*m)(std::ios_base& os)) {
data_->manipulated << m;
return *this;
}
+// NOLINTBEGIN(runtime/int)
+// NOLINTBEGIN(google-runtime-int)
template LogMessage& LogMessage::operator<<(const char& v);
template LogMessage& LogMessage::operator<<(const signed char& v);
template LogMessage& LogMessage::operator<<(const unsigned char& v);
-template LogMessage& LogMessage::operator<<(const short& v); // NOLINT
-template LogMessage& LogMessage::operator<<(const unsigned short& v); // NOLINT
+template LogMessage& LogMessage::operator<<(const short& v);
+template LogMessage& LogMessage::operator<<(const unsigned short& v);
template LogMessage& LogMessage::operator<<(const int& v);
template LogMessage& LogMessage::operator<<(const unsigned int& v);
-template LogMessage& LogMessage::operator<<(const long& v); // NOLINT
-template LogMessage& LogMessage::operator<<(const unsigned long& v); // NOLINT
-template LogMessage& LogMessage::operator<<(const long long& v); // NOLINT
-template LogMessage& LogMessage::operator<<(
- const unsigned long long& v); // NOLINT
+template LogMessage& LogMessage::operator<<(const long& v);
+template LogMessage& LogMessage::operator<<(const unsigned long& v);
+template LogMessage& LogMessage::operator<<(const long long& v);
+template LogMessage& LogMessage::operator<<(const unsigned long long& v);
template LogMessage& LogMessage::operator<<(void* const& v);
template LogMessage& LogMessage::operator<<(const void* const& v);
template LogMessage& LogMessage::operator<<(const float& v);
template LogMessage& LogMessage::operator<<(const double& v);
template LogMessage& LogMessage::operator<<(const bool& v);
+// NOLINTEND(google-runtime-int)
+// NOLINTEND(runtime/int)
void LogMessage::Flush() {
if (data_->entry.log_severity() < absl::MinLogLevel()) return;
@@ -575,16 +581,17 @@ void LogMessage::LogBacktraceIfNeeded() {
template <LogMessage::StringType str_type>
void LogMessage::CopyToEncodedBuffer(absl::string_view str) {
auto encoded_remaining_copy = data_->encoded_remaining();
+ constexpr uint8_t tag_value = str_type == StringType::kLiteral
+ ? ValueTag::kStringLiteral
+ : ValueTag::kString;
auto start = EncodeMessageStart(
- EventTag::kValue, BufferSizeFor(WireType::kLengthDelimited) + str.size(),
+ EventTag::kValue,
+ BufferSizeFor(tag_value, WireType::kLengthDelimited) + str.size(),
&encoded_remaining_copy);
// If the `logging.proto.Event.value` field header did not fit,
// `EncodeMessageStart` will have zeroed `encoded_remaining_copy`'s size and
// `EncodeStringTruncate` will fail too.
- if (EncodeStringTruncate(str_type == StringType::kLiteral
- ? ValueTag::kStringLiteral
- : ValueTag::kString,
- str, &encoded_remaining_copy)) {
+ if (EncodeStringTruncate(tag_value, str, &encoded_remaining_copy)) {
// The string may have been truncated, but the field header fit.
EncodeMessageLength(start, &encoded_remaining_copy);
data_->encoded_remaining() = encoded_remaining_copy;
@@ -601,13 +608,14 @@ template void LogMessage::CopyToEncodedBuffer<
template <LogMessage::StringType str_type>
void LogMessage::CopyToEncodedBuffer(char ch, size_t num) {
auto encoded_remaining_copy = data_->encoded_remaining();
+ constexpr uint8_t tag_value = str_type == StringType::kLiteral
+ ? ValueTag::kStringLiteral
+ : ValueTag::kString;
auto value_start = EncodeMessageStart(
- EventTag::kValue, BufferSizeFor(WireType::kLengthDelimited) + num,
+ EventTag::kValue,
+ BufferSizeFor(tag_value, WireType::kLengthDelimited) + num,
&encoded_remaining_copy);
- auto str_start = EncodeMessageStart(str_type == StringType::kLiteral
- ? ValueTag::kStringLiteral
- : ValueTag::kString,
- num, &encoded_remaining_copy);
+ auto str_start = EncodeMessageStart(tag_value, num, &encoded_remaining_copy);
if (str_start.data()) {
// The field headers fit.
log_internal::AppendTruncated(ch, num, encoded_remaining_copy);
@@ -625,6 +633,47 @@ template void LogMessage::CopyToEncodedBuffer<LogMessage::StringType::kLiteral>(
template void LogMessage::CopyToEncodedBuffer<
LogMessage::StringType::kNotLiteral>(char ch, size_t num);
+template void LogMessage::CopyToEncodedBufferWithStructuredProtoField<
+ LogMessage::StringType::kLiteral>(StructuredProtoField field,
+ absl::string_view str);
+template void LogMessage::CopyToEncodedBufferWithStructuredProtoField<
+ LogMessage::StringType::kNotLiteral>(StructuredProtoField field,
+ absl::string_view str);
+
+template <LogMessage::StringType str_type>
+void LogMessage::CopyToEncodedBufferWithStructuredProtoField(
+ StructuredProtoField field, absl::string_view str) {
+ auto encoded_remaining_copy = data_->encoded_remaining();
+ size_t encoded_field_size = BufferSizeForStructuredProtoField(field);
+ constexpr uint8_t tag_value = str_type == StringType::kLiteral
+ ? ValueTag::kStringLiteral
+ : ValueTag::kString;
+ auto start = EncodeMessageStart(
+ EventTag::kValue,
+ encoded_field_size +
+ BufferSizeFor(tag_value, WireType::kLengthDelimited) + str.size(),
+ &encoded_remaining_copy);
+
+ // Write the encoded proto field.
+ if (!EncodeStructuredProtoField(field, encoded_remaining_copy)) {
+ // The header / field will not fit; zero `encoded_remaining()` so we
+ // don't write anything else later.
+ data_->encoded_remaining().remove_suffix(data_->encoded_remaining().size());
+ return;
+ }
+
+ // Write the string, truncating if necessary.
+ if (!EncodeStringTruncate(ValueTag::kString, str, &encoded_remaining_copy)) {
+ // The length of the string itself did not fit; zero `encoded_remaining()`
+ // so the value is not encoded at all.
+ data_->encoded_remaining().remove_suffix(data_->encoded_remaining().size());
+ return;
+ }
+
+ EncodeMessageLength(start, &encoded_remaining_copy);
+ data_->encoded_remaining() = encoded_remaining_copy;
+}
+
// We intentionally don't return from these destructors. Disable MSVC's warning
// about the destructor never returning as we do so intentionally here.
#if defined(_MSC_VER) && !defined(__clang__)
@@ -632,11 +681,11 @@ template void LogMessage::CopyToEncodedBuffer<
#pragma warning(disable : 4722)
#endif
-LogMessageFatal::LogMessageFatal(const char* file, int line)
+LogMessageFatal::LogMessageFatal(absl::Nonnull<const char*> file, int line)
: LogMessage(file, line, absl::LogSeverity::kFatal) {}
-LogMessageFatal::LogMessageFatal(const char* file, int line,
- absl::string_view failure_msg)
+LogMessageFatal::LogMessageFatal(absl::Nonnull<const char*> file, int line,
+ absl::Nonnull<const char*> failure_msg)
: LogMessage(file, line, absl::LogSeverity::kFatal) {
*this << "Check failed: " << failure_msg << " ";
}
@@ -646,7 +695,8 @@ LogMessageFatal::~LogMessageFatal() {
FailWithoutStackTrace();
}
-LogMessageDebugFatal::LogMessageDebugFatal(const char* file, int line)
+LogMessageDebugFatal::LogMessageDebugFatal(absl::Nonnull<const char*> file,
+ int line)
: LogMessage(file, line, absl::LogSeverity::kFatal) {}
LogMessageDebugFatal::~LogMessageDebugFatal() {
@@ -654,8 +704,8 @@ LogMessageDebugFatal::~LogMessageDebugFatal() {
FailWithoutStackTrace();
}
-LogMessageQuietlyDebugFatal::LogMessageQuietlyDebugFatal(const char* file,
- int line)
+LogMessageQuietlyDebugFatal::LogMessageQuietlyDebugFatal(
+ absl::Nonnull<const char*> file, int line)
: LogMessage(file, line, absl::LogSeverity::kFatal) {
SetFailQuietly();
}
@@ -665,15 +715,17 @@ LogMessageQuietlyDebugFatal::~LogMessageQuietlyDebugFatal() {
FailQuietly();
}
-LogMessageQuietlyFatal::LogMessageQuietlyFatal(const char* file, int line)
+LogMessageQuietlyFatal::LogMessageQuietlyFatal(absl::Nonnull<const char*> file,
+ int line)
: LogMessage(file, line, absl::LogSeverity::kFatal) {
SetFailQuietly();
}
-LogMessageQuietlyFatal::LogMessageQuietlyFatal(const char* file, int line,
- absl::string_view failure_msg)
+LogMessageQuietlyFatal::LogMessageQuietlyFatal(
+ absl::Nonnull<const char*> file, int line,
+ absl::Nonnull<const char*> failure_msg)
: LogMessageQuietlyFatal(file, line) {
- *this << "Check failed: " << failure_msg << " ";
+ *this << "Check failed: " << failure_msg << " ";
}
LogMessageQuietlyFatal::~LogMessageQuietlyFatal() {
diff --git a/contrib/restricted/abseil-cpp/absl/log/internal/log_message.h b/contrib/restricted/abseil-cpp/absl/log/internal/log_message.h
index 0c067da9ad..7d0e403e3a 100644
--- a/contrib/restricted/abseil-cpp/absl/log/internal/log_message.h
+++ b/contrib/restricted/abseil-cpp/absl/log/internal/log_message.h
@@ -27,17 +27,21 @@
#ifndef ABSL_LOG_INTERNAL_LOG_MESSAGE_H_
#define ABSL_LOG_INTERNAL_LOG_MESSAGE_H_
+#include <cstddef>
#include <ios>
#include <memory>
#include <ostream>
#include <streambuf>
#include <string>
+#include <type_traits>
#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/errno_saver.h"
#include "absl/base/log_severity.h"
+#include "absl/base/nullability.h"
#include "absl/log/internal/nullguard.h"
+#include "absl/log/internal/structured_proto.h"
#include "absl/log/log_entry.h"
#include "absl/log/log_sink.h"
#include "absl/strings/has_absl_stringify.h"
@@ -49,6 +53,8 @@ ABSL_NAMESPACE_BEGIN
namespace log_internal {
constexpr int kLogMessageBufferSize = 15000;
+enum class StructuredStringType;
+
class LogMessage {
public:
struct InfoTag {};
@@ -56,15 +62,15 @@ class LogMessage {
struct ErrorTag {};
// Used for `LOG`.
- LogMessage(const char* file, int line,
+ LogMessage(absl::Nonnull<const char*> file, int line,
absl::LogSeverity severity) ABSL_ATTRIBUTE_COLD;
// These constructors are slightly smaller/faster to call; the severity is
// curried into the function pointer.
- LogMessage(const char* file, int line,
+ LogMessage(absl::Nonnull<const char*> file, int line,
InfoTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE;
- LogMessage(const char* file, int line,
+ LogMessage(absl::Nonnull<const char*> file, int line,
WarningTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE;
- LogMessage(const char* file, int line,
+ LogMessage(absl::Nonnull<const char*> file, int line,
ErrorTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE;
LogMessage(const LogMessage&) = delete;
LogMessage& operator=(const LogMessage&) = delete;
@@ -95,59 +101,67 @@ class LogMessage {
// of `errno`.
LogMessage& WithPerror();
// Sends this message to `*sink` in addition to whatever other sinks it would
- // otherwise have been sent to. `sink` must not be null.
- LogMessage& ToSinkAlso(absl::LogSink* sink);
- // Sends this message to `*sink` and no others. `sink` must not be null.
- LogMessage& ToSinkOnly(absl::LogSink* sink);
+ // otherwise have been sent to.
+ LogMessage& ToSinkAlso(absl::Nonnull<absl::LogSink*> sink);
+ // Sends this message to `*sink` and no others.
+ LogMessage& ToSinkOnly(absl::Nonnull<absl::LogSink*> sink);
// Don't call this method from outside this library.
LogMessage& InternalStream() { return *this; }
// By-value overloads for small, common types let us overlook common failures
// to define globals and static data members (i.e. in a .cc file).
- // clang-format off
- // The CUDA toolchain cannot handle these <<<'s:
+ // NOLINTBEGIN(runtime/int)
+ // NOLINTBEGIN(google-runtime-int)
+ // clang-format off: The CUDA toolchain cannot handle these <<<'s
LogMessage& operator<<(char v) { return operator<< <char>(v); }
LogMessage& operator<<(signed char v) { return operator<< <signed char>(v); }
LogMessage& operator<<(unsigned char v) {
return operator<< <unsigned char>(v);
}
- LogMessage& operator<<(signed short v) { // NOLINT
- return operator<< <signed short>(v); // NOLINT
+ LogMessage& operator<<(signed short v) {
+ return operator<< <signed short>(v);
}
LogMessage& operator<<(signed int v) { return operator<< <signed int>(v); }
- LogMessage& operator<<(signed long v) { // NOLINT
- return operator<< <signed long>(v); // NOLINT
+ LogMessage& operator<<(signed long v) {
+ return operator<< <signed long>(v);
}
- LogMessage& operator<<(signed long long v) { // NOLINT
- return operator<< <signed long long>(v); // NOLINT
+ LogMessage& operator<<(signed long long v) {
+ return operator<< <signed long long>(v);
}
- LogMessage& operator<<(unsigned short v) { // NOLINT
- return operator<< <unsigned short>(v); // NOLINT
+ LogMessage& operator<<(unsigned short v) {
+ return operator<< <unsigned short>(v);
}
LogMessage& operator<<(unsigned int v) {
return operator<< <unsigned int>(v);
}
- LogMessage& operator<<(unsigned long v) { // NOLINT
- return operator<< <unsigned long>(v); // NOLINT
+ LogMessage& operator<<(unsigned long v) {
+ return operator<< <unsigned long>(v);
+ }
+ LogMessage& operator<<(unsigned long long v) {
+ return operator<< <unsigned long long>(v);
}
- LogMessage& operator<<(unsigned long long v) { // NOLINT
- return operator<< <unsigned long long>(v); // NOLINT
+ LogMessage& operator<<(absl::Nullable<void*> v) {
+ return operator<< <void*>(v);
+ }
+ LogMessage& operator<<(absl::Nullable<const void*> v) {
+ return operator<< <const void*>(v);
}
- LogMessage& operator<<(void* v) { return operator<< <void*>(v); }
- LogMessage& operator<<(const void* v) { return operator<< <const void*>(v); }
LogMessage& operator<<(float v) { return operator<< <float>(v); }
LogMessage& operator<<(double v) { return operator<< <double>(v); }
LogMessage& operator<<(bool v) { return operator<< <bool>(v); }
// clang-format on
+ // NOLINTEND(google-runtime-int)
+ // NOLINTEND(runtime/int)
// These overloads are more efficient since no `ostream` is involved.
LogMessage& operator<<(const std::string& v);
LogMessage& operator<<(absl::string_view v);
// Handle stream manipulators e.g. std::endl.
- LogMessage& operator<<(std::ostream& (*m)(std::ostream& os));
- LogMessage& operator<<(std::ios_base& (*m)(std::ios_base& os));
+ LogMessage& operator<<(absl::Nonnull<std::ostream& (*)(std::ostream & os)> m);
+ LogMessage& operator<<(
+ absl::Nonnull<std::ios_base& (*)(std::ios_base & os)> m);
// Literal strings. This allows us to record C string literals as literals in
// the logging.proto.Value.
@@ -206,6 +220,10 @@ class LogMessage {
struct LogMessageData; // Opaque type containing message state
friend class AsLiteralImpl;
friend class StringifySink;
+ template <StructuredStringType str_type>
+ friend class AsStructuredStringTypeImpl;
+ template <typename T>
+ friend class AsStructuredValueImpl;
// This streambuf writes directly into the structured logging buffer so that
// arbitrary types can be encoded as string data (using
@@ -236,6 +254,13 @@ class LogMessage {
template <StringType str_type>
void CopyToEncodedBuffer(char ch, size_t num) ABSL_ATTRIBUTE_NOINLINE;
+ // Copies `field` to the encoded buffer, then appends `str` after it
+ // (truncating `str` if necessary to fit).
+ template <StringType str_type>
+ void CopyToEncodedBufferWithStructuredProtoField(StructuredProtoField field,
+ absl::string_view str)
+ ABSL_ATTRIBUTE_NOINLINE;
+
// Returns `true` if the message is fatal or enabled debug-fatal.
bool IsFatal() const;
@@ -255,7 +280,7 @@ class LogMessage {
// We keep the data in a separate struct so that each instance of `LogMessage`
// uses less stack space.
- std::unique_ptr<LogMessageData> data_;
+ absl::Nonnull<std::unique_ptr<LogMessageData>> data_;
};
// Helper class so that `AbslStringify()` can modify the LogMessage.
@@ -273,7 +298,8 @@ class StringifySink final {
}
// For types that implement `AbslStringify` using `absl::Format()`.
- friend void AbslFormatFlush(StringifySink* sink, absl::string_view v) {
+ friend void AbslFormatFlush(absl::Nonnull<StringifySink*> sink,
+ absl::string_view v) {
sink->Append(v);
}
@@ -315,27 +341,28 @@ LogMessage& LogMessage::operator<<(char (&buf)[SIZE]) {
// We instantiate these specializations in the library's TU to save space in
// other TUs. Since the template is marked `ABSL_ATTRIBUTE_NOINLINE` we will be
// emitting a function call either way.
+// NOLINTBEGIN(runtime/int)
+// NOLINTBEGIN(google-runtime-int)
extern template LogMessage& LogMessage::operator<<(const char& v);
extern template LogMessage& LogMessage::operator<<(const signed char& v);
extern template LogMessage& LogMessage::operator<<(const unsigned char& v);
-extern template LogMessage& LogMessage::operator<<(const short& v); // NOLINT
-extern template LogMessage& LogMessage::operator<<(
- const unsigned short& v); // NOLINT
+extern template LogMessage& LogMessage::operator<<(const short& v);
+extern template LogMessage& LogMessage::operator<<(const unsigned short& v);
extern template LogMessage& LogMessage::operator<<(const int& v);
+extern template LogMessage& LogMessage::operator<<(const unsigned int& v);
+extern template LogMessage& LogMessage::operator<<(const long& v);
+extern template LogMessage& LogMessage::operator<<(const unsigned long& v);
+extern template LogMessage& LogMessage::operator<<(const long long& v);
+extern template LogMessage& LogMessage::operator<<(const unsigned long long& v);
extern template LogMessage& LogMessage::operator<<(
- const unsigned int& v); // NOLINT
-extern template LogMessage& LogMessage::operator<<(const long& v); // NOLINT
-extern template LogMessage& LogMessage::operator<<(
- const unsigned long& v); // NOLINT
-extern template LogMessage& LogMessage::operator<<(
- const long long& v); // NOLINT
+ absl::Nullable<void*> const& v);
extern template LogMessage& LogMessage::operator<<(
- const unsigned long long& v); // NOLINT
-extern template LogMessage& LogMessage::operator<<(void* const& v);
-extern template LogMessage& LogMessage::operator<<(const void* const& v);
+ absl::Nullable<const void*> const& v);
extern template LogMessage& LogMessage::operator<<(const float& v);
extern template LogMessage& LogMessage::operator<<(const double& v);
extern template LogMessage& LogMessage::operator<<(const bool& v);
+// NOLINTEND(google-runtime-int)
+// NOLINTEND(runtime/int)
extern template void LogMessage::CopyToEncodedBuffer<
LogMessage::StringType::kLiteral>(absl::string_view str);
@@ -351,9 +378,10 @@ extern template void LogMessage::CopyToEncodedBuffer<
// message.
class LogMessageFatal final : public LogMessage {
public:
- LogMessageFatal(const char* file, int line) ABSL_ATTRIBUTE_COLD;
- LogMessageFatal(const char* file, int line,
- absl::string_view failure_msg) ABSL_ATTRIBUTE_COLD;
+ LogMessageFatal(absl::Nonnull<const char*> file,
+ int line) ABSL_ATTRIBUTE_COLD;
+ LogMessageFatal(absl::Nonnull<const char*> file, int line,
+ absl::Nonnull<const char*> failure_msg) ABSL_ATTRIBUTE_COLD;
[[noreturn]] ~LogMessageFatal();
};
@@ -362,7 +390,8 @@ class LogMessageFatal final : public LogMessage {
// for DLOG(FATAL) variants.
class LogMessageDebugFatal final : public LogMessage {
public:
- LogMessageDebugFatal(const char* file, int line) ABSL_ATTRIBUTE_COLD;
+ LogMessageDebugFatal(absl::Nonnull<const char*> file,
+ int line) ABSL_ATTRIBUTE_COLD;
~LogMessageDebugFatal();
};
@@ -371,16 +400,19 @@ class LogMessageQuietlyDebugFatal final : public LogMessage {
// DLOG(QFATAL) calls this instead of LogMessageQuietlyFatal to make sure the
// destructor is not [[noreturn]] even if this is always FATAL as this is only
// invoked when DLOG() is enabled.
- LogMessageQuietlyDebugFatal(const char* file, int line) ABSL_ATTRIBUTE_COLD;
+ LogMessageQuietlyDebugFatal(absl::Nonnull<const char*> file,
+ int line) ABSL_ATTRIBUTE_COLD;
~LogMessageQuietlyDebugFatal();
};
// Used for LOG(QFATAL) to make sure it's properly understood as [[noreturn]].
class LogMessageQuietlyFatal final : public LogMessage {
public:
- LogMessageQuietlyFatal(const char* file, int line) ABSL_ATTRIBUTE_COLD;
- LogMessageQuietlyFatal(const char* file, int line,
- absl::string_view failure_msg) ABSL_ATTRIBUTE_COLD;
+ LogMessageQuietlyFatal(absl::Nonnull<const char*> file,
+ int line) ABSL_ATTRIBUTE_COLD;
+ LogMessageQuietlyFatal(absl::Nonnull<const char*> file, int line,
+ absl::Nonnull<const char*> failure_msg)
+ ABSL_ATTRIBUTE_COLD;
[[noreturn]] ~LogMessageQuietlyFatal();
};
diff --git a/contrib/restricted/abseil-cpp/absl/log/internal/proto.cc b/contrib/restricted/abseil-cpp/absl/log/internal/proto.cc
index eb699ae8e7..3513b15053 100644
--- a/contrib/restricted/abseil-cpp/absl/log/internal/proto.cc
+++ b/contrib/restricted/abseil-cpp/absl/log/internal/proto.cc
@@ -35,9 +35,6 @@ void EncodeRawVarint(uint64_t value, size_t size, absl::Span<char> *buf) {
}
buf->remove_prefix(size);
}
-constexpr uint64_t MakeTagType(uint64_t tag, WireType type) {
- return tag << 3 | static_cast<uint64_t>(type);
-}
} // namespace
bool EncodeVarint(uint64_t tag, uint64_t value, absl::Span<char> *buf) {
diff --git a/contrib/restricted/abseil-cpp/absl/log/internal/proto.h b/contrib/restricted/abseil-cpp/absl/log/internal/proto.h
index c8d14acc47..20a9f3a80b 100644
--- a/contrib/restricted/abseil-cpp/absl/log/internal/proto.h
+++ b/contrib/restricted/abseil-cpp/absl/log/internal/proto.h
@@ -199,23 +199,33 @@ constexpr uint64_t MaxVarintForSize(size_t size) {
return size >= 10 ? (std::numeric_limits<uint64_t>::max)()
: (static_cast<uint64_t>(1) << size * 7) - 1;
}
+constexpr uint64_t MakeTagType(uint64_t tag, WireType type) {
+ return tag << 3 | static_cast<uint64_t>(type);
+}
// `BufferSizeFor` returns a number of bytes guaranteed to be sufficient to
-// store encoded fields of the specified WireTypes regardless of tag numbers and
-// data values. This only makes sense for `WireType::kLengthDelimited` if you
-// add in the length of the contents yourself, e.g. for string and bytes fields
-// by adding the lengths of any encoded strings to the return value or for
-// submessage fields by enumerating the fields you may encode into their
-// contents.
-constexpr size_t BufferSizeFor() { return 0; }
-template <typename... T>
-constexpr size_t BufferSizeFor(WireType type, T... tail) {
- // tag_type + data + ...
- return MaxVarintSize() +
- (type == WireType::kVarint ? MaxVarintSize() : //
- type == WireType::k64Bit ? 8 : //
- type == WireType::k32Bit ? 4 : MaxVarintSize()) + //
- BufferSizeFor(tail...);
+// store encoded fields as `(tag, WireType)`, regardless of data values. This
+// only makes sense for `WireType::kLengthDelimited` if you add in the length of
+// the contents yourself, e.g. for string and bytes fields by adding the lengths
+// of any encoded strings to the return value or for submessage fields by
+// enumerating the fields you may encode into their contents.
+constexpr size_t BufferSizeFor(uint64_t tag, WireType type) {
+ size_t buffer_size = VarintSize(MakeTagType(tag, type));
+ switch (type) {
+ case WireType::kVarint:
+ buffer_size += MaxVarintSize();
+ break;
+ case WireType::k64Bit:
+ buffer_size += size_t{8};
+ break;
+ case WireType::kLengthDelimited:
+ buffer_size += MaxVarintSize();
+ break;
+ case WireType::k32Bit:
+ buffer_size += size_t{4};
+ break;
+ }
+ return buffer_size;
}
// absl::Span<const char> represents a view into the un-processed space in a
diff --git a/contrib/restricted/abseil-cpp/absl/log/internal/structured.h b/contrib/restricted/abseil-cpp/absl/log/internal/structured.h
index 5223dbc310..50783dffd2 100644
--- a/contrib/restricted/abseil-cpp/absl/log/internal/structured.h
+++ b/contrib/restricted/abseil-cpp/absl/log/internal/structured.h
@@ -20,9 +20,14 @@
#define ABSL_LOG_INTERNAL_STRUCTURED_H_
#include <ostream>
+#include <string>
+#include "absl/base/attributes.h"
#include "absl/base/config.h"
+#include "absl/functional/any_invocable.h"
#include "absl/log/internal/log_message.h"
+#include "absl/log/internal/structured_proto.h"
+#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
namespace absl {
@@ -31,14 +36,16 @@ namespace log_internal {
class ABSL_MUST_USE_RESULT AsLiteralImpl final {
public:
- explicit AsLiteralImpl(absl::string_view str) : str_(str) {}
+ explicit AsLiteralImpl(absl::string_view str ABSL_ATTRIBUTE_LIFETIME_BOUND)
+ : str_(str) {}
AsLiteralImpl(const AsLiteralImpl&) = default;
AsLiteralImpl& operator=(const AsLiteralImpl&) = default;
private:
absl::string_view str_;
- friend std::ostream& operator<<(std::ostream& os, AsLiteralImpl as_literal) {
+ friend std::ostream& operator<<(std::ostream& os,
+ AsLiteralImpl&& as_literal) {
return os << as_literal.str_;
}
void AddToMessage(log_internal::LogMessage& m) {
@@ -51,6 +58,105 @@ class ABSL_MUST_USE_RESULT AsLiteralImpl final {
}
};
+enum class StructuredStringType {
+ kLiteral,
+ kNotLiteral,
+};
+
+// Structured log data for a string and associated structured proto field,
+// both of which must outlive this object.
+template <StructuredStringType str_type>
+class ABSL_MUST_USE_RESULT AsStructuredStringTypeImpl final {
+ public:
+ constexpr AsStructuredStringTypeImpl(
+ absl::string_view str ABSL_ATTRIBUTE_LIFETIME_BOUND,
+ StructuredProtoField field ABSL_ATTRIBUTE_LIFETIME_BOUND)
+ : str_(str), field_(field) {}
+
+ private:
+ absl::string_view str_;
+ StructuredProtoField field_;
+
+ friend std::ostream& operator<<(std::ostream& os,
+ const AsStructuredStringTypeImpl& impl) {
+ return os << impl.str_;
+ }
+ void AddToMessage(LogMessage& m) const {
+ if (str_type == StructuredStringType::kLiteral) {
+ return m.CopyToEncodedBufferWithStructuredProtoField<
+ log_internal::LogMessage::StringType::kLiteral>(field_, str_);
+ } else {
+ return m.CopyToEncodedBufferWithStructuredProtoField<
+ log_internal::LogMessage::StringType::kNotLiteral>(field_, str_);
+ }
+ }
+ friend LogMessage& operator<<(LogMessage& m,
+ const AsStructuredStringTypeImpl& impl) {
+ impl.AddToMessage(m);
+ return m;
+ }
+};
+
+using AsStructuredLiteralImpl =
+ AsStructuredStringTypeImpl<StructuredStringType::kLiteral>;
+using AsStructuredNotLiteralImpl =
+ AsStructuredStringTypeImpl<StructuredStringType::kNotLiteral>;
+
+// Structured log data for a stringifyable type T and associated structured
+// proto field, both of which must outlive this object.
+template <typename T>
+class ABSL_MUST_USE_RESULT AsStructuredValueImpl final {
+ public:
+ using ValueFormatter = absl::AnyInvocable<std::string(T) const>;
+
+ constexpr AsStructuredValueImpl(
+ T value ABSL_ATTRIBUTE_LIFETIME_BOUND,
+ StructuredProtoField field ABSL_ATTRIBUTE_LIFETIME_BOUND,
+ ValueFormatter value_formatter =
+ [](T value) { return absl::StrCat(value); })
+ : value_(value),
+ field_(field),
+ value_formatter_(std::move(value_formatter)) {}
+
+ private:
+ T value_;
+ StructuredProtoField field_;
+ ValueFormatter value_formatter_;
+
+ friend std::ostream& operator<<(std::ostream& os,
+ const AsStructuredValueImpl& impl) {
+ return os << impl.value_formatter_(impl.value_);
+ }
+ void AddToMessage(LogMessage& m) const {
+ m.CopyToEncodedBufferWithStructuredProtoField<
+ log_internal::LogMessage::StringType::kNotLiteral>(
+ field_, value_formatter_(value_));
+ }
+ friend LogMessage& operator<<(LogMessage& m,
+ const AsStructuredValueImpl& impl) {
+ impl.AddToMessage(m);
+ return m;
+ }
+};
+
+#ifdef ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
+
+// Template deduction guide so `AsStructuredValueImpl(42, data)` works
+// without specifying the template type.
+template <typename T>
+AsStructuredValueImpl(T value, StructuredProtoField field)
+ -> AsStructuredValueImpl<T>;
+
+// Template deduction guide so `AsStructuredValueImpl(42, data, formatter)`
+// works without specifying the template type.
+template <typename T>
+AsStructuredValueImpl(
+ T value, StructuredProtoField field,
+ typename AsStructuredValueImpl<T>::ValueFormatter value_formatter)
+ -> AsStructuredValueImpl<T>;
+
+#endif // ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
+
} // namespace log_internal
ABSL_NAMESPACE_END
} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/log/internal/structured_proto.cc b/contrib/restricted/abseil-cpp/absl/log/internal/structured_proto.cc
new file mode 100644
index 0000000000..e3829e4b5d
--- /dev/null
+++ b/contrib/restricted/abseil-cpp/absl/log/internal/structured_proto.cc
@@ -0,0 +1,115 @@
+//
+// Copyright 2024 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/log/internal/structured_proto.h"
+
+#include <cstdint>
+
+#include "absl/base/config.h"
+#include "absl/log/internal/proto.h"
+#include "absl/types/span.h"
+#include "absl/types/variant.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace log_internal {
+
+namespace {
+
+// Handles protobuf-encoding a type contained inside
+// `StructuredProtoField::Varint`.
+struct VarintEncoderVisitor final {
+ template <typename T>
+ bool operator()(T value) const {
+ return EncodeVarint(field_number, value, &buf);
+ }
+
+ uint64_t field_number;
+ absl::Span<char>& buf;
+};
+
+// Handles protobuf-encoding a type contained inside
+// `StructuredProtoField::I64`.
+struct I64EncoderVisitor final {
+ bool operator()(uint64_t value) const {
+ return Encode64Bit(field_number, value, &buf);
+ }
+
+ bool operator()(int64_t value) const {
+ return Encode64Bit(field_number, value, &buf);
+ }
+
+ bool operator()(double value) const {
+ return EncodeDouble(field_number, value, &buf);
+ }
+
+ uint64_t field_number;
+ absl::Span<char>& buf;
+};
+
+// Handles protobuf-encoding a type contained inside
+// `StructuredProtoField::I32`.
+struct I32EncoderVisitor final {
+ bool operator()(uint32_t value) const {
+ return Encode32Bit(field_number, value, &buf);
+ }
+
+ bool operator()(int32_t value) const {
+ return Encode32Bit(field_number, value, &buf);
+ }
+
+ bool operator()(float value) const {
+ return EncodeFloat(field_number, value, &buf);
+ }
+
+ uint64_t field_number;
+ absl::Span<char>& buf;
+};
+
+// Handles protobuf-encoding a type contained inside `StructuredProtoField`.
+struct EncoderVisitor final {
+ bool operator()(StructuredProtoField::Varint varint) {
+ return absl::visit(VarintEncoderVisitor{field_number, buf}, varint);
+ }
+
+ bool operator()(StructuredProtoField::I64 i64) {
+ return absl::visit(I64EncoderVisitor{field_number, buf}, i64);
+ }
+
+ bool operator()(StructuredProtoField::LengthDelimited length_delimited) {
+ // No need for a visitor, since `StructuredProtoField::LengthDelimited` is
+ // just `absl::Span<const char>`.
+ return EncodeBytes(field_number, length_delimited, &buf);
+ }
+
+ bool operator()(StructuredProtoField::I32 i32) {
+ return absl::visit(I32EncoderVisitor{field_number, buf}, i32);
+ }
+
+ uint64_t field_number;
+ absl::Span<char>& buf;
+};
+
+} // namespace
+
+bool EncodeStructuredProtoField(StructuredProtoField field,
+ absl::Span<char>& buf) {
+ return absl::visit(EncoderVisitor{field.field_number, buf}, field.value);
+}
+
+} // namespace log_internal
+
+ABSL_NAMESPACE_END
+} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/log/internal/structured_proto.h b/contrib/restricted/abseil-cpp/absl/log/internal/structured_proto.h
new file mode 100644
index 0000000000..3ebc4beb55
--- /dev/null
+++ b/contrib/restricted/abseil-cpp/absl/log/internal/structured_proto.h
@@ -0,0 +1,107 @@
+// Copyright 2024 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: log/internal/structured_proto.h
+// -----------------------------------------------------------------------------
+
+#ifndef ABSL_LOG_INTERNAL_STRUCTURED_PROTO_H_
+#define ABSL_LOG_INTERNAL_STRUCTURED_PROTO_H_
+
+#include <cstddef>
+#include <cstdint>
+
+#include "absl/base/config.h"
+#include "absl/log/internal/proto.h"
+#include "absl/types/span.h"
+#include "absl/types/variant.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace log_internal {
+
+// Sum type holding a single valid protobuf field suitable for encoding.
+struct StructuredProtoField final {
+ // Numeric type encoded with varint encoding:
+ // https://protobuf.dev/programming-guides/encoding/#varints
+ using Varint = absl::variant<uint64_t, int64_t, uint32_t, int32_t, bool>;
+
+ // Fixed-length 64-bit integer encoding:
+ // https://protobuf.dev/programming-guides/encoding/#non-varints
+ using I64 = absl::variant<uint64_t, int64_t, double>;
+
+ // Length-delimited record type (string, sub-message):
+ // https://protobuf.dev/programming-guides/encoding/#length-types
+ using LengthDelimited = absl::Span<const char>;
+
+ // Fixed-length 32-bit integer encoding:
+ // https://protobuf.dev/programming-guides/encoding/#non-varints
+ using I32 = absl::variant<uint32_t, int32_t, float>;
+
+ // Valid record type:
+ // https://protobuf.dev/programming-guides/encoding/#structure
+ using Value = absl::variant<Varint, I64, LengthDelimited, I32>;
+
+ // Field number for the protobuf value.
+ uint64_t field_number;
+
+ // Value to encode.
+ Value value;
+};
+
+// Estimates the number of bytes needed to encode `field` using
+// protobuf encoding.
+//
+// The returned value might be larger than the actual number of bytes needed.
+inline size_t BufferSizeForStructuredProtoField(StructuredProtoField field) {
+ // Visitor to estimate the number of bytes of one of the types contained
+ // inside `StructuredProtoField`.
+ struct BufferSizeVisitor final {
+ size_t operator()(StructuredProtoField::Varint /*unused*/) {
+ return BufferSizeFor(field_number, WireType::kVarint);
+ }
+
+ size_t operator()(StructuredProtoField::I64 /*unused*/) {
+ return BufferSizeFor(field_number, WireType::k64Bit);
+ }
+
+ size_t operator()(StructuredProtoField::LengthDelimited length_delimited) {
+ return BufferSizeFor(field_number, WireType::kLengthDelimited) +
+ length_delimited.size();
+ }
+
+ size_t operator()(StructuredProtoField::I32 /*unused*/) {
+ return BufferSizeFor(field_number, WireType::k32Bit);
+ }
+
+ uint64_t field_number;
+ };
+
+ return absl::visit(BufferSizeVisitor{field.field_number}, field.value);
+}
+
+// Encodes `field` into `buf` using protobuf encoding.
+//
+// On success, returns `true` and advances `buf` to the end of
+// the bytes consumed.
+//
+// On failure (if `buf` was too small), returns `false`.
+bool EncodeStructuredProtoField(StructuredProtoField field,
+ absl::Span<char>& buf);
+
+} // namespace log_internal
+ABSL_NAMESPACE_END
+} // namespace absl
+
+#endif // ABSL_LOG_INTERNAL_STRUCTURED_PROTO_H_
diff --git a/contrib/restricted/abseil-cpp/absl/log/internal/vlog_config.cc b/contrib/restricted/abseil-cpp/absl/log/internal/vlog_config.cc
index b578850041..f7c61bed52 100644
--- a/contrib/restricted/abseil-cpp/absl/log/internal/vlog_config.cc
+++ b/contrib/restricted/abseil-cpp/absl/log/internal/vlog_config.cc
@@ -207,7 +207,14 @@ int PrependVModuleLocked(absl::string_view module_pattern, int log_level)
get_vmodule_info().erase(
std::remove_if(++iter, get_vmodule_info().end(),
[module_pattern](const VModuleInfo& info) {
- return FNMatch(info.module_pattern, module_pattern);
+ // Remove the previous pattern if it is less generic than
+ // the new one. For example, if the new pattern
+ // `module_pattern` is "foo*" and the previous pattern
+ // `info.module_pattern` is "foo", we should remove the
+ // previous pattern. Because the new pattern "foo*" will
+ // match all the files that the previous pattern "foo"
+ // matches.
+ return FNMatch(module_pattern, info.module_pattern);
}),
get_vmodule_info().cend());
return old_log_level.value_or(global_v);
diff --git a/contrib/restricted/abseil-cpp/absl/log/log_sink_registry.h b/contrib/restricted/abseil-cpp/absl/log/log_sink_registry.h
index bf76cceeae..3aa3bf6795 100644
--- a/contrib/restricted/abseil-cpp/absl/log/log_sink_registry.h
+++ b/contrib/restricted/abseil-cpp/absl/log/log_sink_registry.h
@@ -22,6 +22,7 @@
#define ABSL_LOG_LOG_SINK_REGISTRY_H_
#include "absl/base/config.h"
+#include "absl/base/nullability.h"
#include "absl/log/internal/log_sink_set.h"
#include "absl/log/log_sink.h"
@@ -43,8 +44,10 @@ ABSL_NAMESPACE_BEGIN
// sink instead which writes them to `stderr`.
//
// Do not call these inside `absl::LogSink::Send`.
-inline void AddLogSink(absl::LogSink* sink) { log_internal::AddLogSink(sink); }
-inline void RemoveLogSink(absl::LogSink* sink) {
+inline void AddLogSink(absl::Nonnull<absl::LogSink*> sink) {
+ log_internal::AddLogSink(sink);
+}
+inline void RemoveLogSink(absl::Nonnull<absl::LogSink*> sink) {
log_internal::RemoveLogSink(sink);
}
diff --git a/contrib/restricted/abseil-cpp/absl/log/scoped_mock_log.h b/contrib/restricted/abseil-cpp/absl/log/scoped_mock_log.h
index 399e604deb..a383066741 100644
--- a/contrib/restricted/abseil-cpp/absl/log/scoped_mock_log.h
+++ b/contrib/restricted/abseil-cpp/absl/log/scoped_mock_log.h
@@ -40,8 +40,8 @@ enum class MockLogDefault { kIgnoreUnexpected, kDisallowUnexpected };
// ScopedMockLog
//
-// ScopedMockLog is a LogSink that intercepts LOG() messages issued during its
-// lifespan.
+// ScopedMockLog is a LogSink that intercepts LOG() messages issued by all
+// threads when active.
//
// Using this together with GoogleTest, it's easy to test how a piece of code
// calls LOG(). The typical usage, noting the distinction between
diff --git a/contrib/restricted/abseil-cpp/absl/log/structured.h b/contrib/restricted/abseil-cpp/absl/log/structured.h
index 9ad69fbdcd..89d241e4f5 100644
--- a/contrib/restricted/abseil-cpp/absl/log/structured.h
+++ b/contrib/restricted/abseil-cpp/absl/log/structured.h
@@ -32,6 +32,7 @@
#include <ostream>
+#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/log/internal/structured.h"
#include "absl/strings/string_view.h"
@@ -60,7 +61,11 @@ ABSL_NAMESPACE_BEGIN
// int line) {
// LOG(LEVEL(severity)).AtLocation(file, line) << absl::LogAsLiteral(str);
// }
-inline log_internal::AsLiteralImpl LogAsLiteral(absl::string_view s) {
+//
+// `LogAsLiteral` should only be used as a streaming operand and not, for
+// example, as a local variable initializer.
+inline log_internal::AsLiteralImpl LogAsLiteral(
+ absl::string_view s ABSL_ATTRIBUTE_LIFETIME_BOUND) {
return log_internal::AsLiteralImpl(s);
}
diff --git a/contrib/restricted/abseil-cpp/absl/log/vlog_is_on.h b/contrib/restricted/abseil-cpp/absl/log/vlog_is_on.h
index f7539df4ea..c33fcc173d 100644
--- a/contrib/restricted/abseil-cpp/absl/log/vlog_is_on.h
+++ b/contrib/restricted/abseil-cpp/absl/log/vlog_is_on.h
@@ -40,6 +40,8 @@
// last . and everything after it) is stripped from each filename prior to
// matching, as is the special suffix "-inl".
//
+// Example: --vmodule=module_a=1,module_b=2
+//
// Files are matched against globs in `--vmodule` in order, and the first match
// determines the verbosity level.
//
diff --git a/contrib/restricted/abseil-cpp/absl/log/ya.make b/contrib/restricted/abseil-cpp/absl/log/ya.make
index 743000eb5e..6e721ca636 100644
--- a/contrib/restricted/abseil-cpp/absl/log/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/log/ya.make
@@ -6,7 +6,7 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20240722.1)
+VERSION(20250127.0)
PEERDIR(
contrib/restricted/abseil-cpp/absl/base
@@ -48,6 +48,7 @@ SRCS(
internal/log_sink_set.cc
internal/nullguard.cc
internal/proto.cc
+ internal/structured_proto.cc
internal/vlog_config.cc
log_entry.cc
log_sink.cc
diff --git a/contrib/restricted/abseil-cpp/absl/memory/ya.make b/contrib/restricted/abseil-cpp/absl/memory/ya.make
index 7125e13df7..b8267ff47e 100644
--- a/contrib/restricted/abseil-cpp/absl/memory/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/memory/ya.make
@@ -6,9 +6,9 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20240722.1)
+VERSION(20250127.0)
-ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20240722.1.tar.gz)
+ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20250127.0.tar.gz)
PEERDIR(
contrib/restricted/abseil-cpp/absl/meta
diff --git a/contrib/restricted/abseil-cpp/absl/meta/type_traits.h b/contrib/restricted/abseil-cpp/absl/meta/type_traits.h
index ded55820a3..02da0674a8 100644
--- a/contrib/restricted/abseil-cpp/absl/meta/type_traits.h
+++ b/contrib/restricted/abseil-cpp/absl/meta/type_traits.h
@@ -503,10 +503,11 @@ using swap_internal::Swap;
// remove the condition.
//
// Clang on all platforms fails to detect that a type with a user-provided
-// move-assignment operator is not trivially relocatable. So in fact we
-// opt out of Clang altogether, for now.
+// move-assignment operator is not trivially relocatable so we also check for
+// is_trivially_move_assignable for Clang.
//
-// TODO(b/325479096): Remove the opt-out once Clang's behavior is fixed.
+// TODO(b/325479096): Remove the Clang is_trivially_move_assignable version once
+// Clang's behavior is fixed.
//
// According to https://github.com/abseil/abseil-cpp/issues/1479, this does not
// work with NVCC either.
@@ -516,6 +517,15 @@ using swap_internal::Swap;
template <class T>
struct is_trivially_relocatable
: std::integral_constant<bool, __is_trivially_relocatable(T)> {};
+#elif ABSL_HAVE_BUILTIN(__is_trivially_relocatable) && defined(__clang__) && \
+ !(defined(_WIN32) || defined(_WIN64)) && !defined(__APPLE__) && \
+ !defined(__NVCC__)
+template <class T>
+struct is_trivially_relocatable
+ : std::integral_constant<
+ bool, std::is_trivially_copyable<T>::value ||
+ (__is_trivially_relocatable(T) &&
+ std::is_trivially_move_assignable<T>::value)> {};
#else
// Otherwise we use a fallback that detects only those types we can feasibly
// detect. Any type that is trivially copyable is by definition trivially
@@ -648,9 +658,9 @@ struct IsView<std::span<T>> : std::true_type {};
// Until then, we consider an assignment from an "owner" (such as std::string)
// to a "view" (such as std::string_view) to be a lifetime-bound assignment.
template <typename T, typename U>
-using IsLifetimeBoundAssignment =
- std::integral_constant<bool, IsView<absl::remove_cvref_t<T>>::value &&
- IsOwner<absl::remove_cvref_t<U>>::value>;
+using IsLifetimeBoundAssignment = absl::conjunction<
+ std::integral_constant<bool, !std::is_lvalue_reference<U>::value>,
+ IsOwner<absl::remove_cvref_t<U>>, IsView<absl::remove_cvref_t<T>>>;
} // namespace type_traits_internal
diff --git a/contrib/restricted/abseil-cpp/absl/meta/ya.make b/contrib/restricted/abseil-cpp/absl/meta/ya.make
index 8b2d3b836b..0260771d82 100644
--- a/contrib/restricted/abseil-cpp/absl/meta/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/meta/ya.make
@@ -6,9 +6,9 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20240722.1)
+VERSION(20250127.0)
-ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20240722.1.tar.gz)
+ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20250127.0.tar.gz)
PEERDIR(
contrib/restricted/abseil-cpp/absl/base
diff --git a/contrib/restricted/abseil-cpp/absl/numeric/int128.h b/contrib/restricted/abseil-cpp/absl/numeric/int128.h
index 5a067d17b3..ae736b2846 100644
--- a/contrib/restricted/abseil-cpp/absl/numeric/int128.h
+++ b/contrib/restricted/abseil-cpp/absl/numeric/int128.h
@@ -216,7 +216,11 @@ class
// Support for absl::Hash.
template <typename H>
friend H AbslHashValue(H h, uint128 v) {
+#if defined(ABSL_HAVE_INTRINSIC_INT128)
+ return H::combine(std::move(h), static_cast<unsigned __int128>(v));
+#else
return H::combine(std::move(h), Uint128High64(v), Uint128Low64(v));
+#endif
}
// Support for absl::StrCat() etc.
@@ -458,7 +462,11 @@ class int128 {
// Support for absl::Hash.
template <typename H>
friend H AbslHashValue(H h, int128 v) {
+#if defined(ABSL_HAVE_INTRINSIC_INT128)
+ return H::combine(std::move(h), v.v_);
+#else
return H::combine(std::move(h), Int128High64(v), Int128Low64(v));
+#endif
}
// Support for absl::StrCat() etc.
@@ -781,16 +789,20 @@ constexpr uint128::operator unsigned __int128() const {
// Conversion operators to floating point types.
inline uint128::operator float() const {
- return static_cast<float>(lo_) + std::ldexp(static_cast<float>(hi_), 64);
+ // Note: This method might return Inf.
+ constexpr float pow_2_64 = 18446744073709551616.0f;
+ return static_cast<float>(lo_) + static_cast<float>(hi_) * pow_2_64;
}
inline uint128::operator double() const {
- return static_cast<double>(lo_) + std::ldexp(static_cast<double>(hi_), 64);
+ constexpr double pow_2_64 = 18446744073709551616.0;
+ return static_cast<double>(lo_) + static_cast<double>(hi_) * pow_2_64;
}
inline uint128::operator long double() const {
+ constexpr long double pow_2_64 = 18446744073709551616.0L;
return static_cast<long double>(lo_) +
- std::ldexp(static_cast<long double>(hi_), 64);
+ static_cast<long double>(hi_) * pow_2_64;
}
// Comparison operators.
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 51e4b9d485..216115a412 100644
--- a/contrib/restricted/abseil-cpp/absl/numeric/int128_have_intrinsic.inc
+++ b/contrib/restricted/abseil-cpp/absl/numeric/int128_have_intrinsic.inc
@@ -170,27 +170,29 @@ inline int128::operator float() const {
// complement overwhelms the precision of the mantissa.
//
// Also check to make sure we don't negate Int128Min()
+ constexpr float pow_2_64 = 18446744073709551616.0f;
return v_ < 0 && *this != Int128Min()
? -static_cast<float>(-*this)
: static_cast<float>(Int128Low64(*this)) +
- std::ldexp(static_cast<float>(Int128High64(*this)), 64);
+ static_cast<float>(Int128High64(*this)) * pow_2_64;
}
inline int128::operator double() const {
// See comment in int128::operator float() above.
+ constexpr double pow_2_64 = 18446744073709551616.0;
return v_ < 0 && *this != Int128Min()
? -static_cast<double>(-*this)
: static_cast<double>(Int128Low64(*this)) +
- std::ldexp(static_cast<double>(Int128High64(*this)), 64);
+ static_cast<double>(Int128High64(*this)) * pow_2_64;
}
inline int128::operator long double() const {
// See comment in int128::operator float() above.
+ constexpr long double pow_2_64 = 18446744073709551616.0L;
return v_ < 0 && *this != Int128Min()
? -static_cast<long double>(-*this)
: static_cast<long double>(Int128Low64(*this)) +
- std::ldexp(static_cast<long double>(Int128High64(*this)),
- 64);
+ static_cast<long double>(Int128High64(*this)) * pow_2_64;
}
#endif // Clang on PowerPC
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 195b7452ea..a7cdceabfa 100644
--- a/contrib/restricted/abseil-cpp/absl/numeric/int128_no_intrinsic.inc
+++ b/contrib/restricted/abseil-cpp/absl/numeric/int128_no_intrinsic.inc
@@ -139,26 +139,29 @@ inline int128::operator float() const {
// complement overwhelms the precision of the mantissa.
//
// Also check to make sure we don't negate Int128Min()
+ constexpr float pow_2_64 = 18446744073709551616.0f;
return hi_ < 0 && *this != Int128Min()
? -static_cast<float>(-*this)
: static_cast<float>(lo_) +
- std::ldexp(static_cast<float>(hi_), 64);
+ static_cast<float>(hi_) * pow_2_64;
}
inline int128::operator double() const {
// See comment in int128::operator float() above.
+ constexpr double pow_2_64 = 18446744073709551616.0;
return hi_ < 0 && *this != Int128Min()
? -static_cast<double>(-*this)
: static_cast<double>(lo_) +
- std::ldexp(static_cast<double>(hi_), 64);
+ static_cast<double>(hi_) * pow_2_64;
}
inline int128::operator long double() const {
// See comment in int128::operator float() above.
+ constexpr long double pow_2_64 = 18446744073709551616.0L;
return hi_ < 0 && *this != Int128Min()
? -static_cast<long double>(-*this)
: static_cast<long double>(lo_) +
- std::ldexp(static_cast<long double>(hi_), 64);
+ static_cast<long double>(hi_) * pow_2_64;
}
// Comparison operators.
diff --git a/contrib/restricted/abseil-cpp/absl/numeric/ya.make b/contrib/restricted/abseil-cpp/absl/numeric/ya.make
index ff64443a48..4abce215fe 100644
--- a/contrib/restricted/abseil-cpp/absl/numeric/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/numeric/ya.make
@@ -6,7 +6,7 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20240722.1)
+VERSION(20250127.0)
ADDINCL(
GLOBAL contrib/restricted/abseil-cpp
diff --git a/contrib/restricted/abseil-cpp/absl/profiling/ya.make b/contrib/restricted/abseil-cpp/absl/profiling/ya.make
index e5a60c5c9d..8ce0b25df3 100644
--- a/contrib/restricted/abseil-cpp/absl/profiling/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/profiling/ya.make
@@ -6,7 +6,7 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20240722.1)
+VERSION(20250127.0)
ADDINCL(
GLOBAL contrib/restricted/abseil-cpp
diff --git a/contrib/restricted/abseil-cpp/absl/random/bernoulli_distribution.h b/contrib/restricted/abseil-cpp/absl/random/bernoulli_distribution.h
index d81b6ae6b1..10c24e6221 100644
--- a/contrib/restricted/abseil-cpp/absl/random/bernoulli_distribution.h
+++ b/contrib/restricted/abseil-cpp/absl/random/bernoulli_distribution.h
@@ -15,10 +15,12 @@
#ifndef ABSL_RANDOM_BERNOULLI_DISTRIBUTION_H_
#define ABSL_RANDOM_BERNOULLI_DISTRIBUTION_H_
+#include <cassert>
#include <cstdint>
#include <istream>
-#include <limits>
+#include <ostream>
+#include "absl/base/config.h"
#include "absl/base/optimization.h"
#include "absl/random/internal/fast_uniform_bits.h"
#include "absl/random/internal/iostream_state_saver.h"
diff --git a/contrib/restricted/abseil-cpp/absl/random/beta_distribution.h b/contrib/restricted/abseil-cpp/absl/random/beta_distribution.h
index 432c51612a..a3623453b3 100644
--- a/contrib/restricted/abseil-cpp/absl/random/beta_distribution.h
+++ b/contrib/restricted/abseil-cpp/absl/random/beta_distribution.h
@@ -17,14 +17,16 @@
#include <cassert>
#include <cmath>
+#include <cstdint>
#include <istream>
#include <limits>
#include <ostream>
#include <type_traits>
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/meta/type_traits.h"
#include "absl/random/internal/fast_uniform_bits.h"
-#include "absl/random/internal/fastmath.h"
#include "absl/random/internal/generate_real.h"
#include "absl/random/internal/iostream_state_saver.h"
diff --git a/contrib/restricted/abseil-cpp/absl/random/bit_gen_ref.h b/contrib/restricted/abseil-cpp/absl/random/bit_gen_ref.h
index ac26d9d4ab..40e7b60739 100644
--- a/contrib/restricted/abseil-cpp/absl/random/bit_gen_ref.h
+++ b/contrib/restricted/abseil-cpp/absl/random/bit_gen_ref.h
@@ -24,13 +24,14 @@
#ifndef ABSL_RANDOM_BIT_GEN_REF_H_
#define ABSL_RANDOM_BIT_GEN_REF_H_
+#include <cstdint>
#include <limits>
#include <type_traits>
#include <utility>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/internal/fast_type_id.h"
-#include "absl/base/macros.h"
#include "absl/meta/type_traits.h"
#include "absl/random/internal/distribution_caller.h"
#include "absl/random/internal/fast_uniform_bits.h"
diff --git a/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.cc b/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.cc
index 081accee52..247faa84fb 100644
--- a/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.cc
+++ b/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.cc
@@ -14,6 +14,16 @@
#include "absl/random/discrete_distribution.h"
+#include <cassert>
+#include <cmath>
+#include <cstddef>
+#include <iterator>
+#include <numeric>
+#include <utility>
+#include <vector>
+
+#include "absl/base/config.h"
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace random_internal {
diff --git a/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.h b/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.h
index 171aa11a1e..f579a64a8d 100644
--- a/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.h
+++ b/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.h
@@ -16,14 +16,16 @@
#define ABSL_RANDOM_DISCRETE_DISTRIBUTION_H_
#include <cassert>
-#include <cmath>
+#include <cstddef>
+#include <initializer_list>
#include <istream>
#include <limits>
-#include <numeric>
+#include <ostream>
#include <type_traits>
#include <utility>
#include <vector>
+#include "absl/base/config.h"
#include "absl/random/bernoulli_distribution.h"
#include "absl/random/internal/iostream_state_saver.h"
#include "absl/random/uniform_int_distribution.h"
diff --git a/contrib/restricted/abseil-cpp/absl/random/exponential_distribution.h b/contrib/restricted/abseil-cpp/absl/random/exponential_distribution.h
index b5caf8a1e1..4af2fb482b 100644
--- a/contrib/restricted/abseil-cpp/absl/random/exponential_distribution.h
+++ b/contrib/restricted/abseil-cpp/absl/random/exponential_distribution.h
@@ -21,6 +21,7 @@
#include <limits>
#include <type_traits>
+#include "absl/base/config.h"
#include "absl/meta/type_traits.h"
#include "absl/random/internal/fast_uniform_bits.h"
#include "absl/random/internal/generate_real.h"
diff --git a/contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.h b/contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.h
index 4b07a5c0af..ce84d4a56b 100644
--- a/contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.h
+++ b/contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.h
@@ -26,6 +26,7 @@
#include <cstdint>
#include <istream>
#include <limits>
+#include <ostream>
#include <type_traits>
#include "absl/base/config.h"
@@ -57,7 +58,7 @@ class ABSL_DLL gaussian_distribution_base {
bool neg);
// Constants used for the gaussian distribution.
- static constexpr double kR = 3.442619855899; // Start of the tail.
+ static constexpr double kR = 3.442619855899; // Start of the tail.
static constexpr double kRInv = 0.29047645161474317; // ~= (1.0 / kR) .
static constexpr double kV = 9.91256303526217e-3;
static constexpr uint64_t kMask = 0x07f;
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/chi_square.cc b/contrib/restricted/abseil-cpp/absl/random/internal/chi_square.cc
index fbe0173299..4cfc4d7c52 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/chi_square.cc
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/chi_square.cc
@@ -25,9 +25,7 @@ namespace {
#if defined(__EMSCRIPTEN__)
// Workaround __EMSCRIPTEN__ error: llvm_fma_f64 not found.
-inline double fma(double x, double y, double z) {
- return (x * y) + z;
-}
+inline double fma(double x, double y, double z) { return (x * y) + z; }
#endif
// Use Horner's method to evaluate a polynomial.
@@ -105,9 +103,8 @@ double normal_survival(double z) {
// p-value, usually using bisection. Also known by the name CRITCHI.
double ChiSquareValue(int dof, double p) {
static constexpr double kChiEpsilon =
- 0.000001; // Accuracy of the approximation.
- static constexpr double kChiMax =
- 99999.0; // Maximum chi-squared value.
+ 0.000001; // Accuracy of the approximation.
+ static constexpr double kChiMax = 99999.0; // Maximum chi-squared value.
const double p_value = 1.0 - p;
if (dof < 1 || p_value > 1.0) {
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/distribution_caller.h b/contrib/restricted/abseil-cpp/absl/random/internal/distribution_caller.h
index 0f162a4e29..2534ca951d 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/distribution_caller.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/distribution_caller.h
@@ -17,11 +17,13 @@
#ifndef ABSL_RANDOM_INTERNAL_DISTRIBUTION_CALLER_H_
#define ABSL_RANDOM_INTERNAL_DISTRIBUTION_CALLER_H_
-#include <utility>
+#include <tuple>
#include <type_traits>
+#include <utility>
#include "absl/base/config.h"
#include "absl/base/internal/fast_type_id.h"
+#include "absl/meta/type_traits.h"
#include "absl/utility/utility.h"
namespace absl {
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.h b/contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.h
index 6d94cf6c97..1189340e3a 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.h
@@ -16,9 +16,9 @@
#define ABSL_RANDOM_INTERNAL_DISTRIBUTION_TEST_UTIL_H_
#include <cstddef>
-#include <iostream>
-#include <vector>
+#include <ostream>
+#include "absl/base/config.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
@@ -96,7 +96,7 @@ double BetaIncomplete(double x, double p, double q);
// https://www.jstor.org/stable/2346798
// https://www.jstor.org/stable/2346887
//
-// BetaIncompleteInv(p, q, beta, alhpa)
+// BetaIncompleteInv(p, q, beta, alpha)
// `p` is beta parameter p, `q` is beta parameter q.
// `alpha` is the value of the lower tail area.
//
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/iostream_state_saver.h b/contrib/restricted/abseil-cpp/absl/random/internal/iostream_state_saver.h
index e6e242ee1e..0f56bcb834 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/iostream_state_saver.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/iostream_state_saver.h
@@ -16,10 +16,14 @@
#define ABSL_RANDOM_INTERNAL_IOSTREAM_STATE_SAVER_H_
#include <cmath>
-#include <iostream>
+#include <cstdint>
+#include <ios>
+#include <istream>
#include <limits>
+#include <ostream>
#include <type_traits>
+#include "absl/base/config.h"
#include "absl/meta/type_traits.h"
#include "absl/numeric/int128.h"
@@ -95,7 +99,6 @@ typename absl::enable_if_t<!std::is_base_of<std::ios_base, T>::value,
null_state_saver<T>>
make_ostream_state_saver(T& is, // NOLINT(runtime/references)
std::ios_base::fmtflags flags = std::ios_base::dec) {
- std::cerr << "null_state_saver";
using result_type = null_state_saver<T>;
return result_type(is, flags);
}
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/mock_overload_set.h b/contrib/restricted/abseil-cpp/absl/random/internal/mock_overload_set.h
index cfaeeeef1a..a09f035dc3 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/mock_overload_set.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/mock_overload_set.h
@@ -51,10 +51,8 @@ struct MockSingleOverload<DistrT, ValidatorT, Ret(MockingBitGen&, Args...)> {
auto gmock_Call(MockURBG& gen, const ::testing::Matcher<Args>&... matchers)
-> decltype(MockHelpers::MockFor<KeyT>(gen, ValidatorT())
.gmock_Call(matchers...)) {
- static_assert(
- std::is_base_of<MockingBitGenImpl<true>, MockURBG>::value ||
- std::is_base_of<MockingBitGenImpl<false>, MockURBG>::value,
- "Mocking requires an absl::MockingBitGen");
+ static_assert(std::is_base_of<MockingBitGen, MockURBG>::value,
+ "Mocking requires an absl::MockingBitGen");
return MockHelpers::MockFor<KeyT>(gen, ValidatorT())
.gmock_Call(matchers...);
}
@@ -74,10 +72,8 @@ struct MockSingleOverload<DistrT, ValidatorT,
const ::testing::Matcher<Args>&... matchers)
-> decltype(MockHelpers::MockFor<KeyT>(gen, ValidatorT())
.gmock_Call(matcher, matchers...)) {
- static_assert(
- std::is_base_of<MockingBitGenImpl<true>, MockURBG>::value ||
- std::is_base_of<MockingBitGenImpl<false>, MockURBG>::value,
- "Mocking requires an absl::MockingBitGen");
+ static_assert(std::is_base_of<MockingBitGen, MockURBG>::value,
+ "Mocking requires an absl::MockingBitGen");
return MockHelpers::MockFor<KeyT>(gen, ValidatorT())
.gmock_Call(matcher, matchers...);
}
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/platform.h b/contrib/restricted/abseil-cpp/absl/random/internal/platform.h
index d779f481dd..bd2993e181 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/platform.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/platform.h
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+// SKIP_ABSL_INLINE_NAMESPACE_CHECK
+
#ifndef ABSL_RANDOM_INTERNAL_PLATFORM_H_
#define ABSL_RANDOM_INTERNAL_PLATFORM_H_
@@ -134,7 +136,14 @@
// accelerated Randen implementation.
#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 0
-#if defined(ABSL_ARCH_X86_64)
+// iOS does not support dispatch, even on x86, since applications
+// should be bundled as fat binaries, with a different build tailored for
+// each specific supported platform/architecture.
+#if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || \
+ (defined(TARGET_OS_IPHONE_SIMULATOR) && TARGET_OS_IPHONE_SIMULATOR)
+#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
+#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 0
+#elif defined(ABSL_ARCH_X86_64)
// Dispatch is available on x86_64
#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1
@@ -142,8 +151,8 @@
// Or when running linux PPC
#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1
-#elif defined(__linux__) && defined(ABSL_ARCH_AARCH64)
-// Or when running linux AArch64
+#elif (defined(__linux__) || defined(__APPLE__)) && defined(ABSL_ARCH_AARCH64)
+// Or when running linux or macOS AArch64
#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1
#elif defined(__linux__) && defined(ABSL_ARCH_ARM) && (__ARM_ARCH >= 8)
@@ -159,13 +168,4 @@
#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 0
#endif
-// iOS does not support dispatch, even on x86, since applications
-// should be bundled as fat binaries, with a different build tailored for
-// each specific supported platform/architecture.
-#if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || \
- (defined(TARGET_OS_IPHONE_SIMULATOR) && TARGET_OS_IPHONE_SIMULATOR)
-#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
-#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 0
-#endif
-
#endif // ABSL_RANDOM_INTERNAL_PLATFORM_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.cc b/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.cc
index bdeab877b9..828db4790a 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.cc
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.cc
@@ -19,10 +19,21 @@
#include "absl/random/internal/randen_detect.h"
+#if defined(__APPLE__) && defined(__aarch64__)
+#if defined(__has_include)
+#if __has_include(<arm/cpu_capabilities_public.h>)
+#include <arm/cpu_capabilities_public.h>
+#endif
+#endif
+#include <sys/sysctl.h>
+#include <sys/types.h>
+#endif
+
#include <cstdint>
#include <cstring>
#include "absl/random/internal/platform.h"
+#include "absl/types/optional.h" // IWYU pragma: keep
#if !defined(__UCLIBC__) && defined(__GLIBC__) && \
(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 16))
@@ -102,6 +113,19 @@ static uint32_t GetAuxval(uint32_t hwcap_type) {
#endif
+#if defined(__APPLE__) && defined(ABSL_ARCH_AARCH64)
+template <typename T>
+static absl::optional<T> ReadSysctlByName(const char* name) {
+ T val;
+ size_t val_size = sizeof(T);
+ int ret = sysctlbyname(name, &val, &val_size, nullptr, 0);
+ if (ret == -1) {
+ return std::nullopt;
+ }
+ return val;
+}
+#endif
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace random_internal {
@@ -129,7 +153,9 @@ namespace random_internal {
// cpu capabilities, and should allow us to enable crypto in the android
// builds where it is supported.
//
-// 3. Use the default for the compiler architecture.
+// 3. When __APPLE__ is defined on AARCH64, use sysctlbyname().
+//
+// 4. Use the default for the compiler architecture.
//
bool CPUSupportsRandenHwAes() {
@@ -178,8 +204,36 @@ bool CPUSupportsRandenHwAes() {
return ((hwcap & kNEON) != 0) && ((hwcap & kAES) != 0);
#endif
+#elif defined(__APPLE__) && defined(ABSL_ARCH_AARCH64)
+ // 3. Use sysctlbyname.
+
+ // Newer XNU kernels support querying all capabilities in a single
+ // sysctlbyname.
+#if defined(CAP_BIT_AdvSIMD) && defined(CAP_BIT_FEAT_AES)
+ static const absl::optional<uint64_t> caps =
+ ReadSysctlByName<uint64_t>("hw.optional.arm.caps");
+ if (caps.has_value()) {
+ constexpr uint64_t kNeonAndAesCaps =
+ (uint64_t{1} << CAP_BIT_AdvSIMD) | (uint64_t{1} << CAP_BIT_FEAT_AES);
+ return (*caps & kNeonAndAesCaps) == kNeonAndAesCaps;
+ }
+#endif
+
+ // https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics#overview
+ static const absl::optional<int> adv_simd =
+ ReadSysctlByName<int>("hw.optional.AdvSIMD");
+ if (adv_simd.value_or(0) == 0) {
+ return false;
+ }
+ // https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics#3918855
+ static const absl::optional<int> feat_aes =
+ ReadSysctlByName<int>("hw.optional.arm.FEAT_AES");
+ if (feat_aes.value_or(0) == 0) {
+ return false;
+ }
+ return true;
#else // ABSL_INTERNAL_USE_GETAUXVAL
- // 3. By default, assume that the compiler default.
+ // 4. By default, assume that the compiler default.
return ABSL_HAVE_ACCELERATED_AES ? true : false;
#endif
@@ -215,9 +269,6 @@ bool CPUSupportsRandenHwAes() {
// __asm __volatile("mrs %0, id_aa64isar0_el1" :"=&r" (val));
//
// * Use a CPUID-style heuristic database.
- //
- // * On Apple (__APPLE__), AES is available on Arm v8.
- // https://stackoverflow.com/questions/45637888/how-to-determine-armv8-features-at-runtime-on-ios
}
#if defined(__clang__)
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 fe2d9f6c15..925e1bbab5 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_engine.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_engine.h
@@ -18,9 +18,10 @@
#include <algorithm>
#include <cinttypes>
#include <cstdlib>
-#include <iostream>
+#include <istream>
#include <iterator>
#include <limits>
+#include <ostream>
#include <type_traits>
#include "absl/base/internal/endian.h"
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/uniform_helper.h b/contrib/restricted/abseil-cpp/absl/random/internal/uniform_helper.h
index db737e13f3..d230073868 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/uniform_helper.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/uniform_helper.h
@@ -201,8 +201,8 @@ is_uniform_range_valid(FloatType a, FloatType b) {
}
template <typename IntType>
-absl::enable_if_t<IsIntegral<IntType>::value, bool>
-is_uniform_range_valid(IntType a, IntType b) {
+absl::enable_if_t<IsIntegral<IntType>::value, bool> is_uniform_range_valid(
+ IntType a, IntType b) {
return a <= b;
}
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/wide_multiply.h b/contrib/restricted/abseil-cpp/absl/random/internal/wide_multiply.h
index 891e3630b7..b1256813df 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/wide_multiply.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/wide_multiply.h
@@ -75,7 +75,6 @@ inline U256 MultiplyU128ToU256(uint128 a, uint128 b) {
c00 + (c64a << 64) + (c64b << 64)};
}
-
template <>
struct wide_multiply<uint128> {
using input_type = uint128;
diff --git a/contrib/restricted/abseil-cpp/absl/random/log_uniform_int_distribution.h b/contrib/restricted/abseil-cpp/absl/random/log_uniform_int_distribution.h
index 4afff8f604..cbd5e0ca2b 100644
--- a/contrib/restricted/abseil-cpp/absl/random/log_uniform_int_distribution.h
+++ b/contrib/restricted/abseil-cpp/absl/random/log_uniform_int_distribution.h
@@ -21,11 +21,8 @@
#include <istream>
#include <limits>
#include <ostream>
-#include <type_traits>
-#include "absl/numeric/bits.h"
-#include "absl/random/internal/fastmath.h"
-#include "absl/random/internal/generate_real.h"
+#include "absl/base/config.h"
#include "absl/random/internal/iostream_state_saver.h"
#include "absl/random/internal/traits.h"
#include "absl/random/uniform_int_distribution.h"
diff --git a/contrib/restricted/abseil-cpp/absl/random/mock_distributions.h b/contrib/restricted/abseil-cpp/absl/random/mock_distributions.h
index b379262cb6..1983547327 100644
--- a/contrib/restricted/abseil-cpp/absl/random/mock_distributions.h
+++ b/contrib/restricted/abseil-cpp/absl/random/mock_distributions.h
@@ -17,14 +17,14 @@
// -----------------------------------------------------------------------------
//
// This file contains mock distribution functions for use alongside an
-// `absl::MockingBitGen` object within the Googletest testing framework. Such
+// `absl::MockingBitGen` object within the GoogleTest testing framework. Such
// mocks are useful to provide deterministic values as return values within
// (otherwise random) Abseil distribution functions.
//
// The return type of each function is a mock expectation object which
// is used to set the match result.
//
-// More information about the Googletest testing framework is available at
+// More information about the GoogleTest testing framework is available at
// https://github.com/google/googletest
//
// EXPECT_CALL and ON_CALL need to be made within the same DLL component as
diff --git a/contrib/restricted/abseil-cpp/absl/random/mocking_bit_gen.h b/contrib/restricted/abseil-cpp/absl/random/mocking_bit_gen.h
index 041989de20..ba7ceae04a 100644
--- a/contrib/restricted/abseil-cpp/absl/random/mocking_bit_gen.h
+++ b/contrib/restricted/abseil-cpp/absl/random/mocking_bit_gen.h
@@ -17,12 +17,12 @@
// -----------------------------------------------------------------------------
//
// This file includes an `absl::MockingBitGen` class to use as a mock within the
-// Googletest testing framework. Such a mock is useful to provide deterministic
+// GoogleTest testing framework. Such a mock is useful to provide deterministic
// values as return values within (otherwise random) Abseil distribution
// functions. Such determinism within a mock is useful within testing frameworks
// to test otherwise indeterminate APIs.
//
-// More information about the Googletest testing framework is available at
+// More information about the GoogleTest testing framework is available at
// https://github.com/google/googletest
#ifndef ABSL_RANDOM_MOCKING_BIT_GEN_H_
@@ -34,7 +34,6 @@
#include <utility>
#include "gmock/gmock.h"
-#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/fast_type_id.h"
#include "absl/container/flat_hash_map.h"
@@ -52,13 +51,53 @@ namespace random_internal {
template <typename>
struct DistributionCaller;
class MockHelpers;
+} // namespace random_internal
-// Implements MockingBitGen with an option to turn on extra validation.
-template <bool EnableValidation>
-class MockingBitGenImpl {
+// MockingBitGen
+//
+// `absl::MockingBitGen` is a mock Uniform Random Bit Generator (URBG) class
+// which can act in place of an `absl::BitGen` URBG within tests using the
+// GoogleTest testing framework.
+//
+// Usage:
+//
+// Use an `absl::MockingBitGen` along with a mock distribution object (within
+// mock_distributions.h) inside Googletest constructs such as ON_CALL(),
+// EXPECT_TRUE(), etc. to produce deterministic results conforming to the
+// distribution's API contract.
+//
+// Example:
+//
+// // Mock a call to an `absl::Bernoulli` distribution using Googletest
+// absl::MockingBitGen bitgen;
+//
+// ON_CALL(absl::MockBernoulli(), Call(bitgen, 0.5))
+// .WillByDefault(testing::Return(true));
+// EXPECT_TRUE(absl::Bernoulli(bitgen, 0.5));
+//
+// // Mock a call to an `absl::Uniform` distribution within Googletest
+// absl::MockingBitGen bitgen;
+//
+// ON_CALL(absl::MockUniform<int>(), Call(bitgen, testing::_, testing::_))
+// .WillByDefault([] (int low, int high) {
+// return low + (high - low) / 2;
+// });
+//
+// EXPECT_EQ(absl::Uniform<int>(gen, 0, 10), 5);
+// EXPECT_EQ(absl::Uniform<int>(gen, 30, 40), 35);
+//
+// At this time, only mock distributions supplied within the Abseil random
+// library are officially supported.
+//
+// EXPECT_CALL and ON_CALL need to be made within the same DLL component as
+// the call to absl::Uniform and related methods, otherwise mocking will fail
+// since the underlying implementation creates a type-specific pointer which
+// will be distinct across different DLL boundaries.
+//
+class MockingBitGen {
public:
- MockingBitGenImpl() = default;
- ~MockingBitGenImpl() = default;
+ MockingBitGen() = default;
+ ~MockingBitGen() = default;
// URBG interface
using result_type = absl::BitGen::result_type;
@@ -138,25 +177,23 @@ class MockingBitGenImpl {
typename ValidatorT>
auto RegisterMock(SelfT&, base_internal::FastTypeIdType type, ValidatorT)
-> decltype(GetMockFnType(std::declval<ResultT>(),
- std::declval<ArgTupleT>()))& {
- using ActualValidatorT =
- std::conditional_t<EnableValidation, ValidatorT, NoOpValidator>;
+ std::declval<ArgTupleT>())) & {
using MockFnType = decltype(GetMockFnType(std::declval<ResultT>(),
std::declval<ArgTupleT>()));
using WrappedFnType = absl::conditional_t<
- std::is_same<SelfT, ::testing::NiceMock<MockingBitGenImpl>>::value,
+ std::is_same<SelfT, ::testing::NiceMock<MockingBitGen>>::value,
::testing::NiceMock<MockFnType>,
absl::conditional_t<
- std::is_same<SelfT, ::testing::NaggyMock<MockingBitGenImpl>>::value,
+ std::is_same<SelfT, ::testing::NaggyMock<MockingBitGen>>::value,
::testing::NaggyMock<MockFnType>,
absl::conditional_t<
std::is_same<SelfT,
- ::testing::StrictMock<MockingBitGenImpl>>::value,
+ ::testing::StrictMock<MockingBitGen>>::value,
::testing::StrictMock<MockFnType>, MockFnType>>>;
using ImplT =
- FunctionHolderImpl<WrappedFnType, ActualValidatorT, ResultT, ArgTupleT>;
+ FunctionHolderImpl<WrappedFnType, ValidatorT, ResultT, ArgTupleT>;
auto& mock = mocks_[type];
if (!mock) {
mock = absl::make_unique<ImplT>();
@@ -196,58 +233,6 @@ class MockingBitGenImpl {
// InvokeMock
};
-} // namespace random_internal
-
-// MockingBitGen
-//
-// `absl::MockingBitGen` is a mock Uniform Random Bit Generator (URBG) class
-// which can act in place of an `absl::BitGen` URBG within tests using the
-// Googletest testing framework.
-//
-// Usage:
-//
-// Use an `absl::MockingBitGen` along with a mock distribution object (within
-// mock_distributions.h) inside Googletest constructs such as ON_CALL(),
-// EXPECT_TRUE(), etc. to produce deterministic results conforming to the
-// distribution's API contract.
-//
-// Example:
-//
-// // Mock a call to an `absl::Bernoulli` distribution using Googletest
-// absl::MockingBitGen bitgen;
-//
-// ON_CALL(absl::MockBernoulli(), Call(bitgen, 0.5))
-// .WillByDefault(testing::Return(true));
-// EXPECT_TRUE(absl::Bernoulli(bitgen, 0.5));
-//
-// // Mock a call to an `absl::Uniform` distribution within Googletest
-// absl::MockingBitGen bitgen;
-//
-// ON_CALL(absl::MockUniform<int>(), Call(bitgen, testing::_, testing::_))
-// .WillByDefault([] (int low, int high) {
-// return low + (high - low) / 2;
-// });
-//
-// EXPECT_EQ(absl::Uniform<int>(gen, 0, 10), 5);
-// EXPECT_EQ(absl::Uniform<int>(gen, 30, 40), 35);
-//
-// At this time, only mock distributions supplied within the Abseil random
-// library are officially supported.
-//
-// EXPECT_CALL and ON_CALL need to be made within the same DLL component as
-// the call to absl::Uniform and related methods, otherwise mocking will fail
-// since the underlying implementation creates a type-specific pointer which
-// will be distinct across different DLL boundaries.
-//
-using MockingBitGen = random_internal::MockingBitGenImpl<true>;
-
-// UnvalidatedMockingBitGen
-//
-// UnvalidatedMockingBitGen is a variant of MockingBitGen which does no extra
-// validation.
-using UnvalidatedMockingBitGen ABSL_DEPRECATED("Use MockingBitGen instead") =
- random_internal::MockingBitGenImpl<false>;
-
ABSL_NAMESPACE_END
} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/random/poisson_distribution.h b/contrib/restricted/abseil-cpp/absl/random/poisson_distribution.h
index f4573082e1..ae2e095be3 100644
--- a/contrib/restricted/abseil-cpp/absl/random/poisson_distribution.h
+++ b/contrib/restricted/abseil-cpp/absl/random/poisson_distribution.h
@@ -17,11 +17,12 @@
#include <cassert>
#include <cmath>
+#include <cstdint>
#include <istream>
#include <limits>
#include <ostream>
-#include <type_traits>
+#include "absl/base/config.h"
#include "absl/random/internal/fast_uniform_bits.h"
#include "absl/random/internal/fastmath.h"
#include "absl/random/internal/generate_real.h"
@@ -48,8 +49,8 @@ ABSL_NAMESPACE_BEGIN
// the distribution results are limited to the max() value.
//
// The goals of this implementation are to provide good performance while still
-// beig thread-safe: This limits the implementation to not using lgamma provided
-// by <math.h>.
+// being thread-safe: This limits the implementation to not using lgamma
+// provided by <math.h>.
//
template <typename IntType = int>
class poisson_distribution {
diff --git a/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.cc b/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.cc
index fdcb54a86c..6fb4ad3766 100644
--- a/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.cc
+++ b/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.cc
@@ -14,9 +14,8 @@
#include "absl/random/seed_gen_exception.h"
-#include <iostream>
-
#include "absl/base/config.h"
+#include "absl/base/internal/raw_logging.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -36,7 +35,7 @@ void ThrowSeedGenException() {
#ifdef ABSL_HAVE_EXCEPTIONS
throw absl::SeedGenException();
#else
- std::cerr << kExceptionMessage << std::endl;
+ ABSL_RAW_LOG(FATAL, "%s", kExceptionMessage);
std::terminate();
#endif
}
diff --git a/contrib/restricted/abseil-cpp/absl/random/seed_sequences.h b/contrib/restricted/abseil-cpp/absl/random/seed_sequences.h
index 33970be581..dacc5b90c0 100644
--- a/contrib/restricted/abseil-cpp/absl/random/seed_sequences.h
+++ b/contrib/restricted/abseil-cpp/absl/random/seed_sequences.h
@@ -80,8 +80,7 @@ using SeedSeq = random_internal::SaltedSeedSeq<std::seed_seq>;
//
template <typename URBG>
SeedSeq CreateSeedSeqFrom(URBG* urbg) {
- SeedSeq::result_type
- seed_material[random_internal::kEntropyBlocksNeeded];
+ SeedSeq::result_type seed_material[random_internal::kEntropyBlocksNeeded];
if (!random_internal::ReadSeedMaterialFromURBG(
urbg, absl::MakeSpan(seed_material))) {
diff --git a/contrib/restricted/abseil-cpp/absl/random/uniform_int_distribution.h b/contrib/restricted/abseil-cpp/absl/random/uniform_int_distribution.h
index fae80252e3..0dc7c62c3e 100644
--- a/contrib/restricted/abseil-cpp/absl/random/uniform_int_distribution.h
+++ b/contrib/restricted/abseil-cpp/absl/random/uniform_int_distribution.h
@@ -31,8 +31,9 @@
#include <cassert>
#include <istream>
#include <limits>
-#include <type_traits>
+#include <ostream>
+#include "absl/base/config.h"
#include "absl/base/optimization.h"
#include "absl/random/internal/fast_uniform_bits.h"
#include "absl/random/internal/iostream_state_saver.h"
diff --git a/contrib/restricted/abseil-cpp/absl/random/uniform_real_distribution.h b/contrib/restricted/abseil-cpp/absl/random/uniform_real_distribution.h
index 196833415e..8bef9469ae 100644
--- a/contrib/restricted/abseil-cpp/absl/random/uniform_real_distribution.h
+++ b/contrib/restricted/abseil-cpp/absl/random/uniform_real_distribution.h
@@ -37,8 +37,10 @@
#include <cstdint>
#include <istream>
#include <limits>
+#include <ostream>
#include <type_traits>
+#include "absl/base/config.h"
#include "absl/meta/type_traits.h"
#include "absl/random/internal/fast_uniform_bits.h"
#include "absl/random/internal/generate_real.h"
diff --git a/contrib/restricted/abseil-cpp/absl/random/ya.make b/contrib/restricted/abseil-cpp/absl/random/ya.make
index 1026a5d497..c5789234d1 100644
--- a/contrib/restricted/abseil-cpp/absl/random/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/random/ya.make
@@ -6,7 +6,7 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20240722.1)
+VERSION(20250127.0)
PEERDIR(
contrib/restricted/abseil-cpp/absl/base
diff --git a/contrib/restricted/abseil-cpp/absl/random/zipf_distribution.h b/contrib/restricted/abseil-cpp/absl/random/zipf_distribution.h
index 03497b1b26..21e3b709b0 100644
--- a/contrib/restricted/abseil-cpp/absl/random/zipf_distribution.h
+++ b/contrib/restricted/abseil-cpp/absl/random/zipf_distribution.h
@@ -22,6 +22,7 @@
#include <ostream>
#include <type_traits>
+#include "absl/base/config.h"
#include "absl/random/internal/iostream_state_saver.h"
#include "absl/random/internal/traits.h"
#include "absl/random/uniform_real_distribution.h"
@@ -57,8 +58,8 @@ class zipf_distribution {
public:
using distribution_type = zipf_distribution;
- // Preconditions: k > 0, v > 0, q > 1
- // The precondidtions are validated when NDEBUG is not defined via
+ // Preconditions: k >= 0, v > 0, q > 1
+ // The preconditions are validated when NDEBUG is not defined via
// a pair of assert() directives.
// If NDEBUG is defined and either or both of these parameters take invalid
// values, the behavior of the class is undefined.
@@ -152,7 +153,7 @@ zipf_distribution<IntType>::param_type::param_type(
: k_(k), q_(q), v_(v), one_minus_q_(1 - q) {
assert(q > 1);
assert(v > 0);
- assert(k > 0);
+ assert(k >= 0);
one_minus_q_inv_ = 1 / one_minus_q_;
// Setup for the ZRI algorithm (pg 17 of the paper).
@@ -221,7 +222,7 @@ zipf_distribution<IntType>::operator()(
const double v = uniform_double(g);
const double u = p.hxm_ + v * p.hx0_minus_hxm_;
const double x = p.hinv(u);
- k = rint(x); // std::floor(x + 0.5);
+ k = rint(x); // std::floor(x + 0.5);
if (k > static_cast<double>(p.k())) continue; // reject k > max_k
if (k - x <= p.s_) break;
const double h = p.h(k + 0.5);
diff --git a/contrib/restricted/abseil-cpp/absl/status/internal/status_internal.cc b/contrib/restricted/abseil-cpp/absl/status/internal/status_internal.cc
index a91567549e..99bf8faca3 100644
--- a/contrib/restricted/abseil-cpp/absl/status/internal/status_internal.cc
+++ b/contrib/restricted/abseil-cpp/absl/status/internal/status_internal.cc
@@ -28,6 +28,7 @@
#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/base/nullability.h"
+#include "absl/debugging/leak_check.h"
#include "absl/debugging/stacktrace.h"
#include "absl/debugging/symbolize.h"
#include "absl/memory/memory.h"
@@ -234,12 +235,15 @@ absl::StatusCode MapToLocalCode(int value) {
}
}
-absl::Nonnull<std::string*> MakeCheckFailString(
+absl::Nonnull<const char*> MakeCheckFailString(
absl::Nonnull<const absl::Status*> status,
absl::Nonnull<const char*> prefix) {
- return new std::string(
- absl::StrCat(prefix, " (",
- status->ToString(StatusToStringMode::kWithEverything), ")"));
+ // There's no need to free this string since the process is crashing.
+ return absl::IgnoreLeak(
+ new std::string(absl::StrCat(
+ prefix, " (",
+ status->ToString(StatusToStringMode::kWithEverything), ")")))
+ ->c_str();
}
} // namespace status_internal
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 c9f4383272..fe335b0b7c 100644
--- a/contrib/restricted/abseil-cpp/absl/status/internal/status_internal.h
+++ b/contrib/restricted/abseil-cpp/absl/status/internal/status_internal.h
@@ -120,7 +120,7 @@ absl::StatusCode MapToLocalCode(int value);
//
// This is an internal implementation detail for Abseil logging.
ABSL_ATTRIBUTE_PURE_FUNCTION
-absl::Nonnull<std::string*> MakeCheckFailString(
+absl::Nonnull<const char*> MakeCheckFailString(
absl::Nonnull<const absl::Status*> status,
absl::Nonnull<const char*> prefix);
diff --git a/contrib/restricted/abseil-cpp/absl/status/status.h b/contrib/restricted/abseil-cpp/absl/status/status.h
index 6cfe49f2dd..02fd296485 100644
--- a/contrib/restricted/abseil-cpp/absl/status/status.h
+++ b/contrib/restricted/abseil-cpp/absl/status/status.h
@@ -649,7 +649,7 @@ class ABSL_ATTRIBUTE_TRIVIAL_ABI Status final {
// Converts between StatusRep* and the external uintptr_t representation used
// by rep_. See rep_ for details.
- static uintptr_t PointerToRep(status_internal::StatusRep* r);
+ static uintptr_t PointerToRep(absl::Nonnull<status_internal::StatusRep*> r);
static absl::Nonnull<const status_internal::StatusRep*> RepToPointer(
uintptr_t r);
diff --git a/contrib/restricted/abseil-cpp/absl/status/ya.make b/contrib/restricted/abseil-cpp/absl/status/ya.make
index d7e0102e2d..0b2cd3499a 100644
--- a/contrib/restricted/abseil-cpp/absl/status/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/status/ya.make
@@ -6,7 +6,7 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20240722.1)
+VERSION(20250127.0)
PEERDIR(
contrib/restricted/abseil-cpp/absl/base
diff --git a/contrib/restricted/abseil-cpp/absl/strings/ascii.cc b/contrib/restricted/abseil-cpp/absl/strings/ascii.cc
index 20a696a1f6..d15e4249ec 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/ascii.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/ascii.cc
@@ -19,10 +19,8 @@
#include <cstring>
#include <string>
-#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/nullability.h"
-#include "absl/base/optimization.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -177,10 +175,17 @@ constexpr bool AsciiInAZRange(unsigned char c) {
return static_cast<signed char>(u) < threshold;
}
-// Force-inline so the compiler won't merge the short and long implementations.
template <bool ToUpper>
-ABSL_ATTRIBUTE_ALWAYS_INLINE inline constexpr void AsciiStrCaseFoldImpl(
- absl::Nonnull<char*> p, size_t size) {
+constexpr bool AsciiInAZRangeNaive(unsigned char c) {
+ constexpr unsigned char a = (ToUpper ? 'a' : 'A');
+ constexpr unsigned char z = (ToUpper ? 'z' : 'Z');
+ return a <= c && c <= z;
+}
+
+template <bool ToUpper, bool Naive>
+constexpr void AsciiStrCaseFoldImpl(absl::Nonnull<char*> dst,
+ absl::Nullable<const char*> src,
+ size_t size) {
// The upper- and lowercase versions of ASCII characters differ by only 1 bit.
// When we need to flip the case, we can xor with this bit to achieve the
// desired result. Note that the choice of 'a' and 'A' here is arbitrary. We
@@ -189,29 +194,37 @@ ABSL_ATTRIBUTE_ALWAYS_INLINE inline constexpr void AsciiStrCaseFoldImpl(
constexpr unsigned char kAsciiCaseBitFlip = 'a' ^ 'A';
for (size_t i = 0; i < size; ++i) {
- unsigned char v = static_cast<unsigned char>(p[i]);
- v ^= AsciiInAZRange<ToUpper>(v) ? kAsciiCaseBitFlip : 0;
- p[i] = static_cast<char>(v);
+ unsigned char v = static_cast<unsigned char>(src[i]);
+ if ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17 (Naive) {
+ v ^= AsciiInAZRangeNaive<ToUpper>(v) ? kAsciiCaseBitFlip : 0;
+ } else {
+ v ^= AsciiInAZRange<ToUpper>(v) ? kAsciiCaseBitFlip : 0;
+ }
+ dst[i] = static_cast<char>(v);
}
}
-// The string size threshold for starting using the long string version.
-constexpr size_t kCaseFoldThreshold = 16;
-
-// No-inline so the compiler won't merge the short and long implementations.
-template <bool ToUpper>
-ABSL_ATTRIBUTE_NOINLINE constexpr void AsciiStrCaseFoldLong(
- absl::Nonnull<char*> p, size_t size) {
- ABSL_ASSUME(size >= kCaseFoldThreshold);
- AsciiStrCaseFoldImpl<ToUpper>(p, size);
-}
-
// Splitting to short and long strings to allow vectorization decisions
// to be made separately in the long and short cases.
+// Using slightly different implementations so the compiler won't optimize them
+// into the same code (the non-naive version is needed for SIMD, so for short
+// strings it's not important).
+// `src` may be null iff `size` is zero.
template <bool ToUpper>
-constexpr void AsciiStrCaseFold(absl::Nonnull<char*> p, size_t size) {
- size < kCaseFoldThreshold ? AsciiStrCaseFoldImpl<ToUpper>(p, size)
- : AsciiStrCaseFoldLong<ToUpper>(p, size);
+constexpr void AsciiStrCaseFold(absl::Nonnull<char*> dst,
+ absl::Nullable<const char*> src, size_t size) {
+ size < 16 ? AsciiStrCaseFoldImpl<ToUpper, /*Naive=*/true>(dst, src, size)
+ : AsciiStrCaseFoldImpl<ToUpper, /*Naive=*/false>(dst, src, size);
+}
+
+void AsciiStrToLower(absl::Nonnull<char*> dst, absl::Nullable<const char*> src,
+ size_t n) {
+ return AsciiStrCaseFold<false>(dst, src, n);
+}
+
+void AsciiStrToUpper(absl::Nonnull<char*> dst, absl::Nullable<const char*> src,
+ size_t n) {
+ return AsciiStrCaseFold<true>(dst, src, n);
}
static constexpr size_t ValidateAsciiCasefold() {
@@ -222,8 +235,8 @@ static constexpr size_t ValidateAsciiCasefold() {
for (unsigned int i = 0; i < num_chars; ++i) {
uppered[i] = lowered[i] = static_cast<char>(i);
}
- AsciiStrCaseFold<false>(&lowered[0], num_chars);
- AsciiStrCaseFold<true>(&uppered[0], num_chars);
+ AsciiStrCaseFold<false>(&lowered[0], &lowered[0], num_chars);
+ AsciiStrCaseFold<true>(&uppered[0], &uppered[0], num_chars);
for (size_t i = 0; i < num_chars; ++i) {
const char ch = static_cast<char>(i),
ch_upper = ('a' <= ch && ch <= 'z' ? 'A' + (ch - 'a') : ch),
@@ -241,11 +254,13 @@ static_assert(ValidateAsciiCasefold() == 0, "error in case conversion");
} // namespace ascii_internal
void AsciiStrToLower(absl::Nonnull<std::string*> s) {
- return ascii_internal::AsciiStrCaseFold<false>(&(*s)[0], s->size());
+ char* p = &(*s)[0];
+ return ascii_internal::AsciiStrCaseFold<false>(p, p, s->size());
}
void AsciiStrToUpper(absl::Nonnull<std::string*> s) {
- return ascii_internal::AsciiStrCaseFold<true>(&(*s)[0], s->size());
+ char* p = &(*s)[0];
+ return ascii_internal::AsciiStrCaseFold<true>(p, p, s->size());
}
void RemoveExtraAsciiWhitespace(absl::Nonnull<std::string*> str) {
diff --git a/contrib/restricted/abseil-cpp/absl/strings/ascii.h b/contrib/restricted/abseil-cpp/absl/strings/ascii.h
index c238f4de82..d9317eb113 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/ascii.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/ascii.h
@@ -55,10 +55,12 @@
#include <algorithm>
#include <cstddef>
#include <string>
+#include <utility>
#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/nullability.h"
+#include "absl/strings/internal/resize_uninitialized.h"
#include "absl/strings/string_view.h"
namespace absl {
@@ -74,6 +76,12 @@ ABSL_DLL extern const char kToUpper[256];
// Declaration for the array of characters to lower-case characters.
ABSL_DLL extern const char kToLower[256];
+void AsciiStrToLower(absl::Nonnull<char*> dst, absl::Nullable<const char*> src,
+ size_t n);
+
+void AsciiStrToUpper(absl::Nonnull<char*> dst, absl::Nullable<const char*> src,
+ size_t n);
+
} // namespace ascii_internal
// ascii_isalpha()
@@ -131,32 +139,42 @@ inline bool ascii_isxdigit(unsigned char c) {
//
// Determines whether the given character can be represented as a decimal
// digit character (i.e. {0-9}).
-inline bool ascii_isdigit(unsigned char c) { return c >= '0' && c <= '9'; }
+inline constexpr bool ascii_isdigit(unsigned char c) {
+ return c >= '0' && c <= '9';
+}
// ascii_isprint()
//
// Determines whether the given character is printable, including spaces.
-inline bool ascii_isprint(unsigned char c) { return c >= 32 && c < 127; }
+inline constexpr bool ascii_isprint(unsigned char c) {
+ return c >= 32 && c < 127;
+}
// ascii_isgraph()
//
// Determines whether the given character has a graphical representation.
-inline bool ascii_isgraph(unsigned char c) { return c > 32 && c < 127; }
+inline constexpr bool ascii_isgraph(unsigned char c) {
+ return c > 32 && c < 127;
+}
// ascii_isupper()
//
// Determines whether the given character is uppercase.
-inline bool ascii_isupper(unsigned char c) { return c >= 'A' && c <= 'Z'; }
+inline constexpr bool ascii_isupper(unsigned char c) {
+ return c >= 'A' && c <= 'Z';
+}
// ascii_islower()
//
// Determines whether the given character is lowercase.
-inline bool ascii_islower(unsigned char c) { return c >= 'a' && c <= 'z'; }
+inline constexpr bool ascii_islower(unsigned char c) {
+ return c >= 'a' && c <= 'z';
+}
// ascii_isascii()
//
// Determines whether the given character is ASCII.
-inline bool ascii_isascii(unsigned char c) { return c < 128; }
+inline constexpr bool ascii_isascii(unsigned char c) { return c < 128; }
// ascii_tolower()
//
@@ -171,7 +189,18 @@ void AsciiStrToLower(absl::Nonnull<std::string*> s);
// Creates a lowercase string from a given absl::string_view.
ABSL_MUST_USE_RESULT inline std::string AsciiStrToLower(absl::string_view s) {
- std::string result(s);
+ std::string result;
+ strings_internal::STLStringResizeUninitialized(&result, s.size());
+ ascii_internal::AsciiStrToLower(&result[0], s.data(), s.size());
+ return result;
+}
+
+// Creates a lowercase string from a given std::string&&.
+//
+// (Template is used to lower priority of this overload.)
+template <int&... DoNotSpecify>
+ABSL_MUST_USE_RESULT inline std::string AsciiStrToLower(std::string&& s) {
+ std::string result = std::move(s);
absl::AsciiStrToLower(&result);
return result;
}
@@ -189,7 +218,18 @@ void AsciiStrToUpper(absl::Nonnull<std::string*> s);
// Creates an uppercase string from a given absl::string_view.
ABSL_MUST_USE_RESULT inline std::string AsciiStrToUpper(absl::string_view s) {
- std::string result(s);
+ std::string result;
+ strings_internal::STLStringResizeUninitialized(&result, s.size());
+ ascii_internal::AsciiStrToUpper(&result[0], s.data(), s.size());
+ return result;
+}
+
+// Creates an uppercase string from a given std::string&&.
+//
+// (Template is used to lower priority of this overload.)
+template <int&... DoNotSpecify>
+ABSL_MUST_USE_RESULT inline std::string AsciiStrToUpper(std::string&& s) {
+ std::string result = std::move(s);
absl::AsciiStrToUpper(&result);
return result;
}
diff --git a/contrib/restricted/abseil-cpp/absl/strings/charconv.cc b/contrib/restricted/abseil-cpp/absl/strings/charconv.cc
index 0c9227f849..66c12cc73d 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/charconv.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/charconv.cc
@@ -359,16 +359,13 @@ template <typename FloatType>
bool HandleEdgeCase(const strings_internal::ParsedFloat& input, bool negative,
absl::Nonnull<FloatType*> value) {
if (input.type == strings_internal::FloatType::kNan) {
- // A bug in both clang < 7 and gcc would cause the compiler to optimize
- // away the buffer we are building below. Declaring the buffer volatile
- // avoids the issue, and has no measurable performance impact in
- // microbenchmarks.
+ // A bug in gcc would cause the compiler to optimize away the buffer we are
+ // building below. Declaring the buffer volatile avoids the issue, and has
+ // no measurable performance impact in microbenchmarks.
//
- // https://bugs.llvm.org/show_bug.cgi?id=37778
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86113
constexpr ptrdiff_t kNanBufferSize = 128;
-#if (defined(__GNUC__) && !defined(__clang__)) || \
- (defined(__clang__) && __clang_major__ < 7)
+#if (defined(__GNUC__) && !defined(__clang__))
volatile char n_char_sequence[kNanBufferSize];
#else
char n_char_sequence[kNanBufferSize];
diff --git a/contrib/restricted/abseil-cpp/absl/strings/charset.h b/contrib/restricted/abseil-cpp/absl/strings/charset.h
index ff4e81a41f..04ad459bc6 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/charset.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/charset.h
@@ -46,15 +46,13 @@
#ifndef ABSL_STRINGS_CHARSET_H_
#define ABSL_STRINGS_CHARSET_H_
-#include <cstddef>
#include <cstdint>
-#include <cstring>
-#include "absl/base/macros.h"
-#include "absl/base/port.h"
+#include "absl/base/config.h"
#include "absl/strings/string_view.h"
namespace absl {
+ABSL_NAMESPACE_BEGIN
class CharSet {
public:
@@ -159,6 +157,7 @@ class CharSet {
uint64_t m_[4];
};
+ABSL_NAMESPACE_END
} // namespace absl
#endif // ABSL_STRINGS_CHARSET_H_
diff --git a/contrib/restricted/abseil-cpp/absl/strings/cord.h b/contrib/restricted/abseil-cpp/absl/strings/cord.h
index 69aa8ef41f..1f8aafb587 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/cord.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/cord.h
@@ -61,6 +61,7 @@
#define ABSL_STRINGS_CORD_H_
#include <algorithm>
+#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstring>
@@ -68,16 +69,14 @@
#include <iterator>
#include <string>
#include <type_traits>
+#include <utility>
#include "absl/base/attributes.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"
#include "absl/base/nullability.h"
#include "absl/base/optimization.h"
-#include "absl/base/port.h"
-#include "absl/container/inlined_vector.h"
#include "absl/crc/internal/crc_cord_state.h"
#include "absl/functional/function_ref.h"
#include "absl/meta/type_traits.h"
@@ -88,12 +87,10 @@
#include "absl/strings/internal/cord_rep_btree.h"
#include "absl/strings/internal/cord_rep_btree_reader.h"
#include "absl/strings/internal/cord_rep_crc.h"
-#include "absl/strings/internal/cordz_functions.h"
+#include "absl/strings/internal/cord_rep_flat.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"
#include "absl/types/compare.h"
@@ -641,7 +638,6 @@ class Cord {
bool operator==(const CharIterator& other) const;
bool operator!=(const CharIterator& other) const;
reference operator*() const;
- pointer operator->() const;
friend Cord;
@@ -979,15 +975,9 @@ class Cord {
bool IsSame(const InlineRep& other) const { return data_ == other.data_; }
+ // Copies the inline contents into `dst`. Assumes the cord is not empty.
void CopyTo(absl::Nonnull<std::string*> dst) const {
- // memcpy is much faster when operating on a known size. On most supported
- // platforms, the small string optimization is large enough that resizing
- // to 15 bytes does not cause a memory allocation.
- absl::strings_internal::STLStringResizeUninitialized(dst, kMaxInline);
- data_.copy_max_inline_to(&(*dst)[0]);
- // erase is faster than resize because the logic for memory allocation is
- // not needed.
- dst->erase(inline_size());
+ data_.CopyInlineToString(dst);
}
// Copies the inline contents into `dst`. Assumes the cord is not empty.
@@ -1659,10 +1649,6 @@ inline Cord::CharIterator::reference Cord::CharIterator::operator*() const {
return *chunk_iterator_->data();
}
-inline Cord::CharIterator::pointer Cord::CharIterator::operator->() const {
- return chunk_iterator_->data();
-}
-
inline Cord Cord::AdvanceAndRead(absl::Nonnull<CharIterator*> it,
size_t n_bytes) {
assert(it != nullptr);
diff --git a/contrib/restricted/abseil-cpp/absl/strings/escaping.cc b/contrib/restricted/abseil-cpp/absl/strings/escaping.cc
index 4ffef94b63..b70c5041ae 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/escaping.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/escaping.cc
@@ -15,6 +15,7 @@
#include "absl/strings/escaping.h"
#include <algorithm>
+#include <array>
#include <cassert>
#include <cstddef>
#include <cstdint>
@@ -24,6 +25,7 @@
#include <utility>
#include "absl/base/config.h"
+#include "absl/base/internal/endian.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/internal/unaligned_access.h"
#include "absl/base/nullability.h"
@@ -368,7 +370,7 @@ std::string CEscapeInternal(absl::string_view src, bool use_hex,
}
/* clang-format off */
-constexpr unsigned char kCEscapedLen[256] = {
+constexpr std::array<unsigned char, 256> kCEscapedLen = {
4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 4, 4, 2, 4, 4, // \t, \n, \r
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // ", '
@@ -388,6 +390,40 @@ constexpr unsigned char kCEscapedLen[256] = {
};
/* clang-format on */
+constexpr uint32_t MakeCEscapedLittleEndianUint32(size_t c) {
+ size_t char_len = kCEscapedLen[c];
+ if (char_len == 1) {
+ return static_cast<uint32_t>(c);
+ }
+ if (char_len == 2) {
+ switch (c) {
+ case '\n':
+ return '\\' | (static_cast<uint32_t>('n') << 8);
+ case '\r':
+ return '\\' | (static_cast<uint32_t>('r') << 8);
+ case '\t':
+ return '\\' | (static_cast<uint32_t>('t') << 8);
+ case '\"':
+ return '\\' | (static_cast<uint32_t>('\"') << 8);
+ case '\'':
+ return '\\' | (static_cast<uint32_t>('\'') << 8);
+ case '\\':
+ return '\\' | (static_cast<uint32_t>('\\') << 8);
+ }
+ }
+ return static_cast<uint32_t>('\\' | (('0' + (c / 64)) << 8) |
+ (('0' + ((c % 64) / 8)) << 16) |
+ (('0' + (c % 8)) << 24));
+}
+
+template <size_t... indexes>
+inline constexpr std::array<uint32_t, sizeof...(indexes)>
+MakeCEscapedLittleEndianUint32Array(std::index_sequence<indexes...>) {
+ return {MakeCEscapedLittleEndianUint32(indexes)...};
+}
+constexpr std::array<uint32_t, 256> kCEscapedLittleEndianUint32Array =
+ MakeCEscapedLittleEndianUint32Array(std::make_index_sequence<256>());
+
// Calculates the length of the C-style escaped version of 'src'.
// Assumes that non-printable characters are escaped using octal sequences, and
// that UTF-8 bytes are not handled specially.
@@ -421,59 +457,31 @@ void CEscapeAndAppendInternal(absl::string_view src,
return;
}
+ // We keep 3 slop bytes so that we can call `little_endian::Store32`
+ // invariably regardless of the length of the escaped character.
+ constexpr size_t slop_bytes = 3;
size_t cur_dest_len = dest->size();
- ABSL_INTERNAL_CHECK(
- cur_dest_len <= std::numeric_limits<size_t>::max() - escaped_len,
- "std::string size overflow");
- strings_internal::STLStringResizeUninitialized(dest,
- cur_dest_len + escaped_len);
+ size_t new_dest_len = cur_dest_len + escaped_len + slop_bytes;
+ ABSL_INTERNAL_CHECK(new_dest_len > cur_dest_len, "std::string size overflow");
+ strings_internal::AppendUninitializedTraits<std::string>::Append(
+ dest, escaped_len + slop_bytes);
char* append_ptr = &(*dest)[cur_dest_len];
for (char c : src) {
- size_t char_len = kCEscapedLen[static_cast<unsigned char>(c)];
- if (char_len == 1) {
- *append_ptr++ = c;
- } else if (char_len == 2) {
- switch (c) {
- case '\n':
- *append_ptr++ = '\\';
- *append_ptr++ = 'n';
- break;
- case '\r':
- *append_ptr++ = '\\';
- *append_ptr++ = 'r';
- break;
- case '\t':
- *append_ptr++ = '\\';
- *append_ptr++ = 't';
- break;
- case '\"':
- *append_ptr++ = '\\';
- *append_ptr++ = '\"';
- break;
- case '\'':
- *append_ptr++ = '\\';
- *append_ptr++ = '\'';
- break;
- case '\\':
- *append_ptr++ = '\\';
- *append_ptr++ = '\\';
- break;
- }
- } else {
- *append_ptr++ = '\\';
- *append_ptr++ = '0' + static_cast<unsigned char>(c) / 64;
- *append_ptr++ = '0' + (static_cast<unsigned char>(c) % 64) / 8;
- *append_ptr++ = '0' + static_cast<unsigned char>(c) % 8;
- }
+ unsigned char uc = static_cast<unsigned char>(c);
+ size_t char_len = kCEscapedLen[uc];
+ uint32_t little_endian_uint32 = kCEscapedLittleEndianUint32Array[uc];
+ little_endian::Store32(append_ptr, little_endian_uint32);
+ append_ptr += char_len;
}
+ dest->resize(new_dest_len - slop_bytes);
}
// Reverses the mapping in Base64EscapeInternal; see that method's
// documentation for details of the mapping.
bool Base64UnescapeInternal(absl::Nullable<const char*> src_param, size_t szsrc,
absl::Nullable<char*> dest, size_t szdest,
- absl::Nonnull<const signed char*> unbase64,
+ const std::array<signed char, 256>& unbase64,
absl::Nonnull<size_t*> len) {
static const char kPad64Equals = '=';
static const char kPad64Dot = '.';
@@ -738,7 +746,7 @@ bool Base64UnescapeInternal(absl::Nullable<const char*> src_param, size_t szsrc,
// where the value of "Base64[]" was replaced by one of k(WebSafe)Base64Chars
// in the internal escaping.cc.
/* clang-format off */
-constexpr signed char kUnBase64[] = {
+constexpr std::array<signed char, 256> kUnBase64 = {
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
@@ -773,7 +781,7 @@ constexpr signed char kUnBase64[] = {
-1, -1, -1, -1, -1, -1, -1, -1
};
-constexpr signed char kUnWebSafeBase64[] = {
+constexpr std::array<signed char, 256> kUnWebSafeBase64 = {
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
@@ -812,7 +820,7 @@ constexpr signed char kUnWebSafeBase64[] = {
template <typename String>
bool Base64UnescapeInternal(absl::Nullable<const char*> src, size_t slen,
absl::Nonnull<String*> dest,
- absl::Nonnull<const signed char*> unbase64) {
+ const std::array<signed char, 256>& unbase64) {
// Determine the size of the output string. Base64 encodes every 3 bytes into
// 4 characters. Any leftover chars are added directly for good measure.
const size_t dest_len = 3 * (slen / 4) + (slen % 4);
@@ -837,7 +845,7 @@ bool Base64UnescapeInternal(absl::Nullable<const char*> src, size_t slen,
}
/* clang-format off */
-constexpr char kHexValueLenient[256] = {
+constexpr std::array<char, 256> kHexValueLenient = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -856,7 +864,7 @@ constexpr char kHexValueLenient[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
-constexpr signed char kHexValueStrict[256] = {
+constexpr std::array<signed char, 256> kHexValueStrict = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_bigint.h b/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_bigint.h
index cb29767663..2c7a336646 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_bigint.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_bigint.h
@@ -17,7 +17,7 @@
#include <algorithm>
#include <cstdint>
-#include <iostream>
+#include <ostream>
#include <string>
#include "absl/base/config.h"
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 f0060f1015..b68ec2bbc5 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.h
@@ -19,16 +19,18 @@
#include <cassert>
#include <cstddef>
#include <cstdint>
-#include <type_traits>
+#include <cstring>
+#include <string>
#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/endian.h"
#include "absl/base/internal/invoke.h"
+#include "absl/base/macros.h"
+#include "absl/base/nullability.h"
#include "absl/base/optimization.h"
#include "absl/container/internal/compressed_tuple.h"
#include "absl/container/internal/container_memory.h"
-#include "absl/meta/type_traits.h"
#include "absl/strings/string_view.h"
// We can only add poisoning if we can detect consteval executions.
@@ -635,6 +637,19 @@ class InlineData {
poison();
}
+ void CopyInlineToString(absl::Nonnull<std::string*> dst) const {
+ assert(!is_tree());
+ // As Cord can store only 15 bytes it is smaller than std::string's
+ // small string optimization buffer size. Therefore we will always trigger
+ // the fast assign short path.
+ //
+ // Copying with a size equal to the maximum allows more efficient, wider
+ // stores to be used and no branching.
+ dst->assign(rep_.SanitizerSafeCopy().as_chars(), kMaxInline);
+ // After the copy we then change the size and put in a 0 byte.
+ dst->erase(inline_size());
+ }
+
void copy_max_inline_to(char* dst) const {
assert(!is_tree());
memcpy(dst, rep_.SanitizerSafeCopy().as_chars(), kMaxInline);
@@ -713,35 +728,53 @@ class InlineData {
GetOrNull(chars, 13),
GetOrNull(chars, 14)} {}
+#ifdef ABSL_INTERNAL_CORD_HAVE_SANITIZER
+ // Break compiler optimization for cases when value is allocated on the
+ // stack. Compiler assumes that the the variable is fully accessible
+ // regardless of our poisoning.
+ // Missing report: https://github.com/llvm/llvm-project/issues/100640
+ const Rep* self() const {
+ const Rep* volatile ptr = this;
+ return ptr;
+ }
+ Rep* self() {
+ Rep* volatile ptr = this;
+ return ptr;
+ }
+#else
+ constexpr const Rep* self() const { return this; }
+ constexpr Rep* self() { return this; }
+#endif
+
// Disable sanitizer as we must always be able to read `tag`.
ABSL_CORD_INTERNAL_NO_SANITIZE
int8_t tag() const { return reinterpret_cast<const int8_t*>(this)[0]; }
- void set_tag(int8_t rhs) { reinterpret_cast<int8_t*>(this)[0] = rhs; }
+ void set_tag(int8_t rhs) { reinterpret_cast<int8_t*>(self())[0] = rhs; }
- char* as_chars() { return data + 1; }
- const char* as_chars() const { return data + 1; }
+ char* as_chars() { return self()->data + 1; }
+ const char* as_chars() const { return self()->data + 1; }
- bool is_tree() const { return (tag() & 1) != 0; }
+ bool is_tree() const { return (self()->tag() & 1) != 0; }
size_t inline_size() const {
- ABSL_ASSERT(!is_tree());
- return static_cast<size_t>(tag()) >> 1;
+ ABSL_ASSERT(!self()->is_tree());
+ return static_cast<size_t>(self()->tag()) >> 1;
}
void set_inline_size(size_t size) {
ABSL_ASSERT(size <= kMaxInline);
- set_tag(static_cast<int8_t>(size << 1));
+ self()->set_tag(static_cast<int8_t>(size << 1));
}
- CordRep* tree() const { return as_tree.rep; }
- void set_tree(CordRep* rhs) { as_tree.rep = rhs; }
+ CordRep* tree() const { return self()->as_tree.rep; }
+ void set_tree(CordRep* rhs) { self()->as_tree.rep = rhs; }
- cordz_info_t cordz_info() const { return as_tree.cordz_info; }
- void set_cordz_info(cordz_info_t rhs) { as_tree.cordz_info = rhs; }
+ cordz_info_t cordz_info() const { return self()->as_tree.cordz_info; }
+ void set_cordz_info(cordz_info_t rhs) { self()->as_tree.cordz_info = rhs; }
void make_tree(CordRep* tree) {
- as_tree.rep = tree;
- as_tree.cordz_info = kNullCordzInfo;
+ self()->as_tree.rep = tree;
+ self()->as_tree.cordz_info = kNullCordzInfo;
}
#ifdef ABSL_INTERNAL_CORD_HAVE_SANITIZER
diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc
index 8edf520dcd..aa31998088 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc
@@ -17,6 +17,7 @@
#include <string.h>
#include <algorithm>
+#include <array>
#include <cassert>
#include <cmath>
#include <limits>
@@ -159,7 +160,7 @@ class BinaryToDecimal {
// See the current block of digits.
absl::string_view CurrentDigits() const {
- return absl::string_view(digits_ + kDigitsPerChunk - size_, size_);
+ return absl::string_view(&digits_[kDigitsPerChunk - size_], size_);
}
// Advance the current view of digits.
@@ -234,7 +235,7 @@ class BinaryToDecimal {
size_t decimal_start_;
size_t decimal_end_;
- char digits_[kDigitsPerChunk];
+ std::array<char, kDigitsPerChunk> digits_;
size_t size_ = 0;
absl::Span<uint32_t> data_;
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 11ea96f2c1..ed1f117cda 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
@@ -253,6 +253,10 @@ using ShouldUseLifetimeBoundForPair = std::integral_constant<
(std::is_same<First, absl::string_view>::value ||
std::is_same<Second, absl::string_view>::value)>;
+template <typename StringType, typename ElementType, std::size_t Size>
+using ShouldUseLifetimeBoundForArray = std::integral_constant<
+ bool, std::is_same<StringType, std::string>::value &&
+ std::is_same<ElementType, absl::string_view>::value>;
// This class implements the range that is returned by absl::StrSplit(). This
// class has templated conversion operators that allow it to be implicitly
@@ -344,7 +348,38 @@ class Splitter {
return ConvertToPair<First, Second>();
}
+ // Returns an array with its elements set to the first few strings returned by
+ // the begin() iterator. If there is not a corresponding value the empty
+ // string is used.
+ template <typename ElementType, std::size_t Size,
+ std::enable_if_t<ShouldUseLifetimeBoundForArray<
+ StringType, ElementType, Size>::value,
+ std::nullptr_t> = nullptr>
+ // NOLINTNEXTLINE(google-explicit-constructor)
+ operator std::array<ElementType, Size>() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ return ConvertToArray<ElementType, Size>();
+ }
+
+ template <typename ElementType, std::size_t Size,
+ std::enable_if_t<!ShouldUseLifetimeBoundForArray<
+ StringType, ElementType, Size>::value,
+ std::nullptr_t> = nullptr>
+ // NOLINTNEXTLINE(google-explicit-constructor)
+ operator std::array<ElementType, Size>() const {
+ return ConvertToArray<ElementType, Size>();
+ }
+
private:
+ template <typename ElementType, std::size_t Size>
+ std::array<ElementType, Size> ConvertToArray() const {
+ std::array<ElementType, Size> a;
+ auto it = begin();
+ for (std::size_t i = 0; i < Size && it != end(); ++i, ++it) {
+ a[i] = ElementType(*it);
+ }
+ return a;
+ }
+
template <typename First, typename Second>
std::pair<First, Second> ConvertToPair() const {
absl::string_view first, second;
diff --git a/contrib/restricted/abseil-cpp/absl/strings/match.h b/contrib/restricted/abseil-cpp/absl/strings/match.h
index 1eeafbbf67..ce4fe78473 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/match.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/match.h
@@ -55,22 +55,32 @@ inline bool StrContains(absl::string_view haystack, char needle) noexcept {
// StartsWith()
//
// Returns whether a given string `text` begins with `prefix`.
-inline bool StartsWith(absl::string_view text,
- absl::string_view prefix) noexcept {
- return prefix.empty() ||
- (text.size() >= prefix.size() &&
- memcmp(text.data(), prefix.data(), prefix.size()) == 0);
+inline constexpr bool StartsWith(absl::string_view text,
+ absl::string_view prefix) noexcept {
+ if (prefix.empty()) {
+ return true;
+ }
+ if (text.size() < prefix.size()) {
+ return false;
+ }
+ absl::string_view possible_match = text.substr(0, prefix.size());
+
+ return possible_match == prefix;
}
// EndsWith()
//
// Returns whether a given string `text` ends with `suffix`.
-inline bool EndsWith(absl::string_view text,
- absl::string_view suffix) noexcept {
- return suffix.empty() ||
- (text.size() >= suffix.size() &&
- memcmp(text.data() + (text.size() - suffix.size()), suffix.data(),
- suffix.size()) == 0);
+inline constexpr bool EndsWith(absl::string_view text,
+ absl::string_view suffix) noexcept {
+ if (suffix.empty()) {
+ return true;
+ }
+ if (text.size() < suffix.size()) {
+ return false;
+ }
+ absl::string_view possible_match = text.substr(text.size() - suffix.size());
+ return possible_match == suffix;
}
// StrContainsIgnoreCase()
//
diff --git a/contrib/restricted/abseil-cpp/absl/strings/numbers.cc b/contrib/restricted/abseil-cpp/absl/strings/numbers.cc
index b57d9e82e5..83ea80b474 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/numbers.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/numbers.cc
@@ -18,6 +18,7 @@
#include "absl/strings/numbers.h"
#include <algorithm>
+#include <array>
#include <cassert>
#include <cfloat> // for DBL_DIG and FLT_DIG
#include <cmath> // for HUGE_VAL
@@ -674,7 +675,7 @@ namespace {
// Represents integer values of digits.
// Uses 36 to indicate an invalid character since we support
// bases up to 36.
-static const int8_t kAsciiToInt[256] = {
+static constexpr std::array<int8_t, 256> kAsciiToInt = {
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, // 16 36s.
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 0, 1, 2, 3, 4, 5,
diff --git a/contrib/restricted/abseil-cpp/absl/strings/str_cat.h b/contrib/restricted/abseil-cpp/absl/strings/str_cat.h
index b98adc0248..1a80662775 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/str_cat.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/str_cat.h
@@ -101,6 +101,7 @@
#include <vector>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/nullability.h"
#include "absl/base/port.h"
#include "absl/meta/type_traits.h"
@@ -110,6 +111,10 @@
#include "absl/strings/numbers.h"
#include "absl/strings/string_view.h"
+#if defined(ABSL_HAVE_STD_STRING_VIEW) && !defined(ABSL_USES_STD_STRING_VIEW)
+#include <string_view>
+#endif
+
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -361,6 +366,12 @@ class AlphaNum {
ABSL_ATTRIBUTE_LIFETIME_BOUND)
: piece_(pc) {}
+#if defined(ABSL_HAVE_STD_STRING_VIEW) && !defined(ABSL_USES_STD_STRING_VIEW)
+ AlphaNum(std::string_view pc // NOLINT(runtime/explicit)
+ ABSL_ATTRIBUTE_LIFETIME_BOUND)
+ : piece_(pc.data(), pc.size()) {}
+#endif // !ABSL_USES_STD_STRING_VIEW
+
template <typename T, typename = typename std::enable_if<
HasAbslStringify<T>::value>::type>
AlphaNum( // NOLINT(runtime/explicit)
diff --git a/contrib/restricted/abseil-cpp/absl/strings/str_split.h b/contrib/restricted/abseil-cpp/absl/strings/str_split.h
index ba176fca3c..7e8e31c3d8 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/str_split.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/str_split.h
@@ -444,8 +444,10 @@ using EnableSplitIfString =
// behavior works for:
//
// 1) All standard STL containers including `std::vector`, `std::list`,
-// `std::deque`, `std::set`,`std::multiset`, 'std::map`, and `std::multimap`
+// `std::deque`, `std::set`,`std::multiset`, 'std::map`, and `std::multimap`.
// 2) `std::pair` (which is not actually a container). See below.
+// 3) `std::array`, which is a container but has different behavior due to its
+// fixed size. See below.
//
// Example:
//
@@ -487,6 +489,21 @@ using EnableSplitIfString =
// std::pair<std::string, std::string> p = absl::StrSplit("a,b,c", ',');
// // p.first == "a", p.second == "b" // "c" is omitted.
//
+//
+// Splitting to `std::array` is similar to splitting to `std::pair`, but for
+// N elements instead of two; missing elements are filled with the empty string
+// and extra elements are discarded.
+//
+// Examples:
+//
+// // Stores first two split strings as the elements in a std::array.
+// std::array<std::string, 2> a = absl::StrSplit("a,b,c", ',');
+// // a[0] == "a", a[1] == "b" // "c" is omitted.
+//
+// // The second element is empty.
+// std::array<std::string, 2> a = absl::StrSplit("a,", ',');
+// // a[0] == "a", a[1] == ""
+//
// The `StrSplit()` function can be used multiple times to perform more
// complicated splitting logic, such as intelligently parsing key-value pairs.
//
diff --git a/contrib/restricted/abseil-cpp/absl/strings/string_view.h b/contrib/restricted/abseil-cpp/absl/strings/string_view.h
index ff7600144a..b461478f14 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/string_view.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/string_view.h
@@ -159,7 +159,7 @@ ABSL_NAMESPACE_BEGIN
//
// absl::string_view() == absl::string_view("", 0)
// absl::string_view(nullptr, 0) == absl::string_view("abcdef"+6, 0)
-class ABSL_INTERNAL_ATTRIBUTE_VIEW string_view {
+class ABSL_ATTRIBUTE_VIEW string_view {
public:
using traits_type = std::char_traits<char>;
using value_type = char;
@@ -200,13 +200,12 @@ class ABSL_INTERNAL_ATTRIBUTE_VIEW string_view {
absl::Nonnull<const char*> str)
: ptr_(str), length_(str ? StrlenInternal(str) : 0) {}
- // Implicit constructor of a `string_view` from a `const char*` and length.
+ // Constructor of a `string_view` from a `const char*` and length.
constexpr string_view(absl::Nullable<const char*> data, size_type len)
: ptr_(data), length_(CheckLengthInternal(len)) {}
- // NOTE: Harmlessly omitted to work around gdb bug.
- // constexpr string_view(const string_view&) noexcept = default;
- // string_view& operator=(const string_view&) noexcept = default;
+ constexpr string_view(const string_view&) noexcept = default;
+ string_view& operator=(const string_view&) noexcept = default;
// Iterators
@@ -293,7 +292,8 @@ class ABSL_INTERNAL_ATTRIBUTE_VIEW string_view {
// Returns the ith element of the `string_view` using the array operator.
// Note that this operator does not perform any bounds checking.
constexpr const_reference operator[](size_type i) const {
- return ABSL_HARDENING_ASSERT(i < size()), ptr_[i];
+ ABSL_HARDENING_ASSERT(i < size());
+ return ptr_[i];
}
// string_view::at()
@@ -302,25 +302,26 @@ class ABSL_INTERNAL_ATTRIBUTE_VIEW string_view {
// and an exception of type `std::out_of_range` will be thrown on invalid
// access.
constexpr const_reference at(size_type i) const {
- return ABSL_PREDICT_TRUE(i < size())
- ? ptr_[i]
- : ((void)base_internal::ThrowStdOutOfRange(
- "absl::string_view::at"),
- ptr_[i]);
+ if (ABSL_PREDICT_FALSE(i >= size())) {
+ base_internal::ThrowStdOutOfRange("absl::string_view::at");
+ }
+ return ptr_[i];
}
// string_view::front()
//
// Returns the first element of a `string_view`.
constexpr const_reference front() const {
- return ABSL_HARDENING_ASSERT(!empty()), ptr_[0];
+ ABSL_HARDENING_ASSERT(!empty());
+ return ptr_[0];
}
// string_view::back()
//
// Returns the last element of a `string_view`.
constexpr const_reference back() const {
- return ABSL_HARDENING_ASSERT(!empty()), ptr_[size() - 1];
+ ABSL_HARDENING_ASSERT(!empty());
+ return ptr_[size() - 1];
}
// string_view::data()
@@ -394,11 +395,10 @@ class ABSL_INTERNAL_ATTRIBUTE_VIEW string_view {
// `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 {
- return ABSL_PREDICT_FALSE(pos > length_)
- ? (base_internal::ThrowStdOutOfRange(
- "absl::string_view::substr"),
- string_view())
- : string_view(ptr_ + pos, Min(n, length_ - pos));
+ if (ABSL_PREDICT_FALSE(pos > length_)) {
+ base_internal::ThrowStdOutOfRange("absl::string_view::substr");
+ }
+ return string_view(ptr_ + pos, Min(n, length_ - pos));
}
// string_view::compare()
@@ -667,7 +667,8 @@ class ABSL_INTERNAL_ATTRIBUTE_VIEW string_view {
(std::numeric_limits<difference_type>::max)();
static constexpr size_type CheckLengthInternal(size_type len) {
- return ABSL_HARDENING_ASSERT(len <= kMaxSize), len;
+ ABSL_HARDENING_ASSERT(len <= kMaxSize);
+ return len;
}
static constexpr size_type StrlenInternal(absl::Nonnull<const char*> str) {
diff --git a/contrib/restricted/abseil-cpp/absl/strings/strip.h b/contrib/restricted/abseil-cpp/absl/strings/strip.h
index e3cda5bac3..8a55375169 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/strip.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/strip.h
@@ -24,6 +24,7 @@
#include <cstddef>
#include <string>
+#include "absl/base/attributes.h"
#include "absl/base/macros.h"
#include "absl/base/nullability.h"
#include "absl/strings/ascii.h"
@@ -44,8 +45,8 @@ ABSL_NAMESPACE_BEGIN
// absl::string_view input("abc");
// EXPECT_TRUE(absl::ConsumePrefix(&input, "a"));
// EXPECT_EQ(input, "bc");
-inline bool ConsumePrefix(absl::Nonnull<absl::string_view*> str,
- absl::string_view expected) {
+inline constexpr bool ConsumePrefix(absl::Nonnull<absl::string_view*> str,
+ absl::string_view expected) {
if (!absl::StartsWith(*str, expected)) return false;
str->remove_prefix(expected.size());
return true;
@@ -61,8 +62,8 @@ inline bool ConsumePrefix(absl::Nonnull<absl::string_view*> str,
// absl::string_view input("abcdef");
// EXPECT_TRUE(absl::ConsumeSuffix(&input, "def"));
// EXPECT_EQ(input, "abc");
-inline bool ConsumeSuffix(absl::Nonnull<absl::string_view*> str,
- absl::string_view expected) {
+inline constexpr bool ConsumeSuffix(absl::Nonnull<absl::string_view*> str,
+ absl::string_view expected) {
if (!absl::EndsWith(*str, expected)) return false;
str->remove_suffix(expected.size());
return true;
@@ -73,8 +74,9 @@ inline bool ConsumeSuffix(absl::Nonnull<absl::string_view*> str,
// Returns a view into the input string `str` with the given `prefix` removed,
// but leaving the original string intact. If the prefix does not match at the
// start of the string, returns the original string instead.
-ABSL_MUST_USE_RESULT inline absl::string_view StripPrefix(
- absl::string_view str, absl::string_view prefix) {
+ABSL_MUST_USE_RESULT inline constexpr absl::string_view StripPrefix(
+ absl::string_view str ABSL_ATTRIBUTE_LIFETIME_BOUND,
+ absl::string_view prefix) {
if (absl::StartsWith(str, prefix)) str.remove_prefix(prefix.size());
return str;
}
@@ -84,8 +86,9 @@ ABSL_MUST_USE_RESULT inline absl::string_view StripPrefix(
// Returns a view into the input string `str` with the given `suffix` removed,
// but leaving the original string intact. If the suffix does not match at the
// end of the string, returns the original string instead.
-ABSL_MUST_USE_RESULT inline absl::string_view StripSuffix(
- absl::string_view str, absl::string_view suffix) {
+ABSL_MUST_USE_RESULT inline constexpr absl::string_view StripSuffix(
+ absl::string_view str ABSL_ATTRIBUTE_LIFETIME_BOUND,
+ absl::string_view suffix) {
if (absl::EndsWith(str, suffix)) str.remove_suffix(suffix.size());
return str;
}
diff --git a/contrib/restricted/abseil-cpp/absl/strings/ya.make b/contrib/restricted/abseil-cpp/absl/strings/ya.make
index ff42ac04ca..95f3fdd5c7 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/strings/ya.make
@@ -6,7 +6,7 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20240722.1)
+VERSION(20250127.0)
PEERDIR(
contrib/restricted/abseil-cpp/absl/base
diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.cc b/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.cc
index d2f82da3bb..a530baf4cc 100644
--- a/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.cc
+++ b/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.cc
@@ -17,6 +17,7 @@
#include <atomic>
#include "absl/base/internal/raw_logging.h"
+#include "absl/base/internal/tracing.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -40,6 +41,7 @@ bool BlockingCounter::DecrementCount() {
ABSL_RAW_CHECK(count >= 0,
"BlockingCounter::DecrementCount() called too many times");
if (count == 0) {
+ base_internal::TraceSignal(this, TraceObjectKind());
MutexLock l(&lock_);
done_ = true;
return true;
@@ -48,19 +50,23 @@ bool BlockingCounter::DecrementCount() {
}
void BlockingCounter::Wait() {
- MutexLock l(&this->lock_);
+ base_internal::TraceWait(this, TraceObjectKind());
+ {
+ MutexLock l(&this->lock_);
- // only one thread may call Wait(). To support more than one thread,
- // implement a counter num_to_exit, like in the Barrier class.
- ABSL_RAW_CHECK(num_waiting_ == 0, "multiple threads called Wait()");
- num_waiting_++;
+ // only one thread may call Wait(). To support more than one thread,
+ // implement a counter num_to_exit, like in the Barrier class.
+ 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.
- // Therefore, the thread calling this method is free to delete the object
- // after we return from this method.
+ // 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.
+ }
+ base_internal::TraceContinue(this, TraceObjectKind());
}
ABSL_NAMESPACE_END
diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.h b/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.h
index 1908fdb1d9..d0504a19bf 100644
--- a/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.h
+++ b/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.h
@@ -22,6 +22,7 @@
#include <atomic>
+#include "absl/base/internal/tracing.h"
#include "absl/base/thread_annotations.h"
#include "absl/synchronization/mutex.h"
@@ -89,6 +90,11 @@ class BlockingCounter {
void Wait();
private:
+ // Convenience helper to reduce verbosity at call sites.
+ static inline constexpr base_internal::ObjectKind TraceObjectKind() {
+ return base_internal::ObjectKind::kBlockingCounter;
+ }
+
Mutex lock_;
std::atomic<int> count_;
int num_waiting_ ABSL_GUARDED_BY(lock_);
diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc b/contrib/restricted/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc
index eacaa28d7b..93cd376bde 100644
--- a/contrib/restricted/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc
+++ b/contrib/restricted/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc
@@ -39,7 +39,8 @@ ABSL_CONST_INIT static base_internal::SpinLock freelist_lock(
ABSL_CONST_INIT static base_internal::ThreadIdentity* thread_identity_freelist;
// A per-thread destructor for reclaiming associated ThreadIdentity objects.
-// Since we must preserve their storage we cache them for re-use.
+// Since we must preserve their storage, we cache them for re-use instead of
+// truly destructing the object.
static void ReclaimThreadIdentity(void* v) {
base_internal::ThreadIdentity* identity =
static_cast<base_internal::ThreadIdentity*>(v);
@@ -124,6 +125,9 @@ static base_internal::ThreadIdentity* NewThreadIdentity() {
identity = reinterpret_cast<base_internal::ThreadIdentity*>(
RoundUp(reinterpret_cast<intptr_t>(allocation),
base_internal::PerThreadSynch::kAlignment));
+ // Note that *identity is never constructed.
+ // TODO(b/357097463): change this "one time init" to be a proper
+ // constructor.
OneTimeInitThreadIdentity(identity);
}
ResetThreadIdentityBetweenReuse(identity);
diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/mutex.cc b/contrib/restricted/abseil-cpp/absl/synchronization/mutex.cc
index cb3c7e74ec..52ed27f696 100644
--- a/contrib/restricted/abseil-cpp/absl/synchronization/mutex.cc
+++ b/contrib/restricted/abseil-cpp/absl/synchronization/mutex.cc
@@ -651,6 +651,13 @@ static const intptr_t kMuSpin = 0x0040L; // spinlock protects wait list
static const intptr_t kMuLow = 0x00ffL; // mask all mutex bits
static const intptr_t kMuHigh = ~kMuLow; // mask pointer/reader count
+static_assert((0xab & (kMuWriter | kMuReader)) == (kMuWriter | kMuReader),
+ "The debug allocator's uninitialized pattern (0xab) must be an "
+ "invalid mutex state");
+static_assert((0xcd & (kMuWriter | kMuReader)) == (kMuWriter | kMuReader),
+ "The debug allocator's freed pattern (0xcd) must be an invalid "
+ "mutex state");
+
// Hack to make constant values available to gdb pretty printer
enum {
kGdbMuSpin = kMuSpin,
@@ -1713,25 +1720,44 @@ void Mutex::Unlock() {
// NOTE: optimized out when kDebugMode is false.
bool should_try_cas = ((v & (kMuEvent | kMuWriter)) == kMuWriter &&
(v & (kMuWait | kMuDesig)) != kMuWait);
+
// But, we can use an alternate computation of it, that compilers
// currently don't find on their own. When that changes, this function
// can be simplified.
- intptr_t x = (v ^ (kMuWriter | kMuWait)) & (kMuWriter | kMuEvent);
- intptr_t y = (v ^ (kMuWriter | kMuWait)) & (kMuWait | kMuDesig);
- // Claim: "x == 0 && y > 0" is equal to should_try_cas.
- // Also, because kMuWriter and kMuEvent exceed kMuDesig and kMuWait,
- // all possible non-zero values for x exceed all possible values for y.
- // Therefore, (x == 0 && y > 0) == (x < y).
- if (kDebugMode && should_try_cas != (x < y)) {
+ //
+ // should_try_cas is true iff the bits satisfy the following conditions:
+ //
+ // Ev Wr Wa De
+ // equal to 0 1
+ // and not equal to 1 0
+ //
+ // after xoring by 0 1 0 1, this is equivalent to:
+ //
+ // equal to 0 0
+ // and not equal to 1 1, which is the same as:
+ //
+ // smaller than 0 0 1 1
+ static_assert(kMuEvent > kMuWait, "Needed for should_try_cas_fast");
+ static_assert(kMuEvent > kMuDesig, "Needed for should_try_cas_fast");
+ static_assert(kMuWriter > kMuWait, "Needed for should_try_cas_fast");
+ static_assert(kMuWriter > kMuDesig, "Needed for should_try_cas_fast");
+
+ bool should_try_cas_fast =
+ ((v ^ (kMuWriter | kMuDesig)) &
+ (kMuEvent | kMuWriter | kMuWait | kMuDesig)) < (kMuWait | kMuDesig);
+
+ if (kDebugMode && should_try_cas != should_try_cas_fast) {
// We would usually use PRIdPTR here, but is not correctly implemented
// within the android toolchain.
ABSL_RAW_LOG(FATAL, "internal logic error %llx %llx %llx\n",
- static_cast<long long>(v), static_cast<long long>(x),
- static_cast<long long>(y));
+ static_cast<long long>(v),
+ static_cast<long long>(should_try_cas),
+ static_cast<long long>(should_try_cas_fast));
}
- if (x < y && mu_.compare_exchange_strong(v, v & ~(kMuWrWait | kMuWriter),
- std::memory_order_release,
- std::memory_order_relaxed)) {
+ if (should_try_cas_fast &&
+ mu_.compare_exchange_strong(v, v & ~(kMuWrWait | kMuWriter),
+ std::memory_order_release,
+ std::memory_order_relaxed)) {
// fast writer release (writer with no waiters or with designated waker)
} else {
this->UnlockSlow(nullptr /*no waitp*/); // take slow path
diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/notification.cc b/contrib/restricted/abseil-cpp/absl/synchronization/notification.cc
index 165ba669fb..a5853ab3d7 100644
--- a/contrib/restricted/abseil-cpp/absl/synchronization/notification.cc
+++ b/contrib/restricted/abseil-cpp/absl/synchronization/notification.cc
@@ -17,6 +17,7 @@
#include <atomic>
#include "absl/base/internal/raw_logging.h"
+#include "absl/base/internal/tracing.h"
#include "absl/synchronization/mutex.h"
#include "absl/time/time.h"
@@ -24,6 +25,7 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
void Notification::Notify() {
+ base_internal::TraceSignal(this, TraceObjectKind());
MutexLock l(&this->mutex_);
#ifndef NDEBUG
@@ -45,31 +47,37 @@ Notification::~Notification() {
}
void Notification::WaitForNotification() const {
+ base_internal::TraceWait(this, TraceObjectKind());
if (!HasBeenNotifiedInternal(&this->notified_yet_)) {
- this->mutex_.LockWhen(Condition(&HasBeenNotifiedInternal,
- &this->notified_yet_));
+ this->mutex_.LockWhen(
+ Condition(&HasBeenNotifiedInternal, &this->notified_yet_));
this->mutex_.Unlock();
}
+ base_internal::TraceContinue(this, TraceObjectKind());
}
bool Notification::WaitForNotificationWithTimeout(
absl::Duration timeout) const {
+ base_internal::TraceWait(this, TraceObjectKind());
bool notified = HasBeenNotifiedInternal(&this->notified_yet_);
if (!notified) {
notified = this->mutex_.LockWhenWithTimeout(
Condition(&HasBeenNotifiedInternal, &this->notified_yet_), timeout);
this->mutex_.Unlock();
}
+ base_internal::TraceContinue(notified ? this : nullptr, TraceObjectKind());
return notified;
}
bool Notification::WaitForNotificationWithDeadline(absl::Time deadline) const {
+ base_internal::TraceWait(this, TraceObjectKind());
bool notified = HasBeenNotifiedInternal(&this->notified_yet_);
if (!notified) {
notified = this->mutex_.LockWhenWithDeadline(
Condition(&HasBeenNotifiedInternal, &this->notified_yet_), deadline);
this->mutex_.Unlock();
}
+ base_internal::TraceContinue(notified ? this : nullptr, TraceObjectKind());
return notified;
}
diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/notification.h b/contrib/restricted/abseil-cpp/absl/synchronization/notification.h
index 8986d9a408..78cdf29608 100644
--- a/contrib/restricted/abseil-cpp/absl/synchronization/notification.h
+++ b/contrib/restricted/abseil-cpp/absl/synchronization/notification.h
@@ -53,6 +53,7 @@
#include <atomic>
#include "absl/base/attributes.h"
+#include "absl/base/internal/tracing.h"
#include "absl/synchronization/mutex.h"
#include "absl/time/time.h"
@@ -75,7 +76,11 @@ class Notification {
//
// Returns the value of the notification's internal "notified" state.
ABSL_MUST_USE_RESULT bool HasBeenNotified() const {
- return HasBeenNotifiedInternal(&this->notified_yet_);
+ if (HasBeenNotifiedInternal(&this->notified_yet_)) {
+ base_internal::TraceObserved(this, TraceObjectKind());
+ return true;
+ }
+ return false;
}
// Notification::WaitForNotification()
@@ -108,6 +113,11 @@ class Notification {
void Notify();
private:
+ // Convenience helper to reduce verbosity at call sites.
+ static inline constexpr base_internal::ObjectKind TraceObjectKind() {
+ return base_internal::ObjectKind::kNotification;
+ }
+
static inline bool HasBeenNotifiedInternal(
const std::atomic<bool>* notified_yet) {
return notified_yet->load(std::memory_order_acquire);
diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/ya.make b/contrib/restricted/abseil-cpp/absl/synchronization/ya.make
index 3a2fb1b4de..bd9b7000b2 100644
--- a/contrib/restricted/abseil-cpp/absl/synchronization/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/synchronization/ya.make
@@ -6,7 +6,7 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20240722.1)
+VERSION(20250127.0)
PEERDIR(
contrib/restricted/abseil-cpp/absl/base
diff --git a/contrib/restricted/abseil-cpp/absl/time/duration.cc b/contrib/restricted/abseil-cpp/absl/time/duration.cc
index 8d0b66f825..19407080a7 100644
--- a/contrib/restricted/abseil-cpp/absl/time/duration.cc
+++ b/contrib/restricted/abseil-cpp/absl/time/duration.cc
@@ -549,50 +549,6 @@ Duration DurationFromTimeval(timeval tv) {
//
// Conversion to other duration types.
//
-
-int64_t ToInt64Nanoseconds(Duration d) {
- if (time_internal::GetRepHi(d) >= 0 &&
- time_internal::GetRepHi(d) >> 33 == 0) {
- return (time_internal::GetRepHi(d) * 1000 * 1000 * 1000) +
- (time_internal::GetRepLo(d) / kTicksPerNanosecond);
- }
- return d / Nanoseconds(1);
-}
-int64_t ToInt64Microseconds(Duration d) {
- if (time_internal::GetRepHi(d) >= 0 &&
- time_internal::GetRepHi(d) >> 43 == 0) {
- return (time_internal::GetRepHi(d) * 1000 * 1000) +
- (time_internal::GetRepLo(d) / (kTicksPerNanosecond * 1000));
- }
- return d / Microseconds(1);
-}
-int64_t ToInt64Milliseconds(Duration d) {
- if (time_internal::GetRepHi(d) >= 0 &&
- time_internal::GetRepHi(d) >> 53 == 0) {
- return (time_internal::GetRepHi(d) * 1000) +
- (time_internal::GetRepLo(d) / (kTicksPerNanosecond * 1000 * 1000));
- }
- return d / Milliseconds(1);
-}
-int64_t ToInt64Seconds(Duration d) {
- int64_t hi = time_internal::GetRepHi(d);
- if (time_internal::IsInfiniteDuration(d)) return hi;
- if (hi < 0 && time_internal::GetRepLo(d) != 0) ++hi;
- return hi;
-}
-int64_t ToInt64Minutes(Duration d) {
- int64_t hi = time_internal::GetRepHi(d);
- if (time_internal::IsInfiniteDuration(d)) return hi;
- if (hi < 0 && time_internal::GetRepLo(d) != 0) ++hi;
- return hi / 60;
-}
-int64_t ToInt64Hours(Duration d) {
- int64_t hi = time_internal::GetRepHi(d);
- if (time_internal::IsInfiniteDuration(d)) return hi;
- if (hi < 0 && time_internal::GetRepLo(d) != 0) ++hi;
- return hi / (60 * 60);
-}
-
double ToDoubleNanoseconds(Duration d) {
return FDivDuration(d, Nanoseconds(1));
}
@@ -718,13 +674,12 @@ struct DisplayUnit {
int prec;
double pow10;
};
-ABSL_CONST_INIT const DisplayUnit kDisplayNano = {"ns", 2, 1e2};
-ABSL_CONST_INIT const DisplayUnit kDisplayMicro = {"us", 5, 1e5};
-ABSL_CONST_INIT const DisplayUnit kDisplayMilli = {"ms", 8, 1e8};
-ABSL_CONST_INIT const DisplayUnit kDisplaySec = {"s", 11, 1e11};
-ABSL_CONST_INIT const DisplayUnit kDisplayMin = {"m", -1, 0.0}; // prec ignored
-ABSL_CONST_INIT const DisplayUnit kDisplayHour = {"h", -1,
- 0.0}; // prec ignored
+constexpr DisplayUnit kDisplayNano = {"ns", 2, 1e2};
+constexpr DisplayUnit kDisplayMicro = {"us", 5, 1e5};
+constexpr DisplayUnit kDisplayMilli = {"ms", 8, 1e8};
+constexpr DisplayUnit kDisplaySec = {"s", 11, 1e11};
+constexpr DisplayUnit kDisplayMin = {"m", -1, 0.0}; // prec ignored
+constexpr DisplayUnit kDisplayHour = {"h", -1, 0.0}; // prec ignored
void AppendNumberUnit(std::string* out, int64_t n, DisplayUnit unit) {
char buf[sizeof("2562047788015216")]; // hours in max duration
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 e09654eaf3..ed7f9cb97a 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
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "time_zone_fixed.h"
+#include "absl/time/internal/cctz/src/time_zone_fixed.h"
#include <algorithm>
#include <cassert>
diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc
index e7e30a2fb7..0e5f32f14a 100644
--- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc
+++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc
@@ -46,7 +46,7 @@
#endif
#include "absl/time/internal/cctz/include/cctz/civil_time.h"
-#include "time_zone_if.h"
+#include "absl/time/internal/cctz/src/time_zone_if.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.cc b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.cc
index 0e65cd9e73..09f83e82f7 100644
--- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.cc
+++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.cc
@@ -12,11 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "time_zone_if.h"
+#include "absl/time/internal/cctz/src/time_zone_if.h"
#include "absl/base/config.h"
-#include "time_zone_info.h"
-#include "time_zone_libc.h"
+#include "absl/time/internal/cctz/src/time_zone_info.h"
+#include "absl/time/internal/cctz/src/time_zone_libc.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc
index aadbb77da2..5f2f49e424 100644
--- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc
+++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "time_zone_impl.h"
+#include "absl/time/internal/cctz/src/time_zone_impl.h"
#include <deque>
#include <memory>
@@ -22,7 +22,7 @@
#include <utility>
#include "absl/base/config.h"
-#include "time_zone_fixed.h"
+#include "absl/time/internal/cctz/src/time_zone_fixed.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.h b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.h
index 8308a3b49e..da3aec525c 100644
--- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.h
+++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.h
@@ -21,8 +21,8 @@
#include "absl/base/config.h"
#include "absl/time/internal/cctz/include/cctz/civil_time.h"
#include "absl/time/internal/cctz/include/cctz/time_zone.h"
-#include "time_zone_if.h"
-#include "time_zone_info.h"
+#include "absl/time/internal/cctz/src/time_zone_if.h"
+#include "absl/time/internal/cctz/src/time_zone_info.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
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 b7178a6b67..f8484c9050 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
@@ -30,7 +30,7 @@
// Note that we assume the proleptic Gregorian calendar and 60-second
// minutes throughout.
-#include "time_zone_info.h"
+#include "absl/time/internal/cctz/src/time_zone_info.h"
#include <algorithm>
#include <cassert>
@@ -49,8 +49,8 @@
#include "absl/base/config.h"
#include "absl/time/internal/cctz/include/cctz/civil_time.h"
-#include "time_zone_fixed.h"
-#include "time_zone_posix.h"
+#include "absl/time/internal/cctz/src/time_zone_fixed.h"
+#include "absl/time/internal/cctz/src/time_zone_posix.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.h b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.h
index 689df6f9c0..efe2f9cbfb 100644
--- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.h
+++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.h
@@ -26,8 +26,8 @@
#include "absl/time/internal/cctz/include/cctz/civil_time.h"
#include "absl/time/internal/cctz/include/cctz/time_zone.h"
#include "absl/time/internal/cctz/include/cctz/zone_info_source.h"
-#include "time_zone_if.h"
-#include "tzfile.h"
+#include "absl/time/internal/cctz/src/time_zone_if.h"
+#include "absl/time/internal/cctz/src/tzfile.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc
index b509402783..362da1ab58 100644
--- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc
+++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc
@@ -16,7 +16,7 @@
#define _CRT_SECURE_NO_WARNINGS 1
#endif
-#include "time_zone_libc.h"
+#include "absl/time/internal/cctz/src/time_zone_libc.h"
#include <chrono>
#include <ctime>
diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.h b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.h
index ae2107376f..f1ed5cd08f 100644
--- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.h
+++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.h
@@ -19,7 +19,7 @@
#include <string>
#include "absl/base/config.h"
-#include "time_zone_if.h"
+#include "absl/time/internal/cctz/src/time_zone_if.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
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 e0d773b831..a6f3430c4a 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
@@ -47,6 +47,7 @@
#include <wchar.h>
#include <windows.globalization.h>
#include <windows.h>
+#include <winstring.h>
#endif
#endif
@@ -54,8 +55,8 @@
#include <cstring>
#include <string>
-#include "time_zone_fixed.h"
-#include "time_zone_impl.h"
+#include "absl/time/internal/cctz/src/time_zone_fixed.h"
+#include "absl/time/internal/cctz/src/time_zone_impl.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc
index 5cdd09e89d..efea080470 100644
--- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc
+++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "time_zone_posix.h"
+#include "absl/time/internal/cctz/src/time_zone_posix.h"
#include <cstddef>
#include <cstring>
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 2be3bb8d98..628143894a 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
@@ -25,7 +25,7 @@
#define TZDEFRULES "posixrules"
#endif /* !defined TZDEFRULES */
-/* See Internet RFC 8536 for more details about the following format. */
+/* See Internet RFC 9636 for more details about the following format. */
/*
** Each file begins with. . .
@@ -75,14 +75,16 @@ struct tzhead {
** If tzh_version is '2' or greater, the above is followed by a second instance
** of tzhead and a second instance of the data in which each coded transition
** time uses 8 rather than 4 chars,
-** then a POSIX-TZ-environment-variable-style string for use in handling
+** then a POSIX.1-2017 proleptic TZ string for use in handling
** instants after the last transition time stored in the file
** (with nothing between the newlines if there is no POSIX.1-2017
** representation for such instants).
**
-** If tz_version is '3' or greater, the above is extended as follows.
+** If tz_version is '3' or greater, the TZ string can be any POSIX.1-2024
+** proleptic TZ string, which means the above is extended as follows.
** First, the TZ string's hour offset may range from -167
-** through 167 as compared to the POSIX-required 0 through 24.
+** through 167 as compared to the range 0 through 24 required
+** by POSIX.1-2017 and earlier.
** Second, its DST start time may be January 1 at 00:00 and its stop
** time December 31 at 24:00 plus the difference between DST and
** standard time, indicating DST all year.
diff --git a/contrib/restricted/abseil-cpp/absl/time/time.h b/contrib/restricted/abseil-cpp/absl/time/time.h
index 15edbb4a66..d73a204c12 100644
--- a/contrib/restricted/abseil-cpp/absl/time/time.h
+++ b/contrib/restricted/abseil-cpp/absl/time/time.h
@@ -74,13 +74,19 @@
// including 'windows.h' so we are picking the lesser of two evils here.
struct timeval;
#endif
-#include <chrono> // NOLINT(build/c++11)
+#include "absl/base/config.h"
+
+// For feature testing and determining which headers can be included.
+#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+#include <version>
+#endif
+
+#include <chrono> // NOLINT(build/c++11)
+#include <cmath>
#ifdef __cpp_lib_three_way_comparison
#include <compare>
#endif // __cpp_lib_three_way_comparison
-
-#include <cmath>
#include <cstdint>
#include <ctime>
#include <limits>
@@ -91,12 +97,16 @@ struct timeval;
#include <utility>
#include "absl/base/attributes.h"
-#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/strings/string_view.h"
#include "absl/time/civil_time.h"
#include "absl/time/internal/cctz/include/cctz/time_zone.h"
+#if defined(__cpp_impl_three_way_comparison) && \
+ defined(__cpp_lib_three_way_comparison)
+#define ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON 1
+#endif
+
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -138,7 +148,8 @@ using EnableIfFloat =
// the result of subtracting one `absl::Time` from another. Durations behave
// like unit-safe integers and they support all the natural integer-like
// arithmetic operations. Arithmetic overflows and saturates at +/- infinity.
-// `Duration` should be passed by value rather than const reference.
+// `Duration` is trivially destructible and should be passed by value rather
+// than const reference.
//
// Factory functions `Nanoseconds()`, `Microseconds()`, `Milliseconds()`,
// `Seconds()`, `Minutes()`, `Hours()` and `InfiniteDuration()` allow for
@@ -313,12 +324,12 @@ class Duration {
// Relational Operators
-#ifdef __cpp_lib_three_way_comparison
+#ifdef ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr std::strong_ordering operator<=>(
Duration lhs, Duration rhs);
-#endif // __cpp_lib_three_way_comparison
+#endif // ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator<(Duration lhs,
Duration rhs);
@@ -609,12 +620,12 @@ ABSL_ATTRIBUTE_CONST_FUNCTION Duration Hours(T n) {
//
// absl::Duration d = absl::Milliseconds(1500);
// int64_t isec = absl::ToInt64Seconds(d); // isec == 1
-ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToInt64Nanoseconds(Duration d);
-ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToInt64Microseconds(Duration d);
-ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToInt64Milliseconds(Duration d);
-ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToInt64Seconds(Duration d);
-ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToInt64Minutes(Duration d);
-ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToInt64Hours(Duration d);
+ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64Nanoseconds(Duration d);
+ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64Microseconds(Duration d);
+ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64Milliseconds(Duration d);
+ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64Seconds(Duration d);
+ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64Minutes(Duration d);
+ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64Hours(Duration d);
// ToDoubleNanoseconds()
// ToDoubleMicroseconds()
@@ -738,8 +749,9 @@ std::string UnparseFlag(Duration d);
// are provided for naturally expressing time calculations. Instances are
// created using `absl::Now()` and the `absl::From*()` factory functions that
// accept the gamut of other time representations. Formatting and parsing
-// functions are provided for conversion to and from strings. `absl::Time`
-// should be passed by value rather than const reference.
+// functions are provided for conversion to and from strings. `absl::Time` is
+// trivially destructible and should be passed by value rather than const
+// reference.
//
// `absl::Time` assumes there are 60 seconds in a minute, which means the
// underlying time scales must be "smeared" to eliminate leap seconds.
@@ -853,9 +865,9 @@ class Time {
friend constexpr Time time_internal::FromUnixDuration(Duration d);
friend constexpr Duration time_internal::ToUnixDuration(Time t);
-#ifdef __cpp_lib_three_way_comparison
+#ifdef ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
friend constexpr std::strong_ordering operator<=>(Time lhs, Time rhs);
-#endif // __cpp_lib_three_way_comparison
+#endif // ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
friend constexpr bool operator<(Time lhs, Time rhs);
friend constexpr bool operator==(Time lhs, Time rhs);
@@ -868,14 +880,14 @@ class Time {
};
// Relational Operators
-#ifdef __cpp_lib_three_way_comparison
+#ifdef ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr std::strong_ordering operator<=>(
Time lhs, Time rhs) {
return lhs.rep_ <=> rhs.rep_;
}
-#endif // __cpp_lib_three_way_comparison
+#endif // ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator<(Time lhs, Time rhs) {
return lhs.rep_ < rhs.rep_;
@@ -1752,8 +1764,7 @@ ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator<(Duration lhs,
: time_internal::GetRepLo(lhs) < time_internal::GetRepLo(rhs);
}
-
-#ifdef __cpp_lib_three_way_comparison
+#ifdef ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr std::strong_ordering operator<=>(
Duration lhs, Duration rhs) {
@@ -1769,7 +1780,7 @@ ABSL_ATTRIBUTE_CONST_FUNCTION constexpr std::strong_ordering operator<=>(
: lhs_lo <=> rhs_lo;
}
-#endif // __cpp_lib_three_way_comparison
+#endif // ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator==(Duration lhs,
Duration rhs) {
@@ -1853,6 +1864,56 @@ ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromTimeT(time_t t) {
return time_internal::FromUnixDuration(Seconds(t));
}
+ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64Nanoseconds(Duration d) {
+ if (time_internal::GetRepHi(d) >= 0 &&
+ time_internal::GetRepHi(d) >> 33 == 0) {
+ return (time_internal::GetRepHi(d) * 1000 * 1000 * 1000) +
+ (time_internal::GetRepLo(d) / time_internal::kTicksPerNanosecond);
+ }
+ return d / Nanoseconds(1);
+}
+
+ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64Microseconds(Duration d) {
+ if (time_internal::GetRepHi(d) >= 0 &&
+ time_internal::GetRepHi(d) >> 43 == 0) {
+ return (time_internal::GetRepHi(d) * 1000 * 1000) +
+ (time_internal::GetRepLo(d) /
+ (time_internal::kTicksPerNanosecond * 1000));
+ }
+ return d / Microseconds(1);
+}
+
+ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64Milliseconds(Duration d) {
+ if (time_internal::GetRepHi(d) >= 0 &&
+ time_internal::GetRepHi(d) >> 53 == 0) {
+ return (time_internal::GetRepHi(d) * 1000) +
+ (time_internal::GetRepLo(d) /
+ (time_internal::kTicksPerNanosecond * 1000 * 1000));
+ }
+ return d / Milliseconds(1);
+}
+
+ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64Seconds(Duration d) {
+ int64_t hi = time_internal::GetRepHi(d);
+ if (time_internal::IsInfiniteDuration(d)) return hi;
+ if (hi < 0 && time_internal::GetRepLo(d) != 0) ++hi;
+ return hi;
+}
+
+ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64Minutes(Duration d) {
+ int64_t hi = time_internal::GetRepHi(d);
+ if (time_internal::IsInfiniteDuration(d)) return hi;
+ if (hi < 0 && time_internal::GetRepLo(d) != 0) ++hi;
+ return hi / 60;
+}
+
+ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64Hours(Duration d) {
+ int64_t hi = time_internal::GetRepHi(d);
+ if (time_internal::IsInfiniteDuration(d)) return hi;
+ if (hi < 0 && time_internal::GetRepLo(d) != 0) ++hi;
+ return hi / (60 * 60);
+}
+
ABSL_NAMESPACE_END
} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/time/ya.make b/contrib/restricted/abseil-cpp/absl/time/ya.make
index 65dd554e05..d1535c64a8 100644
--- a/contrib/restricted/abseil-cpp/absl/time/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/time/ya.make
@@ -9,7 +9,7 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20240722.1)
+VERSION(20250127.0)
PEERDIR(
contrib/restricted/abseil-cpp/absl/base
diff --git a/contrib/restricted/abseil-cpp/absl/types/internal/span.h b/contrib/restricted/abseil-cpp/absl/types/internal/span.h
index ab89ba3ca7..1039f612b6 100644
--- a/contrib/restricted/abseil-cpp/absl/types/internal/span.h
+++ b/contrib/restricted/abseil-cpp/absl/types/internal/span.h
@@ -22,6 +22,7 @@
#include <type_traits>
#include "absl/algorithm/algorithm.h"
+#include "absl/base/config.h"
#include "absl/base/internal/throw_delegate.h"
#include "absl/meta/type_traits.h"
@@ -86,13 +87,13 @@ using EnableIfMutable =
typename std::enable_if<!std::is_const<T>::value, int>::type;
template <template <typename> class SpanT, typename T>
-bool EqualImpl(SpanT<T> a, SpanT<T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool EqualImpl(SpanT<T> a, SpanT<T> b) {
static_assert(std::is_const<T>::value, "");
return std::equal(a.begin(), a.end(), b.begin(), b.end());
}
template <template <typename> class SpanT, typename T>
-bool LessThanImpl(SpanT<T> a, SpanT<T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool LessThanImpl(SpanT<T> a, SpanT<T> b) {
// We can't use value_type since that is remove_cv_t<T>, so we go the long way
// around.
static_assert(std::is_const<T>::value, "");
diff --git a/contrib/restricted/abseil-cpp/absl/types/optional.h b/contrib/restricted/abseil-cpp/absl/types/optional.h
index cf7249cbe3..0d8f8704c5 100644
--- a/contrib/restricted/abseil-cpp/absl/types/optional.h
+++ b/contrib/restricted/abseil-cpp/absl/types/optional.h
@@ -429,14 +429,16 @@ class optional : private optional_internal::optional_data<T>,
// Accesses the underlying `T` value of an `optional`. If the `optional` is
// empty, behavior is undefined.
constexpr const T& operator*() const& ABSL_ATTRIBUTE_LIFETIME_BOUND {
- return ABSL_HARDENING_ASSERT(this->engaged_), reference();
+ ABSL_HARDENING_ASSERT(this->engaged_);
+ return reference();
}
T& operator*() & ABSL_ATTRIBUTE_LIFETIME_BOUND {
ABSL_HARDENING_ASSERT(this->engaged_);
return reference();
}
constexpr const T&& operator*() const&& ABSL_ATTRIBUTE_LIFETIME_BOUND {
- return ABSL_HARDENING_ASSERT(this->engaged_), std::move(reference());
+ ABSL_HARDENING_ASSERT(this->engaged_);
+ return std::move(reference());
}
T&& operator*() && ABSL_ATTRIBUTE_LIFETIME_BOUND {
ABSL_HARDENING_ASSERT(this->engaged_);
diff --git a/contrib/restricted/abseil-cpp/absl/types/span.h b/contrib/restricted/abseil-cpp/absl/types/span.h
index a0f80272e9..33904a904b 100644
--- a/contrib/restricted/abseil-cpp/absl/types/span.h
+++ b/contrib/restricted/abseil-cpp/absl/types/span.h
@@ -61,6 +61,7 @@
#include <utility>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/internal/throw_delegate.h"
#include "absl/base/macros.h"
#include "absl/base/nullability.h"
@@ -72,6 +73,33 @@
namespace absl {
ABSL_NAMESPACE_BEGIN
+template <typename T>
+class Span;
+
+ABSL_NAMESPACE_END
+} // namespace absl
+
+// If std::ranges is available, mark Span as satisfying the `view` and
+// `borrowed_range` concepts, just like std::span.
+#if !defined(__has_include)
+#define __has_include(header) 0
+#endif
+#if __has_include(<version>)
+#include <version> // NOLINT(misc-include-cleaner)
+#endif
+#if defined(__cpp_lib_ranges) && __cpp_lib_ranges >= 201911L
+#include <ranges> // NOLINT(build/c++20)
+template <typename T>
+ // NOLINTNEXTLINE(build/c++20)
+inline constexpr bool std::ranges::enable_view<absl::Span<T>> = true;
+template <typename T>
+ // NOLINTNEXTLINE(build/c++20)
+inline constexpr bool std::ranges::enable_borrowed_range<absl::Span<T>> = true;
+#endif
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+
//------------------------------------------------------------------------------
// Span
//------------------------------------------------------------------------------
@@ -151,7 +179,7 @@ ABSL_NAMESPACE_BEGIN
// int* my_array = new int[10];
// MyRoutine(absl::Span<const int>(my_array, 10));
template <typename T>
-class ABSL_INTERNAL_ATTRIBUTE_VIEW Span {
+class ABSL_ATTRIBUTE_VIEW Span {
private:
// Used to determine whether a Span can be constructed from a container of
// type C.
@@ -187,15 +215,18 @@ class ABSL_INTERNAL_ATTRIBUTE_VIEW Span {
using difference_type = ptrdiff_t;
using absl_internal_is_view = std::true_type;
+ // NOLINTNEXTLINE
static const size_type npos = ~(size_type(0));
constexpr Span() noexcept : Span(nullptr, 0) {}
- constexpr Span(pointer array, size_type length) noexcept
+ constexpr Span(pointer array ABSL_ATTRIBUTE_LIFETIME_BOUND,
+ size_type length) noexcept
: ptr_(array), len_(length) {}
// Implicit conversion constructors
template <size_t N>
- constexpr Span(T (&a)[N]) noexcept // NOLINT(runtime/explicit)
+ constexpr Span(T( // NOLINT(google-explicit-constructor)
+ &a ABSL_ATTRIBUTE_LIFETIME_BOUND)[N]) noexcept
: Span(a, N) {}
// Explicit reference constructor for a mutable `Span<T>` type. Can be
@@ -212,9 +243,8 @@ class ABSL_INTERNAL_ATTRIBUTE_VIEW Span {
template <typename V, typename = EnableIfConvertibleFrom<V>,
typename = EnableIfValueIsConst<V>,
typename = span_internal::EnableIfNotIsView<V>>
- constexpr Span(
- const V& v
- ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept // NOLINT(runtime/explicit)
+ // NOLINTNEXTLINE(google-explicit-constructor)
+ constexpr Span(const V& v ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept
: Span(span_internal::GetData(v), v.size()) {}
// Overloads of the above two functions that are only enabled for view types.
@@ -229,7 +259,7 @@ class ABSL_INTERNAL_ATTRIBUTE_VIEW Span {
template <typename V, typename = EnableIfConvertibleFrom<V>,
typename = EnableIfValueIsConst<V>,
span_internal::EnableIfIsView<V> = 0>
- constexpr Span(const V& v) noexcept // NOLINT(runtime/explicit)
+ constexpr Span(const V& v) noexcept // NOLINT(google-explicit-constructor)
: Span(span_internal::GetData(v), v.size()) {}
// Implicit constructor from an initializer list, making it possible to pass a
@@ -300,7 +330,8 @@ class ABSL_INTERNAL_ATTRIBUTE_VIEW Span {
//
// Returns a reference to the i'th element of this span.
constexpr reference operator[](size_type i) const noexcept {
- return ABSL_HARDENING_ASSERT(i < size()), ptr_[i];
+ ABSL_HARDENING_ASSERT(i < size());
+ return ptr_[i];
}
// Span::at()
@@ -319,7 +350,8 @@ class ABSL_INTERNAL_ATTRIBUTE_VIEW Span {
// Returns a reference to the first element of this span. The span must not
// be empty.
constexpr reference front() const noexcept {
- return ABSL_HARDENING_ASSERT(size() > 0), *data();
+ ABSL_HARDENING_ASSERT(size() > 0);
+ return *data();
}
// Span::back()
@@ -327,7 +359,8 @@ class ABSL_INTERNAL_ATTRIBUTE_VIEW Span {
// Returns a reference to the last element of this span. The span must not
// be empty.
constexpr reference back() const noexcept {
- return ABSL_HARDENING_ASSERT(size() > 0), *(data() + size() - 1);
+ ABSL_HARDENING_ASSERT(size() > 0);
+ return *(data() + size() - 1);
}
// Span::begin()
@@ -492,157 +525,165 @@ const typename Span<T>::size_type Span<T>::npos;
// operator==
template <typename T>
-bool operator==(Span<T> a, Span<T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator==(Span<T> a, Span<T> b) {
return span_internal::EqualImpl<Span, const T>(a, b);
}
template <typename T>
-bool operator==(Span<const T> a, Span<T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator==(Span<const T> a,
+ Span<T> b) {
return span_internal::EqualImpl<Span, const T>(a, b);
}
template <typename T>
-bool operator==(Span<T> a, Span<const T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator==(Span<T> a,
+ Span<const T> b) {
return span_internal::EqualImpl<Span, const T>(a, b);
}
template <
typename T, typename U,
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
-bool operator==(const U& a, Span<T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator==(const U& a, Span<T> b) {
return span_internal::EqualImpl<Span, const T>(a, b);
}
template <
typename T, typename U,
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
-bool operator==(Span<T> a, const U& b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator==(Span<T> a, const U& b) {
return span_internal::EqualImpl<Span, const T>(a, b);
}
// operator!=
template <typename T>
-bool operator!=(Span<T> a, Span<T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator!=(Span<T> a, Span<T> b) {
return !(a == b);
}
template <typename T>
-bool operator!=(Span<const T> a, Span<T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator!=(Span<const T> a,
+ Span<T> b) {
return !(a == b);
}
template <typename T>
-bool operator!=(Span<T> a, Span<const T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator!=(Span<T> a,
+ Span<const T> b) {
return !(a == b);
}
template <
typename T, typename U,
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
-bool operator!=(const U& a, Span<T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator!=(const U& a, Span<T> b) {
return !(a == b);
}
template <
typename T, typename U,
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
-bool operator!=(Span<T> a, const U& b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator!=(Span<T> a, const U& b) {
return !(a == b);
}
// operator<
template <typename T>
-bool operator<(Span<T> a, Span<T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<(Span<T> a, Span<T> b) {
return span_internal::LessThanImpl<Span, const T>(a, b);
}
template <typename T>
-bool operator<(Span<const T> a, Span<T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<(Span<const T> a, Span<T> b) {
return span_internal::LessThanImpl<Span, const T>(a, b);
}
template <typename T>
-bool operator<(Span<T> a, Span<const T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<(Span<T> a, Span<const T> b) {
return span_internal::LessThanImpl<Span, const T>(a, b);
}
template <
typename T, typename U,
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
-bool operator<(const U& a, Span<T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<(const U& a, Span<T> b) {
return span_internal::LessThanImpl<Span, const T>(a, b);
}
template <
typename T, typename U,
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
-bool operator<(Span<T> a, const U& b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<(Span<T> a, const U& b) {
return span_internal::LessThanImpl<Span, const T>(a, b);
}
// operator>
template <typename T>
-bool operator>(Span<T> a, Span<T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>(Span<T> a, Span<T> b) {
return b < a;
}
template <typename T>
-bool operator>(Span<const T> a, Span<T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>(Span<const T> a, Span<T> b) {
return b < a;
}
template <typename T>
-bool operator>(Span<T> a, Span<const T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>(Span<T> a, Span<const T> b) {
return b < a;
}
template <
typename T, typename U,
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
-bool operator>(const U& a, Span<T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>(const U& a, Span<T> b) {
return b < a;
}
template <
typename T, typename U,
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
-bool operator>(Span<T> a, const U& b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>(Span<T> a, const U& b) {
return b < a;
}
// operator<=
template <typename T>
-bool operator<=(Span<T> a, Span<T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<=(Span<T> a, Span<T> b) {
return !(b < a);
}
template <typename T>
-bool operator<=(Span<const T> a, Span<T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<=(Span<const T> a,
+ Span<T> b) {
return !(b < a);
}
template <typename T>
-bool operator<=(Span<T> a, Span<const T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<=(Span<T> a,
+ Span<const T> b) {
return !(b < a);
}
template <
typename T, typename U,
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
-bool operator<=(const U& a, Span<T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<=(const U& a, Span<T> b) {
return !(b < a);
}
template <
typename T, typename U,
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
-bool operator<=(Span<T> a, const U& b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<=(Span<T> a, const U& b) {
return !(b < a);
}
// operator>=
template <typename T>
-bool operator>=(Span<T> a, Span<T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>=(Span<T> a, Span<T> b) {
return !(a < b);
}
template <typename T>
-bool operator>=(Span<const T> a, Span<T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>=(Span<const T> a,
+ Span<T> b) {
return !(a < b);
}
template <typename T>
-bool operator>=(Span<T> a, Span<const T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>=(Span<T> a,
+ Span<const T> b) {
return !(a < b);
}
template <
typename T, typename U,
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
-bool operator>=(const U& a, Span<T> b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>=(const U& a, Span<T> b) {
return !(a < b);
}
template <
typename T, typename U,
typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
-bool operator>=(Span<T> a, const U& b) {
+ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>=(Span<T> a, const U& b) {
return !(a < b);
}
@@ -689,8 +730,8 @@ constexpr Span<T> MakeSpan(absl::Nullable<T*> ptr, size_t size) noexcept {
template <int&... ExplicitArgumentBarrier, typename T>
Span<T> MakeSpan(absl::Nullable<T*> begin, absl::Nullable<T*> end) noexcept {
- return ABSL_HARDENING_ASSERT(begin <= end),
- Span<T>(begin, static_cast<size_t>(end - begin));
+ ABSL_HARDENING_ASSERT(begin <= end);
+ return Span<T>(begin, static_cast<size_t>(end - begin));
}
template <int&... ExplicitArgumentBarrier, typename C>
@@ -737,7 +778,8 @@ constexpr Span<const T> MakeConstSpan(absl::Nullable<T*> ptr,
template <int&... ExplicitArgumentBarrier, typename T>
Span<const T> MakeConstSpan(absl::Nullable<T*> begin,
absl::Nullable<T*> end) noexcept {
- return ABSL_HARDENING_ASSERT(begin <= end), Span<const T>(begin, end - begin);
+ ABSL_HARDENING_ASSERT(begin <= end);
+ return Span<const T>(begin, end - begin);
}
template <int&... ExplicitArgumentBarrier, typename C>
diff --git a/contrib/restricted/abseil-cpp/absl/types/ya.make b/contrib/restricted/abseil-cpp/absl/types/ya.make
index 9b6bb742e8..6dbfc699fe 100644
--- a/contrib/restricted/abseil-cpp/absl/types/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/types/ya.make
@@ -6,7 +6,7 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20240722.1)
+VERSION(20250127.0)
PEERDIR(
contrib/restricted/abseil-cpp/absl/base
diff --git a/contrib/restricted/abseil-cpp/absl/utility/ya.make b/contrib/restricted/abseil-cpp/absl/utility/ya.make
index 4e3328995c..2deef3b2a7 100644
--- a/contrib/restricted/abseil-cpp/absl/utility/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/utility/ya.make
@@ -6,9 +6,9 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20240722.1)
+VERSION(20250127.0)
-ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20240722.1.tar.gz)
+ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20250127.0.tar.gz)
NO_RUNTIME()
diff --git a/contrib/restricted/abseil-cpp/patches/pr1728-fix-ndk-r25.patch b/contrib/restricted/abseil-cpp/patches/pr1728-fix-ndk-r25.patch
deleted file mode 100644
index 6c2740f66f..0000000000
--- a/contrib/restricted/abseil-cpp/patches/pr1728-fix-ndk-r25.patch
+++ /dev/null
@@ -1,87 +0,0 @@
-From 90a8bda23077508ca208e7afc535da1e2c7d59ae Mon Sep 17 00:00:00 2001
-From: Yuriy Chernyshov <thegeorg@yandex-team.com>
-Date: Thu, 25 Jul 2024 22:50:40 +0300
-Subject: [PATCH 1/3] Workaround broken compilation against NDK r25
-
----
- absl/time/time.h | 20 ++++++++++----------
- 1 file changed, 10 insertions(+), 10 deletions(-)
-
-diff --git a/absl/time/time.h b/absl/time/time.h
-index f133c2d2ca8..15edbb4a667 100644
---- a/absl/time/time.h
-+++ b/absl/time/time.h
-@@ -76,9 +76,9 @@ struct timeval;
- #endif
- #include <chrono> // NOLINT(build/c++11)
-
--#ifdef __cpp_impl_three_way_comparison
-+#ifdef __cpp_lib_three_way_comparison
- #include <compare>
--#endif // __cpp_impl_three_way_comparison
-+#endif // __cpp_lib_three_way_comparison
-
- #include <cmath>
- #include <cstdint>
-@@ -313,12 +313,12 @@ class Duration {
-
- // Relational Operators
-
--#ifdef __cpp_impl_three_way_comparison
-+#ifdef __cpp_lib_three_way_comparison
-
- ABSL_ATTRIBUTE_CONST_FUNCTION constexpr std::strong_ordering operator<=>(
- Duration lhs, Duration rhs);
-
--#endif // __cpp_impl_three_way_comparison
-+#endif // __cpp_lib_three_way_comparison
-
- ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator<(Duration lhs,
- Duration rhs);
-@@ -853,9 +853,9 @@ class Time {
- friend constexpr Time time_internal::FromUnixDuration(Duration d);
- friend constexpr Duration time_internal::ToUnixDuration(Time t);
-
--#ifdef __cpp_impl_three_way_comparison
-+#ifdef __cpp_lib_three_way_comparison
- friend constexpr std::strong_ordering operator<=>(Time lhs, Time rhs);
--#endif // __cpp_impl_three_way_comparison
-+#endif // __cpp_lib_three_way_comparison
-
- friend constexpr bool operator<(Time lhs, Time rhs);
- friend constexpr bool operator==(Time lhs, Time rhs);
-@@ -868,14 +868,14 @@ class Time {
- };
-
- // Relational Operators
--#ifdef __cpp_impl_three_way_comparison
-+#ifdef __cpp_lib_three_way_comparison
-
- ABSL_ATTRIBUTE_CONST_FUNCTION constexpr std::strong_ordering operator<=>(
- Time lhs, Time rhs) {
- return lhs.rep_ <=> rhs.rep_;
- }
-
--#endif // __cpp_impl_three_way_comparison
-+#endif // __cpp_lib_three_way_comparison
-
- ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator<(Time lhs, Time rhs) {
- return lhs.rep_ < rhs.rep_;
-@@ -1753,7 +1753,7 @@ ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator<(Duration lhs,
- }
-
-
--#ifdef __cpp_impl_three_way_comparison
-+#ifdef __cpp_lib_three_way_comparison
-
- ABSL_ATTRIBUTE_CONST_FUNCTION constexpr std::strong_ordering operator<=>(
- Duration lhs, Duration rhs) {
-@@ -1769,7 +1769,7 @@ ABSL_ATTRIBUTE_CONST_FUNCTION constexpr std::strong_ordering operator<=>(
- : lhs_lo <=> rhs_lo;
- }
-
--#endif // __cpp_impl_three_way_comparison
-+#endif // __cpp_lib_three_way_comparison
-
- ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator==(Duration lhs,
- Duration rhs) {
diff --git a/contrib/restricted/abseil-cpp/ya.make b/contrib/restricted/abseil-cpp/ya.make
index 4e45866048..51c20bfbc2 100644
--- a/contrib/restricted/abseil-cpp/ya.make
+++ b/contrib/restricted/abseil-cpp/ya.make
@@ -6,9 +6,9 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(20240722.1)
+VERSION(20250127.0)
-ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20240722.1.tar.gz)
+ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20250127.0.tar.gz)
PEERDIR(
contrib/restricted/abseil-cpp/absl/algorithm