aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorInnokentii Mokin <innokentii@ydb.tech>2024-01-27 10:01:54 +0000
committerInnokentii Mokin <innokentii@ydb.tech>2024-01-27 10:01:54 +0000
commit621e3d86c4e02bf3c88bb68e5aba5856fbf0185d (patch)
tree2d517d0985015d27ce6862003509de502be44ccc
parenta7dad28338e49d920879eb2b3e728ee6dd166b6e (diff)
parent00b9982cd019afca788639aa8279f2dc1f342383 (diff)
downloadydb-621e3d86c4e02bf3c88bb68e5aba5856fbf0185d.tar.gz
Merge branch 'mergelibs11' into main
-rw-r--r--build/conf/go.conf3
-rw-r--r--build/conf/python.conf11
-rw-r--r--build/export_generators/hardcoded-cmake/cmake/common.cmake4
-rw-r--r--build/export_generators/hardcoded-cmake/generator.toml2
-rw-r--r--build/external_resources/gdb/resources.json4
-rw-r--r--build/external_resources/go_tools/go1.20.json19
-rw-r--r--build/external_resources/go_tools/go1.21.json10
-rw-r--r--build/external_resources/go_tools/ya.make4
-rw-r--r--build/mapping.conf.json20
-rw-r--r--build/platform/test_tool/host.ya.make.inc20
-rw-r--r--build/platform/test_tool/host_os.ya.make.inc20
-rw-r--r--build/plugins/lib/test_const/__init__.py1
-rw-r--r--build/plugins/pybuild.py25
-rw-r--r--build/sysincl/stl-to-libcxx.yml52
-rw-r--r--build/sysincl/stl-to-nothing.yml2
-rw-r--r--build/ya.conf.json598
-rw-r--r--build/ymake.core.conf4
-rw-r--r--cmake/common.cmake4
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/boring/notboring.go1
-rw-r--r--contrib/go/_std_1.21/src/crypto/rand/rand.go2
-rw-r--r--contrib/go/_std_1.21/src/crypto/rand/rand_windows.go7
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/cipher_suites.go8
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/handshake_client.go4
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/handshake_client_tls13.go4
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/handshake_server_tls13.go7
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/notboring.go2
-rw-r--r--contrib/go/_std_1.21/src/go/types/call.go8
-rw-r--r--contrib/go/_std_1.21/src/internal/buildcfg/zbootstrap.go2
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/splice_linux.go21
-rw-r--r--contrib/go/_std_1.21/src/internal/safefilepath/path_windows.go98
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/reparse_windows.go1
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/syscall_windows.go2
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/zsyscall_windows.go21
-rw-r--r--contrib/go/_std_1.21/src/net/http/h2_bundle.go1
-rw-r--r--contrib/go/_std_1.21/src/net/http/internal/chunked.go34
-rw-r--r--contrib/go/_std_1.21/src/os/rlimit.go32
-rw-r--r--contrib/go/_std_1.21/src/os/rlimit_darwin.go22
-rw-r--r--contrib/go/_std_1.21/src/os/rlimit_stub.go12
-rw-r--r--contrib/go/_std_1.21/src/os/types_windows.go18
-rw-r--r--contrib/go/_std_1.21/src/os/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/path/filepath/path.go17
-rw-r--r--contrib/go/_std_1.21/src/path/filepath/path_nonwindows.go9
-rw-r--r--contrib/go/_std_1.21/src/path/filepath/path_windows.go188
-rw-r--r--contrib/go/_std_1.21/src/path/filepath/ya.make6
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/asm_amd64.s7
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/asm_arm64.s7
-rw-r--r--contrib/go/_std_1.21/src/runtime/extern.go7
-rw-r--r--contrib/go/_std_1.21/src/runtime/malloc.go4
-rw-r--r--contrib/go/_std_1.21/src/runtime/map.go22
-rw-r--r--contrib/go/_std_1.21/src/runtime/mem_linux.go8
-rw-r--r--contrib/go/_std_1.21/src/runtime/mgc.go4
-rw-r--r--contrib/go/_std_1.21/src/runtime/mgcscavenge.go20
-rw-r--r--contrib/go/_std_1.21/src/runtime/mpagealloc.go4
-rw-r--r--contrib/go/_std_1.21/src/runtime/mstats.go114
-rw-r--r--contrib/go/_std_1.21/src/runtime/os_windows.go33
-rw-r--r--contrib/go/_std_1.21/src/runtime/pprof/proto.go7
-rw-r--r--contrib/go/_std_1.21/src/runtime/runtime.go13
-rw-r--r--contrib/go/_std_1.21/src/runtime/runtime1.go2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/comp_ref_type.h4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/copy.h162
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/copy_backward.h143
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/copy_move_common.h163
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/iter_swap.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/iterator_operations.h5
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/move.h175
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/move_backward.h160
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/partial_sort.h1
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_binary_search.h4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy.h5
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy_backward.h1
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy_n.h3
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_iterator_concept.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_move.h1
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_move_backward.h11
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_search_n.h8
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_difference.h5
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_symmetric_difference.h5
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_union.h5
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/rotate.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/set_difference.h10
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/set_symmetric_difference.h9
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/set_union.h9
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/shuffle.h1
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/sort.h8
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__algorithm/unwrap_iter.h4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__assert2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__availability17
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__bit/bit_cast.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__bit/bit_ceil.h46
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__bit/bit_floor.h34
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__bit/bit_log2.h34
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__bit/bit_width.h33
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__bit/blsr.h34
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__bit/countl.h104
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__bit/countr.h70
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__bit/endian.h38
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__bit/has_single_bit.h37
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__bit/popcount.h61
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__bit/rotate.h53
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__bit_reference9
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__bits75
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__chrono/convert_to_tm.h61
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__chrono/duration.h15
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__chrono/formatter.h277
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__chrono/hh_mm_ss.h8
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__chrono/ostream.h93
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__chrono/parser_std_format_spec.h13
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__chrono/statically_widen.h8
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__chrono/time_point.h10
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__compare/common_comparison_category.h5
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__compare/compare_partial_order_fallback.h3
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__compare/compare_strong_order_fallback.h3
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__compare/compare_three_way_result.h6
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__compare/compare_weak_order_fallback.h3
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__compare/ordering.h3
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__compare/partial_order.h5
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__compare/strong_order.h5
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__compare/synth_three_way.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__compare/three_way_comparable.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__compare/weak_order.h4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__concepts/arithmetic.h4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__concepts/assignable.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__concepts/class_or_enum.h5
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__concepts/common_reference_with.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__concepts/common_with.h9
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__concepts/constructible.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__concepts/convertible_to.h4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__concepts/derived_from.h3
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__concepts/destructible.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__concepts/different_from.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__concepts/equality_comparable.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__concepts/invocable.h1
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__concepts/movable.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__concepts/predicate.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__concepts/same_as.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__concepts/swappable.h6
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__concepts/totally_ordered.h3
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__config74
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__coroutine/coroutine_handle.h3
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__coroutine/coroutine_traits.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__debug2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__filesystem/filesystem_error.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__filesystem/path.h6
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__format/buffer.h69
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__format/concepts.h13
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__format/container_adaptor.h70
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__format/extended_grapheme_cluster_table.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__format/format_arg.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__format/format_arg_store.h4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__format/format_context.h78
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__format/format_functions.h40
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__format/format_parse_context.h8
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__format/format_string.h7
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__format/formatter.h11
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__format/formatter_floating_point.h5
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__format/formatter_integral.h6
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__format/formatter_output.h29
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__format/formatter_string.h7
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__format/formatter_tuple.h178
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__format/parser_std_format_spec.h79
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__format/range_default_formatter.h201
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__format/range_formatter.h255
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__format/unicode.h1
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__functional/function.h84
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__functional/hash.h77
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__functional/invoke.h14
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__functional/reference_wrapper.h9
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__functional/unwrap_ref.h1
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__functional/weak_result_type.h7
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__fwd/get.h22
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__fwd/subrange.h38
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__hash_table96
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__iterator/advance.h6
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__iterator/bounded_iter.h4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__iterator/common_iterator.h24
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__iterator/concepts.h8
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__iterator/counted_iterator.h3
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__iterator/distance.h3
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__iterator/incrementable_traits.h8
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__iterator/iter_move.h9
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__iterator/iter_swap.h9
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__iterator/iterator_traits.h19
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__iterator/iterator_with_data.h100
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__iterator/move_iterator.h12
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__iterator/move_sentinel.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__iterator/next.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__iterator/prev.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__iterator/projected.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__iterator/readable_traits.h8
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__iterator/reverse_iterator.h25
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__iterator/segmented_iterator.h81
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__iterator/size.h3
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__iterator/wrap_iter.h3
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__locale26
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__memory/allocate_at_least.h1
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__memory/allocator.h5
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__memory/allocator_arg_t.h4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__memory/allocator_traits.h19
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__memory/assume_aligned.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__memory/compressed_pair.h11
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__memory/concepts.h3
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__memory/construct_at.h18
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__memory/pointer_traits.h21
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__memory/ranges_construct_at.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__memory/ranges_uninitialized_algorithms.h8
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__memory/shared_ptr.h278
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__memory/uninitialized_algorithms.h78
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__memory/unique_ptr.h37
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__memory/uses_allocator.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__memory/uses_allocator_construction.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__memory_resource/monotonic_buffer_resource.h11
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__memory_resource/polymorphic_allocator.h48
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__memory_resource/synchronized_pool_resource.h4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__memory_resource/unsynchronized_pool_resource.h4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__numeric/gcd_lcm.h6
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__numeric/midpoint.h18
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__random/binomial_distribution.h6
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__random/is_valid.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__random/uniform_int_distribution.h3
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__ranges/access.h9
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__ranges/all.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__ranges/as_rvalue_view.h137
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__ranges/concepts.h10
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__ranges/dangling.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__ranges/data.h7
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__ranges/elements_view.h413
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__ranges/empty.h1
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__ranges/enable_view.h4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__ranges/filter_view.h5
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__ranges/istream_view.h15
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__ranges/join_view.h84
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__ranges/ref_view.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__ranges/size.h8
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__ranges/split_view.h226
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__ranges/subrange.h28
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__ranges/take_view.h8
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__ranges/view_interface.h8
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__ranges/zip_view.h6
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__split_buffer10
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__string/char_traits.h181
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__support/android/locale_bionic.h9
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__support/musl/xlocale.h16
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__support/openbsd/xlocale.h8
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__nop_locale_mgmt.h25
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__posix_l_fallback.h129
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__strtonum_fallback.h26
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__tree12
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__tuple_dir/apply_cv.h (renamed from contrib/libs/cxxsupp/libcxx/include/__tuple/apply_cv.h)0
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__tuple_dir/make_tuple_types.h (renamed from contrib/libs/cxxsupp/libcxx/include/__tuple/make_tuple_types.h)10
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__tuple_dir/pair_like.h32
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__tuple_dir/sfinae_helpers.h (renamed from contrib/libs/cxxsupp/libcxx/include/__tuple/sfinae_helpers.h)24
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_element.h (renamed from contrib/libs/cxxsupp/libcxx/include/__tuple/tuple_element.h)5
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_indices.h (renamed from contrib/libs/cxxsupp/libcxx/include/__tuple/tuple_indices.h)0
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_like.h (renamed from contrib/libs/cxxsupp/libcxx/include/__tuple/tuple_like.h)29
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_like_ext.h44
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_size.h (renamed from contrib/libs/cxxsupp/libcxx/include/__tuple/tuple_size.h)2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_types.h (renamed from contrib/libs/cxxsupp/libcxx/include/__tuple/tuple_types.h)0
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/add_pointer.h4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/aligned_storage.h10
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/aligned_union.h5
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/common_reference.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/common_type.h6
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/conjunction.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/enable_if.h6
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/is_allocator.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/is_always_bitcastable.h82
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/is_callable.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/is_convertible.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/is_destructible.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/is_implicitly_default_constructible.h4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/is_member_pointer.h1
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/is_nothrow_constructible.h8
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/is_nothrow_convertible.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/is_nothrow_destructible.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/is_scalar.h1
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/is_signed.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/is_specialization.h45
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/is_swappable.h6
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/is_trivially_destructible.h1
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/is_valid_expansion.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/is_void.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/promote.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/remove_pointer.h4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__type_traits/strip_signature.h79
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__utility/as_const.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__utility/auto_cast.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__utility/cmp.h6
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__utility/declval.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__utility/exception_guard.h139
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__utility/exchange.h3
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__utility/forward.h8
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__utility/forward_like.h3
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__utility/in_place.h3
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__utility/integer_sequence.h11
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__utility/move.h15
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__utility/pair.h27
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__utility/rel_ops.h3
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__utility/swap.h6
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__utility/to_underlying.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__utility/transaction.h97
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__utility/unreachable.h16
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/__verbose_abort54
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/algorithm3
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/any12
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/array6
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/atomic116
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/barrier4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/bit190
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/charconv72
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/chrono53
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/cmath188
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/compare4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/complex700
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/concepts4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/condition_variable1
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/coroutine1
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/cstring48
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/cwchar50
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/deque584
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/exception12
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/format38
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/fstream21
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/future25
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/iomanip8
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/ios4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/istream23
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/iterator2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/limits8
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/locale182
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/math.h507
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/memory17
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/mutex17
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/new43
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/numeric1
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/optional78
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/ostream83
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/queue4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/ranges42
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/ratio6
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/regex44
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/semaphore2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/source_location87
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/sstream6
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/stack2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/stdlib.h10
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/string58
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/string_view46
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/thread2
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/tuple42
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/type_traits15
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/unordered_map4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/unordered_set4
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/utility9
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/valarray34
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/variant59
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/vector145
-rw-r--r--contrib/libs/cxxsupp/libcxx/include/version18
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/atomic.cpp21
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/memory_resource.cpp33
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/thread.cpp2
-rw-r--r--contrib/libs/cxxsupp/libcxx/ya.make4
-rw-r--r--contrib/libs/opentelemetry-proto/CHANGELOG.md40
-rw-r--r--contrib/libs/opentelemetry-proto/opentelemetry/proto/logs/v1/logs.proto14
-rw-r--r--contrib/libs/opentelemetry-proto/opentelemetry/proto/metrics/v1/metrics.proto8
-rw-r--r--contrib/libs/opentelemetry-proto/opentelemetry/proto/trace/v1/trace.proto57
-rw-r--r--contrib/libs/opentelemetry-proto/ya.make4
-rw-r--r--contrib/python/Jinja2/py3/.dist-info/METADATA14
-rw-r--r--contrib/python/Jinja2/py3/README.rst2
-rw-r--r--contrib/python/Jinja2/py3/jinja2/__init__.py2
-rw-r--r--contrib/python/Jinja2/py3/jinja2/async_utils.py2
-rw-r--r--contrib/python/Jinja2/py3/jinja2/compiler.py5
-rw-r--r--contrib/python/Jinja2/py3/jinja2/environment.py12
-rw-r--r--contrib/python/Jinja2/py3/jinja2/ext.py20
-rw-r--r--contrib/python/Jinja2/py3/jinja2/filters.py28
-rw-r--r--contrib/python/Jinja2/py3/jinja2/loaders.py36
-rw-r--r--contrib/python/Jinja2/py3/jinja2/nativetypes.py2
-rw-r--r--contrib/python/Jinja2/py3/jinja2/parser.py16
-rw-r--r--contrib/python/Jinja2/py3/jinja2/runtime.py8
-rw-r--r--contrib/python/Jinja2/py3/jinja2/utils.py4
-rw-r--r--contrib/python/Jinja2/py3/tests/test_ext.py13
-rw-r--r--contrib/python/Jinja2/py3/tests/test_filters.py8
-rw-r--r--contrib/python/Jinja2/py3/tests/test_inheritance.py39
-rw-r--r--contrib/python/Jinja2/py3/tests/test_loader.py6
-rw-r--r--contrib/python/Jinja2/py3/ya.make2
-rw-r--r--contrib/python/fonttools/.dist-info/METADATA14
-rw-r--r--contrib/python/fonttools/fontTools/__init__.py2
-rw-r--r--contrib/python/fonttools/fontTools/merge/__init__.py54
-rw-r--r--contrib/python/fonttools/fontTools/merge/options.py3
-rw-r--r--contrib/python/fonttools/fontTools/otlLib/builder.py26
-rw-r--r--contrib/python/fonttools/fontTools/varLib/featureVars.py35
-rw-r--r--contrib/python/fonttools/fontTools/varLib/interpolatable.py14
-rw-r--r--contrib/python/fonttools/ya.make2
-rw-r--r--contrib/python/google-auth/py3/.dist-info/METADATA2
-rw-r--r--contrib/python/google-auth/py3/google/auth/external_account_authorized_user.py1
-rw-r--r--contrib/python/google-auth/py3/google/auth/version.py2
-rw-r--r--contrib/python/google-auth/py3/tests/data/external_account_authorized_user_non_gdu.json10
-rw-r--r--contrib/python/google-auth/py3/tests/test__default.py13
-rw-r--r--contrib/python/google-auth/py3/ya.make2
-rw-r--r--contrib/python/hypothesis/py3/.dist-info/METADATA2
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/control.py11
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/core.py4
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/errors.py3
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/internal/filtering.py51
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/internal/reflection.py4
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/strategies/_internal/collections.py18
-rw-r--r--contrib/python/hypothesis/py3/hypothesis/version.py2
-rw-r--r--contrib/python/hypothesis/py3/ya.make2
-rw-r--r--contrib/python/ydb/py3/.dist-info/METADATA2
-rw-r--r--contrib/python/ydb/py3/ya.make4
-rw-r--r--contrib/python/ydb/py3/ydb/__init__.py1
-rw-r--r--contrib/python/ydb/py3/ydb/_apis.py26
-rw-r--r--contrib/python/ydb/py3/ydb/draft/__init__.py1
-rw-r--r--contrib/python/ydb/py3/ydb/draft/dynamic_config.py173
-rw-r--r--contrib/python/ydb/py3/ydb/ydb_version.py2
-rw-r--r--contrib/restricted/abseil-cpp/absl/algorithm/algorithm.h111
-rw-r--r--contrib/restricted/abseil-cpp/absl/algorithm/container.h128
-rw-r--r--contrib/restricted/abseil-cpp/absl/algorithm/ya.make4
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/attributes.h63
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/call_once.h24
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/casts.h2
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/config.h117
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/internal/endian.h25
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/internal/identity.h6
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/internal/inline_variable.h37
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc.cc2
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/internal/nullability_impl.h106
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/internal/raw_logging.cc20
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/internal/raw_logging.h2
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/internal/spinlock.h21
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/internal/thread_annotations.h280
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/internal/thread_identity.cc14
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/internal/unaligned_access.h19
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/log_severity.cc1
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/log_severity.h33
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/no_destructor.h217
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/nullability.h224
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/optimization.h1
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/options.h28
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/prefetch.h39
-rw-r--r--contrib/restricted/abseil-cpp/absl/base/thread_annotations.h2
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/flat_hash_map.h6
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/flat_hash_set.h2
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/internal/common_policy_traits.h6
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/internal/container_memory.h22
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler.h14
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/internal/inlined_vector.h13
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/internal/layout.h743
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_map.h13
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set.cc179
-rw-r--r--contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set.h995
-rw-r--r--contrib/restricted/abseil-cpp/absl/crc/internal/cpu_detect.cc28
-rw-r--r--contrib/restricted/abseil-cpp/absl/crc/internal/cpu_detect.h6
-rw-r--r--contrib/restricted/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h39
-rw-r--r--contrib/restricted/abseil-cpp/absl/crc/internal/crc_memcpy.h9
-rw-r--r--contrib/restricted/abseil-cpp/absl/crc/internal/crc_memcpy_fallback.cc6
-rw-r--r--contrib/restricted/abseil-cpp/absl/crc/internal/crc_memcpy_x86_arm_combined.cc (renamed from contrib/restricted/abseil-cpp/absl/crc/internal/crc_memcpy_x86_64.cc)112
-rw-r--r--contrib/restricted/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc12
-rw-r--r--contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.cc2
-rw-r--r--contrib/restricted/abseil-cpp/absl/debugging/internal/address_is_readable.cc6
-rw-r--r--contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.cc24
-rw-r--r--contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.h68
-rw-r--r--contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc58
-rw-r--r--contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc152
-rw-r--r--contrib/restricted/abseil-cpp/absl/flags/declare.h5
-rw-r--r--contrib/restricted/abseil-cpp/absl/flags/flag.h11
-rw-r--r--contrib/restricted/abseil-cpp/absl/flags/internal/flag.h5
-rw-r--r--contrib/restricted/abseil-cpp/absl/flags/internal/flag_msvc.inc116
-rw-r--r--contrib/restricted/abseil-cpp/absl/flags/internal/usage.cc5
-rw-r--r--contrib/restricted/abseil-cpp/absl/flags/marshalling.cc11
-rw-r--r--contrib/restricted/abseil-cpp/absl/flags/parse.cc2
-rw-r--r--contrib/restricted/abseil-cpp/absl/flags/reflection.cc3
-rw-r--r--contrib/restricted/abseil-cpp/absl/flags/ya.make1
-rw-r--r--contrib/restricted/abseil-cpp/absl/functional/function_ref.h8
-rw-r--r--contrib/restricted/abseil-cpp/absl/functional/internal/any_invocable.h4
-rw-r--r--contrib/restricted/abseil-cpp/absl/functional/ya.make4
-rw-r--r--contrib/restricted/abseil-cpp/absl/hash/internal/hash.h51
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/absl_vlog_is_on.h93
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/flags.cc23
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/globals.h23
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/initialize.cc8
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/internal/check_op.h60
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/internal/conditions.h55
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/internal/flags.h8
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/internal/fnmatch.cc73
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/internal/fnmatch.h (renamed from contrib/restricted/abseil-cpp/absl/flags/flag.cc)35
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/internal/log_impl.h66
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/internal/log_message.h16
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/internal/log_sink_set.cc16
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/internal/strip.h7
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/internal/vlog_config.cc340
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/internal/vlog_config.h163
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/log.h41
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/log_entry.cc12
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/log_entry.h3
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/vlog_is_on.h72
-rw-r--r--contrib/restricted/abseil-cpp/absl/log/ya.make2
-rw-r--r--contrib/restricted/abseil-cpp/absl/memory/ya.make4
-rw-r--r--contrib/restricted/abseil-cpp/absl/meta/ya.make4
-rw-r--r--contrib/restricted/abseil-cpp/absl/numeric/bits.h55
-rw-r--r--contrib/restricted/abseil-cpp/absl/status/internal/status_internal.cc248
-rw-r--r--contrib/restricted/abseil-cpp/absl/status/internal/status_internal.h69
-rw-r--r--contrib/restricted/abseil-cpp/absl/status/internal/statusor_internal.h55
-rw-r--r--contrib/restricted/abseil-cpp/absl/status/status.cc274
-rw-r--r--contrib/restricted/abseil-cpp/absl/status/status.h148
-rw-r--r--contrib/restricted/abseil-cpp/absl/status/status_payload_printer.cc4
-rw-r--r--contrib/restricted/abseil-cpp/absl/status/status_payload_printer.h5
-rw-r--r--contrib/restricted/abseil-cpp/absl/status/statusor.cc7
-rw-r--r--contrib/restricted/abseil-cpp/absl/status/statusor.h46
-rw-r--r--contrib/restricted/abseil-cpp/absl/status/ya.make1
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/ascii.cc96
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/ascii.h14
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/charconv.cc31
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/charconv.h9
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/charset.h164
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/cord.cc335
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/cord.h230
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/cord_analysis.cc52
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/cord_analysis.h7
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/escaping.cc9
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/has_absl_stringify.h (renamed from contrib/restricted/abseil-cpp/absl/strings/internal/has_absl_stringify.h)20
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/has_ostream_operator.h42
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/internal/char_map.h158
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.cc6
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.h64
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_ring.cc773
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_ring.h607
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info.cc51
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/internal/memutil.cc16
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.cc153
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.h96
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.cc18
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.h11
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/internal/str_format/constexpr_parser.h11
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/internal/str_format/extension.h14
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/internal/str_format/parser.h9
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/match.cc3
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/numbers.cc549
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/numbers.h228
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/str_cat.cc172
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/str_cat.h152
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/str_format.h50
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/str_join.h32
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/str_replace.cc15
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/str_replace.h13
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/str_split.cc14
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/str_split.h18
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/string_view.cc31
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/string_view.h117
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/strip.h7
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/substitute.cc16
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/substitute.h194
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/ya.make3
-rw-r--r--contrib/restricted/abseil-cpp/absl/synchronization/internal/pthread_waiter.h4
-rw-r--r--contrib/restricted/abseil-cpp/absl/synchronization/internal/win32_waiter.h6
-rw-r--r--contrib/restricted/abseil-cpp/absl/synchronization/mutex.cc628
-rw-r--r--contrib/restricted/abseil-cpp/absl/synchronization/mutex.h123
-rw-r--r--contrib/restricted/abseil-cpp/absl/time/civil_time.h26
-rw-r--r--contrib/restricted/abseil-cpp/absl/time/clock.h6
-rw-r--r--contrib/restricted/abseil-cpp/absl/time/duration.cc6
-rw-r--r--contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h4
-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_info.cc23
-rw-r--r--contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/tzfile.h8
-rw-r--r--contrib/restricted/abseil-cpp/absl/types/bad_any_cast.cc18
-rw-r--r--contrib/restricted/abseil-cpp/absl/types/bad_optional_access.cc18
-rw-r--r--contrib/restricted/abseil-cpp/absl/types/bad_variant_access.cc18
-rw-r--r--contrib/restricted/abseil-cpp/absl/types/internal/variant.h6
-rw-r--r--contrib/restricted/abseil-cpp/absl/types/optional.h5
-rw-r--r--contrib/restricted/abseil-cpp/absl/types/span.h13
-rw-r--r--contrib/restricted/abseil-cpp/absl/utility/utility.h104
-rw-r--r--contrib/restricted/abseil-cpp/absl/utility/ya.make4
-rw-r--r--contrib/restricted/abseil-cpp/ya.make4
-rw-r--r--contrib/restricted/boost/assert/include/boost/assert/source_location.hpp2
-rw-r--r--library/cpp/lcs/lcs_via_lis_ut.cpp2
-rw-r--r--library/cpp/tld/tlds-alpha-by-domain.txt2
-rw-r--r--library/cpp/yt/misc/enum.h1
-rw-r--r--library/cpp/yt/misc/enum_indexed_array-inl.h73
-rw-r--r--library/cpp/yt/misc/enum_indexed_array.h64
-rw-r--r--library/cpp/yt/misc/unittests/enum_indexed_array_ut.cpp45
-rw-r--r--library/cpp/yt/misc/unittests/ya.make1
-rw-r--r--library/cpp/yt/string/format-inl.h22
-rw-r--r--library/cpp/yt/string/unittests/enum_ut.cpp1
-rw-r--r--library/cpp/ytalloc/api/fallback.cpp18
-rw-r--r--library/cpp/ytalloc/api/ytalloc.h21
-rw-r--r--library/cpp/ytalloc/impl/core-inl.h70
-rw-r--r--library/rightlib_sha.txt2
-rw-r--r--util/generic/yexception.cpp8
-rwxr-xr-xya20
-rw-r--r--yt/cpp/mapreduce/client/file_writer.cpp5
-rw-r--r--yt/cpp/mapreduce/client/file_writer.h1
-rw-r--r--yt/cpp/mapreduce/client/retryful_writer.cpp2
-rw-r--r--yt/cpp/mapreduce/client/retryful_writer.h2
-rw-r--r--yt/cpp/mapreduce/client/retryless_writer.cpp2
-rw-r--r--yt/cpp/mapreduce/client/retryless_writer.h4
-rw-r--r--yt/cpp/mapreduce/client/ya.make15
-rw-r--r--yt/cpp/mapreduce/interface/client_method_options.h20
-rw-r--r--yt/cpp/mapreduce/interface/finish_or_die.h6
-rw-r--r--yt/cpp/mapreduce/interface/io-inl.h2
-rw-r--r--yt/cpp/mapreduce/interface/operation.h13
-rw-r--r--yt/yt/client/api/client_common.h2
-rw-r--r--yt/yt/client/api/config.cpp2
-rw-r--r--yt/yt/client/api/operation_client.h8
-rw-r--r--yt/yt/client/api/public.h4
-rw-r--r--yt/yt/client/api/rpc_proxy/client_base.cpp1
-rw-r--r--yt/yt/client/api/rpc_proxy/helpers.cpp8
-rw-r--r--yt/yt/client/api/security_client.h4
-rw-r--r--yt/yt/client/driver/authentication_commands.cpp6
-rw-r--r--yt/yt/client/driver/command-inl.h7
-rw-r--r--yt/yt/client/driver/command.cpp1
-rw-r--r--yt/yt/client/driver/driver.cpp12
-rw-r--r--yt/yt/client/driver/flow_commands.cpp286
-rw-r--r--yt/yt/client/driver/flow_commands.h130
-rw-r--r--yt/yt/client/federated/client.cpp4
-rw-r--r--yt/yt/client/job_tracker_client/public.h4
-rw-r--r--yt/yt/client/table_client/blob_reader.cpp2
-rw-r--r--yt/yt/client/table_client/helpers.cpp2
-rw-r--r--yt/yt/client/tablet_client/table_mount_cache.h2
-rw-r--r--yt/yt/core/bus/tcp/config.h4
-rw-r--r--yt/yt/core/bus/tcp/dispatcher.h4
-rw-r--r--yt/yt/core/bus/tcp/dispatcher_impl.h2
-rw-r--r--yt/yt/core/concurrency/config.cpp20
-rw-r--r--yt/yt/core/concurrency/config.h21
-rw-r--r--yt/yt/core/concurrency/retrying_periodic_executor.cpp23
-rw-r--r--yt/yt/core/concurrency/retrying_periodic_executor.h7
-rw-r--r--yt/yt/core/misc/backoff_strategy.cpp13
-rw-r--r--yt/yt/core/misc/backoff_strategy.h34
-rw-r--r--yt/yt/core/misc/backoff_strategy_config.cpp44
-rw-r--r--yt/yt/core/misc/backoff_strategy_config.h37
-rw-r--r--yt/yt/core/misc/config.cpp54
-rw-r--r--yt/yt/core/misc/config.h64
-rw-r--r--yt/yt/core/misc/protobuf_helpers-inl.h10
-rw-r--r--yt/yt/core/misc/public.h14
-rw-r--r--yt/yt/core/misc/serialize-inl.h18
-rw-r--r--yt/yt/core/rpc/bus/channel.cpp2
-rw-r--r--yt/yt/core/ya.make1
-rw-r--r--yt/yt/core/yson/pull_parser_deserialize-inl.h4
-rw-r--r--yt/yt/core/yson/pull_parser_deserialize.h12
-rw-r--r--yt/yt/core/ytalloc/bindings.cpp4
-rw-r--r--yt/yt/core/ytree/serialize-inl.h8
-rw-r--r--yt/yt/core/ytree/serialize.h10
-rw-r--r--yt/yt/core/ytree/ypath_detail.cpp2
-rw-r--r--yt/yt/flow/lib/client/public.h4
-rw-r--r--yt/yt/library/column_converters/column_converter.cpp2
-rw-r--r--yt/yt/library/column_converters/string_column_converter.cpp4
-rw-r--r--yt/yt/library/formats/web_json_writer.cpp2
-rw-r--r--yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto1
646 files changed, 17057 insertions, 9254 deletions
diff --git a/build/conf/go.conf b/build/conf/go.conf
index c58492e17c..397a55cd5e 100644
--- a/build/conf/go.conf
+++ b/build/conf/go.conf
@@ -63,9 +63,6 @@ GOSTD_VERSION=1.21
when ($GOSTD_VERSION == "1.21") {
GOSTD=contrib/go/_std_1.21/src
}
-elsewhen ($GOSTD_VERSION == "1.20") {
- GOSTD=contrib/go/_std_1.20/src
-}
otherwise {
GOSTD=__unsupported_go_std_library_version_[$GOSTD_VERSION]__
}
diff --git a/build/conf/python.conf b/build/conf/python.conf
index 8fcd11593d..27a8bcd47a 100644
--- a/build/conf/python.conf
+++ b/build/conf/python.conf
@@ -237,6 +237,17 @@ macro STYLE_PYTHON(pyproject...) {
}
# tag:python-specific tag:test
+STYLE_RUFF_VALUE=no
+STYLE_RUFF_PYPROJECT_VALUE=
+### @usage: STYLE_RUFF([pyproject])
+###
+### Check python3 sources for style issues using ruff.
+macro STYLE_RUFF(pyproject...) {
+ SET(STYLE_RUFF_VALUE yes)
+ SET(STYLE_RUFF_PYPROJECT_VALUE ${pyproject})
+}
+
+# tag:python-specific tag:test
### @usage: NO_DOCTESTS()
###
### Disable doctests in PY[|3|23_]TEST
diff --git a/build/export_generators/hardcoded-cmake/cmake/common.cmake b/build/export_generators/hardcoded-cmake/cmake/common.cmake
index 0ffe61ad17..f85875ec40 100644
--- a/build/export_generators/hardcoded-cmake/cmake/common.cmake
+++ b/build/export_generators/hardcoded-cmake/cmake/common.cmake
@@ -296,13 +296,13 @@ function(set_yunittest_property)
get_property(SPLIT_FACTOR TARGET ${YUNITTEST_ARGS_TEST} PROPERTY SPLIT_FACTOR)
if ((${SPLIT_FACTOR} EQUAL 1) OR (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/run_testpack"))
- set_property(TEST ${YUNITTEST_ARGS_TEST} PROPERTY ${YUNITTEST_ARGS_PROPERTY} ${YUNITTEST_ARGS_UNPARSED_ARGUMENTS})
+ set_property(TEST ${YUNITTEST_ARGS_TEST} PROPERTY ${YUNITTEST_ARGS_PROPERTY} "${YUNITTEST_ARGS_UNPARSED_ARGUMENTS}")
return()
endif()
math(EXPR LastIdx "${SPLIT_FACTOR} - 1")
foreach(Idx RANGE ${LastIdx})
- set_property(TEST ${YUNITTEST_ARGS_TEST}_${Idx} PROPERTY ${YUNITTEST_ARGS_PROPERTY} ${YUNITTEST_ARGS_UNPARSED_ARGUMENTS})
+ set_property(TEST ${YUNITTEST_ARGS_TEST}_${Idx} PROPERTY ${YUNITTEST_ARGS_PROPERTY} "${YUNITTEST_ARGS_UNPARSED_ARGUMENTS}")
endforeach()
endfunction()
diff --git a/build/export_generators/hardcoded-cmake/generator.toml b/build/export_generators/hardcoded-cmake/generator.toml
index 648d69108a..8d1fe96420 100644
--- a/build/export_generators/hardcoded-cmake/generator.toml
+++ b/build/export_generators/hardcoded-cmake/generator.toml
@@ -84,7 +84,7 @@ attrs=[
"target_sources_custom",
"use_export_script",
"add_yunittest",
- "set_yunittest_property",
+ "set_yunittest_property",
]
copy=[
"cmake/common.cmake",
diff --git a/build/external_resources/gdb/resources.json b/build/external_resources/gdb/resources.json
index 15c8f4e246..4f14a48ebe 100644
--- a/build/external_resources/gdb/resources.json
+++ b/build/external_resources/gdb/resources.json
@@ -7,10 +7,10 @@
"uri": "sbr:2319130389"
},
"linux-x86_64": {
- "uri": "sbr:5709310220"
+ "uri": "sbr:5720181629"
},
"linux-aarch64": {
- "uri": "sbr:5709435327"
+ "uri": "sbr:5720688825"
}
},
"platform_replacements": {},
diff --git a/build/external_resources/go_tools/go1.20.json b/build/external_resources/go_tools/go1.20.json
deleted file mode 100644
index 703d0ede76..0000000000
--- a/build/external_resources/go_tools/go1.20.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "by_platform": {
- "darwin-arm64": {
- "uri": "sbr:4773521027"
- },
- "darwin-x86_64": {
- "uri": "sbr:4773516480"
- },
- "linux-x86_64": {
- "uri": "sbr:4773507347"
- },
- "linux-aarch64": {
- "uri": "sbr:4773511397"
- },
- "win32-x86_64": {
- "uri": "sbr:4773525032"
- }
- }
-}
diff --git a/build/external_resources/go_tools/go1.21.json b/build/external_resources/go_tools/go1.21.json
index 7cc1c52c3d..30dd9f3369 100644
--- a/build/external_resources/go_tools/go1.21.json
+++ b/build/external_resources/go_tools/go1.21.json
@@ -1,19 +1,19 @@
{
"by_platform": {
"darwin-arm64": {
- "uri": "sbr:5424061624"
+ "uri": "sbr:5720722976"
},
"darwin-x86_64": {
- "uri": "sbr:5424057306"
+ "uri": "sbr:5720717636"
},
"linux-x86_64": {
- "uri": "sbr:5424033677"
+ "uri": "sbr:5720706939"
},
"linux-aarch64": {
- "uri": "sbr:5424038053"
+ "uri": "sbr:5720713011"
},
"win32-x86_64": {
- "uri": "sbr:5424051723"
+ "uri": "sbr:5720736838"
}
}
}
diff --git a/build/external_resources/go_tools/ya.make b/build/external_resources/go_tools/ya.make
index 24807da914..697ae83a5e 100644
--- a/build/external_resources/go_tools/ya.make
+++ b/build/external_resources/go_tools/ya.make
@@ -1,8 +1,6 @@
RESOURCES_LIBRARY()
-IF(GOSTD_VERSION == 1.20)
- DECLARE_EXTERNAL_HOST_RESOURCES_BUNDLE_BY_JSON(GO_TOOLS go1.20.json)
-ELSEIF(GOSTD_VERSION == 1.21)
+IF(GOSTD_VERSION == 1.21)
DECLARE_EXTERNAL_HOST_RESOURCES_BUNDLE_BY_JSON(GO_TOOLS go1.21.json)
ELSE()
MESSAGE(FATAL_ERROR Unsupported version [${GOSTD_VERSION}] of Go Standard Library)
diff --git a/build/mapping.conf.json b/build/mapping.conf.json
index 07c8b9afc5..d931e3d12a 100644
--- a/build/mapping.conf.json
+++ b/build/mapping.conf.json
@@ -36,6 +36,11 @@
"5424033677": "https://devtools-registry.s3.yandex.net/5424033677",
"5424038053": "https://devtools-registry.s3.yandex.net/5424038053",
"5424051723": "https://devtools-registry.s3.yandex.net/5424051723",
+ "5720717636": "https://devtools-registry.s3.yandex.net/5720717636",
+ "5720722976": "https://devtools-registry.s3.yandex.net/5720722976",
+ "5720706939": "https://devtools-registry.s3.yandex.net/5720706939",
+ "5720713011": "https://devtools-registry.s3.yandex.net/5720713011",
+ "5720736838": "https://devtools-registry.s3.yandex.net/5720736838",
"5543659225": "https://devtools-registry.s3.yandex.net/5543659225",
"5560184603": "https://devtools-registry.s3.yandex.net/5560184603",
"5553311553": "https://devtools-registry.s3.yandex.net/5553311553",
@@ -51,7 +56,9 @@
"1966560555": "https://devtools-registry.s3.yandex.net/1966560555",
"309054781": "https://devtools-registry.s3.yandex.net/309054781",
"5298918458": "https://devtools-registry.s3.yandex.net/5298918458",
+ "5720688825": "https://devtools-registry.s3.yandex.net/5720688825",
"5298901591": "https://devtools-registry.s3.yandex.net/5298901591",
+ "5720181629": "https://devtools-registry.s3.yandex.net/5720181629",
"5709310220": "https://devtools-registry.s3.yandex.net/5709310220",
"5709435327": "https://devtools-registry.s3.yandex.net/5709435327",
"360916612": "https://devtools-registry.s3.yandex.net/360916612",
@@ -102,6 +109,7 @@
"5675381622": "https://devtools-registry.s3.yandex.net/5675381622",
"5683487438": "https://devtools-registry.s3.yandex.net/5683487438",
"5707396874": "https://devtools-registry.s3.yandex.net/5707396874",
+ "5720350134": "https://devtools-registry.s3.yandex.net/5720350134",
"5486731632": "https://devtools-registry.s3.yandex.net/5486731632",
"5514350352": "https://devtools-registry.s3.yandex.net/5514350352",
"5514360398": "https://devtools-registry.s3.yandex.net/5514360398",
@@ -121,6 +129,8 @@
"5683523790": "https://devtools-registry.s3.yandex.net/5683523790",
"5707396152": "https://devtools-registry.s3.yandex.net/5707396152",
"5707407435": "https://devtools-registry.s3.yandex.net/5707407435",
+ "5720351188": "https://devtools-registry.s3.yandex.net/5720351188",
+ "5720356918": "https://devtools-registry.s3.yandex.net/5720356918",
"4307890075": "https://devtools-registry.s3.yandex.net/4307890075",
"5517245192": "https://devtools-registry.s3.yandex.net/5517245192",
"4307901240": "https://devtools-registry.s3.yandex.net/4307901240",
@@ -235,6 +245,11 @@
"5424033677": "OTHER_RESOURCE-none-1.21.3-y_go1.21.3.linux-amd64.tar.gz",
"5424038053": "OTHER_RESOURCE-none-1.21.3-y_go1.21.3.linux-arm64.tar.gz",
"5424051723": "OTHER_RESOURCE-none-1.21.3-y_go1.21.3.windows-amd64.tar.gz",
+ "5720717636": "OTHER_RESOURCE-none-1.21.6-y_go1.21.6.darwin-amd64.tar.gz",
+ "5720722976": "OTHER_RESOURCE-none-1.21.6-y_go1.21.6.darwin-arm64.tar.gz",
+ "5720706939": "OTHER_RESOURCE-none-1.21.6-y_go1.21.6.linux-amd64.tar.gz",
+ "5720713011": "OTHER_RESOURCE-none-1.21.6-y_go1.21.6.linux-arm64.tar.gz",
+ "5720736838": "OTHER_RESOURCE-none-1.21.6-y_go1.21.6.windows-amd64.tar.gz",
"5543659225": "OTHER_RESOURCE-none-none-clang-darwin-arm64.tgz",
"5560184603": "OTHER_RESOURCE-none-none-clang-mingw64.tgz",
"5553311553": "OTHER_RESOURCE-none-none-clang-new-darwin-arm64.tgz",
@@ -250,7 +265,9 @@
"1966560555": "Ubuntu 14 x86-64 native SDK (patched, v3)",
"309054781": "Ubuntu 16 x86-64 -> Ubuntu 16 aarch64 cross SDK",
"5298918458": "bin-gdb-reloc-ya-linux-aarch64-62901b3b39a8b08c2d39a3bf08a1fc3a6d76eb78",
+ "5720688825": "bin-gdb-reloc-ya-linux-aarch64-62901b3b39a8b08c2d39a3bf08a1fc3a6d76eb78",
"5298901591": "bin-gdb-reloc-ya-linux-x86_64-62901b3b39a8b08c2d39a3bf08a1fc3a6d76eb78",
+ "5720181629": "bin-gdb-reloc-ya-linux-x86_64-62901b3b39a8b08c2d39a3bf08a1fc3a6d76eb78",
"5709310220": "bin-gdb-reloc-ya-linux-x86_64-70970b31ef83c56b51291cd8fe4f24449b582b59",
"5709435327": "bin-gdb-reloc-ya-linux-x86_64-70970b31ef83c56b51291cd8fe4f24449b582b59",
"360916612": "binutils 2.26 for linux_ubuntu_10.04_lucid",
@@ -301,6 +318,7 @@
"5675381622": "devtools/ya/test/programs/test_tool/bin/test_tool for linux",
"5683487438": "devtools/ya/test/programs/test_tool/bin/test_tool for linux",
"5707396874": "devtools/ya/test/programs/test_tool/bin/test_tool for linux",
+ "5720350134": "devtools/ya/test/programs/test_tool/bin/test_tool for linux",
"5486731632": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux",
"5514350352": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux",
"5514360398": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux",
@@ -320,6 +338,8 @@
"5683523790": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux",
"5707396152": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux",
"5707407435": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux",
+ "5720351188": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux",
+ "5720356918": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux",
"4307890075": "flake8_linter for linux",
"5517245192": "flake8_linter for linux",
"4307901240": "flake8_linter for linux-aarch64",
diff --git a/build/platform/test_tool/host.ya.make.inc b/build/platform/test_tool/host.ya.make.inc
index 00cdf84292..6c7d6bb454 100644
--- a/build/platform/test_tool/host.ya.make.inc
+++ b/build/platform/test_tool/host.ya.make.inc
@@ -1,17 +1,17 @@
IF (HOST_OS_DARWIN AND HOST_ARCH_X86_64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5707394532)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5707406472)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5720349017)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5720356281)
ELSEIF (HOST_OS_DARWIN AND HOST_ARCH_ARM64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5707393572)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5707406025)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5720348354)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5720355987)
ELSEIF (HOST_OS_LINUX AND HOST_ARCH_X86_64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5707396874)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5707407435)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5720350134)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5720356918)
ELSEIF (HOST_OS_LINUX AND HOST_ARCH_AARCH64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5707391802)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5707405475)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5720347692)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5720355628)
ELSEIF (HOST_OS_WINDOWS AND HOST_ARCH_X86_64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5707395940)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5707406839)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5720349493)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5720356619)
ENDIF()
diff --git a/build/platform/test_tool/host_os.ya.make.inc b/build/platform/test_tool/host_os.ya.make.inc
index 3f4805fef4..96dc65b607 100644
--- a/build/platform/test_tool/host_os.ya.make.inc
+++ b/build/platform/test_tool/host_os.ya.make.inc
@@ -1,17 +1,17 @@
IF (HOST_OS_DARWIN AND HOST_ARCH_X86_64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5707395021)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5707395021)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5720350265)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5720350265)
ELSEIF (HOST_OS_DARWIN AND HOST_ARCH_ARM64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5707394418)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5707394418)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5720349877)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5720349877)
ELSEIF (HOST_OS_LINUX AND HOST_ARCH_X86_64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5707396152)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5707396152)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5720351188)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5720351188)
ELSEIF (HOST_OS_LINUX AND HOST_ARCH_AARCH64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5707393967)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5707393967)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5720349514)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5720349514)
ELSEIF (HOST_OS_WINDOWS AND HOST_ARCH_X86_64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5707395714)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5707395714)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:5720350722)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL3_HOST sbr:5720350722)
ENDIF()
diff --git a/build/plugins/lib/test_const/__init__.py b/build/plugins/lib/test_const/__init__.py
index 8037a5c266..8a91bd5ebe 100644
--- a/build/plugins/lib/test_const/__init__.py
+++ b/build/plugins/lib/test_const/__init__.py
@@ -200,6 +200,7 @@ GO_TOOLS_RESOURCE = 'GO_TOOLS_RESOURCE_GLOBAL'
JSTYLE_RUNNER_LIB = 'JSTYLE_LIB_RESOURCE_GLOBAL'
NODEJS_RESOURCE = 'NODEJS_RESOURCE_GLOBAL'
NYC_RESOURCE = 'NYC_RESOURCE_GLOBAL'
+RUFF_RESOURCE = 'RUFF_RESOURCE_GLOBAL'
TEST_TOOL3_HOST = 'TEST_TOOL3_HOST_RESOURCE_GLOBAL'
TEST_TOOL3_HOST_LOCAL = 'TEST_TOOL3_HOST_LOCAL'
TEST_TOOL_HOST = 'TEST_TOOL_HOST_RESOURCE_GLOBAL'
diff --git a/build/plugins/pybuild.py b/build/plugins/pybuild.py
index 23ace17669..e58f0906cd 100644
--- a/build/plugins/pybuild.py
+++ b/build/plugins/pybuild.py
@@ -145,6 +145,8 @@ def add_python_lint_checks(unit, py_ver, files):
resolved_files.append(resolved)
return resolved_files
+ upath = unit.path()[3:]
+
no_lint_value = get_no_lint_value(unit)
if no_lint_value == "none":
no_lint_allowed_paths = (
@@ -161,8 +163,6 @@ def add_python_lint_checks(unit, py_ver, files):
"yt/python/", # YT-20053
)
- upath = unit.path()[3:]
-
if not upath.startswith(no_lint_allowed_paths):
ymake.report_configure_error("NO_LINT() is allowed only in " + ", ".join(no_lint_allowed_paths))
@@ -193,6 +193,27 @@ def add_python_lint_checks(unit, py_ver, files):
params += ["EXTRA_PARAMS"] + extra_params
unit.on_add_linter_check(params)
+ # ruff related stuff
+ if unit.get('STYLE_RUFF_VALUE') == 'yes':
+ if no_lint_value in ("none", "none_internal"):
+ ymake.report_configure_error(
+ 'NO_LINT() and STYLE_RUFF() can\'t be enabled both at the same time',
+ )
+ # temporary allow using ruff for taxi only
+ ruff_allowed_paths = ("taxi/",)
+ if not upath.startswith(ruff_allowed_paths):
+ ymake.report_configure_error("STYLE_RUFF() is allowed only in " + ", ".join(ruff_allowed_paths))
+
+ resolved_files = get_resolved_files()
+ if resolved_files:
+ resource = "build/external_resources/ruff"
+ params = ["ruff", "tools/ruff_linter/bin/ruff_linter"]
+ params += ["FILES"] + resolved_files
+ params += ["GLOBAL_RESOURCES", resource]
+ ruff_cfg = unit.get('STYLE_RUFF_PYPROJECT_VALUE') or 'build/config/tests/ruff/ruff.toml'
+ params += ['CONFIGS', ruff_cfg]
+ unit.on_add_linter_check(params)
+
if files and unit.get('STYLE_PYTHON_VALUE') == 'yes' and is_py3(unit):
resolved_files = get_resolved_files()
if resolved_files:
diff --git a/build/sysincl/stl-to-libcxx.yml b/build/sysincl/stl-to-libcxx.yml
index 102c1b517e..7b3149fef0 100644
--- a/build/sysincl/stl-to-libcxx.yml
+++ b/build/sysincl/stl-to-libcxx.yml
@@ -88,6 +88,7 @@
- cwctype: contrib/libs/cxxsupp/libcxx/include/cwctype
- deque: contrib/libs/cxxsupp/libcxx/include/deque
- exception: contrib/libs/cxxsupp/libcxx/include/exception
+ - expected: contrib/libs/cxxsupp/libcxx/include/expected
- filesystem: contrib/libs/cxxsupp/libcxx/include/filesystem
- forward_list: contrib/libs/cxxsupp/libcxx/include/forward_list
- fstream: contrib/libs/cxxsupp/libcxx/include/fstream
@@ -119,6 +120,7 @@
- scoped_allocator: contrib/libs/cxxsupp/libcxx/include/scoped_allocator
- set: contrib/libs/cxxsupp/libcxx/include/set
- shared_mutex: contrib/libs/cxxsupp/libcxx/include/shared_mutex
+ - source_location: contrib/libs/cxxsupp/libcxx/include/source_location
- span: contrib/libs/cxxsupp/libcxx/include/span
- sstream: contrib/libs/cxxsupp/libcxx/include/sstream
- stack: contrib/libs/cxxsupp/libcxx/include/stack
@@ -168,7 +170,6 @@
- __assert: contrib/libs/cxxsupp/libcxx/include/__assert
- __availability: contrib/libs/cxxsupp/libcxx/include/__availability
- __bit_reference: contrib/libs/cxxsupp/libcxx/include/__bit_reference
- - __bits: contrib/libs/cxxsupp/libcxx/include/__bits
- __bsd_locale_defaults.h: contrib/libs/cxxsupp/libcxx/include/__bsd_locale_defaults.h
- __bsd_locale_fallbacks.h: contrib/libs/cxxsupp/libcxx/include/__bsd_locale_fallbacks.h
- __config: contrib/libs/cxxsupp/libcxx/include/__config
@@ -197,6 +198,7 @@
- __algorithm/copy.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/copy.h
- __algorithm/copy_backward.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/copy_backward.h
- __algorithm/copy_if.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/copy_if.h
+ - __algorithm/copy_move_common.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/copy_move_common.h
- __algorithm/copy_n.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/copy_n.h
- __algorithm/count.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/count.h
- __algorithm/count_if.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/count_if.h
@@ -378,7 +380,18 @@
- __algorithm/unwrap_range.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/unwrap_range.h
- __algorithm/upper_bound.h: contrib/libs/cxxsupp/libcxx/include/__algorithm/upper_bound.h
- __bit/bit_cast.h: contrib/libs/cxxsupp/libcxx/include/__bit/bit_cast.h
+ - __bit/bit_ceil.h: contrib/libs/cxxsupp/libcxx/include/__bit/bit_ceil.h
+ - __bit/bit_floor.h: contrib/libs/cxxsupp/libcxx/include/__bit/bit_floor.h
+ - __bit/bit_log2.h: contrib/libs/cxxsupp/libcxx/include/__bit/bit_log2.h
+ - __bit/bit_width.h: contrib/libs/cxxsupp/libcxx/include/__bit/bit_width.h
+ - __bit/blsr.h: contrib/libs/cxxsupp/libcxx/include/__bit/blsr.h
- __bit/byteswap.h: contrib/libs/cxxsupp/libcxx/include/__bit/byteswap.h
+ - __bit/countl.h: contrib/libs/cxxsupp/libcxx/include/__bit/countl.h
+ - __bit/countr.h: contrib/libs/cxxsupp/libcxx/include/__bit/countr.h
+ - __bit/endian.h: contrib/libs/cxxsupp/libcxx/include/__bit/endian.h
+ - __bit/has_single_bit.h: contrib/libs/cxxsupp/libcxx/include/__bit/has_single_bit.h
+ - __bit/popcount.h: contrib/libs/cxxsupp/libcxx/include/__bit/popcount.h
+ - __bit/rotate.h: contrib/libs/cxxsupp/libcxx/include/__bit/rotate.h
- __charconv/chars_format.h: contrib/libs/cxxsupp/libcxx/include/__charconv/chars_format.h
- __charconv/from_chars_result.h: contrib/libs/cxxsupp/libcxx/include/__charconv/from_chars_result.h
- __charconv/tables.h: contrib/libs/cxxsupp/libcxx/include/__charconv/tables.h
@@ -448,6 +461,10 @@
- __coroutine/noop_coroutine_handle.h: contrib/libs/cxxsupp/libcxx/include/__coroutine/noop_coroutine_handle.h
- __coroutine/trivial_awaitables.h: contrib/libs/cxxsupp/libcxx/include/__coroutine/trivial_awaitables.h
- __debug_utils/randomize_range.h: contrib/libs/cxxsupp/libcxx/include/__debug_utils/randomize_range.h
+ - __expected/bad_expected_access.h: contrib/libs/cxxsupp/libcxx/include/__expected/bad_expected_access.h
+ - __expected/expected.h: contrib/libs/cxxsupp/libcxx/include/__expected/expected.h
+ - __expected/unexpect.h: contrib/libs/cxxsupp/libcxx/include/__expected/unexpect.h
+ - __expected/unexpected.h: contrib/libs/cxxsupp/libcxx/include/__expected/unexpected.h
- __filesystem/copy_options.h: contrib/libs/cxxsupp/libcxx/include/__filesystem/copy_options.h
- __filesystem/directory_entry.h: contrib/libs/cxxsupp/libcxx/include/__filesystem/directory_entry.h
- __filesystem/directory_iterator.h: contrib/libs/cxxsupp/libcxx/include/__filesystem/directory_iterator.h
@@ -466,6 +483,7 @@
- __filesystem/u8path.h: contrib/libs/cxxsupp/libcxx/include/__filesystem/u8path.h
- __format/buffer.h: contrib/libs/cxxsupp/libcxx/include/__format/buffer.h
- __format/concepts.h: contrib/libs/cxxsupp/libcxx/include/__format/concepts.h
+ - __format/container_adaptor.h: contrib/libs/cxxsupp/libcxx/include/__format/container_adaptor.h
- __format/enable_insertable.h: contrib/libs/cxxsupp/libcxx/include/__format/enable_insertable.h
- __format/escaped_output_table.h: contrib/libs/cxxsupp/libcxx/include/__format/escaped_output_table.h
- __format/extended_grapheme_cluster_table.h: contrib/libs/cxxsupp/libcxx/include/__format/extended_grapheme_cluster_table.h
@@ -488,7 +506,10 @@
- __format/formatter_output.h: contrib/libs/cxxsupp/libcxx/include/__format/formatter_output.h
- __format/formatter_pointer.h: contrib/libs/cxxsupp/libcxx/include/__format/formatter_pointer.h
- __format/formatter_string.h: contrib/libs/cxxsupp/libcxx/include/__format/formatter_string.h
+ - __format/formatter_tuple.h: contrib/libs/cxxsupp/libcxx/include/__format/formatter_tuple.h
- __format/parser_std_format_spec.h: contrib/libs/cxxsupp/libcxx/include/__format/parser_std_format_spec.h
+ - __format/range_default_formatter.h: contrib/libs/cxxsupp/libcxx/include/__format/range_default_formatter.h
+ - __format/range_formatter.h: contrib/libs/cxxsupp/libcxx/include/__format/range_formatter.h
- __format/unicode.h: contrib/libs/cxxsupp/libcxx/include/__format/unicode.h
- __functional/binary_function.h: contrib/libs/cxxsupp/libcxx/include/__functional/binary_function.h
- __functional/binary_negate.h: contrib/libs/cxxsupp/libcxx/include/__functional/binary_negate.h
@@ -526,6 +547,7 @@
- __fwd/span.h: contrib/libs/cxxsupp/libcxx/include/__fwd/span.h
- __fwd/string.h: contrib/libs/cxxsupp/libcxx/include/__fwd/string.h
- __fwd/string_view.h: contrib/libs/cxxsupp/libcxx/include/__fwd/string_view.h
+ - __fwd/subrange.h: contrib/libs/cxxsupp/libcxx/include/__fwd/subrange.h
- __fwd/tuple.h: contrib/libs/cxxsupp/libcxx/include/__fwd/tuple.h
- __ios/fpos.h: contrib/libs/cxxsupp/libcxx/include/__ios/fpos.h
- __iterator/access.h: contrib/libs/cxxsupp/libcxx/include/__iterator/access.h
@@ -550,6 +572,7 @@
- __iterator/iter_swap.h: contrib/libs/cxxsupp/libcxx/include/__iterator/iter_swap.h
- __iterator/iterator.h: contrib/libs/cxxsupp/libcxx/include/__iterator/iterator.h
- __iterator/iterator_traits.h: contrib/libs/cxxsupp/libcxx/include/__iterator/iterator_traits.h
+ - __iterator/iterator_with_data.h: contrib/libs/cxxsupp/libcxx/include/__iterator/iterator_with_data.h
- __iterator/mergeable.h: contrib/libs/cxxsupp/libcxx/include/__iterator/mergeable.h
- __iterator/move_iterator.h: contrib/libs/cxxsupp/libcxx/include/__iterator/move_iterator.h
- __iterator/move_sentinel.h: contrib/libs/cxxsupp/libcxx/include/__iterator/move_sentinel.h
@@ -562,6 +585,7 @@
- __iterator/readable_traits.h: contrib/libs/cxxsupp/libcxx/include/__iterator/readable_traits.h
- __iterator/reverse_access.h: contrib/libs/cxxsupp/libcxx/include/__iterator/reverse_access.h
- __iterator/reverse_iterator.h: contrib/libs/cxxsupp/libcxx/include/__iterator/reverse_iterator.h
+ - __iterator/segmented_iterator.h: contrib/libs/cxxsupp/libcxx/include/__iterator/segmented_iterator.h
- __iterator/size.h: contrib/libs/cxxsupp/libcxx/include/__iterator/size.h
- __iterator/sortable.h: contrib/libs/cxxsupp/libcxx/include/__iterator/sortable.h
- __iterator/unreachable_sentinel.h: contrib/libs/cxxsupp/libcxx/include/__iterator/unreachable_sentinel.h
@@ -653,6 +677,7 @@
- __random/weibull_distribution.h: contrib/libs/cxxsupp/libcxx/include/__random/weibull_distribution.h
- __ranges/access.h: contrib/libs/cxxsupp/libcxx/include/__ranges/access.h
- __ranges/all.h: contrib/libs/cxxsupp/libcxx/include/__ranges/all.h
+ - __ranges/as_rvalue_view.h: contrib/libs/cxxsupp/libcxx/include/__ranges/as_rvalue_view.h
- __ranges/common_view.h: contrib/libs/cxxsupp/libcxx/include/__ranges/common_view.h
- __ranges/concepts.h: contrib/libs/cxxsupp/libcxx/include/__ranges/concepts.h
- __ranges/copyable_box.h: contrib/libs/cxxsupp/libcxx/include/__ranges/copyable_box.h
@@ -661,6 +686,7 @@
- __ranges/data.h: contrib/libs/cxxsupp/libcxx/include/__ranges/data.h
- __ranges/drop_view.h: contrib/libs/cxxsupp/libcxx/include/__ranges/drop_view.h
- __ranges/drop_while_view.h: contrib/libs/cxxsupp/libcxx/include/__ranges/drop_while_view.h
+ - __ranges/elements_view.h: contrib/libs/cxxsupp/libcxx/include/__ranges/elements_view.h
- __ranges/empty.h: contrib/libs/cxxsupp/libcxx/include/__ranges/empty.h
- __ranges/empty_view.h: contrib/libs/cxxsupp/libcxx/include/__ranges/empty_view.h
- __ranges/enable_borrowed_range.h: contrib/libs/cxxsupp/libcxx/include/__ranges/enable_borrowed_range.h
@@ -679,6 +705,7 @@
- __ranges/reverse_view.h: contrib/libs/cxxsupp/libcxx/include/__ranges/reverse_view.h
- __ranges/single_view.h: contrib/libs/cxxsupp/libcxx/include/__ranges/single_view.h
- __ranges/size.h: contrib/libs/cxxsupp/libcxx/include/__ranges/size.h
+ - __ranges/split_view.h: contrib/libs/cxxsupp/libcxx/include/__ranges/split_view.h
- __ranges/subrange.h: contrib/libs/cxxsupp/libcxx/include/__ranges/subrange.h
- __ranges/take_view.h: contrib/libs/cxxsupp/libcxx/include/__ranges/take_view.h
- __ranges/take_while_view.h: contrib/libs/cxxsupp/libcxx/include/__ranges/take_while_view.h
@@ -707,14 +734,16 @@
- __support/xlocale/__strtonum_fallback.h: contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__strtonum_fallback.h
- __thread/poll_with_backoff.h: contrib/libs/cxxsupp/libcxx/include/__thread/poll_with_backoff.h
- __thread/timed_backoff_policy.h: contrib/libs/cxxsupp/libcxx/include/__thread/timed_backoff_policy.h
- - __tuple/apply_cv.h: contrib/libs/cxxsupp/libcxx/include/__tuple/apply_cv.h
- - __tuple/make_tuple_types.h: contrib/libs/cxxsupp/libcxx/include/__tuple/make_tuple_types.h
- - __tuple/sfinae_helpers.h: contrib/libs/cxxsupp/libcxx/include/__tuple/sfinae_helpers.h
- - __tuple/tuple_element.h: contrib/libs/cxxsupp/libcxx/include/__tuple/tuple_element.h
- - __tuple/tuple_indices.h: contrib/libs/cxxsupp/libcxx/include/__tuple/tuple_indices.h
- - __tuple/tuple_like.h: contrib/libs/cxxsupp/libcxx/include/__tuple/tuple_like.h
- - __tuple/tuple_size.h: contrib/libs/cxxsupp/libcxx/include/__tuple/tuple_size.h
- - __tuple/tuple_types.h: contrib/libs/cxxsupp/libcxx/include/__tuple/tuple_types.h
+ - __tuple_dir/apply_cv.h: contrib/libs/cxxsupp/libcxx/include/__tuple_dir/apply_cv.h
+ - __tuple_dir/make_tuple_types.h: contrib/libs/cxxsupp/libcxx/include/__tuple_dir/make_tuple_types.h
+ - __tuple_dir/pair_like.h: contrib/libs/cxxsupp/libcxx/include/__tuple_dir/pair_like.h
+ - __tuple_dir/sfinae_helpers.h: contrib/libs/cxxsupp/libcxx/include/__tuple_dir/sfinae_helpers.h
+ - __tuple_dir/tuple_element.h: contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_element.h
+ - __tuple_dir/tuple_indices.h: contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_indices.h
+ - __tuple_dir/tuple_like.h: contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_like.h
+ - __tuple_dir/tuple_like_ext.h: contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_like_ext.h
+ - __tuple_dir/tuple_size.h: contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_size.h
+ - __tuple_dir/tuple_types.h: contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_types.h
- __type_traits/add_const.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/add_const.h
- __type_traits/add_cv.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/add_cv.h
- __type_traits/add_lvalue_reference.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/add_lvalue_reference.h
@@ -743,6 +772,7 @@
- __type_traits/is_abstract.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/is_abstract.h
- __type_traits/is_aggregate.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/is_aggregate.h
- __type_traits/is_allocator.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/is_allocator.h
+ - __type_traits/is_always_bitcastable.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/is_always_bitcastable.h
- __type_traits/is_arithmetic.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/is_arithmetic.h
- __type_traits/is_array.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/is_array.h
- __type_traits/is_assignable.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/is_assignable.h
@@ -798,6 +828,7 @@
- __type_traits/is_scoped_enum.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/is_scoped_enum.h
- __type_traits/is_signed.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/is_signed.h
- __type_traits/is_signed_integer.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/is_signed_integer.h
+ - __type_traits/is_specialization.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/is_specialization.h
- __type_traits/is_standard_layout.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/is_standard_layout.h
- __type_traits/is_swappable.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/is_swappable.h
- __type_traits/is_trivial.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/is_trivial.h
@@ -838,6 +869,7 @@
- __type_traits/remove_reference.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/remove_reference.h
- __type_traits/remove_volatile.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/remove_volatile.h
- __type_traits/result_of.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/result_of.h
+ - __type_traits/strip_signature.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/strip_signature.h
- __type_traits/type_identity.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/type_identity.h
- __type_traits/type_list.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/type_list.h
- __type_traits/underlying_type.h: contrib/libs/cxxsupp/libcxx/include/__type_traits/underlying_type.h
@@ -847,6 +879,7 @@
- __utility/cmp.h: contrib/libs/cxxsupp/libcxx/include/__utility/cmp.h
- __utility/convert_to_integral.h: contrib/libs/cxxsupp/libcxx/include/__utility/convert_to_integral.h
- __utility/declval.h: contrib/libs/cxxsupp/libcxx/include/__utility/declval.h
+ - __utility/exception_guard.h: contrib/libs/cxxsupp/libcxx/include/__utility/exception_guard.h
- __utility/exchange.h: contrib/libs/cxxsupp/libcxx/include/__utility/exchange.h
- __utility/forward.h: contrib/libs/cxxsupp/libcxx/include/__utility/forward.h
- __utility/forward_like.h: contrib/libs/cxxsupp/libcxx/include/__utility/forward_like.h
@@ -859,7 +892,6 @@
- __utility/rel_ops.h: contrib/libs/cxxsupp/libcxx/include/__utility/rel_ops.h
- __utility/swap.h: contrib/libs/cxxsupp/libcxx/include/__utility/swap.h
- __utility/to_underlying.h: contrib/libs/cxxsupp/libcxx/include/__utility/to_underlying.h
- - __utility/transaction.h: contrib/libs/cxxsupp/libcxx/include/__utility/transaction.h
- __utility/unreachable.h: contrib/libs/cxxsupp/libcxx/include/__utility/unreachable.h
- __variant/monostate.h: contrib/libs/cxxsupp/libcxx/include/__variant/monostate.h
# END OF GENERATION
diff --git a/build/sysincl/stl-to-nothing.yml b/build/sysincl/stl-to-nothing.yml
index 2d03265c86..f2f3efdcab 100644
--- a/build/sysincl/stl-to-nothing.yml
+++ b/build/sysincl/stl-to-nothing.yml
@@ -71,6 +71,7 @@
- cxxabi.h
- deque
- exception
+ - expected
- filesystem
- forward_list
- fstream
@@ -102,6 +103,7 @@
- scoped_allocator
- set
- shared_mutex
+ - source_location
- span
- sstream
- stack
diff --git a/build/ya.conf.json b/build/ya.conf.json
index b85b11a80a..44022d1330 100644
--- a/build/ya.conf.json
+++ b/build/ya.conf.json
@@ -58,6 +58,55 @@
}
}
},
+ "clang14": {
+ "executable": {
+ "c++": [
+ "bin",
+ "clang++"
+ ],
+ "c++filt": [
+ "bin",
+ "llvm-cxxfilt"
+ ],
+ "cc": [
+ "bin",
+ "clang"
+ ],
+ "clang-rename": [
+ "bin",
+ "clang-rename"
+ ],
+ "llvm-cov": [
+ "bin",
+ "llvm-cov"
+ ],
+ "llvm-gcov": [
+ "bin",
+ "llvm-gcov"
+ ],
+ "llvm-nm": [
+ "bin",
+ "llvm-nm"
+ ],
+ "llvm-objcopy": [
+ "bin",
+ "llvm-objcopy"
+ ],
+ "llvm-profdata": [
+ "bin",
+ "llvm-profdata"
+ ],
+ "llvm-strip": [
+ "bin",
+ "llvm-strip"
+ ],
+ "llvm-symbolizer": [
+ "bin",
+ "llvm-symbolizer"
+ ]
+ },
+ "formula": "build/platform/clang/clang14.json"
+ },
"clang16": {
"executable": {
"c++": [
@@ -313,6 +362,555 @@
}
}
},
+ "clang14": {
+ "env": {
+ "CPATH": [
+ ""
+ ],
+ "LIBRARY_PATH": [
+ ""
+ ],
+ "SDKROOT": [
+ ""
+ ]
+ },
+ "params": {
+ "c_compiler": "$(CLANG)/bin/clang",
+ "cxx_compiler": "$(CLANG)/bin/clang++",
+ "gcc_version": "14",
+ "llvm-symbolizer": "$(CLANG)/bin/llvm-symbolizer",
+ "match_root": "CLANG",
+ "objcopy": "$(CLANG)/bin/llvm-objcopy",
+ "profiles": "$(XCODE_TOOLS_ROOT-sbr:799017771)/Xcode/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles",
+ "simctl": "$(XCODE_TOOLS_ROOT-sbr:799017771)/Xcode/SystemRoot/PrivateFrameworks/CoreSimulator.framework/Resources/bin/simctl",
+ "strip": "$(CLANG)/bin/llvm-strip",
+ "type": "clang",
+ "use_bundle": true,
+ "werror_mode": "all"
+ },
+ "platforms": [
+ {
+ "default": false,
+ "host": {
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "x86_64",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "aarch64",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "arch": "aarch64",
+ "os": "LINUX"
+ },
+ "target": {
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "arch": "aarch64",
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "aarch64",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "ppc64le",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "power9le",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "x86_64",
+ "os": "DARWIN"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "arm64",
+ "os": "DARWIN"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "i386",
+ "os": "IOS"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "x86_64",
+ "os": "IOS"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "armv7",
+ "os": "IOS"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "arm64",
+ "os": "IOS"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "arm64",
+ "os": "IOSSIM"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "armv7a",
+ "os": "YOCTO"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "x86_64",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "aarch64",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "ppc64le",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "power9le",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "x86_64",
+ "os": "DARWIN"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "arm64",
+ "os": "DARWIN"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "i386",
+ "os": "IOS"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "x86_64",
+ "os": "IOS"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "armv7",
+ "os": "IOS"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "arm64",
+ "os": "IOS"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "arm64",
+ "os": "IOSSIM"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "arch": "arm64",
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "x86_64",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "arch": "arm64",
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "aarch64",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "arch": "arm64",
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "ppc64le",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "arch": "arm64",
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "power9le",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "arch": "arm64",
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "x86_64",
+ "os": "DARWIN"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "arch": "arm64",
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "arm64",
+ "os": "DARWIN"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "arch": "arm64",
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "i386",
+ "os": "IOS"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "arch": "arm64",
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "x86_64",
+ "os": "IOS"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "arch": "arm64",
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "armv7",
+ "os": "IOS"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "arch": "arm64",
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "arm64",
+ "os": "IOS"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "arch": "arm64",
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "arm64",
+ "os": "IOSSIM"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "armv7a",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "armv7a_cortex_a9",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "armv7ahf_cortex_a35",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "armv7ahf_cortex_a53",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "armv7ahf",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "armv8a_cortex_a35",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "armv8a_cortex_a53",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "arch": "ppc64le",
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "ppc64le",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "arch": "ppc64le",
+ "os": "LINUX"
+ },
+ "target": {
+ "arch": "power9le",
+ "os": "LINUX"
+ }
+ },
+ {
+ "default": false,
+ "host": {
+ "os": "DARWIN"
+ },
+ "target": {
+ "arch": "armv7ahf_cortex_a53",
+ "os": "LINUX"
+ }
+ }
+ ],
+ "tools": {
+ "c++": {
+ "bottle": "clang14",
+ "executable": "c++"
+ },
+ "c++filt": {
+ "bottle": "clang14",
+ "executable": "c++filt"
+ },
+ "cc": {
+ "bottle": "clang14",
+ "executable": "cc"
+ },
+ "clang-rename": {
+ "bottle": "clang14",
+ "executable": "clang-rename"
+ },
+ "gcov": {
+ "bottle": "clang14",
+ "executable": "llvm-gcov"
+ },
+ "llvm-cov": {
+ "bottle": "clang14",
+ "executable": "llvm-cov"
+ },
+ "llvm-profdata": {
+ "bottle": "clang14",
+ "executable": "llvm-profdata"
+ },
+ "llvm-symbolizer": {
+ "bottle": "clang14",
+ "executable": "llvm-symbolizer"
+ },
+ "nm": {
+ "bottle": "clang14",
+ "executable": "llvm-nm"
+ },
+ "objcopy": {
+ "bottle": "clang14",
+ "executable": "llvm-objcopy"
+ },
+ "strip": {
+ "bottle": "clang14",
+ "executable": "llvm-strip"
+ }
+ }
+ },
"clang16": {
"env": {
"CPATH": [
diff --git a/build/ymake.core.conf b/build/ymake.core.conf
index 1ccfa2d48d..c0c2a070f5 100644
--- a/build/ymake.core.conf
+++ b/build/ymake.core.conf
@@ -9,7 +9,7 @@
FAKEID=628318530716
SANDBOX_FAKEID=${FAKEID}.7600000
-CPP_FAKEID=2023-12-08
+CPP_FAKEID=2024-01-23
GO_FAKEID=11100371
ANDROID_FAKEID=2023-05-17
CLANG_TIDY_FAKEID=2023-06-06
@@ -1248,6 +1248,7 @@ UNITTEST_SEM=$CPP_PROGRAM_SEM \
&& add_yunittest NAME $REALPRJNAME TEST_TARGET $REALPRJNAME TEST_ARG --print-before-suite --print-before-test --fork-tests --print-times --show-fails \
&& set_yunittest_property TEST $REALPRJNAME PROPERTY LABELS $TEST_SIZE_NAME $FILTER_ONLY_TEST_TAGS \
&& add_ytest_requirements $REALPRJNAME $DEFAULT_REQUIREMENTS $TEST_REQUIREMENTS_VALUE \
+ && set_yunittest_property_escaped TEST $REALPRJNAME PROPERTY ENVIRONMENT $TEST_ENV_VALUE \
$_TEST_TIMEOUT_SEM
# tag:test
@@ -1301,6 +1302,7 @@ GTEST_SEM=$CPP_PROGRAM_SEM \
&& add_test NAME $REALPRJNAME COMMAND $REALPRJNAME \
&& set_property TEST $REALPRJNAME PROPERTY LABELS $TEST_SIZE_NAME $FILTER_ONLY_TEST_TAGS \
&& add_test_requirements $REALPRJNAME $DEFAULT_REQUIREMENTS $TEST_REQUIREMENTS_VALUE \
+ && set_property_escaped TEST $REALPRJNAME PROPERTY ENVIRONMENT $TEST_ENV_VALUE \
$_TEST_TIMEOUT_SEM
# tag:cpp-specific tag:test
diff --git a/cmake/common.cmake b/cmake/common.cmake
index 0ffe61ad17..f85875ec40 100644
--- a/cmake/common.cmake
+++ b/cmake/common.cmake
@@ -296,13 +296,13 @@ function(set_yunittest_property)
get_property(SPLIT_FACTOR TARGET ${YUNITTEST_ARGS_TEST} PROPERTY SPLIT_FACTOR)
if ((${SPLIT_FACTOR} EQUAL 1) OR (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/run_testpack"))
- set_property(TEST ${YUNITTEST_ARGS_TEST} PROPERTY ${YUNITTEST_ARGS_PROPERTY} ${YUNITTEST_ARGS_UNPARSED_ARGUMENTS})
+ set_property(TEST ${YUNITTEST_ARGS_TEST} PROPERTY ${YUNITTEST_ARGS_PROPERTY} "${YUNITTEST_ARGS_UNPARSED_ARGUMENTS}")
return()
endif()
math(EXPR LastIdx "${SPLIT_FACTOR} - 1")
foreach(Idx RANGE ${LastIdx})
- set_property(TEST ${YUNITTEST_ARGS_TEST}_${Idx} PROPERTY ${YUNITTEST_ARGS_PROPERTY} ${YUNITTEST_ARGS_UNPARSED_ARGUMENTS})
+ set_property(TEST ${YUNITTEST_ARGS_TEST}_${Idx} PROPERTY ${YUNITTEST_ARGS_PROPERTY} "${YUNITTEST_ARGS_UNPARSED_ARGUMENTS}")
endforeach()
endfunction()
diff --git a/contrib/go/_std_1.21/src/crypto/internal/boring/notboring.go b/contrib/go/_std_1.21/src/crypto/internal/boring/notboring.go
index 1c5e4c742d..e478791217 100644
--- a/contrib/go/_std_1.21/src/crypto/internal/boring/notboring.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/boring/notboring.go
@@ -50,6 +50,7 @@ func NewHMAC(h func() hash.Hash, key []byte) hash.Hash { panic("boringcrypto: no
func NewAESCipher(key []byte) (cipher.Block, error) { panic("boringcrypto: not available") }
func NewGCMTLS(cipher.Block) (cipher.AEAD, error) { panic("boringcrypto: not available") }
+func NewGCMTLS13(cipher.Block) (cipher.AEAD, error) { panic("boringcrypto: not available") }
type PublicKeyECDSA struct{ _ int }
type PrivateKeyECDSA struct{ _ int }
diff --git a/contrib/go/_std_1.21/src/crypto/rand/rand.go b/contrib/go/_std_1.21/src/crypto/rand/rand.go
index 62738e2cb1..d0dcc7cc71 100644
--- a/contrib/go/_std_1.21/src/crypto/rand/rand.go
+++ b/contrib/go/_std_1.21/src/crypto/rand/rand.go
@@ -15,7 +15,7 @@ import "io"
// available, /dev/urandom otherwise.
// On OpenBSD and macOS, Reader uses getentropy(2).
// On other Unix-like systems, Reader reads from /dev/urandom.
-// On Windows systems, Reader uses the RtlGenRandom API.
+// On Windows systems, Reader uses the ProcessPrng API.
// On JS/Wasm, Reader uses the Web Crypto API.
// On WASIP1/Wasm, Reader uses random_get from wasi_snapshot_preview1.
var Reader io.Reader
diff --git a/contrib/go/_std_1.21/src/crypto/rand/rand_windows.go b/contrib/go/_std_1.21/src/crypto/rand/rand_windows.go
index 6c0655c72b..7380f1f0f1 100644
--- a/contrib/go/_std_1.21/src/crypto/rand/rand_windows.go
+++ b/contrib/go/_std_1.21/src/crypto/rand/rand_windows.go
@@ -15,11 +15,8 @@ func init() { Reader = &rngReader{} }
type rngReader struct{}
-func (r *rngReader) Read(b []byte) (n int, err error) {
- // RtlGenRandom only returns 1<<32-1 bytes at a time. We only read at
- // most 1<<31-1 bytes at a time so that this works the same on 32-bit
- // and 64-bit systems.
- if err := batched(windows.RtlGenRandom, 1<<31-1)(b); err != nil {
+func (r *rngReader) Read(b []byte) (int, error) {
+ if err := windows.ProcessPrng(b); err != nil {
return 0, err
}
return len(b), nil
diff --git a/contrib/go/_std_1.21/src/crypto/tls/cipher_suites.go b/contrib/go/_std_1.21/src/crypto/tls/cipher_suites.go
index 589e8b6faf..fd538da0f7 100644
--- a/contrib/go/_std_1.21/src/crypto/tls/cipher_suites.go
+++ b/contrib/go/_std_1.21/src/crypto/tls/cipher_suites.go
@@ -532,7 +532,13 @@ func aeadAESGCMTLS13(key, nonceMask []byte) aead {
if err != nil {
panic(err)
}
- aead, err := cipher.NewGCM(aes)
+ var aead cipher.AEAD
+ if boring.Enabled {
+ aead, err = boring.NewGCMTLS13(aes)
+ } else {
+ boring.Unreachable()
+ aead, err = cipher.NewGCM(aes)
+ }
if err != nil {
panic(err)
}
diff --git a/contrib/go/_std_1.21/src/crypto/tls/handshake_client.go b/contrib/go/_std_1.21/src/crypto/tls/handshake_client.go
index 4649f36dea..e81764a912 100644
--- a/contrib/go/_std_1.21/src/crypto/tls/handshake_client.go
+++ b/contrib/go/_std_1.21/src/crypto/tls/handshake_client.go
@@ -139,7 +139,9 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, *ecdh.PrivateKey, error) {
if len(hello.supportedVersions) == 1 {
hello.cipherSuites = nil
}
- if hasAESGCMHardwareSupport {
+ if needFIPS() {
+ hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13FIPS...)
+ } else if hasAESGCMHardwareSupport {
hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13...)
} else {
hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13NoAES...)
diff --git a/contrib/go/_std_1.21/src/crypto/tls/handshake_client_tls13.go b/contrib/go/_std_1.21/src/crypto/tls/handshake_client_tls13.go
index 2f59f6888c..a84cede1b0 100644
--- a/contrib/go/_std_1.21/src/crypto/tls/handshake_client_tls13.go
+++ b/contrib/go/_std_1.21/src/crypto/tls/handshake_client_tls13.go
@@ -41,10 +41,6 @@ type clientHandshakeStateTLS13 struct {
func (hs *clientHandshakeStateTLS13) handshake() error {
c := hs.c
- if needFIPS() {
- return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode")
- }
-
// The server must not select TLS 1.3 in a renegotiation. See RFC 8446,
// sections 4.1.2 and 4.1.3.
if c.handshakes > 0 {
diff --git a/contrib/go/_std_1.21/src/crypto/tls/handshake_server_tls13.go b/contrib/go/_std_1.21/src/crypto/tls/handshake_server_tls13.go
index 07b1a3851e..dd5298b728 100644
--- a/contrib/go/_std_1.21/src/crypto/tls/handshake_server_tls13.go
+++ b/contrib/go/_std_1.21/src/crypto/tls/handshake_server_tls13.go
@@ -45,10 +45,6 @@ type serverHandshakeStateTLS13 struct {
func (hs *serverHandshakeStateTLS13) handshake() error {
c := hs.c
- if needFIPS() {
- return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode")
- }
-
// For an overview of the TLS 1.3 handshake, see RFC 8446, Section 2.
if err := hs.processClientHello(); err != nil {
return err
@@ -163,6 +159,9 @@ func (hs *serverHandshakeStateTLS13) processClientHello() error {
if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) {
preferenceList = defaultCipherSuitesTLS13NoAES
}
+ if needFIPS() {
+ preferenceList = defaultCipherSuitesTLS13FIPS
+ }
for _, suiteID := range preferenceList {
hs.suite = mutualCipherSuiteTLS13(hs.clientHello.cipherSuites, suiteID)
if hs.suite != nil {
diff --git a/contrib/go/_std_1.21/src/crypto/tls/notboring.go b/contrib/go/_std_1.21/src/crypto/tls/notboring.go
index 7d85b39c59..edccb44d87 100644
--- a/contrib/go/_std_1.21/src/crypto/tls/notboring.go
+++ b/contrib/go/_std_1.21/src/crypto/tls/notboring.go
@@ -18,3 +18,5 @@ func fipsCurvePreferences(c *Config) []CurveID { panic("fipsCurvePreferences") }
func fipsCipherSuites(c *Config) []uint16 { panic("fipsCipherSuites") }
var fipsSupportedSignatureAlgorithms []SignatureScheme
+
+var defaultCipherSuitesTLS13FIPS []uint16
diff --git a/contrib/go/_std_1.21/src/go/types/call.go b/contrib/go/_std_1.21/src/go/types/call.go
index 8a3cec7309..f00290a74f 100644
--- a/contrib/go/_std_1.21/src/go/types/call.go
+++ b/contrib/go/_std_1.21/src/go/types/call.go
@@ -571,6 +571,14 @@ func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, targs []Type
for i, arg := range args {
// generic arguments cannot have a defined (*Named) type - no need for underlying type below
if asig, _ := arg.typ.(*Signature); asig != nil && asig.TypeParams().Len() > 0 {
+ // The argument type is a generic function signature. This type is
+ // pointer-identical with (it's copied from) the type of the generic
+ // function argument and thus the function object.
+ // Before we change the type (type parameter renaming, below), make
+ // a clone of it as otherwise we implicitly modify the object's type
+ // (go.dev/issues/63260).
+ clone := *asig
+ asig = &clone
// Rename type parameters for cases like f(g, g); this gives each
// generic function argument a unique type identity (go.dev/issues/59956).
// TODO(gri) Consider only doing this if a function argument appears
diff --git a/contrib/go/_std_1.21/src/internal/buildcfg/zbootstrap.go b/contrib/go/_std_1.21/src/internal/buildcfg/zbootstrap.go
index f5b4f3486b..b83b3ead43 100644
--- a/contrib/go/_std_1.21/src/internal/buildcfg/zbootstrap.go
+++ b/contrib/go/_std_1.21/src/internal/buildcfg/zbootstrap.go
@@ -13,6 +13,6 @@ const defaultGOPPC64 = `power8`
const defaultGOEXPERIMENT = ``
const defaultGO_EXTLINK_ENABLED = ``
const defaultGO_LDSO = ``
-const version = `go1.21.3`
+const version = `go1.21.6`
const defaultGOOS = runtime.GOOS
const defaultGOARCH = runtime.GOARCH
diff --git a/contrib/go/_std_1.21/src/internal/poll/splice_linux.go b/contrib/go/_std_1.21/src/internal/poll/splice_linux.go
index 9505c5dcfc..72cca34fe4 100644
--- a/contrib/go/_std_1.21/src/internal/poll/splice_linux.go
+++ b/contrib/go/_std_1.21/src/internal/poll/splice_linux.go
@@ -13,6 +13,12 @@ import (
)
const (
+ // spliceNonblock doesn't make the splice itself necessarily nonblocking
+ // (because the actual file descriptors that are spliced from/to may block
+ // unless they have the O_NONBLOCK flag set), but it makes the splice pipe
+ // operations nonblocking.
+ spliceNonblock = 0x2
+
// maxSpliceSize is the maximum amount of data Splice asks
// the kernel to move in a single call to splice(2).
// We use 1MB as Splice writes data through a pipe, and 1MB is the default maximum pipe buffer size,
@@ -89,7 +95,11 @@ func spliceDrain(pipefd int, sock *FD, max int) (int, error) {
return 0, err
}
for {
- n, err := splice(pipefd, sock.Sysfd, max, 0)
+ // In theory calling splice(2) with SPLICE_F_NONBLOCK could end up an infinite loop here,
+ // because it could return EAGAIN ceaselessly when the write end of the pipe is full,
+ // but this shouldn't be a concern here, since the pipe buffer must be sufficient for
+ // this data transmission on the basis of the workflow in Splice.
+ n, err := splice(pipefd, sock.Sysfd, max, spliceNonblock)
if err == syscall.EINTR {
continue
}
@@ -127,7 +137,14 @@ func splicePump(sock *FD, pipefd int, inPipe int) (int, error) {
}
written := 0
for inPipe > 0 {
- n, err := splice(sock.Sysfd, pipefd, inPipe, 0)
+ // In theory calling splice(2) with SPLICE_F_NONBLOCK could end up an infinite loop here,
+ // because it could return EAGAIN ceaselessly when the read end of the pipe is empty,
+ // but this shouldn't be a concern here, since the pipe buffer must contain inPipe size of
+ // data on the basis of the workflow in Splice.
+ n, err := splice(sock.Sysfd, pipefd, inPipe, spliceNonblock)
+ if err == syscall.EINTR {
+ continue
+ }
// Here, the condition n == 0 && err == nil should never be
// observed, since Splice controls the write side of the pipe.
if n > 0 {
diff --git a/contrib/go/_std_1.21/src/internal/safefilepath/path_windows.go b/contrib/go/_std_1.21/src/internal/safefilepath/path_windows.go
index 909c150edc..7cfd6ce2ea 100644
--- a/contrib/go/_std_1.21/src/internal/safefilepath/path_windows.go
+++ b/contrib/go/_std_1.21/src/internal/safefilepath/path_windows.go
@@ -20,15 +20,10 @@ func fromFS(path string) (string, error) {
for p := path; p != ""; {
// Find the next path element.
i := 0
- dot := -1
for i < len(p) && p[i] != '/' {
switch p[i] {
case 0, '\\', ':':
return "", errInvalidPath
- case '.':
- if dot < 0 {
- dot = i
- }
}
i++
}
@@ -39,22 +34,8 @@ func fromFS(path string) (string, error) {
} else {
p = ""
}
- // Trim the extension and look for a reserved name.
- base := part
- if dot >= 0 {
- base = part[:dot]
- }
- if isReservedName(base) {
- if dot < 0 {
- return "", errInvalidPath
- }
- // The path element is a reserved name with an extension.
- // Some Windows versions consider this a reserved name,
- // while others do not. Use FullPath to see if the name is
- // reserved.
- if p, _ := syscall.FullPath(part); len(p) >= 4 && p[:4] == `\\.\` {
- return "", errInvalidPath
- }
+ if IsReservedName(part) {
+ return "", errInvalidPath
}
}
if containsSlash {
@@ -70,23 +51,88 @@ func fromFS(path string) (string, error) {
return path, nil
}
-// isReservedName reports if name is a Windows reserved device name.
+// IsReservedName reports if name is a Windows reserved device name.
// It does not detect names with an extension, which are also reserved on some Windows versions.
//
// For details, search for PRN in
// https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file.
-func isReservedName(name string) bool {
- if 3 <= len(name) && len(name) <= 4 {
+func IsReservedName(name string) bool {
+ // Device names can have arbitrary trailing characters following a dot or colon.
+ base := name
+ for i := 0; i < len(base); i++ {
+ switch base[i] {
+ case ':', '.':
+ base = base[:i]
+ }
+ }
+ // Trailing spaces in the last path element are ignored.
+ for len(base) > 0 && base[len(base)-1] == ' ' {
+ base = base[:len(base)-1]
+ }
+ if !isReservedBaseName(base) {
+ return false
+ }
+ if len(base) == len(name) {
+ return true
+ }
+ // The path element is a reserved name with an extension.
+ // Some Windows versions consider this a reserved name,
+ // while others do not. Use FullPath to see if the name is
+ // reserved.
+ if p, _ := syscall.FullPath(name); len(p) >= 4 && p[:4] == `\\.\` {
+ return true
+ }
+ return false
+}
+
+func isReservedBaseName(name string) bool {
+ if len(name) == 3 {
switch string([]byte{toUpper(name[0]), toUpper(name[1]), toUpper(name[2])}) {
case "CON", "PRN", "AUX", "NUL":
- return len(name) == 3
+ return true
+ }
+ }
+ if len(name) >= 4 {
+ switch string([]byte{toUpper(name[0]), toUpper(name[1]), toUpper(name[2])}) {
case "COM", "LPT":
- return len(name) == 4 && '1' <= name[3] && name[3] <= '9'
+ if len(name) == 4 && '1' <= name[3] && name[3] <= '9' {
+ return true
+ }
+ // Superscript ¹, ², and ³ are considered numbers as well.
+ switch name[3:] {
+ case "\u00b2", "\u00b3", "\u00b9":
+ return true
+ }
+ return false
}
}
+
+ // Passing CONIN$ or CONOUT$ to CreateFile opens a console handle.
+ // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea#consoles
+ //
+ // While CONIN$ and CONOUT$ aren't documented as being files,
+ // they behave the same as CON. For example, ./CONIN$ also opens the console input.
+ if len(name) == 6 && name[5] == '$' && equalFold(name, "CONIN$") {
+ return true
+ }
+ if len(name) == 7 && name[6] == '$' && equalFold(name, "CONOUT$") {
+ return true
+ }
return false
}
+func equalFold(a, b string) bool {
+ if len(a) != len(b) {
+ return false
+ }
+ for i := 0; i < len(a); i++ {
+ if toUpper(a[i]) != toUpper(b[i]) {
+ return false
+ }
+ }
+ return true
+}
+
func toUpper(c byte) byte {
if 'a' <= c && c <= 'z' {
return c - ('a' - 'A')
diff --git a/contrib/go/_std_1.21/src/internal/syscall/windows/reparse_windows.go b/contrib/go/_std_1.21/src/internal/syscall/windows/reparse_windows.go
index 6e111392f0..6caf47e867 100644
--- a/contrib/go/_std_1.21/src/internal/syscall/windows/reparse_windows.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/reparse_windows.go
@@ -12,6 +12,7 @@ import (
const (
FSCTL_SET_REPARSE_POINT = 0x000900A4
IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003
+ IO_REPARSE_TAG_DEDUP = 0x80000013
SYMLINK_FLAG_RELATIVE = 1
)
diff --git a/contrib/go/_std_1.21/src/internal/syscall/windows/syscall_windows.go b/contrib/go/_std_1.21/src/internal/syscall/windows/syscall_windows.go
index 892b878d16..e9390b07cd 100644
--- a/contrib/go/_std_1.21/src/internal/syscall/windows/syscall_windows.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/syscall_windows.go
@@ -373,7 +373,7 @@ func ErrorLoadingGetTempPath2() error {
//sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock
//sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) = kernel32.CreateEventW
-//sys RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036
+//sys ProcessPrng(buf []byte) (err error) = bcryptprimitives.ProcessPrng
//sys RtlLookupFunctionEntry(pc uintptr, baseAddress *uintptr, table *byte) (ret uintptr) = kernel32.RtlLookupFunctionEntry
//sys RtlVirtualUnwind(handlerType uint32, baseAddress uintptr, pc uintptr, entry uintptr, ctxt uintptr, data *uintptr, frame *uintptr, ctxptrs *byte) (ret uintptr) = kernel32.RtlVirtualUnwind
diff --git a/contrib/go/_std_1.21/src/internal/syscall/windows/zsyscall_windows.go b/contrib/go/_std_1.21/src/internal/syscall/windows/zsyscall_windows.go
index a5c246b773..26ec290e02 100644
--- a/contrib/go/_std_1.21/src/internal/syscall/windows/zsyscall_windows.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/zsyscall_windows.go
@@ -37,13 +37,14 @@ func errnoErr(e syscall.Errno) error {
}
var (
- modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll"))
- modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll"))
- modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll"))
- modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll"))
- modpsapi = syscall.NewLazyDLL(sysdll.Add("psapi.dll"))
- moduserenv = syscall.NewLazyDLL(sysdll.Add("userenv.dll"))
- modws2_32 = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll"))
+ modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll"))
+ modbcryptprimitives = syscall.NewLazyDLL(sysdll.Add("bcryptprimitives.dll"))
+ modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll"))
+ modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll"))
+ modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll"))
+ modpsapi = syscall.NewLazyDLL(sysdll.Add("psapi.dll"))
+ moduserenv = syscall.NewLazyDLL(sysdll.Add("userenv.dll"))
+ modws2_32 = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll"))
procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
procDuplicateTokenEx = modadvapi32.NewProc("DuplicateTokenEx")
@@ -52,7 +53,7 @@ var (
procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken")
procRevertToSelf = modadvapi32.NewProc("RevertToSelf")
procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation")
- procSystemFunction036 = modadvapi32.NewProc("SystemFunction036")
+ procProcessPrng = modbcryptprimitives.NewProc("ProcessPrng")
procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses")
procCreateEventW = modkernel32.NewProc("CreateEventW")
procGetACP = modkernel32.NewProc("GetACP")
@@ -148,12 +149,12 @@ func SetTokenInformation(tokenHandle syscall.Token, tokenInformationClass uint32
return
}
-func RtlGenRandom(buf []byte) (err error) {
+func ProcessPrng(buf []byte) (err error) {
var _p0 *byte
if len(buf) > 0 {
_p0 = &buf[0]
}
- r1, _, e1 := syscall.Syscall(procSystemFunction036.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0)
+ r1, _, e1 := syscall.Syscall(procProcessPrng.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0)
if r1 == 0 {
err = errnoErr(e1)
}
diff --git a/contrib/go/_std_1.21/src/net/http/h2_bundle.go b/contrib/go/_std_1.21/src/net/http/h2_bundle.go
index 9cd6a3490f..dd59e1f4f2 100644
--- a/contrib/go/_std_1.21/src/net/http/h2_bundle.go
+++ b/contrib/go/_std_1.21/src/net/http/h2_bundle.go
@@ -7012,6 +7012,7 @@ func (sc *http2serverConn) startPush(msg *http2startPushRequest) {
panic(fmt.Sprintf("newWriterAndRequestNoBody(%+v): %v", msg.url, err))
}
+ sc.curHandlers++
go sc.runHandler(rw, req, sc.handler.ServeHTTP)
return promisedID, nil
}
diff --git a/contrib/go/_std_1.21/src/net/http/internal/chunked.go b/contrib/go/_std_1.21/src/net/http/internal/chunked.go
index 5a174415dc..aad8e5aa09 100644
--- a/contrib/go/_std_1.21/src/net/http/internal/chunked.go
+++ b/contrib/go/_std_1.21/src/net/http/internal/chunked.go
@@ -39,7 +39,8 @@ type chunkedReader struct {
n uint64 // unread bytes in chunk
err error
buf [2]byte
- checkEnd bool // whether need to check for \r\n chunk footer
+ checkEnd bool // whether need to check for \r\n chunk footer
+ excess int64 // "excessive" chunk overhead, for malicious sender detection
}
func (cr *chunkedReader) beginChunk() {
@@ -49,10 +50,36 @@ func (cr *chunkedReader) beginChunk() {
if cr.err != nil {
return
}
+ cr.excess += int64(len(line)) + 2 // header, plus \r\n after the chunk data
+ line = trimTrailingWhitespace(line)
+ line, cr.err = removeChunkExtension(line)
+ if cr.err != nil {
+ return
+ }
cr.n, cr.err = parseHexUint(line)
if cr.err != nil {
return
}
+ // A sender who sends one byte per chunk will send 5 bytes of overhead
+ // for every byte of data. ("1\r\nX\r\n" to send "X".)
+ // We want to allow this, since streaming a byte at a time can be legitimate.
+ //
+ // A sender can use chunk extensions to add arbitrary amounts of additional
+ // data per byte read. ("1;very long extension\r\nX\r\n" to send "X".)
+ // We don't want to disallow extensions (although we discard them),
+ // but we also don't want to allow a sender to reduce the signal/noise ratio
+ // arbitrarily.
+ //
+ // We track the amount of excess overhead read,
+ // and produce an error if it grows too large.
+ //
+ // Currently, we say that we're willing to accept 16 bytes of overhead per chunk,
+ // plus twice the amount of real data in the chunk.
+ cr.excess -= 16 + (2 * int64(cr.n))
+ cr.excess = max(cr.excess, 0)
+ if cr.excess > 16*1024 {
+ cr.err = errors.New("chunked encoding contains too much non-data")
+ }
if cr.n == 0 {
cr.err = io.EOF
}
@@ -140,11 +167,6 @@ func readChunkLine(b *bufio.Reader) ([]byte, error) {
if len(p) >= maxLineLength {
return nil, ErrLineTooLong
}
- p = trimTrailingWhitespace(p)
- p, err = removeChunkExtension(p)
- if err != nil {
- return nil, err
- }
return p, nil
}
diff --git a/contrib/go/_std_1.21/src/os/rlimit.go b/contrib/go/_std_1.21/src/os/rlimit.go
deleted file mode 100644
index e0d0ef9b62..0000000000
--- a/contrib/go/_std_1.21/src/os/rlimit.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build unix
-
-package os
-
-import "syscall"
-
-// Some systems set an artificially low soft limit on open file count, for compatibility
-// with code that uses select and its hard-coded maximum file descriptor
-// (limited by the size of fd_set).
-//
-// Go does not use select, so it should not be subject to these limits.
-// On some systems the limit is 256, which is very easy to run into,
-// even in simple programs like gofmt when they parallelize walking
-// a file tree.
-//
-// After a long discussion on go.dev/issue/46279, we decided the
-// best approach was for Go to raise the limit unconditionally for itself,
-// and then leave old software to set the limit back as needed.
-// Code that really wants Go to leave the limit alone can set the hard limit,
-// which Go of course has no choice but to respect.
-func init() {
- var lim syscall.Rlimit
- if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &lim); err == nil && lim.Cur != lim.Max {
- lim.Cur = lim.Max
- adjustFileLimit(&lim)
- syscall.Setrlimit(syscall.RLIMIT_NOFILE, &lim)
- }
-}
diff --git a/contrib/go/_std_1.21/src/os/rlimit_darwin.go b/contrib/go/_std_1.21/src/os/rlimit_darwin.go
deleted file mode 100644
index b28982a83a..0000000000
--- a/contrib/go/_std_1.21/src/os/rlimit_darwin.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build darwin
-
-package os
-
-import "syscall"
-
-// adjustFileLimit adds per-OS limitations on the Rlimit used for RLIMIT_NOFILE. See rlimit.go.
-func adjustFileLimit(lim *syscall.Rlimit) {
- // On older macOS, setrlimit(RLIMIT_NOFILE, lim) with lim.Cur = infinity fails.
- // Set to the value of kern.maxfilesperproc instead.
- n, err := syscall.SysctlUint32("kern.maxfilesperproc")
- if err != nil {
- return
- }
- if lim.Cur > uint64(n) {
- lim.Cur = uint64(n)
- }
-}
diff --git a/contrib/go/_std_1.21/src/os/rlimit_stub.go b/contrib/go/_std_1.21/src/os/rlimit_stub.go
deleted file mode 100644
index cbe28400c5..0000000000
--- a/contrib/go/_std_1.21/src/os/rlimit_stub.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build aix || dragonfly || freebsd || linux || netbsd || openbsd || solaris
-
-package os
-
-import "syscall"
-
-// adjustFileLimit adds per-OS limitations on the Rlimit used for RLIMIT_NOFILE. See rlimit.go.
-func adjustFileLimit(lim *syscall.Rlimit) {}
diff --git a/contrib/go/_std_1.21/src/os/types_windows.go b/contrib/go/_std_1.21/src/os/types_windows.go
index 9a3d508783..effb0148df 100644
--- a/contrib/go/_std_1.21/src/os/types_windows.go
+++ b/contrib/go/_std_1.21/src/os/types_windows.go
@@ -141,7 +141,23 @@ func (fs *fileStat) Mode() (m FileMode) {
m |= ModeDevice | ModeCharDevice
}
if fs.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0 && m&ModeType == 0 {
- m |= ModeIrregular
+ if fs.ReparseTag == windows.IO_REPARSE_TAG_DEDUP {
+ // If the Data Deduplication service is enabled on Windows Server, its
+ // Optimization job may convert regular files to IO_REPARSE_TAG_DEDUP
+ // whenever that job runs.
+ //
+ // However, DEDUP reparse points remain similar in most respects to
+ // regular files: they continue to support random-access reads and writes
+ // of persistent data, and they shouldn't add unexpected latency or
+ // unavailability in the way that a network filesystem might.
+ //
+ // Go programs may use ModeIrregular to filter out unusual files (such as
+ // raw device files on Linux, POSIX FIFO special files, and so on), so
+ // to avoid files changing unpredictably from regular to irregular we will
+ // consider DEDUP files to be close enough to regular to treat as such.
+ } else {
+ m |= ModeIrregular
+ }
}
return m
}
diff --git a/contrib/go/_std_1.21/src/os/ya.make b/contrib/go/_std_1.21/src/os/ya.make
index dc812bdd07..8c4c417f82 100644
--- a/contrib/go/_std_1.21/src/os/ya.make
+++ b/contrib/go/_std_1.21/src/os/ya.make
@@ -29,8 +29,6 @@ ELSEIF (OS_LINUX AND ARCH_X86_64)
rawconn.go
readfrom_linux.go
removeall_at.go
- rlimit.go
- rlimit_stub.go
stat.go
stat_linux.go
stat_unix.go
@@ -71,8 +69,6 @@ ELSEIF (OS_LINUX AND ARCH_ARM64)
rawconn.go
readfrom_linux.go
removeall_at.go
- rlimit.go
- rlimit_stub.go
stat.go
stat_linux.go
stat_unix.go
@@ -113,8 +109,6 @@ ELSEIF (OS_LINUX AND ARCH_AARCH64)
rawconn.go
readfrom_linux.go
removeall_at.go
- rlimit.go
- rlimit_stub.go
stat.go
stat_linux.go
stat_unix.go
@@ -154,8 +148,6 @@ ELSEIF (OS_DARWIN AND ARCH_X86_64)
rawconn.go
readfrom_stub.go
removeall_at.go
- rlimit.go
- rlimit_darwin.go
stat.go
stat_darwin.go
stat_unix.go
@@ -195,8 +187,6 @@ ELSEIF (OS_DARWIN AND ARCH_ARM64)
rawconn.go
readfrom_stub.go
removeall_at.go
- rlimit.go
- rlimit_darwin.go
stat.go
stat_darwin.go
stat_unix.go
@@ -236,8 +226,6 @@ ELSEIF (OS_DARWIN AND ARCH_AARCH64)
rawconn.go
readfrom_stub.go
removeall_at.go
- rlimit.go
- rlimit_darwin.go
stat.go
stat_darwin.go
stat_unix.go
diff --git a/contrib/go/_std_1.21/src/path/filepath/path.go b/contrib/go/_std_1.21/src/path/filepath/path.go
index ca1d8b3116..3bf3ff6b89 100644
--- a/contrib/go/_std_1.21/src/path/filepath/path.go
+++ b/contrib/go/_std_1.21/src/path/filepath/path.go
@@ -15,7 +15,6 @@ import (
"errors"
"io/fs"
"os"
- "runtime"
"sort"
"strings"
)
@@ -167,21 +166,7 @@ func Clean(path string) string {
out.append('.')
}
- if runtime.GOOS == "windows" && out.volLen == 0 && out.buf != nil {
- // If a ':' appears in the path element at the start of a Windows path,
- // insert a .\ at the beginning to avoid converting relative paths
- // like a/../c: into c:.
- for _, c := range out.buf {
- if os.IsPathSeparator(c) {
- break
- }
- if c == ':' {
- out.prepend('.', Separator)
- break
- }
- }
- }
-
+ postClean(&out) // avoid creating absolute paths on Windows
return FromSlash(out.string())
}
diff --git a/contrib/go/_std_1.21/src/path/filepath/path_nonwindows.go b/contrib/go/_std_1.21/src/path/filepath/path_nonwindows.go
new file mode 100644
index 0000000000..db69f0228b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/path/filepath/path_nonwindows.go
@@ -0,0 +1,9 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !windows
+
+package filepath
+
+func postClean(out *lazybuf) {}
diff --git a/contrib/go/_std_1.21/src/path/filepath/path_windows.go b/contrib/go/_std_1.21/src/path/filepath/path_windows.go
index 4dca9e0f55..eacab0e5ce 100644
--- a/contrib/go/_std_1.21/src/path/filepath/path_windows.go
+++ b/contrib/go/_std_1.21/src/path/filepath/path_windows.go
@@ -5,6 +5,8 @@
package filepath
import (
+ "internal/safefilepath"
+ "os"
"strings"
"syscall"
)
@@ -20,34 +22,6 @@ func toUpper(c byte) byte {
return c
}
-// isReservedName reports if name is a Windows reserved device name or a console handle.
-// It does not detect names with an extension, which are also reserved on some Windows versions.
-//
-// For details, search for PRN in
-// https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file.
-func isReservedName(name string) bool {
- if 3 <= len(name) && len(name) <= 4 {
- switch string([]byte{toUpper(name[0]), toUpper(name[1]), toUpper(name[2])}) {
- case "CON", "PRN", "AUX", "NUL":
- return len(name) == 3
- case "COM", "LPT":
- return len(name) == 4 && '1' <= name[3] && name[3] <= '9'
- }
- }
- // Passing CONIN$ or CONOUT$ to CreateFile opens a console handle.
- // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea#consoles
- //
- // While CONIN$ and CONOUT$ aren't documented as being files,
- // they behave the same as CON. For example, ./CONIN$ also opens the console input.
- if len(name) == 6 && name[5] == '$' && strings.EqualFold(name, "CONIN$") {
- return true
- }
- if len(name) == 7 && name[6] == '$' && strings.EqualFold(name, "CONOUT$") {
- return true
- }
- return false
-}
-
func isLocal(path string) bool {
if path == "" {
return false
@@ -68,25 +42,8 @@ func isLocal(path string) bool {
if part == "." || part == ".." {
hasDots = true
}
- // Trim the extension and look for a reserved name.
- base, _, hasExt := strings.Cut(part, ".")
- if isReservedName(base) {
- if !hasExt {
- return false
- }
- // The path element is a reserved name with an extension. Some Windows
- // versions consider this a reserved name, while others do not. Use
- // FullPath to see if the name is reserved.
- //
- // FullPath will convert references to reserved device names to their
- // canonical form: \\.\${DEVICE_NAME}
- //
- // FullPath does not perform this conversion for paths which contain
- // a reserved device name anywhere other than in the last element,
- // so check the part rather than the full path.
- if p, _ := syscall.FullPath(part); len(p) >= 4 && p[:4] == `\\.\` {
- return false
- }
+ if safefilepath.IsReservedName(part) {
+ return false
}
}
if hasDots {
@@ -118,40 +75,93 @@ func IsAbs(path string) (b bool) {
// volumeNameLen returns length of the leading volume name on Windows.
// It returns 0 elsewhere.
//
-// See: https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats
+// See:
+// https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats
+// https://googleprojectzero.blogspot.com/2016/02/the-definitive-guide-on-win32-to-nt.html
func volumeNameLen(path string) int {
- if len(path) < 2 {
- return 0
- }
- // with drive letter
- c := path[0]
- if path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {
+ switch {
+ case len(path) >= 2 && path[1] == ':':
+ // Path starts with a drive letter.
+ //
+ // Not all Windows functions necessarily enforce the requirement that
+ // drive letters be in the set A-Z, and we don't try to here.
+ //
+ // We don't handle the case of a path starting with a non-ASCII character,
+ // in which case the "drive letter" might be multiple bytes long.
return 2
- }
- // UNC and DOS device paths start with two slashes.
- if !isSlash(path[0]) || !isSlash(path[1]) {
+
+ case len(path) == 0 || !isSlash(path[0]):
+ // Path does not have a volume component.
return 0
+
+ case pathHasPrefixFold(path, `\\.\UNC`):
+ // We're going to treat the UNC host and share as part of the volume
+ // prefix for historical reasons, but this isn't really principled;
+ // Windows's own GetFullPathName will happily remove the first
+ // component of the path in this space, converting
+ // \\.\unc\a\b\..\c into \\.\unc\a\c.
+ return uncLen(path, len(`\\.\UNC\`))
+
+ case pathHasPrefixFold(path, `\\.`) ||
+ pathHasPrefixFold(path, `\\?`) || pathHasPrefixFold(path, `\??`):
+ // Path starts with \\.\, and is a Local Device path; or
+ // path starts with \\?\ or \??\ and is a Root Local Device path.
+ //
+ // We treat the next component after the \\.\ prefix as
+ // part of the volume name, which means Clean(`\\?\c:\`)
+ // won't remove the trailing \. (See #64028.)
+ if len(path) == 3 {
+ return 3 // exactly \\.
+ }
+ _, rest, ok := cutPath(path[4:])
+ if !ok {
+ return len(path)
+ }
+ return len(path) - len(rest) - 1
+
+ case len(path) >= 2 && isSlash(path[1]):
+ // Path starts with \\, and is a UNC path.
+ return uncLen(path, 2)
}
- rest := path[2:]
- p1, rest, _ := cutPath(rest)
- p2, rest, ok := cutPath(rest)
- if !ok {
- return len(path)
+ return 0
+}
+
+// pathHasPrefixFold tests whether the path s begins with prefix,
+// ignoring case and treating all path separators as equivalent.
+// If s is longer than prefix, then s[len(prefix)] must be a path separator.
+func pathHasPrefixFold(s, prefix string) bool {
+ if len(s) < len(prefix) {
+ return false
}
- if p1 != "." && p1 != "?" {
- // This is a UNC path: \\${HOST}\${SHARE}\
- return len(path) - len(rest) - 1
+ for i := 0; i < len(prefix); i++ {
+ if isSlash(prefix[i]) {
+ if !isSlash(s[i]) {
+ return false
+ }
+ } else if toUpper(prefix[i]) != toUpper(s[i]) {
+ return false
+ }
}
- // This is a DOS device path.
- if len(p2) == 3 && toUpper(p2[0]) == 'U' && toUpper(p2[1]) == 'N' && toUpper(p2[2]) == 'C' {
- // This is a DOS device path that links to a UNC: \\.\UNC\${HOST}\${SHARE}\
- _, rest, _ = cutPath(rest) // host
- _, rest, ok = cutPath(rest) // share
- if !ok {
- return len(path)
+ if len(s) > len(prefix) && !isSlash(s[len(prefix)]) {
+ return false
+ }
+ return true
+}
+
+// uncLen returns the length of the volume prefix of a UNC path.
+// prefixLen is the prefix prior to the start of the UNC host;
+// for example, for "//host/share", the prefixLen is len("//")==2.
+func uncLen(path string, prefixLen int) int {
+ count := 0
+ for i := prefixLen; i < len(path); i++ {
+ if isSlash(path[i]) {
+ count++
+ if count == 2 {
+ return i
+ }
}
}
- return len(path) - len(rest) - 1
+ return len(path)
}
// cutPath slices path around the first path separator.
@@ -238,6 +248,12 @@ func join(elem []string) string {
for len(e) > 0 && isSlash(e[0]) {
e = e[1:]
}
+ // If the path is \ and the next path element is ??,
+ // add an extra .\ to create \.\?? rather than \??\
+ // (a Root Local Device path).
+ if b.Len() == 1 && pathHasPrefixFold(e, "??") {
+ b.WriteString(`.\`)
+ }
case lastChar == ':':
// If the path ends in a colon, keep the path relative to the current directory
// on a drive and don't add a separator. Preserve leading slashes in the next
@@ -304,3 +320,29 @@ func isUNC(path string) bool {
func sameWord(a, b string) bool {
return strings.EqualFold(a, b)
}
+
+// postClean adjusts the results of Clean to avoid turning a relative path
+// into an absolute or rooted one.
+func postClean(out *lazybuf) {
+ if out.volLen != 0 || out.buf == nil {
+ return
+ }
+ // If a ':' appears in the path element at the start of a path,
+ // insert a .\ at the beginning to avoid converting relative paths
+ // like a/../c: into c:.
+ for _, c := range out.buf {
+ if os.IsPathSeparator(c) {
+ break
+ }
+ if c == ':' {
+ out.prepend('.', Separator)
+ return
+ }
+ }
+ // If a path begins with \??\, insert a \. at the beginning
+ // to avoid converting paths like \a\..\??\c:\x into \??\c:\x
+ // (equivalent to c:\x).
+ if len(out.buf) >= 3 && os.IsPathSeparator(out.buf[0]) && out.buf[1] == '?' && out.buf[2] == '?' {
+ out.prepend(Separator, '.')
+ }
+}
diff --git a/contrib/go/_std_1.21/src/path/filepath/ya.make b/contrib/go/_std_1.21/src/path/filepath/ya.make
index 4b6a0333a7..9d04957bac 100644
--- a/contrib/go/_std_1.21/src/path/filepath/ya.make
+++ b/contrib/go/_std_1.21/src/path/filepath/ya.make
@@ -6,6 +6,7 @@ ELSEIF (OS_LINUX AND ARCH_X86_64)
SRCS(
match.go
path.go
+ path_nonwindows.go
path_unix.go
symlink.go
symlink_unix.go
@@ -14,6 +15,7 @@ ELSEIF (OS_LINUX AND ARCH_ARM64)
SRCS(
match.go
path.go
+ path_nonwindows.go
path_unix.go
symlink.go
symlink_unix.go
@@ -22,6 +24,7 @@ ELSEIF (OS_LINUX AND ARCH_AARCH64)
SRCS(
match.go
path.go
+ path_nonwindows.go
path_unix.go
symlink.go
symlink_unix.go
@@ -30,6 +33,7 @@ ELSEIF (OS_DARWIN AND ARCH_X86_64)
SRCS(
match.go
path.go
+ path_nonwindows.go
path_unix.go
symlink.go
symlink_unix.go
@@ -38,6 +42,7 @@ ELSEIF (OS_DARWIN AND ARCH_ARM64)
SRCS(
match.go
path.go
+ path_nonwindows.go
path_unix.go
symlink.go
symlink_unix.go
@@ -46,6 +51,7 @@ ELSEIF (OS_DARWIN AND ARCH_AARCH64)
SRCS(
match.go
path.go
+ path_nonwindows.go
path_unix.go
symlink.go
symlink_unix.go
diff --git a/contrib/go/_std_1.21/src/runtime/cgo/asm_amd64.s b/contrib/go/_std_1.21/src/runtime/cgo/asm_amd64.s
index f254622f23..e319094a45 100644
--- a/contrib/go/_std_1.21/src/runtime/cgo/asm_amd64.s
+++ b/contrib/go/_std_1.21/src/runtime/cgo/asm_amd64.s
@@ -7,12 +7,17 @@
// Set the x_crosscall2_ptr C function pointer variable point to crosscall2.
// It's such a pointer chain: _crosscall2_ptr -> x_crosscall2_ptr -> crosscall2
+// Use a local trampoline, to avoid taking the address of a dynamically exported
+// function.
TEXT ·set_crosscall2(SB),NOSPLIT,$0-0
MOVQ _crosscall2_ptr(SB), AX
- MOVQ $crosscall2(SB), BX
+ MOVQ $crosscall2_trampoline<>(SB), BX
MOVQ BX, (AX)
RET
+TEXT crosscall2_trampoline<>(SB),NOSPLIT,$0-0
+ JMP crosscall2(SB)
+
// Called by C code generated by cmd/cgo.
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
// Saves C callee-saved registers and calls cgocallback with three arguments.
diff --git a/contrib/go/_std_1.21/src/runtime/cgo/asm_arm64.s b/contrib/go/_std_1.21/src/runtime/cgo/asm_arm64.s
index ce8909b492..5492dc142c 100644
--- a/contrib/go/_std_1.21/src/runtime/cgo/asm_arm64.s
+++ b/contrib/go/_std_1.21/src/runtime/cgo/asm_arm64.s
@@ -7,12 +7,17 @@
// Set the x_crosscall2_ptr C function pointer variable point to crosscall2.
// It's such a pointer chain: _crosscall2_ptr -> x_crosscall2_ptr -> crosscall2
+// Use a local trampoline, to avoid taking the address of a dynamically exported
+// function.
TEXT ·set_crosscall2(SB),NOSPLIT,$0-0
MOVD _crosscall2_ptr(SB), R1
- MOVD $crosscall2(SB), R2
+ MOVD $crosscall2_trampoline<>(SB), R2
MOVD R2, (R1)
RET
+TEXT crosscall2_trampoline<>(SB),NOSPLIT,$0-0
+ JMP crosscall2(SB)
+
// Called by C code generated by cmd/cgo.
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
// Saves C callee-saved registers and calls cgocallback with three arguments.
diff --git a/contrib/go/_std_1.21/src/runtime/extern.go b/contrib/go/_std_1.21/src/runtime/extern.go
index 26dcf0bd52..de4a0ca2da 100644
--- a/contrib/go/_std_1.21/src/runtime/extern.go
+++ b/contrib/go/_std_1.21/src/runtime/extern.go
@@ -55,6 +55,13 @@ It is a comma-separated list of name=val pairs setting these named variables:
cgocheck mode can be enabled using GOEXPERIMENT (which
requires a rebuild), see https://pkg.go.dev/internal/goexperiment for details.
+ disablethp: setting disablethp=1 on Linux disables transparent huge pages for the heap.
+ It has no effect on other platforms. disablethp is meant for compatibility with versions
+ of Go before 1.21, which stopped working around a Linux kernel default that can result
+ in significant memory overuse. See https://go.dev/issue/64332. This setting will be
+ removed in a future release, so operators should tweak their Linux configuration to suit
+ their needs before then. See https://go.dev/doc/gc-guide#Linux_transparent_huge_pages.
+
dontfreezetheworld: by default, the start of a fatal panic or throw
"freezes the world", preempting all threads to stop all running
goroutines, which makes it possible to traceback all goroutines, and
diff --git a/contrib/go/_std_1.21/src/runtime/malloc.go b/contrib/go/_std_1.21/src/runtime/malloc.go
index 44479cc2be..b2026ad0dc 100644
--- a/contrib/go/_std_1.21/src/runtime/malloc.go
+++ b/contrib/go/_std_1.21/src/runtime/malloc.go
@@ -853,6 +853,10 @@ retry:
//
// The heap lock must not be held over this operation, since it will briefly acquire
// the heap lock.
+//
+// Must be called on the system stack because it acquires the heap lock.
+//
+//go:systemstack
func (h *mheap) enableMetadataHugePages() {
// Enable huge pages for page structure.
h.pages.enableChunkHugePages()
diff --git a/contrib/go/_std_1.21/src/runtime/map.go b/contrib/go/_std_1.21/src/runtime/map.go
index 6b85681447..22aeb86847 100644
--- a/contrib/go/_std_1.21/src/runtime/map.go
+++ b/contrib/go/_std_1.21/src/runtime/map.go
@@ -1481,12 +1481,24 @@ func moveToBmap(t *maptype, h *hmap, dst *bmap, pos int, src *bmap) (*bmap, int)
dst.tophash[pos] = src.tophash[i]
if t.IndirectKey() {
- *(*unsafe.Pointer)(dstK) = *(*unsafe.Pointer)(srcK)
+ srcK = *(*unsafe.Pointer)(srcK)
+ if t.NeedKeyUpdate() {
+ kStore := newobject(t.Key)
+ typedmemmove(t.Key, kStore, srcK)
+ srcK = kStore
+ }
+ // Note: if NeedKeyUpdate is false, then the memory
+ // used to store the key is immutable, so we can share
+ // it between the original map and its clone.
+ *(*unsafe.Pointer)(dstK) = srcK
} else {
typedmemmove(t.Key, dstK, srcK)
}
if t.IndirectElem() {
- *(*unsafe.Pointer)(dstEle) = *(*unsafe.Pointer)(srcEle)
+ srcEle = *(*unsafe.Pointer)(srcEle)
+ eStore := newobject(t.Elem)
+ typedmemmove(t.Elem, eStore, srcEle)
+ *(*unsafe.Pointer)(dstEle) = eStore
} else {
typedmemmove(t.Elem, dstEle, srcEle)
}
@@ -1510,14 +1522,14 @@ func mapclone2(t *maptype, src *hmap) *hmap {
fatal("concurrent map clone and map write")
}
- if src.B == 0 {
+ if src.B == 0 && !(t.IndirectKey() && t.NeedKeyUpdate()) && !t.IndirectElem() {
+ // Quick copy for small maps.
dst.buckets = newobject(t.Bucket)
dst.count = src.count
typedmemmove(t.Bucket, dst.buckets, src.buckets)
return dst
}
- //src.B != 0
if dst.B == 0 {
dst.buckets = newobject(t.Bucket)
}
@@ -1565,6 +1577,8 @@ func mapclone2(t *maptype, src *hmap) *hmap {
continue
}
+ // oldB < dst.B, so a single source bucket may go to multiple destination buckets.
+ // Process entries one at a time.
for srcBmap != nil {
// move from oldBlucket to new bucket
for i := uintptr(0); i < bucketCnt; i++ {
diff --git a/contrib/go/_std_1.21/src/runtime/mem_linux.go b/contrib/go/_std_1.21/src/runtime/mem_linux.go
index c9823d3011..d63c38c209 100644
--- a/contrib/go/_std_1.21/src/runtime/mem_linux.go
+++ b/contrib/go/_std_1.21/src/runtime/mem_linux.go
@@ -170,4 +170,12 @@ func sysMapOS(v unsafe.Pointer, n uintptr) {
print("runtime: mmap(", v, ", ", n, ") returned ", p, ", ", err, "\n")
throw("runtime: cannot map pages in arena address space")
}
+
+ // Disable huge pages if the GODEBUG for it is set.
+ //
+ // Note that there are a few sysHugePage calls that can override this, but
+ // they're all for GC metadata.
+ if debug.disablethp != 0 {
+ sysNoHugePageOS(v, n)
+ }
}
diff --git a/contrib/go/_std_1.21/src/runtime/mgc.go b/contrib/go/_std_1.21/src/runtime/mgc.go
index de5ae0ae00..a12dbfe9df 100644
--- a/contrib/go/_std_1.21/src/runtime/mgc.go
+++ b/contrib/go/_std_1.21/src/runtime/mgc.go
@@ -1186,7 +1186,9 @@ func gcMarkTermination() {
// Enable huge pages on some metadata if we cross a heap threshold.
if gcController.heapGoal() > minHeapForMetadataHugePages {
- mheap_.enableMetadataHugePages()
+ systemstack(func() {
+ mheap_.enableMetadataHugePages()
+ })
}
semrelease(&worldsema)
diff --git a/contrib/go/_std_1.21/src/runtime/mgcscavenge.go b/contrib/go/_std_1.21/src/runtime/mgcscavenge.go
index 4c6d6be4f0..659ca8df2e 100644
--- a/contrib/go/_std_1.21/src/runtime/mgcscavenge.go
+++ b/contrib/go/_std_1.21/src/runtime/mgcscavenge.go
@@ -1145,21 +1145,11 @@ func (s *scavengeIndex) alloc(ci chunkIdx, npages uint) {
// Mark that we're considering this chunk as backed by huge pages.
sc.setHugePage()
- // Collapse dense chunks into huge pages and mark that
- // we did that, but only if we're not allocating to
- // use the entire chunk. If we're allocating an entire chunk,
- // this is likely part of a much bigger allocation. For
- // instance, if the caller is allocating a 1 GiB slice of bytes, we
- // don't want to go and manually collapse all those pages; we want
- // them to be demand-paged. If the caller is actually going to use
- // all that memory, it'll naturally get backed by huge pages later.
- //
- // This also avoids having sysHugePageCollapse fail. On Linux,
- // the call requires that some part of the huge page being collapsed
- // is already paged in.
- if !s.test && npages < pallocChunkPages {
- sysHugePageCollapse(unsafe.Pointer(chunkBase(ci)), pallocChunkBytes)
- }
+ // TODO(mknyszek): Consider eagerly backing memory with huge pages
+ // here. In the past we've attempted to use sysHugePageCollapse
+ // (which uses MADV_COLLAPSE on Linux, and is unsupported elswhere)
+ // for this purpose, but that caused performance issues in production
+ // environments.
}
s.chunks[ci].store(sc)
}
diff --git a/contrib/go/_std_1.21/src/runtime/mpagealloc.go b/contrib/go/_std_1.21/src/runtime/mpagealloc.go
index 3e789ab85c..2861fa93eb 100644
--- a/contrib/go/_std_1.21/src/runtime/mpagealloc.go
+++ b/contrib/go/_std_1.21/src/runtime/mpagealloc.go
@@ -437,6 +437,10 @@ func (p *pageAlloc) grow(base, size uintptr) {
//
// The heap lock must not be held over this operation, since it will briefly acquire
// the heap lock.
+//
+// Must be called on the system stack because it acquires the heap lock.
+//
+//go:systemstack
func (p *pageAlloc) enableChunkHugePages() {
// Grab the heap lock to turn on huge pages for new chunks and clone the current
// heap address space ranges.
diff --git a/contrib/go/_std_1.21/src/runtime/mstats.go b/contrib/go/_std_1.21/src/runtime/mstats.go
index 9cdc565137..308bed67d7 100644
--- a/contrib/go/_std_1.21/src/runtime/mstats.go
+++ b/contrib/go/_std_1.21/src/runtime/mstats.go
@@ -367,6 +367,11 @@ func ReadMemStats(m *MemStats) {
startTheWorld()
}
+// doubleCheckReadMemStats controls a double-check mode for ReadMemStats that
+// ensures consistency between the values that ReadMemStats is using and the
+// runtime-internal stats.
+var doubleCheckReadMemStats = false
+
// readmemstats_m populates stats for internal runtime values.
//
// The world must be stopped.
@@ -441,56 +446,65 @@ func readmemstats_m(stats *MemStats) {
heapGoal := gcController.heapGoal()
- // The world is stopped, so the consistent stats (after aggregation)
- // should be identical to some combination of memstats. In particular:
- //
- // * memstats.heapInUse == inHeap
- // * memstats.heapReleased == released
- // * memstats.heapInUse + memstats.heapFree == committed - inStacks - inWorkBufs - inPtrScalarBits
- // * memstats.totalAlloc == totalAlloc
- // * memstats.totalFree == totalFree
- //
- // Check if that's actually true.
- //
- // TODO(mknyszek): Maybe don't throw here. It would be bad if a
- // bug in otherwise benign accounting caused the whole application
- // to crash.
- if gcController.heapInUse.load() != uint64(consStats.inHeap) {
- print("runtime: heapInUse=", gcController.heapInUse.load(), "\n")
- print("runtime: consistent value=", consStats.inHeap, "\n")
- throw("heapInUse and consistent stats are not equal")
- }
- if gcController.heapReleased.load() != uint64(consStats.released) {
- print("runtime: heapReleased=", gcController.heapReleased.load(), "\n")
- print("runtime: consistent value=", consStats.released, "\n")
- throw("heapReleased and consistent stats are not equal")
- }
- heapRetained := gcController.heapInUse.load() + gcController.heapFree.load()
- consRetained := uint64(consStats.committed - consStats.inStacks - consStats.inWorkBufs - consStats.inPtrScalarBits)
- if heapRetained != consRetained {
- print("runtime: global value=", heapRetained, "\n")
- print("runtime: consistent value=", consRetained, "\n")
- throw("measures of the retained heap are not equal")
- }
- if gcController.totalAlloc.Load() != totalAlloc {
- print("runtime: totalAlloc=", gcController.totalAlloc.Load(), "\n")
- print("runtime: consistent value=", totalAlloc, "\n")
- throw("totalAlloc and consistent stats are not equal")
- }
- if gcController.totalFree.Load() != totalFree {
- print("runtime: totalFree=", gcController.totalFree.Load(), "\n")
- print("runtime: consistent value=", totalFree, "\n")
- throw("totalFree and consistent stats are not equal")
- }
- // Also check that mappedReady lines up with totalMapped - released.
- // This isn't really the same type of "make sure consistent stats line up" situation,
- // but this is an opportune time to check.
- if gcController.mappedReady.Load() != totalMapped-uint64(consStats.released) {
- print("runtime: mappedReady=", gcController.mappedReady.Load(), "\n")
- print("runtime: totalMapped=", totalMapped, "\n")
- print("runtime: released=", uint64(consStats.released), "\n")
- print("runtime: totalMapped-released=", totalMapped-uint64(consStats.released), "\n")
- throw("mappedReady and other memstats are not equal")
+ if doubleCheckReadMemStats {
+ // Only check this if we're debugging. It would be bad to crash an application
+ // just because the debugging stats are wrong. We mostly rely on tests to catch
+ // these issues, and we enable the double check mode for tests.
+ //
+ // The world is stopped, so the consistent stats (after aggregation)
+ // should be identical to some combination of memstats. In particular:
+ //
+ // * memstats.heapInUse == inHeap
+ // * memstats.heapReleased == released
+ // * memstats.heapInUse + memstats.heapFree == committed - inStacks - inWorkBufs - inPtrScalarBits
+ // * memstats.totalAlloc == totalAlloc
+ // * memstats.totalFree == totalFree
+ //
+ // Check if that's actually true.
+ //
+ // Prevent sysmon and the tracer from skewing the stats since they can
+ // act without synchronizing with a STW. See #64401.
+ lock(&sched.sysmonlock)
+ lock(&trace.lock)
+ if gcController.heapInUse.load() != uint64(consStats.inHeap) {
+ print("runtime: heapInUse=", gcController.heapInUse.load(), "\n")
+ print("runtime: consistent value=", consStats.inHeap, "\n")
+ throw("heapInUse and consistent stats are not equal")
+ }
+ if gcController.heapReleased.load() != uint64(consStats.released) {
+ print("runtime: heapReleased=", gcController.heapReleased.load(), "\n")
+ print("runtime: consistent value=", consStats.released, "\n")
+ throw("heapReleased and consistent stats are not equal")
+ }
+ heapRetained := gcController.heapInUse.load() + gcController.heapFree.load()
+ consRetained := uint64(consStats.committed - consStats.inStacks - consStats.inWorkBufs - consStats.inPtrScalarBits)
+ if heapRetained != consRetained {
+ print("runtime: global value=", heapRetained, "\n")
+ print("runtime: consistent value=", consRetained, "\n")
+ throw("measures of the retained heap are not equal")
+ }
+ if gcController.totalAlloc.Load() != totalAlloc {
+ print("runtime: totalAlloc=", gcController.totalAlloc.Load(), "\n")
+ print("runtime: consistent value=", totalAlloc, "\n")
+ throw("totalAlloc and consistent stats are not equal")
+ }
+ if gcController.totalFree.Load() != totalFree {
+ print("runtime: totalFree=", gcController.totalFree.Load(), "\n")
+ print("runtime: consistent value=", totalFree, "\n")
+ throw("totalFree and consistent stats are not equal")
+ }
+ // Also check that mappedReady lines up with totalMapped - released.
+ // This isn't really the same type of "make sure consistent stats line up" situation,
+ // but this is an opportune time to check.
+ if gcController.mappedReady.Load() != totalMapped-uint64(consStats.released) {
+ print("runtime: mappedReady=", gcController.mappedReady.Load(), "\n")
+ print("runtime: totalMapped=", totalMapped, "\n")
+ print("runtime: released=", uint64(consStats.released), "\n")
+ print("runtime: totalMapped-released=", totalMapped-uint64(consStats.released), "\n")
+ throw("mappedReady and other memstats are not equal")
+ }
+ unlock(&trace.lock)
+ unlock(&sched.sysmonlock)
}
// We've calculated all the values we need. Now, populate stats.
diff --git a/contrib/go/_std_1.21/src/runtime/os_windows.go b/contrib/go/_std_1.21/src/runtime/os_windows.go
index f5c2429a05..735a905b61 100644
--- a/contrib/go/_std_1.21/src/runtime/os_windows.go
+++ b/contrib/go/_std_1.21/src/runtime/os_windows.go
@@ -127,15 +127,8 @@ var (
_AddVectoredContinueHandler,
_ stdFunction
- // Use RtlGenRandom to generate cryptographically random data.
- // This approach has been recommended by Microsoft (see issue
- // 15589 for details).
- // The RtlGenRandom is not listed in advapi32.dll, instead
- // RtlGenRandom function can be found by searching for SystemFunction036.
- // Also some versions of Mingw cannot link to SystemFunction036
- // when building executable as Cgo. So load SystemFunction036
- // manually during runtime startup.
- _RtlGenRandom stdFunction
+ // Use ProcessPrng to generate cryptographically random data.
+ _ProcessPrng stdFunction
// Load ntdll.dll manually during startup, otherwise Mingw
// links wrong printf function to cgo executable (see issue
@@ -152,12 +145,12 @@ var (
)
var (
- advapi32dll = [...]uint16{'a', 'd', 'v', 'a', 'p', 'i', '3', '2', '.', 'd', 'l', 'l', 0}
- kernel32dll = [...]uint16{'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', 0}
- ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0}
- powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0}
- winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0}
- ws2_32dll = [...]uint16{'w', 's', '2', '_', '3', '2', '.', 'd', 'l', 'l', 0}
+ bcryptprimitivesdll = [...]uint16{'b', 'c', 'r', 'y', 'p', 't', 'p', 'r', 'i', 'm', 'i', 't', 'i', 'v', 'e', 's', '.', 'd', 'l', 'l', 0}
+ kernel32dll = [...]uint16{'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', 0}
+ ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0}
+ powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0}
+ winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0}
+ ws2_32dll = [...]uint16{'w', 's', '2', '_', '3', '2', '.', 'd', 'l', 'l', 0}
)
// Function to be called by windows CreateThread
@@ -256,11 +249,11 @@ func loadOptionalSyscalls() {
}
_AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000"))
- a32 := windowsLoadSystemLib(advapi32dll[:])
- if a32 == 0 {
- throw("advapi32.dll not found")
+ bcryptPrimitives := windowsLoadSystemLib(bcryptprimitivesdll[:])
+ if bcryptPrimitives == 0 {
+ throw("bcryptprimitives.dll not found")
}
- _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000"))
+ _ProcessPrng = windowsFindfunc(bcryptPrimitives, []byte("ProcessPrng\000"))
n32 := windowsLoadSystemLib(ntdlldll[:])
if n32 == 0 {
@@ -617,7 +610,7 @@ func initWine(k32 uintptr) {
//go:nosplit
func getRandomData(r []byte) {
n := 0
- if stdcall2(_RtlGenRandom, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 {
+ if stdcall2(_ProcessPrng, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 {
n = len(r)
}
extendRandom(r, n)
diff --git a/contrib/go/_std_1.21/src/runtime/pprof/proto.go b/contrib/go/_std_1.21/src/runtime/pprof/proto.go
index cdc4bd7c80..db9384eb21 100644
--- a/contrib/go/_std_1.21/src/runtime/pprof/proto.go
+++ b/contrib/go/_std_1.21/src/runtime/pprof/proto.go
@@ -611,13 +611,14 @@ func (b *profileBuilder) emitLocation() uint64 {
b.pb.uint64Opt(tagLocation_Address, uint64(firstFrame.PC))
for _, frame := range b.deck.frames {
// Write out each line in frame expansion.
- funcID := uint64(b.funcs[frame.Function])
+ funcName := runtime_FrameSymbolName(&frame)
+ funcID := uint64(b.funcs[funcName])
if funcID == 0 {
funcID = uint64(len(b.funcs)) + 1
- b.funcs[frame.Function] = int(funcID)
+ b.funcs[funcName] = int(funcID)
newFuncs = append(newFuncs, newFunc{
id: funcID,
- name: runtime_FrameSymbolName(&frame),
+ name: funcName,
file: frame.File,
startLine: int64(runtime_FrameStartLine(&frame)),
})
diff --git a/contrib/go/_std_1.21/src/runtime/runtime.go b/contrib/go/_std_1.21/src/runtime/runtime.go
index 0822d0e805..15119cf5df 100644
--- a/contrib/go/_std_1.21/src/runtime/runtime.go
+++ b/contrib/go/_std_1.21/src/runtime/runtime.go
@@ -101,12 +101,17 @@ func (g *godebugInc) IncNonDefault() {
if newInc == nil {
return
}
- // If other goroutines are racing here, no big deal. One will win,
- // and all the inc functions will be using the same underlying
- // *godebug.Setting.
inc = new(func())
*inc = (*newInc)(g.name)
- g.inc.Store(inc)
+ if raceenabled {
+ racereleasemerge(unsafe.Pointer(&g.inc))
+ }
+ if !g.inc.CompareAndSwap(nil, inc) {
+ inc = g.inc.Load()
+ }
+ }
+ if raceenabled {
+ raceacquire(unsafe.Pointer(&g.inc))
}
(*inc)()
}
diff --git a/contrib/go/_std_1.21/src/runtime/runtime1.go b/contrib/go/_std_1.21/src/runtime/runtime1.go
index 92a7e021ee..7174c63af3 100644
--- a/contrib/go/_std_1.21/src/runtime/runtime1.go
+++ b/contrib/go/_std_1.21/src/runtime/runtime1.go
@@ -309,6 +309,7 @@ type dbgVar struct {
var debug struct {
cgocheck int32
clobberfree int32
+ disablethp int32
dontfreezetheworld int32
efence int32
gccheckmark int32
@@ -342,6 +343,7 @@ var dbgvars = []*dbgVar{
{name: "allocfreetrace", value: &debug.allocfreetrace},
{name: "clobberfree", value: &debug.clobberfree},
{name: "cgocheck", value: &debug.cgocheck},
+ {name: "disablethp", value: &debug.disablethp},
{name: "dontfreezetheworld", value: &debug.dontfreezetheworld},
{name: "efence", value: &debug.efence},
{name: "gccheckmark", value: &debug.gccheckmark},
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/comp_ref_type.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/comp_ref_type.h
index f0a0a31665..f2338e1446 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/comp_ref_type.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/comp_ref_type.h
@@ -49,8 +49,8 @@ struct __debug_less
template <class _LHS, class _RHS>
_LIBCPP_CONSTEXPR_SINCE_CXX14
inline _LIBCPP_INLINE_VISIBILITY
- decltype((void)declval<_Compare&>()(
- declval<_LHS &>(), declval<_RHS &>()))
+ decltype((void)std::declval<_Compare&>()(
+ std::declval<_LHS &>(), std::declval<_RHS &>()))
__do_compare_assert(int, _LHS & __l, _RHS & __r) {
_LIBCPP_DEBUG_ASSERT(!__comp_(__l, __r),
"Comparator does not induce a strict weak ordering");
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/copy.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/copy.h
index d6a46f6952..193a6df316 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/copy.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/copy.h
@@ -9,100 +9,118 @@
#ifndef _LIBCPP___ALGORITHM_COPY_H
#define _LIBCPP___ALGORITHM_COPY_H
-#include <__algorithm/unwrap_iter.h>
-#include <__algorithm/unwrap_range.h>
+#include <__algorithm/copy_move_common.h>
+#include <__algorithm/iterator_operations.h>
+#include <__algorithm/min.h>
#include <__config>
-#include <__iterator/iterator_traits.h>
-#include <__iterator/reverse_iterator.h>
+#include <__iterator/segmented_iterator.h>
+#include <__type_traits/common_type.h>
#include <__utility/move.h>
#include <__utility/pair.h>
-#include <cstring>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
-// copy
+template <class, class _InIter, class _Sent, class _OutIter>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> __copy(_InIter, _Sent, _OutIter);
+
+template <class _AlgPolicy>
+struct __copy_loop {
+ template <class _InIter, class _Sent, class _OutIter>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+ operator()(_InIter __first, _Sent __last, _OutIter __result) const {
+ while (__first != __last) {
+ *__result = *__first;
+ ++__first;
+ ++__result;
+ }
-template <class _InIter, class _Sent, class _OutIter>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
-pair<_InIter, _OutIter> __copy_impl(_InIter __first, _Sent __last, _OutIter __result) {
- while (__first != __last) {
- *__result = *__first;
- ++__first;
- ++__result;
+ return std::make_pair(std::move(__first), std::move(__result));
}
- return pair<_InIter, _OutIter>(std::move(__first), std::move(__result));
-}
-template <class _InValueT,
- class _OutValueT,
- class = __enable_if_t<is_same<__remove_const_t<_InValueT>, _OutValueT>::value
- && is_trivially_copy_assignable<_OutValueT>::value> >
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
-pair<_InValueT*, _OutValueT*> __copy_impl(_InValueT* __first, _InValueT* __last, _OutValueT* __result) {
- if (__libcpp_is_constant_evaluated()
-// TODO: Remove this once GCC supports __builtin_memmove during constant evaluation
-#ifndef _LIBCPP_COMPILER_GCC
- && !is_trivially_copyable<_InValueT>::value
-#endif
- )
- return std::__copy_impl<_InValueT*, _InValueT*, _OutValueT*>(__first, __last, __result);
- const size_t __n = static_cast<size_t>(__last - __first);
- if (__n > 0)
- ::__builtin_memmove(__result, __first, __n * sizeof(_OutValueT));
- return std::make_pair(__first + __n, __result + __n);
-}
+ template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+ operator()(_InIter __first, _InIter __last, _OutIter __result) const {
+ using _Traits = __segmented_iterator_traits<_InIter>;
+ auto __sfirst = _Traits::__segment(__first);
+ auto __slast = _Traits::__segment(__last);
+ if (__sfirst == __slast) {
+ auto __iters = std::__copy<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
+ return std::make_pair(__last, std::move(__iters.second));
+ }
-template <class _InIter, class _OutIter,
- __enable_if_t<is_same<__remove_const_t<__iter_value_type<_InIter> >, __iter_value_type<_OutIter> >::value
- && __is_cpp17_contiguous_iterator<typename _InIter::iterator_type>::value
- && __is_cpp17_contiguous_iterator<typename _OutIter::iterator_type>::value
- && is_trivially_copy_assignable<__iter_value_type<_OutIter> >::value
- && __is_reverse_iterator<_InIter>::value
- && __is_reverse_iterator<_OutIter>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
-pair<_InIter, _OutIter>
-__copy_impl(_InIter __first, _InIter __last, _OutIter __result) {
- auto __first_base = std::__unwrap_iter(__first.base());
- auto __last_base = std::__unwrap_iter(__last.base());
- auto __result_base = std::__unwrap_iter(__result.base());
- auto __result_first = __result_base - (__first_base - __last_base);
- std::__copy_impl(__last_base, __first_base, __result_first);
- return std::make_pair(__last, _OutIter(std::__rewrap_iter(__result.base(), __result_first)));
-}
+ __result = std::__copy<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__sfirst), std::move(__result)).second;
+ ++__sfirst;
+ while (__sfirst != __slast) {
+ __result =
+ std::__copy<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), std::move(__result)).second;
+ ++__sfirst;
+ }
+ __result =
+ std::__copy<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__local(__last), std::move(__result)).second;
+ return std::make_pair(__last, std::move(__result));
+ }
-template <class _InIter, class _Sent, class _OutIter,
- __enable_if_t<!(is_copy_constructible<_InIter>::value
- && is_copy_constructible<_Sent>::value
- && is_copy_constructible<_OutIter>::value), int> = 0 >
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
-pair<_InIter, _OutIter> __copy(_InIter __first, _Sent __last, _OutIter __result) {
- return std::__copy_impl(std::move(__first), std::move(__last), std::move(__result));
-}
+ template <class _InIter,
+ class _OutIter,
+ __enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value &&
+ !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
+ int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+ operator()(_InIter __first, _InIter __last, _OutIter __result) {
+ using _Traits = __segmented_iterator_traits<_OutIter>;
+ using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
-template <class _InIter, class _Sent, class _OutIter,
- __enable_if_t<is_copy_constructible<_InIter>::value
- && is_copy_constructible<_Sent>::value
- && is_copy_constructible<_OutIter>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
-pair<_InIter, _OutIter> __copy(_InIter __first, _Sent __last, _OutIter __result) {
- auto __range = std::__unwrap_range(__first, __last);
- auto __ret = std::__copy_impl(std::move(__range.first), std::move(__range.second), std::__unwrap_iter(__result));
- return std::make_pair(
- std::__rewrap_range<_Sent>(__first, __ret.first), std::__rewrap_iter(__result, __ret.second));
+ if (__first == __last)
+ return std::make_pair(std::move(__first), std::move(__result));
+
+ auto __local_first = _Traits::__local(__result);
+ auto __segment_iterator = _Traits::__segment(__result);
+ while (true) {
+ auto __local_last = _Traits::__end(__segment_iterator);
+ auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first);
+ auto __iters = std::__copy<_AlgPolicy>(__first, __first + __size, __local_first);
+ __first = std::move(__iters.first);
+
+ if (__first == __last)
+ return std::make_pair(std::move(__first), _Traits::__compose(__segment_iterator, std::move(__iters.second)));
+
+ __local_first = _Traits::__begin(++__segment_iterator);
+ }
+ }
+};
+
+struct __copy_trivial {
+ // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
+ template <class _In, class _Out,
+ __enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
+ operator()(_In* __first, _In* __last, _Out* __result) const {
+ return std::__copy_trivial_impl(__first, __last, __result);
+ }
+};
+
+template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
+pair<_InIter, _OutIter> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
+__copy(_InIter __first, _Sent __last, _OutIter __result) {
+ return std::__dispatch_copy_or_move<_AlgPolicy, __copy_loop<_AlgPolicy>, __copy_trivial>(
+ std::move(__first), std::move(__last), std::move(__result));
}
template <class _InputIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
-_OutputIterator
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
- return std::__copy(__first, __last, __result).second;
+ return std::__copy<_ClassicAlgPolicy>(__first, __last, __result).second;
}
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___ALGORITHM_COPY_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/copy_backward.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/copy_backward.h
index 1db4f1e2d5..bb2a432878 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/copy_backward.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/copy_backward.h
@@ -9,54 +9,135 @@
#ifndef _LIBCPP___ALGORITHM_COPY_BACKWARD_H
#define _LIBCPP___ALGORITHM_COPY_BACKWARD_H
-#include <__algorithm/copy.h>
+#include <__algorithm/copy_move_common.h>
#include <__algorithm/iterator_operations.h>
-#include <__algorithm/ranges_copy.h>
-#include <__algorithm/unwrap_iter.h>
-#include <__concepts/same_as.h>
+#include <__algorithm/min.h>
#include <__config>
-#include <__iterator/iterator_traits.h>
-#include <__iterator/reverse_iterator.h>
-#include <__ranges/subrange.h>
+#include <__iterator/segmented_iterator.h>
+#include <__type_traits/common_type.h>
+#include <__type_traits/is_copy_constructible.h>
#include <__utility/move.h>
#include <__utility/pair.h>
-#include <cstring>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _AlgPolicy, class _InputIterator, class _OutputIterator,
- __enable_if_t<is_same<_AlgPolicy, _ClassicAlgPolicy>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InputIterator, _OutputIterator>
-__copy_backward(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
- auto __ret = std::__copy(
- __unconstrained_reverse_iterator<_InputIterator>(__last),
- __unconstrained_reverse_iterator<_InputIterator>(__first),
- __unconstrained_reverse_iterator<_OutputIterator>(__result));
- return pair<_InputIterator, _OutputIterator>(__ret.first.base(), __ret.second.base());
-}
+template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter>
+__copy_backward(_InIter __first, _Sent __last, _OutIter __result);
+
+template <class _AlgPolicy>
+struct __copy_backward_loop {
+ template <class _InIter, class _Sent, class _OutIter>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+ operator()(_InIter __first, _Sent __last, _OutIter __result) const {
+ auto __last_iter = _IterOps<_AlgPolicy>::next(__first, __last);
+ auto __original_last_iter = __last_iter;
+
+ while (__first != __last_iter) {
+ *--__result = *--__last_iter;
+ }
+
+ return std::make_pair(std::move(__original_last_iter), std::move(__result));
+ }
+
+ template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+ operator()(_InIter __first, _InIter __last, _OutIter __result) const {
+ using _Traits = __segmented_iterator_traits<_InIter>;
+ auto __sfirst = _Traits::__segment(__first);
+ auto __slast = _Traits::__segment(__last);
+ if (__sfirst == __slast) {
+ auto __iters =
+ std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
+ return std::make_pair(__last, __iters.second);
+ }
+
+ __result =
+ std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__local(__last), std::move(__result))
+ .second;
+ --__slast;
+ while (__sfirst != __slast) {
+ __result =
+ std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__end(__slast), std::move(__result))
+ .second;
+ --__slast;
+ }
+ __result = std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__slast), std::move(__result))
+ .second;
+ return std::make_pair(__last, std::move(__result));
+ }
+
+ template <class _InIter,
+ class _OutIter,
+ __enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value &&
+ !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
+ int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+ operator()(_InIter __first, _InIter __last, _OutIter __result) {
+ using _Traits = __segmented_iterator_traits<_OutIter>;
+ auto __orig_last = __last;
+ auto __segment_iterator = _Traits::__segment(__result);
-#if _LIBCPP_STD_VER > 17
-template <class _AlgPolicy, class _Iter1, class _Sent1, class _Iter2,
- __enable_if_t<is_same<_AlgPolicy, _RangeAlgPolicy>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI constexpr pair<_Iter1, _Iter2> __copy_backward(_Iter1 __first, _Sent1 __last, _Iter2 __result) {
- auto __last_iter = _IterOps<_AlgPolicy>::next(__first, std::move(__last));
- auto __reverse_range = std::__reverse_range(std::ranges::subrange(std::move(__first), __last_iter));
- auto __ret = ranges::copy(std::move(__reverse_range), std::make_reverse_iterator(__result));
- return std::make_pair(__last_iter, __ret.out.base());
+ // When the range contains no elements, __result might not be a valid iterator
+ if (__first == __last)
+ return std::make_pair(__first, __result);
+
+ auto __local_last = _Traits::__local(__result);
+ while (true) {
+ using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
+
+ auto __local_first = _Traits::__begin(__segment_iterator);
+ auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first);
+ auto __iter = std::__copy_backward<_AlgPolicy>(__last - __size, __last, __local_last).second;
+ __last -= __size;
+
+ if (__first == __last)
+ return std::make_pair(std::move(__orig_last), _Traits::__compose(__segment_iterator, std::move(__iter)));
+ --__segment_iterator;
+ __local_last = _Traits::__end(__segment_iterator);
+ }
+ }
+};
+
+struct __copy_backward_trivial {
+ // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
+ template <class _In, class _Out,
+ __enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
+ operator()(_In* __first, _In* __last, _Out* __result) const {
+ return std::__copy_backward_trivial_impl(__first, __last, __result);
+ }
+};
+
+template <class _AlgPolicy, class _BidirectionalIterator1, class _Sentinel, class _BidirectionalIterator2>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2>
+__copy_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result) {
+ return std::__dispatch_copy_or_move<_AlgPolicy, __copy_backward_loop<_AlgPolicy>, __copy_backward_trivial>(
+ std::move(__first), std::move(__last), std::move(__result));
}
-#endif // _LIBCPP_STD_VER > 17
template <class _BidirectionalIterator1, class _BidirectionalIterator2>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _BidirectionalIterator2
-copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, _BidirectionalIterator2 __result) {
- return std::__copy_backward<_ClassicAlgPolicy>(__first, __last, __result).second;
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+_BidirectionalIterator2
+copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
+ _BidirectionalIterator2 __result)
+{
+ static_assert(std::is_copy_constructible<_BidirectionalIterator1>::value &&
+ std::is_copy_constructible<_BidirectionalIterator1>::value, "Iterators must be copy constructible.");
+
+ return std::__copy_backward<_ClassicAlgPolicy>(
+ std::move(__first), std::move(__last), std::move(__result)).second;
}
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___ALGORITHM_COPY_BACKWARD_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/copy_move_common.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/copy_move_common.h
new file mode 100644
index 0000000000..b88c14911b
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/copy_move_common.h
@@ -0,0 +1,163 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_COPY_MOVE_COMMON_H
+#define _LIBCPP___ALGORITHM_COPY_MOVE_COMMON_H
+
+#include <__algorithm/iterator_operations.h>
+#include <__algorithm/unwrap_iter.h>
+#include <__algorithm/unwrap_range.h>
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__memory/pointer_traits.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_always_bitcastable.h>
+#include <__type_traits/is_constant_evaluated.h>
+#include <__type_traits/is_copy_constructible.h>
+#include <__type_traits/is_trivially_assignable.h>
+#include <__type_traits/is_trivially_copyable.h>
+#include <__type_traits/is_volatile.h>
+#include <__utility/move.h>
+#include <__utility/pair.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// Type traits.
+
+template <class _From, class _To>
+struct __can_lower_copy_assignment_to_memmove {
+ static const bool value =
+ // If the types are always bitcastable, it's valid to do a bitwise copy between them.
+ __is_always_bitcastable<_From, _To>::value &&
+ // Reject conversions that wouldn't be performed by the regular built-in assignment (e.g. between arrays).
+ is_trivially_assignable<_To&, const _From&>::value &&
+ // `memmove` doesn't accept `volatile` pointers, make sure the optimization SFINAEs away in that case.
+ !is_volatile<_From>::value &&
+ !is_volatile<_To>::value;
+};
+
+template <class _From, class _To>
+struct __can_lower_move_assignment_to_memmove {
+ static const bool value =
+ __is_always_bitcastable<_From, _To>::value &&
+ is_trivially_assignable<_To&, _From&&>::value &&
+ !is_volatile<_From>::value &&
+ !is_volatile<_To>::value;
+};
+
+// `memmove` algorithms implementation.
+
+template <class _In, class _Out>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
+__copy_trivial_impl(_In* __first, _In* __last, _Out* __result) {
+ const size_t __n = static_cast<size_t>(__last - __first);
+ ::__builtin_memmove(__result, __first, __n * sizeof(_Out));
+
+ return std::make_pair(__last, __result + __n);
+}
+
+template <class _In, class _Out>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
+__copy_backward_trivial_impl(_In* __first, _In* __last, _Out* __result) {
+ const size_t __n = static_cast<size_t>(__last - __first);
+ __result -= __n;
+
+ ::__builtin_memmove(__result, __first, __n * sizeof(_Out));
+
+ return std::make_pair(__last, __result);
+}
+
+// Iterator unwrapping and dispatching to the correct overload.
+
+template <class _F1, class _F2>
+struct __overload : _F1, _F2 {
+ using _F1::operator();
+ using _F2::operator();
+};
+
+template <class _InIter, class _Sent, class _OutIter, class = void>
+struct __can_rewrap : false_type {};
+
+template <class _InIter, class _Sent, class _OutIter>
+struct __can_rewrap<_InIter,
+ _Sent,
+ _OutIter,
+ // Note that sentinels are always copy-constructible.
+ __enable_if_t< is_copy_constructible<_InIter>::value &&
+ is_copy_constructible<_OutIter>::value > > : true_type {};
+
+template <class _Algorithm,
+ class _InIter,
+ class _Sent,
+ class _OutIter,
+ __enable_if_t<__can_rewrap<_InIter, _Sent, _OutIter>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter>
+__unwrap_and_dispatch(_InIter __first, _Sent __last, _OutIter __out_first) {
+ auto __range = std::__unwrap_range(__first, std::move(__last));
+ auto __result = _Algorithm()(std::move(__range.first), std::move(__range.second), std::__unwrap_iter(__out_first));
+ return std::make_pair(std::__rewrap_range<_Sent>(std::move(__first), std::move(__result.first)),
+ std::__rewrap_iter(std::move(__out_first), std::move(__result.second)));
+}
+
+template <class _Algorithm,
+ class _InIter,
+ class _Sent,
+ class _OutIter,
+ __enable_if_t<!__can_rewrap<_InIter, _Sent, _OutIter>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter>
+__unwrap_and_dispatch(_InIter __first, _Sent __last, _OutIter __out_first) {
+ return _Algorithm()(std::move(__first), std::move(__last), std::move(__out_first));
+}
+
+template <class _IterOps, class _InValue, class _OutIter, class = void>
+struct __can_copy_without_conversion : false_type {};
+
+template <class _IterOps, class _InValue, class _OutIter>
+struct __can_copy_without_conversion<
+ _IterOps,
+ _InValue,
+ _OutIter,
+ __enable_if_t<is_same<_InValue, typename _IterOps::template __value_type<_OutIter> >::value> > : true_type {};
+
+template <class _AlgPolicy,
+ class _NaiveAlgorithm,
+ class _OptimizedAlgorithm,
+ class _InIter,
+ class _Sent,
+ class _OutIter>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter>
+__dispatch_copy_or_move(_InIter __first, _Sent __last, _OutIter __out_first) {
+#ifdef _LIBCPP_COMPILER_GCC
+ // GCC doesn't support `__builtin_memmove` during constant evaluation.
+ if (__libcpp_is_constant_evaluated()) {
+ return std::__unwrap_and_dispatch<_NaiveAlgorithm>(std::move(__first), std::move(__last), std::move(__out_first));
+ }
+#else
+ // In Clang, `__builtin_memmove` only supports fully trivially copyable types (just having trivial copy assignment is
+ // insufficient). Also, conversions are not supported.
+ if (__libcpp_is_constant_evaluated()) {
+ using _InValue = typename _IterOps<_AlgPolicy>::template __value_type<_InIter>;
+ if (!is_trivially_copyable<_InValue>::value ||
+ !__can_copy_without_conversion<_IterOps<_AlgPolicy>, _InValue, _OutIter>::value) {
+ return std::__unwrap_and_dispatch<_NaiveAlgorithm>(std::move(__first), std::move(__last), std::move(__out_first));
+ }
+ }
+#endif // _LIBCPP_COMPILER_GCC
+
+ using _Algorithm = __overload<_NaiveAlgorithm, _OptimizedAlgorithm>;
+ return std::__unwrap_and_dispatch<_Algorithm>(std::move(__first), std::move(__last), std::move(__out_first));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ALGORITHM_COPY_MOVE_COMMON_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/iter_swap.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/iter_swap.h
index 0d93f7f756..44422b5de0 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/iter_swap.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/iter_swap.h
@@ -23,7 +23,7 @@ template <class _ForwardIterator1, class _ForwardIterator2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void iter_swap(_ForwardIterator1 __a,
_ForwardIterator2 __b)
// _NOEXCEPT_(_NOEXCEPT_(swap(*__a, *__b)))
- _NOEXCEPT_(_NOEXCEPT_(swap(*declval<_ForwardIterator1>(), *declval<_ForwardIterator2>()))) {
+ _NOEXCEPT_(_NOEXCEPT_(swap(*std::declval<_ForwardIterator1>(), *std::declval<_ForwardIterator2>()))) {
swap(*__a, *__b);
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/iterator_operations.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/iterator_operations.h
index bfe82c2028..bd3e6f1d38 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/iterator_operations.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/iterator_operations.h
@@ -21,10 +21,13 @@
#include <__iterator/next.h>
#include <__iterator/prev.h>
#include <__iterator/readable_traits.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/remove_cvref.h>
#include <__utility/declval.h>
#include <__utility/forward.h>
#include <__utility/move.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/move.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/move.h
index e2f8b22800..ac95bda7b6 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/move.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/move.h
@@ -9,111 +9,122 @@
#ifndef _LIBCPP___ALGORITHM_MOVE_H
#define _LIBCPP___ALGORITHM_MOVE_H
+#include <__algorithm/copy_move_common.h>
#include <__algorithm/iterator_operations.h>
-#include <__algorithm/unwrap_iter.h>
+#include <__algorithm/min.h>
#include <__config>
-#include <__iterator/iterator_traits.h>
-#include <__iterator/reverse_iterator.h>
+#include <__iterator/segmented_iterator.h>
+#include <__type_traits/common_type.h>
+#include <__type_traits/is_copy_constructible.h>
#include <__utility/move.h>
#include <__utility/pair.h>
-#include <cstring>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
-_LIBCPP_BEGIN_NAMESPACE_STD
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
-// move
+_LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
-pair<_InIter, _OutIter> __move_impl(_InIter __first, _Sent __last, _OutIter __result) {
- while (__first != __last) {
- *__result = _IterOps<_AlgPolicy>::__iter_move(__first);
- ++__first;
- ++__result;
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+__move(_InIter __first, _Sent __last, _OutIter __result);
+
+template <class _AlgPolicy>
+struct __move_loop {
+ template <class _InIter, class _Sent, class _OutIter>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+ operator()(_InIter __first, _Sent __last, _OutIter __result) const {
+ while (__first != __last) {
+ *__result = _IterOps<_AlgPolicy>::__iter_move(__first);
+ ++__first;
+ ++__result;
+ }
+ return std::make_pair(std::move(__first), std::move(__result));
}
- return std::make_pair(std::move(__first), std::move(__result));
-}
-
-template <class _AlgPolicy,
- class _InType,
- class _OutType,
- class = __enable_if_t<is_same<__remove_const_t<_InType>, _OutType>::value
- && is_trivially_move_assignable<_OutType>::value> >
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
-pair<_InType*, _OutType*> __move_impl(_InType* __first, _InType* __last, _OutType* __result) {
- if (__libcpp_is_constant_evaluated()
-// TODO: Remove this once GCC supports __builtin_memmove during constant evaluation
-#ifndef _LIBCPP_COMPILER_GCC
- && !is_trivially_copyable<_InType>::value
-#endif
- )
- return std::__move_impl<_AlgPolicy, _InType*, _InType*, _OutType*>(__first, __last, __result);
- const size_t __n = static_cast<size_t>(__last - __first);
- ::__builtin_memmove(__result, __first, __n * sizeof(_OutType));
- return std::make_pair(__first + __n, __result + __n);
-}
-template <class>
-struct __is_trivially_move_assignable_unwrapped_impl : false_type {};
-
-template <class _Type>
-struct __is_trivially_move_assignable_unwrapped_impl<_Type*> : is_trivially_move_assignable<_Type> {};
-
-template <class _Iter>
-struct __is_trivially_move_assignable_unwrapped
- : __is_trivially_move_assignable_unwrapped_impl<decltype(std::__unwrap_iter<_Iter>(std::declval<_Iter>()))> {};
-
-template <class _AlgPolicy,
- class _InIter,
- class _OutIter,
- __enable_if_t<is_same<__remove_const_t<typename iterator_traits<_InIter>::value_type>,
- typename iterator_traits<_OutIter>::value_type>::value
- && __is_cpp17_contiguous_iterator<_InIter>::value
- && __is_cpp17_contiguous_iterator<_OutIter>::value
- && is_trivially_move_assignable<__iter_value_type<_OutIter> >::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
-pair<reverse_iterator<_InIter>, reverse_iterator<_OutIter> >
-__move_impl(reverse_iterator<_InIter> __first,
- reverse_iterator<_InIter> __last,
- reverse_iterator<_OutIter> __result) {
- auto __first_base = std::__unwrap_iter(__first.base());
- auto __last_base = std::__unwrap_iter(__last.base());
- auto __result_base = std::__unwrap_iter(__result.base());
- auto __result_first = __result_base - (__first_base - __last_base);
- std::__move_impl<_AlgPolicy>(__last_base, __first_base, __result_first);
- return std::make_pair(__last, reverse_iterator<_OutIter>(std::__rewrap_iter(__result.base(), __result_first)));
-}
+ template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+ operator()(_InIter __first, _InIter __last, _OutIter __result) const {
+ using _Traits = __segmented_iterator_traits<_InIter>;
+ auto __sfirst = _Traits::__segment(__first);
+ auto __slast = _Traits::__segment(__last);
+ if (__sfirst == __slast) {
+ auto __iters = std::__move<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
+ return std::make_pair(__last, std::move(__iters.second));
+ }
+
+ __result = std::__move<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__sfirst), std::move(__result)).second;
+ ++__sfirst;
+ while (__sfirst != __slast) {
+ __result =
+ std::__move<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), std::move(__result)).second;
+ ++__sfirst;
+ }
+ __result =
+ std::__move<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__local(__last), std::move(__result)).second;
+ return std::make_pair(__last, std::move(__result));
+ }
-template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
-__enable_if_t<is_copy_constructible<_InIter>::value
- && is_copy_constructible<_Sent>::value
- && is_copy_constructible<_OutIter>::value, pair<_InIter, _OutIter> >
-__move(_InIter __first, _Sent __last, _OutIter __result) {
- auto __ret = std::__move_impl<_AlgPolicy>(
- std::__unwrap_iter(__first), std::__unwrap_iter(__last), std::__unwrap_iter(__result));
- return std::make_pair(std::__rewrap_iter(__first, __ret.first), std::__rewrap_iter(__result, __ret.second));
-}
+ template <class _InIter,
+ class _OutIter,
+ __enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value &&
+ !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
+ int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+ operator()(_InIter __first, _InIter __last, _OutIter __result) {
+ using _Traits = __segmented_iterator_traits<_OutIter>;
+ using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
+
+ if (__first == __last)
+ return std::make_pair(std::move(__first), std::move(__result));
+
+ auto __local_first = _Traits::__local(__result);
+ auto __segment_iterator = _Traits::__segment(__result);
+ while (true) {
+ auto __local_last = _Traits::__end(__segment_iterator);
+ auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first);
+ auto __iters = std::__move<_AlgPolicy>(__first, __first + __size, __local_first);
+ __first = std::move(__iters.first);
+
+ if (__first == __last)
+ return std::make_pair(std::move(__first), _Traits::__compose(__segment_iterator, std::move(__iters.second)));
+
+ __local_first = _Traits::__begin(++__segment_iterator);
+ }
+ }
+};
+
+struct __move_trivial {
+ // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
+ template <class _In, class _Out,
+ __enable_if_t<__can_lower_move_assignment_to_memmove<_In, _Out>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
+ operator()(_In* __first, _In* __last, _Out* __result) const {
+ return std::__copy_trivial_impl(__first, __last, __result);
+ }
+};
template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
-__enable_if_t<!is_copy_constructible<_InIter>::value
- || !is_copy_constructible<_Sent>::value
- || !is_copy_constructible<_OutIter>::value, pair<_InIter, _OutIter> >
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
__move(_InIter __first, _Sent __last, _OutIter __result) {
- return std::__move_impl<_AlgPolicy>(std::move(__first), std::move(__last), std::move(__result));
+ return std::__dispatch_copy_or_move<_AlgPolicy, __move_loop<_AlgPolicy>, __move_trivial>(
+ std::move(__first), std::move(__last), std::move(__result));
}
template <class _InputIterator, class _OutputIterator>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
-_OutputIterator move(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
- return std::__move<_ClassicAlgPolicy>(__first, __last, __result).second;
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
+move(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
+ static_assert(is_copy_constructible<_InputIterator>::value, "Iterators has to be copy constructible.");
+ static_assert(is_copy_constructible<_OutputIterator>::value, "The output iterator has to be copy constructible.");
+
+ return std::__move<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)).second;
}
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___ALGORITHM_MOVE_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/move_backward.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/move_backward.h
index 02aae26fc4..d4f013be68 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/move_backward.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/move_backward.h
@@ -9,81 +9,131 @@
#ifndef _LIBCPP___ALGORITHM_MOVE_BACKWARD_H
#define _LIBCPP___ALGORITHM_MOVE_BACKWARD_H
+#include <__algorithm/copy_move_common.h>
#include <__algorithm/iterator_operations.h>
-#include <__algorithm/unwrap_iter.h>
+#include <__algorithm/min.h>
#include <__config>
+#include <__iterator/segmented_iterator.h>
+#include <__type_traits/common_type.h>
+#include <__type_traits/is_copy_constructible.h>
#include <__utility/move.h>
-#include <cstring>
-#include <type_traits>
+#include <__utility/pair.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _AlgPolicy, class _InputIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
-_OutputIterator
-__move_backward_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
-{
- while (__first != __last)
- *--__result = _IterOps<_AlgPolicy>::__iter_move(--__last);
- return __result;
-}
+template <class _AlgPolicy, class _BidirectionalIterator1, class _Sentinel, class _BidirectionalIterator2>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2>
+__move_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result);
-template <class _AlgPolicy, class _InputIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
-_OutputIterator
-__move_backward_impl(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
-{
- return _VSTD::__move_backward_constexpr<_AlgPolicy>(__first, __last, __result);
-}
+template <class _AlgPolicy>
+struct __move_backward_loop {
+ template <class _InIter, class _Sent, class _OutIter>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+ operator()(_InIter __first, _Sent __last, _OutIter __result) const {
+ auto __last_iter = _IterOps<_AlgPolicy>::next(__first, __last);
+ auto __original_last_iter = __last_iter;
-template <class _AlgPolicy, class _Tp, class _Up>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
-typename enable_if
-<
- is_same<__remove_const_t<_Tp>, _Up>::value &&
- is_trivially_move_assignable<_Up>::value,
- _Up*
->::type
-__move_backward_impl(_Tp* __first, _Tp* __last, _Up* __result)
-{
- const size_t __n = static_cast<size_t>(__last - __first);
- if (__n > 0)
- {
- __result -= __n;
- _VSTD::memmove(__result, __first, __n * sizeof(_Up));
+ while (__first != __last_iter) {
+ *--__result = _IterOps<_AlgPolicy>::__iter_move(--__last_iter);
}
- return __result;
-}
-template <class _AlgPolicy, class _BidirectionalIterator1, class _BidirectionalIterator2>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
-_BidirectionalIterator2
-__move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
- _BidirectionalIterator2 __result)
-{
- if (__libcpp_is_constant_evaluated()) {
- return _VSTD::__move_backward_constexpr<_AlgPolicy>(__first, __last, __result);
- } else {
- return _VSTD::__rewrap_iter(__result,
- _VSTD::__move_backward_impl<_AlgPolicy>(_VSTD::__unwrap_iter(__first),
- _VSTD::__unwrap_iter(__last),
- _VSTD::__unwrap_iter(__result)));
+ return std::make_pair(std::move(__original_last_iter), std::move(__result));
+ }
+
+ template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+ operator()(_InIter __first, _InIter __last, _OutIter __result) const {
+ using _Traits = __segmented_iterator_traits<_InIter>;
+ auto __sfirst = _Traits::__segment(__first);
+ auto __slast = _Traits::__segment(__last);
+ if (__sfirst == __slast) {
+ auto __iters =
+ std::__move_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
+ return std::make_pair(__last, __iters.second);
+ }
+
+ __result =
+ std::__move_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__local(__last), std::move(__result))
+ .second;
+ --__slast;
+ while (__sfirst != __slast) {
+ __result =
+ std::__move_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__end(__slast), std::move(__result))
+ .second;
+ --__slast;
+ }
+ __result = std::__move_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__slast), std::move(__result))
+ .second;
+ return std::make_pair(__last, std::move(__result));
+ }
+
+ template <class _InIter,
+ class _OutIter,
+ __enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value &&
+ !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
+ int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+ operator()(_InIter __first, _InIter __last, _OutIter __result) {
+ using _Traits = __segmented_iterator_traits<_OutIter>;
+ using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
+
+ // When the range contains no elements, __result might not be a valid iterator
+ if (__first == __last)
+ return std::make_pair(__first, __result);
+
+ auto __orig_last = __last;
+
+ auto __local_last = _Traits::__local(__result);
+ auto __segment_iterator = _Traits::__segment(__result);
+ while (true) {
+ auto __local_first = _Traits::__begin(__segment_iterator);
+ auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first);
+ auto __iter = std::__move_backward<_AlgPolicy>(__last - __size, __last, __local_last).second;
+ __last -= __size;
+
+ if (__first == __last)
+ return std::make_pair(std::move(__orig_last), _Traits::__compose(__segment_iterator, std::move(__iter)));
+
+ __local_last = _Traits::__end(--__segment_iterator);
}
+ }
+};
+
+struct __move_backward_trivial {
+ // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
+ template <class _In, class _Out,
+ __enable_if_t<__can_lower_move_assignment_to_memmove<_In, _Out>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
+ operator()(_In* __first, _In* __last, _Out* __result) const {
+ return std::__copy_backward_trivial_impl(__first, __last, __result);
+ }
+};
+
+template <class _AlgPolicy, class _BidirectionalIterator1, class _Sentinel, class _BidirectionalIterator2>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2>
+__move_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result) {
+ static_assert(std::is_copy_constructible<_BidirectionalIterator1>::value &&
+ std::is_copy_constructible<_BidirectionalIterator1>::value, "Iterators must be copy constructible.");
+
+ return std::__dispatch_copy_or_move<_AlgPolicy, __move_backward_loop<_AlgPolicy>, __move_backward_trivial>(
+ std::move(__first), std::move(__last), std::move(__result));
}
template <class _BidirectionalIterator1, class _BidirectionalIterator2>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
-_BidirectionalIterator2
-move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
- _BidirectionalIterator2 __result)
-{
- return std::__move_backward<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result));
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _BidirectionalIterator2
+move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, _BidirectionalIterator2 __result) {
+ return std::__move_backward<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)).second;
}
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___ALGORITHM_MOVE_BACKWARD_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/partial_sort.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/partial_sort.h
index 861a5b28dd..e0812affe6 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/partial_sort.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/partial_sort.h
@@ -47,7 +47,6 @@ _RandomAccessIterator __partial_sort_impl(
_IterOps<_AlgPolicy>::iter_swap(__i, __first);
std::__sift_down<_AlgPolicy>(__first, __comp, __len, __first);
}
-
}
std::__sort_heap<_AlgPolicy>(std::move(__first), std::move(__middle), __comp);
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_binary_search.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_binary_search.h
index b2a8977652..d72d4e0574 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_binary_search.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_binary_search.h
@@ -36,7 +36,7 @@ struct __fn {
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
bool operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
- return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__first));
+ return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret));
}
template <forward_range _Range, class _Type, class _Proj = identity,
@@ -46,7 +46,7 @@ struct __fn {
auto __first = ranges::begin(__r);
auto __last = ranges::end(__r);
auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
- return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__first));
+ return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret));
}
};
} // namespace __binary_search
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy.h
index 87a6a1e136..bb02c84efb 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy.h
@@ -11,6 +11,7 @@
#include <__algorithm/copy.h>
#include <__algorithm/in_out_result.h>
+#include <__algorithm/iterator_operations.h>
#include <__config>
#include <__functional/identity.h>
#include <__iterator/concepts.h>
@@ -40,7 +41,7 @@ struct __fn {
requires indirectly_copyable<_InIter, _OutIter>
_LIBCPP_HIDE_FROM_ABI constexpr
copy_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const {
- auto __ret = std::__copy(std::move(__first), std::move(__last), std::move(__result));
+ auto __ret = std::__copy<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result));
return {std::move(__ret.first), std::move(__ret.second)};
}
@@ -48,7 +49,7 @@ struct __fn {
requires indirectly_copyable<iterator_t<_Range>, _OutIter>
_LIBCPP_HIDE_FROM_ABI constexpr
copy_result<borrowed_iterator_t<_Range>, _OutIter> operator()(_Range&& __r, _OutIter __result) const {
- auto __ret = std::__copy(ranges::begin(__r), ranges::end(__r), std::move(__result));
+ auto __ret = std::__copy<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), std::move(__result));
return {std::move(__ret.first), std::move(__ret.second)};
}
};
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy_backward.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy_backward.h
index 67977201fa..f41af66f39 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy_backward.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy_backward.h
@@ -14,7 +14,6 @@
#include <__algorithm/iterator_operations.h>
#include <__config>
#include <__iterator/concepts.h>
-#include <__iterator/reverse_iterator.h>
#include <__ranges/access.h>
#include <__ranges/concepts.h>
#include <__ranges/dangling.h>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy_n.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy_n.h
index 38a0a308d3..04bb80b3ba 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy_n.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_copy_n.h
@@ -11,6 +11,7 @@
#include <__algorithm/copy.h>
#include <__algorithm/in_out_result.h>
+#include <__algorithm/iterator_operations.h>
#include <__algorithm/ranges_copy.h>
#include <__config>
#include <__functional/identity.h>
@@ -51,7 +52,7 @@ struct __fn {
template <random_access_iterator _InIter, class _DiffType, random_access_iterator _OutIter>
_LIBCPP_HIDE_FROM_ABI constexpr static
copy_n_result<_InIter, _OutIter> __go(_InIter __first, _DiffType __n, _OutIter __result) {
- auto __ret = std::__copy(__first, __first + __n, __result);
+ auto __ret = std::__copy<_RangeAlgPolicy>(__first, __first + __n, __result);
return {__ret.first, __ret.second};
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_iterator_concept.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_iterator_concept.h
index c2a508dc9a..3ac6b31703 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_iterator_concept.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_iterator_concept.h
@@ -12,7 +12,7 @@
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/iterator_traits.h>
-#include <type_traits>
+#include <__type_traits/remove_cvref.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_move.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_move.h
index 94f9970ed2..46a0970f83 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_move.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_move.h
@@ -14,7 +14,6 @@
#include <__algorithm/move.h>
#include <__config>
#include <__iterator/concepts.h>
-#include <__iterator/iter_move.h>
#include <__ranges/access.h>
#include <__ranges/concepts.h>
#include <__ranges/dangling.h>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_move_backward.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_move_backward.h
index 134e087737..d4e8eb1a50 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_move_backward.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_move_backward.h
@@ -10,12 +10,12 @@
#define _LIBCPP___ALGORITHM_RANGES_MOVE_BACKWARD_H
#include <__algorithm/in_out_result.h>
-#include <__algorithm/ranges_move.h>
+#include <__algorithm/iterator_operations.h>
+#include <__algorithm/move_backward.h>
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/iter_move.h>
#include <__iterator/next.h>
-#include <__iterator/reverse_iterator.h>
#include <__ranges/access.h>
#include <__ranges/concepts.h>
#include <__ranges/dangling.h>
@@ -40,11 +40,8 @@ struct __fn {
template <class _InIter, class _Sent, class _OutIter>
_LIBCPP_HIDE_FROM_ABI constexpr static
move_backward_result<_InIter, _OutIter> __move_backward_impl(_InIter __first, _Sent __last, _OutIter __result) {
- auto __last_iter = ranges::next(__first, std::move(__last));
- auto __ret = ranges::move(std::make_reverse_iterator(__last_iter),
- std::make_reverse_iterator(__first),
- std::make_reverse_iterator(__result));
- return {std::move(__last_iter), std::move(__ret.out.base())};
+ auto __ret = std::__move_backward<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result));
+ return {std::move(__ret.first), std::move(__ret.second)};
}
template <bidirectional_iterator _InIter, sentinel_for<_InIter> _Sent, bidirectional_iterator _OutIter>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_search_n.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_search_n.h
index f44afde03e..56ec8f33d4 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_search_n.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_search_n.h
@@ -53,12 +53,8 @@ struct __fn {
}
if constexpr (random_access_iterator<_Iter1>) {
- auto __ret = __search_n_random_access_impl<_RangeAlgPolicy>(__first, __last,
- __count,
- __value,
- __pred,
- __proj,
- __size);
+ auto __ret = std::__search_n_random_access_impl<_RangeAlgPolicy>(
+ __first, __last, __count, __value, __pred, __proj, __size);
return {std::move(__ret.first), std::move(__ret.second)};
}
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_difference.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_difference.h
index 398ccc975f..607dd687a5 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_difference.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_difference.h
@@ -10,6 +10,7 @@
#define _LIBCPP___ALGORITHM_RANGES_SET_DIFFERENCE_H
#include <__algorithm/in_out_result.h>
+#include <__algorithm/iterator_operations.h>
#include <__algorithm/make_projected.h>
#include <__algorithm/set_difference.h>
#include <__config>
@@ -60,7 +61,7 @@ struct __fn {
_Comp __comp = {},
_Proj1 __proj1 = {},
_Proj2 __proj2 = {}) const {
- auto __ret = std::__set_difference(
+ auto __ret = std::__set_difference<_RangeAlgPolicy>(
__first1, __last1, __first2, __last2, __result, ranges::__make_projected_comp(__comp, __proj1, __proj2));
return {std::move(__ret.first), std::move(__ret.second)};
}
@@ -81,7 +82,7 @@ struct __fn {
_Comp __comp = {},
_Proj1 __proj1 = {},
_Proj2 __proj2 = {}) const {
- auto __ret = std::__set_difference(
+ auto __ret = std::__set_difference<_RangeAlgPolicy>(
ranges::begin(__range1),
ranges::end(__range1),
ranges::begin(__range2),
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_symmetric_difference.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_symmetric_difference.h
index b0c79537b1..bc4a906550 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_symmetric_difference.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_symmetric_difference.h
@@ -10,6 +10,7 @@
#define _LIBCPP___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H
#include <__algorithm/in_in_out_result.h>
+#include <__algorithm/iterator_operations.h>
#include <__algorithm/make_projected.h>
#include <__algorithm/set_symmetric_difference.h>
#include <__config>
@@ -58,7 +59,7 @@ struct __fn {
_Comp __comp = {},
_Proj1 __proj1 = {},
_Proj2 __proj2 = {}) const {
- auto __ret = std::__set_symmetric_difference(
+ auto __ret = std::__set_symmetric_difference<_RangeAlgPolicy>(
std::move(__first1),
std::move(__last1),
std::move(__first2),
@@ -92,7 +93,7 @@ struct __fn {
_Comp __comp = {},
_Proj1 __proj1 = {},
_Proj2 __proj2 = {}) const {
- auto __ret = std::__set_symmetric_difference(
+ auto __ret = std::__set_symmetric_difference<_RangeAlgPolicy>(
ranges::begin(__range1),
ranges::end(__range1),
ranges::begin(__range2),
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_union.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_union.h
index 500c0b2c2d..f8cd45ca0e 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_union.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/ranges_set_union.h
@@ -10,6 +10,7 @@
#define _LIBCPP___ALGORITHM_RANGES_SET_UNION_H
#include <__algorithm/in_in_out_result.h>
+#include <__algorithm/iterator_operations.h>
#include <__algorithm/make_projected.h>
#include <__algorithm/set_union.h>
#include <__config>
@@ -61,7 +62,7 @@ struct __fn {
_Comp __comp = {},
_Proj1 __proj1 = {},
_Proj2 __proj2 = {}) const {
- auto __ret = std::__set_union(
+ auto __ret = std::__set_union<_RangeAlgPolicy>(
std::move(__first1),
std::move(__last1),
std::move(__first2),
@@ -95,7 +96,7 @@ struct __fn {
_Comp __comp = {},
_Proj1 __proj1 = {},
_Proj2 __proj2 = {}) const {
- auto __ret = std::__set_union(
+ auto __ret = std::__set_union<_RangeAlgPolicy>(
ranges::begin(__range1),
ranges::end(__range1),
ranges::begin(__range2),
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/rotate.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/rotate.h
index 32682936e3..8934ce095b 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/rotate.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/rotate.h
@@ -48,7 +48,7 @@ __rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last)
_BidirectionalIterator __lm1 = _Ops::prev(__last);
value_type __tmp = _Ops::__iter_move(__lm1);
- _BidirectionalIterator __fp1 = std::__move_backward<_AlgPolicy>(__first, __lm1, std::move(__last));
+ _BidirectionalIterator __fp1 = std::__move_backward<_AlgPolicy>(__first, __lm1, std::move(__last)).second;
*__first = _VSTD::move(__tmp);
return __fp1;
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_difference.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_difference.h
index e0385bf822..cffdc8fc4f 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_difference.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_difference.h
@@ -12,6 +12,7 @@
#include <__algorithm/comp.h>
#include <__algorithm/comp_ref_type.h>
#include <__algorithm/copy.h>
+#include <__algorithm/iterator_operations.h>
#include <__config>
#include <__functional/identity.h>
#include <__functional/invoke.h>
@@ -26,7 +27,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template < class _Comp, class _InIter1, class _Sent1, class _InIter2, class _Sent2, class _OutIter>
+template <class _AlgPolicy, class _Comp, class _InIter1, class _Sent1, class _InIter2, class _Sent2, class _OutIter>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<__remove_cvref_t<_InIter1>, __remove_cvref_t<_OutIter> >
__set_difference(
_InIter1&& __first1, _Sent1&& __last1, _InIter2&& __first2, _Sent2&& __last2, _OutIter&& __result, _Comp&& __comp) {
@@ -42,7 +43,7 @@ __set_difference(
++__first2;
}
}
- return std::__copy(std::move(__first1), std::move(__last1), std::move(__result));
+ return std::__copy<_AlgPolicy>(std::move(__first1), std::move(__last1), std::move(__result));
}
template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
@@ -53,7 +54,8 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_d
_InputIterator2 __last2,
_OutputIterator __result,
_Compare __comp) {
- return std::__set_difference<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __result, __comp)
+ return std::__set_difference<_ClassicAlgPolicy, __comp_ref_type<_Compare> >(
+ __first1, __last1, __first2, __last2, __result, __comp)
.second;
}
@@ -64,7 +66,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_d
_InputIterator2 __first2,
_InputIterator2 __last2,
_OutputIterator __result) {
- return std::__set_difference(
+ return std::__set_difference<_ClassicAlgPolicy>(
__first1,
__last1,
__first2,
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_symmetric_difference.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_symmetric_difference.h
index 97d3f1da7c..bcb0958703 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_symmetric_difference.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_symmetric_difference.h
@@ -12,6 +12,7 @@
#include <__algorithm/comp.h>
#include <__algorithm/comp_ref_type.h>
#include <__algorithm/copy.h>
+#include <__algorithm/iterator_operations.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__utility/move.h>
@@ -35,13 +36,13 @@ struct __set_symmetric_difference_result {
: __in1_(std::move(__in_iter1)), __in2_(std::move(__in_iter2)), __out_(std::move(__out_iter)) {}
};
-template <class _Compare, class _InIter1, class _Sent1, class _InIter2, class _Sent2, class _OutIter>
+template <class _AlgPolicy, class _Compare, class _InIter1, class _Sent1, class _InIter2, class _Sent2, class _OutIter>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __set_symmetric_difference_result<_InIter1, _InIter2, _OutIter>
__set_symmetric_difference(
_InIter1 __first1, _Sent1 __last1, _InIter2 __first2, _Sent2 __last2, _OutIter __result, _Compare&& __comp) {
while (__first1 != __last1) {
if (__first2 == __last2) {
- auto __ret1 = std::__copy_impl(std::move(__first1), std::move(__last1), std::move(__result));
+ auto __ret1 = std::__copy<_AlgPolicy>(std::move(__first1), std::move(__last1), std::move(__result));
return __set_symmetric_difference_result<_InIter1, _InIter2, _OutIter>(
std::move(__ret1.first), std::move(__first2), std::move((__ret1.second)));
}
@@ -59,7 +60,7 @@ __set_symmetric_difference(
++__first2;
}
}
- auto __ret2 = std::__copy_impl(std::move(__first2), std::move(__last2), std::move(__result));
+ auto __ret2 = std::__copy<_AlgPolicy>(std::move(__first2), std::move(__last2), std::move(__result));
return __set_symmetric_difference_result<_InIter1, _InIter2, _OutIter>(
std::move(__first1), std::move(__ret2.first), std::move((__ret2.second)));
}
@@ -72,7 +73,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_symmetri
_InputIterator2 __last2,
_OutputIterator __result,
_Compare __comp) {
- return std::__set_symmetric_difference<__comp_ref_type<_Compare> >(
+ return std::__set_symmetric_difference<_ClassicAlgPolicy, __comp_ref_type<_Compare> >(
std::move(__first1),
std::move(__last1),
std::move(__first2),
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_union.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_union.h
index addc77b7d8..4d154b81e0 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_union.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/set_union.h
@@ -12,6 +12,7 @@
#include <__algorithm/comp.h>
#include <__algorithm/comp_ref_type.h>
#include <__algorithm/copy.h>
+#include <__algorithm/iterator_operations.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__utility/move.h>
@@ -35,12 +36,12 @@ struct __set_union_result {
: __in1_(std::move(__in_iter1)), __in2_(std::move(__in_iter2)), __out_(std::move(__out_iter)) {}
};
-template <class _Compare, class _InIter1, class _Sent1, class _InIter2, class _Sent2, class _OutIter>
+template <class _AlgPolicy, class _Compare, class _InIter1, class _Sent1, class _InIter2, class _Sent2, class _OutIter>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __set_union_result<_InIter1, _InIter2, _OutIter> __set_union(
_InIter1 __first1, _Sent1 __last1, _InIter2 __first2, _Sent2 __last2, _OutIter __result, _Compare&& __comp) {
for (; __first1 != __last1; ++__result) {
if (__first2 == __last2) {
- auto __ret1 = std::__copy_impl(std::move(__first1), std::move(__last1), std::move(__result));
+ auto __ret1 = std::__copy<_AlgPolicy>(std::move(__first1), std::move(__last1), std::move(__result));
return __set_union_result<_InIter1, _InIter2, _OutIter>(
std::move(__ret1.first), std::move(__first2), std::move((__ret1.second)));
}
@@ -55,7 +56,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __set_union_result<_InIter1,
++__first1;
}
}
- auto __ret2 = std::__copy_impl(std::move(__first2), std::move(__last2), std::move(__result));
+ auto __ret2 = std::__copy<_AlgPolicy>(std::move(__first2), std::move(__last2), std::move(__result));
return __set_union_result<_InIter1, _InIter2, _OutIter>(
std::move(__first1), std::move(__ret2.first), std::move((__ret2.second)));
}
@@ -68,7 +69,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_union(
_InputIterator2 __last2,
_OutputIterator __result,
_Compare __comp) {
- return std::__set_union<__comp_ref_type<_Compare> >(
+ return std::__set_union<_ClassicAlgPolicy, __comp_ref_type<_Compare> >(
std::move(__first1),
std::move(__last1),
std::move(__first2),
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/shuffle.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/shuffle.h
index c2f5c37efa..f7bce68697 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/shuffle.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/shuffle.h
@@ -16,6 +16,7 @@
#include <__random/uniform_int_distribution.h>
#include <__utility/forward.h>
#include <__utility/move.h>
+#include <__utility/swap.h>
#include <cstddef>
#include <cstdint>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/sort.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/sort.h
index 81f6eeb238..a236be0a4d 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/sort.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/sort.h
@@ -15,7 +15,6 @@
#include <__algorithm/min_element.h>
#include <__algorithm/partial_sort.h>
#include <__algorithm/unwrap_iter.h>
-#include <__bits>
#include <__config>
#include <__debug>
#include <__debug_utils/randomize_range.h>
@@ -24,8 +23,13 @@
#include <__iterator/iterator_traits.h>
#include <__memory/destruct_n.h>
#include <__memory/unique_ptr.h>
+#include <__type_traits/is_arithmetic.h>
+#include <__type_traits/is_trivially_copy_assignable.h>
+#include <__type_traits/is_trivially_copy_constructible.h>
#include <__utility/move.h>
+#include <bit>
#include <climits>
+#include <cstdint>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -626,7 +630,7 @@ inline _LIBCPP_HIDE_FROM_ABI _Number __log2i(_Number __n) {
template <class _WrappedComp, class _RandomAccessIterator>
_LIBCPP_HIDDEN void __sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _WrappedComp __wrapped_comp) {
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
- difference_type __depth_limit = 2 * __log2i(__last - __first);
+ difference_type __depth_limit = 2 * std::__log2i(__last - __first);
using _Unwrap = _UnwrapAlgPolicy<_WrappedComp>;
using _AlgPolicy = typename _Unwrap::_AlgPolicy;
diff --git a/contrib/libs/cxxsupp/libcxx/include/__algorithm/unwrap_iter.h b/contrib/libs/cxxsupp/libcxx/include/__algorithm/unwrap_iter.h
index 07d8d23e33..0f661e10a7 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__algorithm/unwrap_iter.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__algorithm/unwrap_iter.h
@@ -12,8 +12,10 @@
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__memory/pointer_traits.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_copy_constructible.h>
+#include <__utility/declval.h>
#include <__utility/move.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__assert b/contrib/libs/cxxsupp/libcxx/include/__assert
index 5905d28c02..9bfab8716e 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__assert
+++ b/contrib/libs/cxxsupp/libcxx/include/__assert
@@ -41,7 +41,7 @@
# define _LIBCPP_ASSERT(expression, message) \
(__builtin_expect(static_cast<bool>(expression), 1) ? \
(void)0 : \
- ::std::__libcpp_verbose_abort("%s:%d: assertion %s failed: %s", __FILE__, __LINE__, #expression, message))
+ _LIBCPP_VERBOSE_ABORT("%s:%d: assertion %s failed: %s", __FILE__, __LINE__, #expression, message))
// Disable Clang builtins which nvcc does not understand
#elif !defined(_LIBCPP_ASSERTIONS_DISABLE_ASSUME) && __has_builtin(__builtin_assume) && !defined(__CUDACC__)
# define _LIBCPP_ASSERT(expression, message) \
diff --git a/contrib/libs/cxxsupp/libcxx/include/__availability b/contrib/libs/cxxsupp/libcxx/include/__availability
index 72ff663334..6dfca3fa8b 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__availability
+++ b/contrib/libs/cxxsupp/libcxx/include/__availability
@@ -156,20 +156,9 @@
# define _LIBCPP_AVAILABILITY_FORMAT
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format
- // This controls whether the default verbose termination function is
- // provided by the library.
- //
- // Note that when users provide their own custom function, it doesn't
- // matter whether the dylib provides a default function, and the
- // availability markup can actually give a false positive diagnostic
- // (it will think that no function is provided, when in reality the
- // user has provided their own).
- //
- // Users can pass -D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED
- // to the compiler to tell the library not to define its own verbose abort.
- // Note that defining this macro but failing to define a custom function
- // will lead to a load-time error on back-deployment targets, so it should
- // be avoided.
+ // This controls whether the library claims to provide a default verbose
+ // termination function, and consequently whether the headers will try
+ // to use it when the mechanism isn't overriden at compile-time.
// # define _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY
#elif defined(__APPLE__)
diff --git a/contrib/libs/cxxsupp/libcxx/include/__bit/bit_cast.h b/contrib/libs/cxxsupp/libcxx/include/__bit/bit_cast.h
index 831207671e..2ca4120c76 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__bit/bit_cast.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__bit/bit_cast.h
@@ -11,7 +11,7 @@
#define _LIBCPP___BIT_BIT_CAST_H
#include <__config>
-#include <type_traits>
+#include <__type_traits/is_trivially_copyable.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__bit/bit_ceil.h b/contrib/libs/cxxsupp/libcxx/include/__bit/bit_ceil.h
new file mode 100644
index 0000000000..a558d61942
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__bit/bit_ceil.h
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___BIT_BIT_CEIL_H
+#define _LIBCPP___BIT_BIT_CEIL_H
+
+#include <__assert>
+#include <__bit/countl.h>
+#include <__concepts/arithmetic.h>
+#include <__config>
+#include <limits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_ceil(_Tp __t) noexcept {
+ if (__t < 2)
+ return 1;
+ const unsigned __n = numeric_limits<_Tp>::digits - std::countl_zero((_Tp)(__t - 1u));
+ _LIBCPP_ASSERT(__n != numeric_limits<_Tp>::digits, "Bad input to bit_ceil");
+
+ if constexpr (sizeof(_Tp) >= sizeof(unsigned))
+ return _Tp{1} << __n;
+ else {
+ const unsigned __extra = numeric_limits<unsigned>::digits - numeric_limits<_Tp>::digits;
+ const unsigned __retVal = 1u << (__n + __extra);
+ return (_Tp)(__retVal >> __extra);
+ }
+}
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___BIT_BIT_CEIL_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__bit/bit_floor.h b/contrib/libs/cxxsupp/libcxx/include/__bit/bit_floor.h
new file mode 100644
index 0000000000..b2e38092f2
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__bit/bit_floor.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___BIT_BIT_FLOOR_H
+#define _LIBCPP___BIT_BIT_FLOOR_H
+
+#include <__bit/bit_log2.h>
+#include <__concepts/arithmetic.h>
+#include <__config>
+#include <limits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_floor(_Tp __t) noexcept {
+ return __t == 0 ? 0 : _Tp{1} << std::__bit_log2(__t);
+}
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___BIT_BIT_FLOOR_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__bit/bit_log2.h b/contrib/libs/cxxsupp/libcxx/include/__bit/bit_log2.h
new file mode 100644
index 0000000000..62936f6786
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__bit/bit_log2.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___BIT_BIT_LOG2_H
+#define _LIBCPP___BIT_BIT_LOG2_H
+
+#include <__bit/countl.h>
+#include <__concepts/arithmetic.h>
+#include <__config>
+#include <limits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp __bit_log2(_Tp __t) noexcept {
+ return numeric_limits<_Tp>::digits - 1 - std::countl_zero(__t);
+}
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___BIT_BIT_LOG2_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__bit/bit_width.h b/contrib/libs/cxxsupp/libcxx/include/__bit/bit_width.h
new file mode 100644
index 0000000000..4381f227f5
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__bit/bit_width.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___BIT_BIT_WIDTH_H
+#define _LIBCPP___BIT_BIT_WIDTH_H
+
+#include <__bit/bit_log2.h>
+#include <__concepts/arithmetic.h>
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 20
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr int bit_width(_Tp __t) noexcept {
+ return __t == 0 ? 0 : std::__bit_log2(__t) + 1;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 20
+
+#endif // _LIBCPP___BIT_BIT_WIDTH_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__bit/blsr.h b/contrib/libs/cxxsupp/libcxx/include/__bit/blsr.h
new file mode 100644
index 0000000000..de991e9adb
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__bit/blsr.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___BIT_BLSR_H
+#define _LIBCPP___BIT_BLSR_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unsigned __libcpp_blsr(unsigned __x) _NOEXCEPT {
+ return __x ^ (__x & -__x);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unsigned long __libcpp_blsr(unsigned long __x) _NOEXCEPT {
+ return __x ^ (__x & -__x);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unsigned long long __libcpp_blsr(unsigned long long __x) _NOEXCEPT {
+ return __x ^ (__x & -__x);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___BIT_BLSR_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__bit/countl.h b/contrib/libs/cxxsupp/libcxx/include/__bit/countl.h
new file mode 100644
index 0000000000..86eaee0c1b
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__bit/countl.h
@@ -0,0 +1,104 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___BIT_COUNTL_H
+#define _LIBCPP___BIT_COUNTL_H
+
+#include <__bit/rotate.h>
+#include <__concepts/arithmetic.h>
+#include <__config>
+#include <__type_traits/is_unsigned_integer.h>
+#include <limits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+int __libcpp_clz(unsigned __x) _NOEXCEPT { return __builtin_clz(__x); }
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+int __libcpp_clz(unsigned long __x) _NOEXCEPT { return __builtin_clzl(__x); }
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+int __libcpp_clz(unsigned long long __x) _NOEXCEPT { return __builtin_clzll(__x); }
+
+# ifndef _LIBCPP_HAS_NO_INT128
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+int __libcpp_clz(__uint128_t __x) _NOEXCEPT {
+ // The function is written in this form due to C++ constexpr limitations.
+ // The algorithm:
+ // - Test whether any bit in the high 64-bits is set
+ // - No bits set:
+ // - The high 64-bits contain 64 leading zeros,
+ // - Add the result of the low 64-bits.
+ // - Any bits set:
+ // - The number of leading zeros of the input is the number of leading
+ // zeros in the high 64-bits.
+ return ((__x >> 64) == 0)
+ ? (64 + __builtin_clzll(static_cast<unsigned long long>(__x)))
+ : __builtin_clzll(static_cast<unsigned long long>(__x >> 64));
+}
+# endif // _LIBCPP_HAS_NO_INT128
+
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
+int __countl_zero(_Tp __t) _NOEXCEPT
+{
+ static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countl_zero requires an unsigned integer type");
+ if (__t == 0)
+ return numeric_limits<_Tp>::digits;
+
+ if (sizeof(_Tp) <= sizeof(unsigned int))
+ return std::__libcpp_clz(static_cast<unsigned int>(__t))
+ - (numeric_limits<unsigned int>::digits - numeric_limits<_Tp>::digits);
+ else if (sizeof(_Tp) <= sizeof(unsigned long))
+ return std::__libcpp_clz(static_cast<unsigned long>(__t))
+ - (numeric_limits<unsigned long>::digits - numeric_limits<_Tp>::digits);
+ else if (sizeof(_Tp) <= sizeof(unsigned long long))
+ return std::__libcpp_clz(static_cast<unsigned long long>(__t))
+ - (numeric_limits<unsigned long long>::digits - numeric_limits<_Tp>::digits);
+ else
+ {
+ int __ret = 0;
+ int __iter = 0;
+ const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits;
+ while (true) {
+ __t = std::__rotr(__t, __ulldigits);
+ if ((__iter = std::__countl_zero(static_cast<unsigned long long>(__t))) != __ulldigits)
+ break;
+ __ret += __iter;
+ }
+ return __ret + __iter;
+ }
+}
+
+#if _LIBCPP_STD_VER >= 20
+
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr int countl_zero(_Tp __t) noexcept {
+ return std::__countl_zero(__t);
+}
+
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept {
+ return __t != numeric_limits<_Tp>::max() ? std::countl_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits;
+}
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___BIT_COUNTL_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__bit/countr.h b/contrib/libs/cxxsupp/libcxx/include/__bit/countr.h
new file mode 100644
index 0000000000..d3ca5b6c94
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__bit/countr.h
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___BIT_COUNTR_H
+#define _LIBCPP___BIT_COUNTR_H
+
+#include <__bit/rotate.h>
+#include <__concepts/arithmetic.h>
+#include <__config>
+#include <limits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+int __libcpp_ctz(unsigned __x) _NOEXCEPT { return __builtin_ctz(__x); }
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+int __libcpp_ctz(unsigned long __x) _NOEXCEPT { return __builtin_ctzl(__x); }
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+int __libcpp_ctz(unsigned long long __x) _NOEXCEPT { return __builtin_ctzll(__x); }
+
+#if _LIBCPP_STD_VER >= 20
+
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept {
+ if (__t == 0)
+ return numeric_limits<_Tp>::digits;
+
+ if (sizeof(_Tp) <= sizeof(unsigned int))
+ return std::__libcpp_ctz(static_cast<unsigned int>(__t));
+ else if (sizeof(_Tp) <= sizeof(unsigned long))
+ return std::__libcpp_ctz(static_cast<unsigned long>(__t));
+ else if (sizeof(_Tp) <= sizeof(unsigned long long))
+ return std::__libcpp_ctz(static_cast<unsigned long long>(__t));
+ else {
+ int __ret = 0;
+ const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits;
+ while (static_cast<unsigned long long>(__t) == 0uLL) {
+ __ret += __ulldigits;
+ __t >>= __ulldigits;
+ }
+ return __ret + std::__libcpp_ctz(static_cast<unsigned long long>(__t));
+ }
+}
+
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept {
+ return __t != numeric_limits<_Tp>::max() ? std::countr_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits;
+}
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___BIT_COUNTR_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__bit/endian.h b/contrib/libs/cxxsupp/libcxx/include/__bit/endian.h
new file mode 100644
index 0000000000..52635f2d24
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__bit/endian.h
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___BIT_ENDIAN_H
+#define _LIBCPP___BIT_ENDIAN_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 20
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+enum class endian {
+ little = 0xDEAD,
+ big = 0xFACE,
+# if defined(_LIBCPP_LITTLE_ENDIAN)
+ native = little
+# elif defined(_LIBCPP_BIG_ENDIAN)
+ native = big
+# else
+ native = 0xCAFE
+# endif
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 20
+
+#endif // _LIBCPP___BIT_ENDIAN_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__bit/has_single_bit.h b/contrib/libs/cxxsupp/libcxx/include/__bit/has_single_bit.h
new file mode 100644
index 0000000000..b89f5995b3
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__bit/has_single_bit.h
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___BIT_HAS_SINGLE_BIT_H
+#define _LIBCPP___BIT_HAS_SINGLE_BIT_H
+
+#include <__concepts/arithmetic.h>
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if _LIBCPP_STD_VER >= 20
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept {
+ return __t != 0 && (((__t & (__t - 1)) == 0));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___BIT_HAS_SINGLE_BIT_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__bit/popcount.h b/contrib/libs/cxxsupp/libcxx/include/__bit/popcount.h
new file mode 100644
index 0000000000..33b94cff71
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__bit/popcount.h
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___BIT_POPCOUNT_H
+#define _LIBCPP___BIT_POPCOUNT_H
+
+#include <__bit/rotate.h>
+#include <__concepts/arithmetic.h>
+#include <__config>
+#include <limits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+int __libcpp_popcount(unsigned __x) _NOEXCEPT { return __builtin_popcount(__x); }
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+int __libcpp_popcount(unsigned long __x) _NOEXCEPT { return __builtin_popcountl(__x); }
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+int __libcpp_popcount(unsigned long long __x) _NOEXCEPT { return __builtin_popcountll(__x); }
+
+#if _LIBCPP_STD_VER >= 20
+
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept {
+ if (sizeof(_Tp) <= sizeof(unsigned int))
+ return std::__libcpp_popcount(static_cast<unsigned int>(__t));
+ else if (sizeof(_Tp) <= sizeof(unsigned long))
+ return std::__libcpp_popcount(static_cast<unsigned long>(__t));
+ else if (sizeof(_Tp) <= sizeof(unsigned long long))
+ return std::__libcpp_popcount(static_cast<unsigned long long>(__t));
+ else {
+ int __ret = 0;
+ while (__t != 0) {
+ __ret += std::__libcpp_popcount(static_cast<unsigned long long>(__t));
+ __t >>= numeric_limits<unsigned long long>::digits;
+ }
+ return __ret;
+ }
+}
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___BIT_POPCOUNT_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__bit/rotate.h b/contrib/libs/cxxsupp/libcxx/include/__bit/rotate.h
new file mode 100644
index 0000000000..5aa7518b3c
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__bit/rotate.h
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___BIT_ROTATE_H
+#define _LIBCPP___BIT_ROTATE_H
+
+#include <__concepts/arithmetic.h>
+#include <__config>
+#include <__type_traits/is_unsigned_integer.h>
+#include <limits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template<class _Tp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
+_Tp __rotr(_Tp __t, unsigned int __cnt) _NOEXCEPT
+{
+ static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotr requires an unsigned integer type");
+ const unsigned int __dig = numeric_limits<_Tp>::digits;
+ if ((__cnt % __dig) == 0)
+ return __t;
+ return (__t >> (__cnt % __dig)) | (__t << (__dig - (__cnt % __dig)));
+}
+
+#if _LIBCPP_STD_VER >= 20
+
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, unsigned int __cnt) noexcept {
+ const unsigned int __dig = numeric_limits<_Tp>::digits;
+ if ((__cnt % __dig) == 0)
+ return __t;
+ return (__t << (__cnt % __dig)) | (__t >> (__dig - (__cnt % __dig)));
+}
+
+template <__libcpp_unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, unsigned int __cnt) noexcept {
+ return std::__rotr(__t, __cnt);
+}
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___BIT_ROTATE_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__bit_reference b/contrib/libs/cxxsupp/libcxx/include/__bit_reference
index e104a989fa..5cfa8ecee1 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__bit_reference
+++ b/contrib/libs/cxxsupp/libcxx/include/__bit_reference
@@ -13,7 +13,8 @@
#include <__algorithm/copy_n.h>
#include <__algorithm/fill_n.h>
#include <__algorithm/min.h>
-#include <__bits>
+#include <__bit/countr.h>
+#include <__bit/popcount.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__memory/construct_at.h>
@@ -54,6 +55,8 @@ class __bit_reference
friend class __bit_const_reference<_Cp>;
friend class __bit_iterator<_Cp, false>;
public:
+ using __container = typename _Cp::__self;
+
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
__bit_reference(const __bit_reference&) = default;
@@ -88,7 +91,7 @@ public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void flip() _NOEXCEPT {*__seg_ ^= __mask_;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> operator&() const _NOEXCEPT
- {return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(__libcpp_ctz(__mask_)));}
+ {return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(std::__libcpp_ctz(__mask_)));}
private:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
explicit __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
@@ -163,7 +166,7 @@ public:
{return static_cast<bool>(*__seg_ & __mask_);}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, true> operator&() const _NOEXCEPT
- {return __bit_iterator<_Cp, true>(__seg_, static_cast<unsigned>(__libcpp_ctz(__mask_)));}
+ {return __bit_iterator<_Cp, true>(__seg_, static_cast<unsigned>(std::__libcpp_ctz(__mask_)));}
private:
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR
diff --git a/contrib/libs/cxxsupp/libcxx/include/__bits b/contrib/libs/cxxsupp/libcxx/include/__bits
deleted file mode 100644
index d2c8439a6b..0000000000
--- a/contrib/libs/cxxsupp/libcxx/include/__bits
+++ /dev/null
@@ -1,75 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___BITS
-#define _LIBCPP___BITS
-
-#include <__config>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-int __libcpp_ctz(unsigned __x) _NOEXCEPT { return __builtin_ctz(__x); }
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-int __libcpp_ctz(unsigned long __x) _NOEXCEPT { return __builtin_ctzl(__x); }
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-int __libcpp_ctz(unsigned long long __x) _NOEXCEPT { return __builtin_ctzll(__x); }
-
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-int __libcpp_clz(unsigned __x) _NOEXCEPT { return __builtin_clz(__x); }
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-int __libcpp_clz(unsigned long __x) _NOEXCEPT { return __builtin_clzl(__x); }
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-int __libcpp_clz(unsigned long long __x) _NOEXCEPT { return __builtin_clzll(__x); }
-
-# ifndef _LIBCPP_HAS_NO_INT128
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-int __libcpp_clz(__uint128_t __x) _NOEXCEPT {
- // The function is written in this form due to C++ constexpr limitations.
- // The algorithm:
- // - Test whether any bit in the high 64-bits is set
- // - No bits set:
- // - The high 64-bits contain 64 leading zeros,
- // - Add the result of the low 64-bits.
- // - Any bits set:
- // - The number of leading zeros of the input is the number of leading
- // zeros in the high 64-bits.
- return ((__x >> 64) == 0)
- ? (64 + __builtin_clzll(static_cast<unsigned long long>(__x)))
- : __builtin_clzll(static_cast<unsigned long long>(__x >> 64));
-}
-# endif
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-int __libcpp_popcount(unsigned __x) _NOEXCEPT { return __builtin_popcount(__x); }
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-int __libcpp_popcount(unsigned long __x) _NOEXCEPT { return __builtin_popcountl(__x); }
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-int __libcpp_popcount(unsigned long long __x) _NOEXCEPT { return __builtin_popcountll(__x); }
-
-_LIBCPP_END_NAMESPACE_STD
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___BITS
diff --git a/contrib/libs/cxxsupp/libcxx/include/__chrono/convert_to_tm.h b/contrib/libs/cxxsupp/libcxx/include/__chrono/convert_to_tm.h
index dea9758efb..36846b3f71 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__chrono/convert_to_tm.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__chrono/convert_to_tm.h
@@ -12,12 +12,23 @@
#include <__chrono/day.h>
#include <__chrono/duration.h>
+#include <__chrono/hh_mm_ss.h>
#include <__chrono/month.h>
+#include <__chrono/month_weekday.h>
+#include <__chrono/monthday.h>
+#include <__chrono/statically_widen.h>
+#include <__chrono/system_clock.h>
+#include <__chrono/time_point.h>
#include <__chrono/weekday.h>
#include <__chrono/year.h>
+#include <__chrono/year_month.h>
+#include <__chrono/year_month_day.h>
+#include <__chrono/year_month_weekday.h>
#include <__concepts/same_as.h>
#include <__config>
+#include <__memory/addressof.h>
#include <cstdint>
+#include <ctime>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -27,6 +38,35 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
+// Conerts a chrono date and weekday to a given _Tm type.
+//
+// This is an implementation detail for the function
+// template <class _Tm, class _ChronoT>
+// _Tm __convert_to_tm(const _ChronoT& __value)
+//
+// This manually converts the two values to the proper type. It is possible to
+// convert from sys_days to time_t and then to _Tm. But this leads to the Y2K
+// bug when time_t is a 32-bit signed integer. Chrono considers years beyond
+// the year 2038 valid, so instead do the transformation manually.
+template <class _Tm, class _Date>
+ requires(same_as<_Date, chrono::year_month_day> || same_as<_Date, chrono::year_month_day_last>)
+_LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _Date& __date, chrono::weekday __weekday) {
+ _Tm __result = {};
+# ifdef __GLIBC__
+ __result.tm_zone = "UTC";
+# endif
+ __result.tm_year = static_cast<int>(__date.year()) - 1900;
+ __result.tm_mon = static_cast<unsigned>(__date.month()) - 1;
+ __result.tm_mday = static_cast<unsigned>(__date.day());
+ __result.tm_wday = static_cast<unsigned>(__weekday.c_encoding());
+ __result.tm_yday =
+ (static_cast<chrono::sys_days>(__date) -
+ static_cast<chrono::sys_days>(chrono::year_month_day{__date.year(), chrono::January, chrono::day{1}}))
+ .count();
+
+ return __result;
+}
+
// Convert a chrono (calendar) time point, or dururation to the given _Tm type,
// which must have the same properties as std::tm.
template <class _Tm, class _ChronoT>
@@ -55,7 +95,26 @@ _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _ChronoT& __value) {
__result.tm_year = static_cast<int>(__value) - 1900;
else if constexpr (same_as<_ChronoT, chrono::weekday>)
__result.tm_wday = __value.c_encoding();
- else
+ else if constexpr (same_as<_ChronoT, chrono::weekday_indexed> || same_as<_ChronoT, chrono::weekday_last>)
+ __result.tm_wday = __value.weekday().c_encoding();
+ else if constexpr (same_as<_ChronoT, chrono::month_day>) {
+ __result.tm_mday = static_cast<unsigned>(__value.day());
+ __result.tm_mon = static_cast<unsigned>(__value.month()) - 1;
+ } else if constexpr (same_as<_ChronoT, chrono::month_day_last>) {
+ __result.tm_mon = static_cast<unsigned>(__value.month()) - 1;
+ } else if constexpr (same_as<_ChronoT, chrono::month_weekday> || same_as<_ChronoT, chrono::month_weekday_last>) {
+ __result.tm_wday = __value.weekday_indexed().weekday().c_encoding();
+ __result.tm_mon = static_cast<unsigned>(__value.month()) - 1;
+ } else if constexpr (same_as<_ChronoT, chrono::year_month>) {
+ __result.tm_year = static_cast<int>(__value.year()) - 1900;
+ __result.tm_mon = static_cast<unsigned>(__value.month()) - 1;
+ } else if constexpr (same_as<_ChronoT, chrono::year_month_day> || same_as<_ChronoT, chrono::year_month_day_last>) {
+ return std::__convert_to_tm<_Tm>(
+ chrono::year_month_day{__value}, chrono::weekday{static_cast<chrono::sys_days>(__value)});
+ } else if constexpr (same_as<_ChronoT, chrono::year_month_weekday> ||
+ same_as<_ChronoT, chrono::year_month_weekday_last>) {
+ return std::__convert_to_tm<_Tm>(chrono::year_month_day{static_cast<chrono::sys_days>(__value)}, __value.weekday());
+ } else
static_assert(sizeof(_ChronoT) == 0, "Add the missing type specialization");
return __result;
diff --git a/contrib/libs/cxxsupp/libcxx/include/__chrono/duration.h b/contrib/libs/cxxsupp/libcxx/include/__chrono/duration.h
index 4ad6467b2a..afcc38b5cf 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__chrono/duration.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__chrono/duration.h
@@ -11,9 +11,12 @@
#define _LIBCPP___CHRONO_DURATION_H
#include <__config>
+#include <__type_traits/common_type.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_floating_point.h>
#include <limits>
#include <ratio>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -151,7 +154,7 @@ typename enable_if
>::type
floor(const duration<_Rep, _Period>& __d)
{
- _ToDuration __t = duration_cast<_ToDuration>(__d);
+ _ToDuration __t = chrono::duration_cast<_ToDuration>(__d);
if (__t > __d)
__t = __t - _ToDuration{1};
return __t;
@@ -166,7 +169,7 @@ typename enable_if
>::type
ceil(const duration<_Rep, _Period>& __d)
{
- _ToDuration __t = duration_cast<_ToDuration>(__d);
+ _ToDuration __t = chrono::duration_cast<_ToDuration>(__d);
if (__t < __d)
__t = __t + _ToDuration{1};
return __t;
@@ -181,7 +184,7 @@ typename enable_if
>::type
round(const duration<_Rep, _Period>& __d)
{
- _ToDuration __lower = floor<_ToDuration>(__d);
+ _ToDuration __lower = chrono::floor<_ToDuration>(__d);
_ToDuration __upper = __lower + _ToDuration{1};
auto __lowerDiff = __d - __lower;
auto __upperDiff = __upper - __d;
@@ -612,4 +615,8 @@ _LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
+#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+# include <type_traits>
+#endif
+
#endif // _LIBCPP___CHRONO_DURATION_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__chrono/formatter.h b/contrib/libs/cxxsupp/libcxx/include/__chrono/formatter.h
index 89c1e82f42..2015783acb 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__chrono/formatter.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__chrono/formatter.h
@@ -10,17 +10,23 @@
#ifndef _LIBCPP___CHRONO_FORMATTER_H
#define _LIBCPP___CHRONO_FORMATTER_H
+#include <__chrono/calendar.h>
#include <__chrono/convert_to_tm.h>
#include <__chrono/day.h>
#include <__chrono/duration.h>
#include <__chrono/hh_mm_ss.h>
#include <__chrono/month.h>
+#include <__chrono/month_weekday.h>
+#include <__chrono/monthday.h>
#include <__chrono/ostream.h>
#include <__chrono/parser_std_format_spec.h>
#include <__chrono/statically_widen.h>
#include <__chrono/time_point.h>
#include <__chrono/weekday.h>
#include <__chrono/year.h>
+#include <__chrono/year_month.h>
+#include <__chrono/year_month_day.h>
+#include <__chrono/year_month_weekday.h>
#include <__concepts/arithmetic.h>
#include <__concepts/same_as.h>
#include <__config>
@@ -195,7 +201,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
// FMT honours precision and has a bug for separator
// https://godbolt.org/z/78b7sMxns
if constexpr (chrono::__is_duration<_Tp>::value) {
- __sstr << format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{}"), __value.count());
+ __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{}"), __value.count());
break;
}
__builtin_unreachable();
@@ -249,6 +255,15 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
__facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1);
} break;
+ case _CharT('F'): {
+ int __year = __t.tm_year + 1900;
+ if (__year < 1000) {
+ __formatter::__format_year(__year, __sstr);
+ __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "-{:02}-{:02}"), __t.tm_mon + 1, __t.tm_mday);
+ } else
+ __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1);
+ } break;
+
case _CharT('O'):
if constexpr (__use_fraction<_Tp>()) {
// Handle OS using the normal representation for the non-fractional
@@ -276,7 +291,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
}
template <class _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr bool __month_name_ok(const _Tp& __value) {
+_LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_ok(const _Tp& __value) {
if constexpr (same_as<_Tp, chrono::day>)
return true;
else if constexpr (same_as<_Tp, chrono::month>)
@@ -285,6 +300,28 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __month_name_ok(const _Tp& __value) {
return true;
else if constexpr (same_as<_Tp, chrono::weekday>)
return true;
+ else if constexpr (same_as<_Tp, chrono::weekday_indexed>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::weekday_last>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::month_day>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::month_day_last>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::month_weekday>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::month_weekday_last>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::year_month>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::year_month_day>)
+ return __value.ok();
+ else if constexpr (same_as<_Tp, chrono::year_month_day_last>)
+ return __value.ok();
+ else if constexpr (same_as<_Tp, chrono::year_month_weekday>)
+ return __value.weekday().ok();
+ else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>)
+ return __value.weekday().ok();
else
static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
}
@@ -299,6 +336,100 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_name_ok(const _Tp& __value) {
return true;
else if constexpr (same_as<_Tp, chrono::weekday>)
return __value.ok();
+ else if constexpr (same_as<_Tp, chrono::weekday_indexed>)
+ return __value.weekday().ok();
+ else if constexpr (same_as<_Tp, chrono::weekday_last>)
+ return __value.weekday().ok();
+ else if constexpr (same_as<_Tp, chrono::month_day>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::month_day_last>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::month_weekday>)
+ return __value.weekday_indexed().ok();
+ else if constexpr (same_as<_Tp, chrono::month_weekday_last>)
+ return __value.weekday_indexed().ok();
+ else if constexpr (same_as<_Tp, chrono::year_month>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::year_month_day>)
+ return __value.ok();
+ else if constexpr (same_as<_Tp, chrono::year_month_day_last>)
+ return __value.ok();
+ else if constexpr (same_as<_Tp, chrono::year_month_weekday>)
+ return __value.weekday().ok();
+ else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>)
+ return __value.weekday().ok();
+ else
+ static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr bool __date_ok(const _Tp& __value) {
+ if constexpr (same_as<_Tp, chrono::day>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::month>)
+ return __value.ok();
+ else if constexpr (same_as<_Tp, chrono::year>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::weekday>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::weekday_indexed>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::weekday_last>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::month_day>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::month_day_last>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::month_weekday>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::month_weekday_last>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::year_month>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::year_month_day>)
+ return __value.ok();
+ else if constexpr (same_as<_Tp, chrono::year_month_day_last>)
+ return __value.ok();
+ else if constexpr (same_as<_Tp, chrono::year_month_weekday>)
+ return __value.ok();
+ else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>)
+ return __value.ok();
+ else
+ static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr bool __month_name_ok(const _Tp& __value) {
+ if constexpr (same_as<_Tp, chrono::day>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::month>)
+ return __value.ok();
+ else if constexpr (same_as<_Tp, chrono::year>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::weekday>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::weekday_indexed>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::weekday_last>)
+ return true;
+ else if constexpr (same_as<_Tp, chrono::month_day>)
+ return __value.month().ok();
+ else if constexpr (same_as<_Tp, chrono::month_day_last>)
+ return __value.month().ok();
+ else if constexpr (same_as<_Tp, chrono::month_weekday>)
+ return __value.month().ok();
+ else if constexpr (same_as<_Tp, chrono::month_weekday_last>)
+ return __value.month().ok();
+ else if constexpr (same_as<_Tp, chrono::year_month>)
+ return __value.month().ok();
+ else if constexpr (same_as<_Tp, chrono::year_month_day>)
+ return __value.month().ok();
+ else if constexpr (same_as<_Tp, chrono::year_month_day_last>)
+ return __value.month().ok();
+ else if constexpr (same_as<_Tp, chrono::year_month_weekday>)
+ return __value.month().ok();
+ else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>)
+ return __value.month().ok();
else
static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
}
@@ -331,9 +462,19 @@ __format_chrono(const _Tp& __value,
// Note that the behaviour what the precision does isn't specified.
__specs.__precision_ = -1;
} else {
+ // Test __weekday_name_ before __weekday_ to give a better error.
if (__specs.__chrono_.__weekday_name_ && !__formatter::__weekday_name_ok(__value))
std::__throw_format_error("formatting a weekday name needs a valid weekday");
+ if (__specs.__chrono_.__weekday_ && !__formatter::__weekday_ok(__value))
+ std::__throw_format_error("formatting a weekday needs a valid weekday");
+
+ if (__specs.__chrono_.__day_of_year_ && !__formatter::__date_ok(__value))
+ std::__throw_format_error("formatting a day of year needs a valid date");
+
+ if (__specs.__chrono_.__week_of_year_ && !__formatter::__date_ok(__value))
+ std::__throw_format_error("formatting a week of year needs a valid date");
+
if (__specs.__chrono_.__month_name_ && !__formatter::__month_name_ok(__value))
std::__throw_format_error("formatting a month name from an invalid month number");
@@ -436,6 +577,138 @@ public:
}
};
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::weekday_indexed, _CharT>
+ : public __formatter_chrono<_CharT> {
+public:
+ using _Base = __formatter_chrono<_CharT>;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+ -> decltype(__parse_ctx.begin()) {
+ return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday);
+ }
+};
+
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::weekday_last, _CharT>
+ : public __formatter_chrono<_CharT> {
+public:
+ using _Base = __formatter_chrono<_CharT>;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+ -> decltype(__parse_ctx.begin()) {
+ return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday);
+ }
+};
+
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month_day, _CharT>
+ : public __formatter_chrono<_CharT> {
+public:
+ using _Base = __formatter_chrono<_CharT>;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+ -> decltype(__parse_ctx.begin()) {
+ return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_day);
+ }
+};
+
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month_day_last, _CharT>
+ : public __formatter_chrono<_CharT> {
+public:
+ using _Base = __formatter_chrono<_CharT>;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+ -> decltype(__parse_ctx.begin()) {
+ return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month);
+ }
+};
+
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month_weekday, _CharT>
+ : public __formatter_chrono<_CharT> {
+public:
+ using _Base = __formatter_chrono<_CharT>;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+ -> decltype(__parse_ctx.begin()) {
+ return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday);
+ }
+};
+
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month_weekday_last, _CharT>
+ : public __formatter_chrono<_CharT> {
+public:
+ using _Base = __formatter_chrono<_CharT>;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+ -> decltype(__parse_ctx.begin()) {
+ return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday);
+ }
+};
+
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month, _CharT>
+ : public __formatter_chrono<_CharT> {
+public:
+ using _Base = __formatter_chrono<_CharT>;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+ -> decltype(__parse_ctx.begin()) {
+ return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__year_month);
+ }
+};
+
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month_day, _CharT>
+ : public __formatter_chrono<_CharT> {
+public:
+ using _Base = __formatter_chrono<_CharT>;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+ -> decltype(__parse_ctx.begin()) {
+ return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
+ }
+};
+
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month_day_last, _CharT>
+ : public __formatter_chrono<_CharT> {
+public:
+ using _Base = __formatter_chrono<_CharT>;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+ -> decltype(__parse_ctx.begin()) {
+ return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
+ }
+};
+
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month_weekday, _CharT>
+ : public __formatter_chrono<_CharT> {
+public:
+ using _Base = __formatter_chrono<_CharT>;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+ -> decltype(__parse_ctx.begin()) {
+ return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
+ }
+};
+
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month_weekday_last, _CharT>
+ : public __formatter_chrono<_CharT> {
+public:
+ using _Base = __formatter_chrono<_CharT>;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+ -> decltype(__parse_ctx.begin()) {
+ return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
+ }
+};
+
#endif // if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/include/__chrono/hh_mm_ss.h b/contrib/libs/cxxsupp/libcxx/include/__chrono/hh_mm_ss.h
index fde005d097..fd61cbe8f8 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__chrono/hh_mm_ss.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__chrono/hh_mm_ss.h
@@ -58,10 +58,10 @@ public:
_LIBCPP_HIDE_FROM_ABI constexpr explicit hh_mm_ss(_Duration __d) noexcept :
__is_neg_(__d < _Duration(0)),
- __h_(duration_cast<chrono::hours> (abs(__d))),
- __m_(duration_cast<chrono::minutes>(abs(__d) - hours())),
- __s_(duration_cast<chrono::seconds>(abs(__d) - hours() - minutes())),
- __f_(duration_cast<precision> (abs(__d) - hours() - minutes() - seconds()))
+ __h_(chrono::duration_cast<chrono::hours> (chrono::abs(__d))),
+ __m_(chrono::duration_cast<chrono::minutes>(chrono::abs(__d) - hours())),
+ __s_(chrono::duration_cast<chrono::seconds>(chrono::abs(__d) - hours() - minutes())),
+ __f_(chrono::duration_cast<precision> (chrono::abs(__d) - hours() - minutes() - seconds()))
{}
_LIBCPP_HIDE_FROM_ABI constexpr bool is_negative() const noexcept { return __is_neg_; }
diff --git a/contrib/libs/cxxsupp/libcxx/include/__chrono/ostream.h b/contrib/libs/cxxsupp/libcxx/include/__chrono/ostream.h
index c48bd6a8b3..30a04bd265 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__chrono/ostream.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__chrono/ostream.h
@@ -13,9 +13,14 @@
#include <__chrono/day.h>
#include <__chrono/duration.h>
#include <__chrono/month.h>
+#include <__chrono/month_weekday.h>
+#include <__chrono/monthday.h>
#include <__chrono/statically_widen.h>
#include <__chrono/weekday.h>
#include <__chrono/year.h>
+#include <__chrono/year_month.h>
+#include <__chrono/year_month_day.h>
+#include <__chrono/year_month_weekday.h>
#include <__concepts/same_as.h>
#include <__config>
#include <__format/format_functions.h>
@@ -136,6 +141,94 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday& __wd) {
static_cast<unsigned>(__wd.c_encoding())));
}
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_indexed& __wdi) {
+ auto __i = __wdi.index();
+ return __os << (__i >= 1 && __i <= 5
+ ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[{}]"), __wdi.weekday(), __i)
+ : std::format(__os.getloc(),
+ _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[{} is not a valid index]"),
+ __wdi.weekday(),
+ __i));
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_last& __wdl) {
+ return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[last]"), __wdl.weekday());
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day& __md) {
+ // TODO FMT The Standard allows 30th of February to be printed.
+ // It would be nice to show an error message instead.
+ return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{}"), __md.month(), __md.day());
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day_last& __mdl) {
+ return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/last"), __mdl.month());
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday& __mwd) {
+ return __os << std::format(
+ __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwd.month(), __mwd.weekday_indexed());
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday_last& __mwdl) {
+ return __os << std::format(
+ __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwdl.month(), __mwdl.weekday_last());
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month& __ym) {
+ return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ym.year(), __ym.month());
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day& __ymd) {
+ return __os << (__ymd.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F}"), __ymd)
+ : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F} is not a valid date"), __ymd));
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day_last& __ymdl) {
+ return __os << std::format(
+ __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ymdl.year(), __ymdl.month_day_last());
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday& __ymwd) {
+ return __os << std::format(
+ __os.getloc(),
+ _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}/{:L}"),
+ __ymwd.year(),
+ __ymwd.month(),
+ __ymwd.weekday_indexed());
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday_last& __ymwdl) {
+ return __os << std::format(
+ __os.getloc(),
+ _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}/{:L}"),
+ __ymwdl.year(),
+ __ymwdl.month(),
+ __ymwdl.weekday_last());
+}
+
} // namespace chrono
#endif //if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
diff --git a/contrib/libs/cxxsupp/libcxx/include/__chrono/parser_std_format_spec.h b/contrib/libs/cxxsupp/libcxx/include/__chrono/parser_std_format_spec.h
index cdf7b9b15f..dbcfe6da60 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__chrono/parser_std_format_spec.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__chrono/parser_std_format_spec.h
@@ -243,17 +243,20 @@ private:
break;
case _CharT('j'):
+ __parser_.__day_of_year_ = true;
__format_spec::__validate_date_or_duration(__flags);
break;
case _CharT('g'):
- case _CharT('x'):
- case _CharT('D'):
- case _CharT('F'):
case _CharT('G'):
case _CharT('U'):
case _CharT('V'):
case _CharT('W'):
+ __parser_.__week_of_year_ = true;
+ [[fallthrough]];
+ case _CharT('x'):
+ case _CharT('D'):
+ case _CharT('F'):
__format_spec::__validate_date(__flags);
break;
@@ -267,6 +270,8 @@ private:
[[fallthrough]];
case _CharT('u'):
case _CharT('w'):
+ __parser_.__weekday_ = true;
+ __validate_weekday(__flags);
__format_spec::__validate_weekday(__flags);
break;
@@ -373,11 +378,13 @@ private:
case _CharT('U'):
case _CharT('V'):
case _CharT('W'):
+ __parser_.__week_of_year_ = true;
__format_spec::__validate_date(__flags);
break;
case _CharT('u'):
case _CharT('w'):
+ __parser_.__weekday_ = true;
__format_spec::__validate_weekday(__flags);
break;
diff --git a/contrib/libs/cxxsupp/libcxx/include/__chrono/statically_widen.h b/contrib/libs/cxxsupp/libcxx/include/__chrono/statically_widen.h
index dd12c3f502..360b6c2c7d 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__chrono/statically_widen.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__chrono/statically_widen.h
@@ -26,26 +26,26 @@ _LIBCPP_BEGIN_NAMESPACE_STD
# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <__fmt_char_type _CharT>
-consteval const _CharT* __statically_widen(const char* __str, const wchar_t* __wstr) {
+_LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __statically_widen(const char* __str, const wchar_t* __wstr) {
if constexpr (same_as<_CharT, char>)
return __str;
else
return __wstr;
}
# define _LIBCPP_STATICALLY_WIDEN(_CharT, __str) ::std::__statically_widen<_CharT>(__str, L##__str)
-# else // _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# else // _LIBCPP_HAS_NO_WIDE_CHARACTERS
// Without this indirection the unit test test/libcxx/modules_include.sh.cpp
// fails for the CI build "No wide characters". This seems like a bug.
// TODO FMT investigate why this is needed.
template <__fmt_char_type _CharT>
-consteval const _CharT* __statically_widen(const char* __str) {
+_LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __statically_widen(const char* __str) {
return __str;
}
# define _LIBCPP_STATICALLY_WIDEN(_CharT, __str) ::std::__statically_widen<_CharT>(__str)
# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
-#endif //if _LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/include/__chrono/time_point.h b/contrib/libs/cxxsupp/libcxx/include/__chrono/time_point.h
index cc9c462c9d..8a8fa2176d 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__chrono/time_point.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__chrono/time_point.h
@@ -12,8 +12,10 @@
#include <__chrono/duration.h>
#include <__config>
+#include <__type_traits/common_type.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_convertible.h>
#include <limits>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -98,7 +100,7 @@ typename enable_if
>::type
floor(const time_point<_Clock, _Duration>& __t)
{
- return time_point<_Clock, _ToDuration>{floor<_ToDuration>(__t.time_since_epoch())};
+ return time_point<_Clock, _ToDuration>{chrono::floor<_ToDuration>(__t.time_since_epoch())};
}
template <class _ToDuration, class _Clock, class _Duration>
@@ -110,7 +112,7 @@ typename enable_if
>::type
ceil(const time_point<_Clock, _Duration>& __t)
{
- return time_point<_Clock, _ToDuration>{ceil<_ToDuration>(__t.time_since_epoch())};
+ return time_point<_Clock, _ToDuration>{chrono::ceil<_ToDuration>(__t.time_since_epoch())};
}
template <class _ToDuration, class _Clock, class _Duration>
@@ -122,7 +124,7 @@ typename enable_if
>::type
round(const time_point<_Clock, _Duration>& __t)
{
- return time_point<_Clock, _ToDuration>{round<_ToDuration>(__t.time_since_epoch())};
+ return time_point<_Clock, _ToDuration>{chrono::round<_ToDuration>(__t.time_since_epoch())};
}
template <class _Rep, class _Period>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__compare/common_comparison_category.h b/contrib/libs/cxxsupp/libcxx/include/__compare/common_comparison_category.h
index deab171846..06c4b28491 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__compare/common_comparison_category.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__compare/common_comparison_category.h
@@ -11,7 +11,8 @@
#include <__compare/ordering.h>
#include <__config>
-#include <type_traits>
+#include <__type_traits/is_same.h>
+#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -64,7 +65,7 @@ _LIBCPP_HIDE_FROM_ABI
constexpr auto __get_comp_type() {
using _CCC = _ClassifyCompCategory;
constexpr _CCC __type_kinds[] = {_StrongOrd, __type_to_enum<_Ts>()...};
- constexpr _CCC _Cat = __compute_comp_type(__type_kinds);
+ constexpr _CCC _Cat = __comp_detail::__compute_comp_type(__type_kinds);
if constexpr (_Cat == _None)
return void();
else if constexpr (_Cat == _PartialOrd)
diff --git a/contrib/libs/cxxsupp/libcxx/include/__compare/compare_partial_order_fallback.h b/contrib/libs/cxxsupp/libcxx/include/__compare/compare_partial_order_fallback.h
index ba746d6c7d..06f03fe7ad 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__compare/compare_partial_order_fallback.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__compare/compare_partial_order_fallback.h
@@ -12,9 +12,10 @@
#include <__compare/ordering.h>
#include <__compare/partial_order.h>
#include <__config>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_same.h>
#include <__utility/forward.h>
#include <__utility/priority_tag.h>
-#include <type_traits>
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__compare/compare_strong_order_fallback.h b/contrib/libs/cxxsupp/libcxx/include/__compare/compare_strong_order_fallback.h
index 312a08ef7e..869386817a 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__compare/compare_strong_order_fallback.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__compare/compare_strong_order_fallback.h
@@ -12,9 +12,10 @@
#include <__compare/ordering.h>
#include <__compare/strong_order.h>
#include <__config>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_same.h>
#include <__utility/forward.h>
#include <__utility/priority_tag.h>
-#include <type_traits>
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__compare/compare_three_way_result.h b/contrib/libs/cxxsupp/libcxx/include/__compare/compare_three_way_result.h
index 3047f5bd2a..8885d7effa 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__compare/compare_three_way_result.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__compare/compare_three_way_result.h
@@ -11,7 +11,7 @@
#include <__config>
#include <__type_traits/make_const_lvalue_ref.h>
-#include <type_traits>
+#include <__utility/declval.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -26,9 +26,9 @@ struct _LIBCPP_HIDE_FROM_ABI __compare_three_way_result { };
template<class _Tp, class _Up>
struct _LIBCPP_HIDE_FROM_ABI __compare_three_way_result<_Tp, _Up, decltype(
- declval<__make_const_lvalue_ref<_Tp>>() <=> declval<__make_const_lvalue_ref<_Up>>(), void()
+ std::declval<__make_const_lvalue_ref<_Tp>>() <=> std::declval<__make_const_lvalue_ref<_Up>>(), void()
)> {
- using type = decltype(declval<__make_const_lvalue_ref<_Tp>>() <=> declval<__make_const_lvalue_ref<_Up>>());
+ using type = decltype(std::declval<__make_const_lvalue_ref<_Tp>>() <=> std::declval<__make_const_lvalue_ref<_Up>>());
};
template<class _Tp, class _Up = _Tp>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__compare/compare_weak_order_fallback.h b/contrib/libs/cxxsupp/libcxx/include/__compare/compare_weak_order_fallback.h
index 844d676087..f434dcb4a3 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__compare/compare_weak_order_fallback.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__compare/compare_weak_order_fallback.h
@@ -12,9 +12,10 @@
#include <__compare/ordering.h>
#include <__compare/weak_order.h>
#include <__config>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_same.h>
#include <__utility/forward.h>
#include <__utility/priority_tag.h>
-#include <type_traits>
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__compare/ordering.h b/contrib/libs/cxxsupp/libcxx/include/__compare/ordering.h
index ab35a598a8..ff148abf23 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__compare/ordering.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__compare/ordering.h
@@ -10,7 +10,8 @@
#define _LIBCPP___COMPARE_ORDERING_H
#include <__config>
-#include <type_traits>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_same.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__compare/partial_order.h b/contrib/libs/cxxsupp/libcxx/include/__compare/partial_order.h
index 970f01b3f1..aee07ebb42 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__compare/partial_order.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__compare/partial_order.h
@@ -13,9 +13,10 @@
#include <__compare/ordering.h>
#include <__compare/weak_order.h>
#include <__config>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_same.h>
#include <__utility/forward.h>
#include <__utility/priority_tag.h>
-#include <type_traits>
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
# pragma GCC system_header
@@ -28,6 +29,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// [cmp.alg]
namespace __partial_order {
struct __fn {
+ // NOLINTBEGIN(libcpp-robust-against-adl) partial_order should use ADL, but only here
template<class _Tp, class _Up>
requires is_same_v<decay_t<_Tp>, decay_t<_Up>>
_LIBCPP_HIDE_FROM_ABI static constexpr auto
@@ -35,6 +37,7 @@ namespace __partial_order {
noexcept(noexcept(partial_ordering(partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))))
-> decltype( partial_ordering(partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))
{ return partial_ordering(partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); }
+ // NOLINTEND(libcpp-robust-against-adl)
template<class _Tp, class _Up>
requires is_same_v<decay_t<_Tp>, decay_t<_Up>>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__compare/strong_order.h b/contrib/libs/cxxsupp/libcxx/include/__compare/strong_order.h
index 67c7b2910b..05856c2093 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__compare/strong_order.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__compare/strong_order.h
@@ -13,12 +13,13 @@
#include <__compare/compare_three_way.h>
#include <__compare/ordering.h>
#include <__config>
+#include <__type_traits/conditional.h>
+#include <__type_traits/decay.h>
#include <__utility/forward.h>
#include <__utility/priority_tag.h>
#include <cmath>
#include <cstdint>
#include <limits>
-#include <type_traits>
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
# pragma GCC system_header
@@ -34,6 +35,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// [cmp.alg]
namespace __strong_order {
struct __fn {
+ // NOLINTBEGIN(libcpp-robust-against-adl) strong_order should use ADL, but only here
template<class _Tp, class _Up>
requires is_same_v<decay_t<_Tp>, decay_t<_Up>>
_LIBCPP_HIDE_FROM_ABI static constexpr auto
@@ -41,6 +43,7 @@ namespace __strong_order {
noexcept(noexcept(strong_ordering(strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))))
-> decltype( strong_ordering(strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))
{ return strong_ordering(strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); }
+ // NOLINTEND(libcpp-robust-against-adl)
template<class _Tp, class _Up, class _Dp = decay_t<_Tp>>
requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__compare/synth_three_way.h b/contrib/libs/cxxsupp/libcxx/include/__compare/synth_three_way.h
index fa8cbda79b..7d338987e0 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__compare/synth_three_way.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__compare/synth_three_way.h
@@ -42,7 +42,7 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr auto __synth_three_way =
};
template <class _Tp, class _Up = _Tp>
-using __synth_three_way_result = decltype(std::__synth_three_way(declval<_Tp&>(), declval<_Up&>()));
+using __synth_three_way_result = decltype(std::__synth_three_way(std::declval<_Tp&>(), std::declval<_Up&>()));
#endif // _LIBCPP_STD_VER > 17
diff --git a/contrib/libs/cxxsupp/libcxx/include/__compare/three_way_comparable.h b/contrib/libs/cxxsupp/libcxx/include/__compare/three_way_comparable.h
index cab2cb2896..6c98916d85 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__compare/three_way_comparable.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__compare/three_way_comparable.h
@@ -16,8 +16,8 @@
#include <__concepts/same_as.h>
#include <__concepts/totally_ordered.h>
#include <__config>
+#include <__type_traits/common_reference.h>
#include <__type_traits/make_const_lvalue_ref.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__compare/weak_order.h b/contrib/libs/cxxsupp/libcxx/include/__compare/weak_order.h
index c2fae1a98d..abb24e3665 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__compare/weak_order.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__compare/weak_order.h
@@ -13,10 +13,10 @@
#include <__compare/ordering.h>
#include <__compare/strong_order.h>
#include <__config>
+#include <__type_traits/decay.h>
#include <__utility/forward.h>
#include <__utility/priority_tag.h>
#include <cmath>
-#include <type_traits>
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
# pragma GCC system_header
@@ -29,6 +29,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// [cmp.alg]
namespace __weak_order {
struct __fn {
+ // NOLINTBEGIN(libcpp-robust-against-adl) weak_order should use ADL, but only here
template<class _Tp, class _Up>
requires is_same_v<decay_t<_Tp>, decay_t<_Up>>
_LIBCPP_HIDE_FROM_ABI static constexpr auto
@@ -36,6 +37,7 @@ namespace __weak_order {
noexcept(noexcept(weak_ordering(weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))))
-> decltype( weak_ordering(weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))
{ return weak_ordering(weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); }
+ // NOLINTEND(libcpp-robust-against-adl)
template<class _Tp, class _Up, class _Dp = decay_t<_Tp>>
requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__concepts/arithmetic.h b/contrib/libs/cxxsupp/libcxx/include/__concepts/arithmetic.h
index d91570f02b..215b52aa02 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__concepts/arithmetic.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__concepts/arithmetic.h
@@ -10,9 +10,11 @@
#define _LIBCPP___CONCEPTS_ARITHMETIC_H
#include <__config>
+#include <__type_traits/is_floating_point.h>
+#include <__type_traits/is_integral.h>
+#include <__type_traits/is_signed.h>
#include <__type_traits/is_signed_integer.h>
#include <__type_traits/is_unsigned_integer.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__concepts/assignable.h b/contrib/libs/cxxsupp/libcxx/include/__concepts/assignable.h
index db09e5a0a5..91edd400ad 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__concepts/assignable.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__concepts/assignable.h
@@ -12,9 +12,9 @@
#include <__concepts/common_reference_with.h>
#include <__concepts/same_as.h>
#include <__config>
+#include <__type_traits/is_reference.h>
#include <__type_traits/make_const_lvalue_ref.h>
#include <__utility/forward.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__concepts/class_or_enum.h b/contrib/libs/cxxsupp/libcxx/include/__concepts/class_or_enum.h
index 6287c52992..c4d2f98952 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__concepts/class_or_enum.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__concepts/class_or_enum.h
@@ -10,7 +10,10 @@
#define _LIBCPP___CONCEPTS_CLASS_OR_ENUM_H
#include <__config>
-#include <type_traits>
+#include <__type_traits/is_class.h>
+#include <__type_traits/is_enum.h>
+#include <__type_traits/is_union.h>
+#include <__type_traits/remove_cvref.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__concepts/common_reference_with.h b/contrib/libs/cxxsupp/libcxx/include/__concepts/common_reference_with.h
index cae2f5bccc..cc92762d31 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__concepts/common_reference_with.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__concepts/common_reference_with.h
@@ -12,7 +12,7 @@
#include <__concepts/convertible_to.h>
#include <__concepts/same_as.h>
#include <__config>
-#include <type_traits>
+#include <__type_traits/common_reference.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__concepts/common_with.h b/contrib/libs/cxxsupp/libcxx/include/__concepts/common_with.h
index 1b5f4da4af..569a0ee3b7 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__concepts/common_with.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__concepts/common_with.h
@@ -12,7 +12,10 @@
#include <__concepts/common_reference_with.h>
#include <__concepts/same_as.h>
#include <__config>
-#include <type_traits>
+#include <__type_traits/add_lvalue_reference.h>
+#include <__type_traits/common_reference.h>
+#include <__type_traits/common_type.h>
+#include <__utility/declval.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -28,8 +31,8 @@ template<class _Tp, class _Up>
concept common_with =
same_as<common_type_t<_Tp, _Up>, common_type_t<_Up, _Tp>> &&
requires {
- static_cast<common_type_t<_Tp, _Up>>(declval<_Tp>());
- static_cast<common_type_t<_Tp, _Up>>(declval<_Up>());
+ static_cast<common_type_t<_Tp, _Up>>(std::declval<_Tp>());
+ static_cast<common_type_t<_Tp, _Up>>(std::declval<_Up>());
} &&
common_reference_with<
add_lvalue_reference_t<const _Tp>,
diff --git a/contrib/libs/cxxsupp/libcxx/include/__concepts/constructible.h b/contrib/libs/cxxsupp/libcxx/include/__concepts/constructible.h
index aaf515417e..1d78eb5fd1 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__concepts/constructible.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__concepts/constructible.h
@@ -12,7 +12,7 @@
#include <__concepts/convertible_to.h>
#include <__concepts/destructible.h>
#include <__config>
-#include <type_traits>
+#include <__type_traits/is_constructible.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__concepts/convertible_to.h b/contrib/libs/cxxsupp/libcxx/include/__concepts/convertible_to.h
index 5d9d437104..2c1d267410 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__concepts/convertible_to.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__concepts/convertible_to.h
@@ -10,8 +10,8 @@
#define _LIBCPP___CONCEPTS_CONVERTIBLE_TO_H
#include <__config>
+#include <__type_traits/is_convertible.h>
#include <__utility/declval.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -27,7 +27,7 @@ template<class _From, class _To>
concept convertible_to =
is_convertible_v<_From, _To> &&
requires {
- static_cast<_To>(declval<_From>());
+ static_cast<_To>(std::declval<_From>());
};
#endif // _LIBCPP_STD_VER > 17
diff --git a/contrib/libs/cxxsupp/libcxx/include/__concepts/derived_from.h b/contrib/libs/cxxsupp/libcxx/include/__concepts/derived_from.h
index 4b29147947..0d3462df6a 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__concepts/derived_from.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__concepts/derived_from.h
@@ -10,7 +10,8 @@
#define _LIBCPP___CONCEPTS_DERIVED_FROM_H
#include <__config>
-#include <type_traits>
+#include <__type_traits/is_base_of.h>
+#include <__type_traits/is_convertible.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__concepts/destructible.h b/contrib/libs/cxxsupp/libcxx/include/__concepts/destructible.h
index 90a043d314..ad3819d5dc 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__concepts/destructible.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__concepts/destructible.h
@@ -10,7 +10,7 @@
#define _LIBCPP___CONCEPTS_DESTRUCTIBLE_H
#include <__config>
-#include <type_traits>
+#include <__type_traits/is_nothrow_destructible.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__concepts/different_from.h b/contrib/libs/cxxsupp/libcxx/include/__concepts/different_from.h
index 3066372e86..15fd8f0551 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__concepts/different_from.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__concepts/different_from.h
@@ -11,7 +11,7 @@
#include <__concepts/same_as.h>
#include <__config>
-#include <type_traits>
+#include <__type_traits/remove_cvref.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__concepts/equality_comparable.h b/contrib/libs/cxxsupp/libcxx/include/__concepts/equality_comparable.h
index c2293d5cd0..b865141705 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__concepts/equality_comparable.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__concepts/equality_comparable.h
@@ -12,8 +12,8 @@
#include <__concepts/boolean_testable.h>
#include <__concepts/common_reference_with.h>
#include <__config>
+#include <__type_traits/common_reference.h>
#include <__type_traits/make_const_lvalue_ref.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__concepts/invocable.h b/contrib/libs/cxxsupp/libcxx/include/__concepts/invocable.h
index d90389e97f..ec39b7b817 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__concepts/invocable.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__concepts/invocable.h
@@ -12,7 +12,6 @@
#include <__config>
#include <__functional/invoke.h>
#include <__utility/forward.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__concepts/movable.h b/contrib/libs/cxxsupp/libcxx/include/__concepts/movable.h
index 639219ed6b..749b78ad10 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__concepts/movable.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__concepts/movable.h
@@ -13,7 +13,7 @@
#include <__concepts/constructible.h>
#include <__concepts/swappable.h>
#include <__config>
-#include <type_traits>
+#include <__type_traits/is_object.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__concepts/predicate.h b/contrib/libs/cxxsupp/libcxx/include/__concepts/predicate.h
index cb23975230..7ae9783264 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__concepts/predicate.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__concepts/predicate.h
@@ -12,7 +12,7 @@
#include <__concepts/boolean_testable.h>
#include <__concepts/invocable.h>
#include <__config>
-#include <type_traits>
+#include <__functional/invoke.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__concepts/same_as.h b/contrib/libs/cxxsupp/libcxx/include/__concepts/same_as.h
index 7654906611..554ebc3b07 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__concepts/same_as.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__concepts/same_as.h
@@ -10,7 +10,7 @@
#define _LIBCPP___CONCEPTS_SAME_AS_H
#include <__config>
-#include <type_traits>
+#include <__type_traits/is_same.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__concepts/swappable.h b/contrib/libs/cxxsupp/libcxx/include/__concepts/swappable.h
index dbb4283645..d91a7a1dc3 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__concepts/swappable.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__concepts/swappable.h
@@ -14,11 +14,15 @@
#include <__concepts/common_reference_with.h>
#include <__concepts/constructible.h>
#include <__config>
+#include <__type_traits/extent.h>
+#include <__type_traits/is_nothrow_move_assignable.h>
+#include <__type_traits/is_nothrow_move_constructible.h>
+#include <__type_traits/remove_cvref.h>
#include <__utility/exchange.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#include <__utility/swap.h>
-#include <type_traits>
+#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__concepts/totally_ordered.h b/contrib/libs/cxxsupp/libcxx/include/__concepts/totally_ordered.h
index 25347790de..f12d26b108 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__concepts/totally_ordered.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__concepts/totally_ordered.h
@@ -12,7 +12,8 @@
#include <__concepts/boolean_testable.h>
#include <__concepts/equality_comparable.h>
#include <__config>
-#include <type_traits>
+#include <__type_traits/common_reference.h>
+#include <__type_traits/make_const_lvalue_ref.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__config b/contrib/libs/cxxsupp/libcxx/include/__config
index b5dd7efc5a..343a284b1a 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__config
+++ b/contrib/libs/cxxsupp/libcxx/include/__config
@@ -23,6 +23,7 @@
#endif
#if defined(__apple_build_version__)
+// Given AppleClang XX.Y.Z, _LIBCPP_APPLE_CLANG_VER is XXYZ (e.g. AppleClang 14.0.3 => 1403)
# define _LIBCPP_COMPILER_CLANG_BASED
# define _LIBCPP_APPLE_CLANG_VER (__apple_build_version__ / 10000)
#elif defined(__clang__)
@@ -59,7 +60,7 @@
// _LIBCPP_VERSION represents the version of libc++, which matches the version of LLVM.
// Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 16.0.1 == 16.00.01), _LIBCPP_VERSION is
// defined to XXYYZZ.
-# define _LIBCPP_VERSION 160000
+# define _LIBCPP_VERSION 160005
# define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y
# define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y)
@@ -161,6 +162,15 @@
# define _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON
// According to the Standard, `bitset::operator[] const` returns bool
# define _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
+// Fix the implementation of CityHash used for std::hash<fundamental-type>.
+// This is an ABI break because `std::hash` will return a different result,
+// which means that hashing the same object in translation units built against
+// different versions of libc++ can return inconsistent results. This is especially
+// tricky since std::hash is used in the implementation of unordered containers.
+//
+// The incorrect implementation of CityHash has the problem that it drops some
+// bits on the floor.
+# define _LIBCPP_ABI_FIX_CITYHASH_IMPLEMENTATION
// Remove the base 10 implementation of std::to_chars from the dylib.
// The implementation moved to the header, but we still export the symbols from
// the dylib for backwards compatibility.
@@ -223,6 +233,10 @@
# define __has_cpp_attribute(__x) 0
# endif
+# ifndef __has_constexpr_builtin
+# define __has_constexpr_builtin(x) 0
+# endif
+
// '__is_identifier' returns '0' if '__x' is a reserved identifier provided by
// the compiler and '1' otherwise.
# ifndef __is_identifier
@@ -633,6 +647,15 @@ typedef __char32_t char32_t;
// Note that we use _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION to ensure that we don't depend
// on _LIBCPP_HIDE_FROM_ABI methods of classes explicitly instantiated in the dynamic library.
//
+// Also note that the _LIBCPP_HIDE_FROM_ABI_VIRTUAL macro should be used on virtual functions
+// instead of _LIBCPP_HIDE_FROM_ABI. That macro does not use an ABI tag. Indeed, the mangled
+// name of a virtual function is part of its ABI, since some architectures like arm64e can sign
+// the virtual function pointer in the vtable based on the mangled name of the function. Since
+// we use an ABI tag that changes with each released version, the mangled name of the virtual
+// function would change, which is incorrect. Note that it doesn't make much sense to change
+// the implementation of a virtual function in an ABI-incompatible way in the first place,
+// since that would be an ABI break anyway. Hence, the lack of ABI tag should not be noticeable.
+//
// TODO: We provide a escape hatch with _LIBCPP_NO_ABI_TAG for folks who want to avoid increasing
// the length of symbols with an ABI tag. In practice, we should remove the escape hatch and
// use compression mangling instead, see https://github.com/itanium-cxx-abi/cxx-abi/issues/70.
@@ -643,6 +666,11 @@ typedef __char32_t char32_t;
# else
# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
# endif
+# define _LIBCPP_HIDE_FROM_ABI_VIRTUAL _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
+
+// This macro provides a HIDE_FROM_ABI equivalent that can be applied to extern
+// "C" function, as those lack mangling.
+# define _LIBCPP_HIDE_FROM_ABI_C _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
# ifdef _LIBCPP_BUILDING_LIBRARY
# if _LIBCPP_ABI_VERSION > 1
@@ -747,6 +775,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
# endif
+// It is not yet possible to use aligned_alloc() on all Apple platforms since
+// 10.15 was the first version to ship an implementation of aligned_alloc().
+# if defined(__APPLE__)
+# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
+ __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500)
+# define _LIBCPP_HAS_NO_C11_ALIGNED_ALLOC
+# endif
+# elif defined(__ANDROID__) && __ANDROID_API__ < 28
+// Android only provides aligned_alloc when targeting API 28 or higher.
+# define _LIBCPP_HAS_NO_C11_ALIGNED_ALLOC
+# endif
+
# if defined(__APPLE__) || defined(__FreeBSD__)
# define _LIBCPP_HAS_DEFAULTRUNELOCALE
# endif
@@ -803,6 +843,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
# define _LIBCPP_DEPRECATED_IN_CXX20
# endif
+#if _LIBCPP_STD_VER >= 23
+# define _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_DEPRECATED
+#else
+# define _LIBCPP_DEPRECATED_IN_CXX23
+#endif
+
# if !defined(_LIBCPP_HAS_NO_CHAR8_T)
# define _LIBCPP_DEPRECATED_WITH_CHAR8_T _LIBCPP_DEPRECATED
# else
@@ -886,7 +932,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
// Try to find out if RTTI is disabled.
# if !defined(__cpp_rtti) || __cpp_rtti < 199711L
-# define _LIBCPP_NO_RTTI
+# define _LIBCPP_HAS_NO_RTTI
# endif
# ifndef _LIBCPP_WEAK
@@ -1061,6 +1107,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
# define _LIBCPP_FALLTHROUGH() ((void)0)
# endif
+# if __has_cpp_attribute(_Clang::__lifetimebound__)
+# define _LIBCPP_LIFETIMEBOUND [[_Clang::__lifetimebound__]]
+# else
+# define _LIBCPP_LIFETIMEBOUND
+# endif
+
# if defined(_LIBCPP_COMPILER_CLANG_BASED)
# define _LIBCPP_REINITIALIZES_OBJECT [[clang::reinitializes]]
# else
@@ -1227,12 +1279,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
// functions are declared by the C library.
# define _LIBCPP_HAS_NO_C8RTOMB_MBRTOC8
// GNU libc 2.36 and newer declare c8rtomb() and mbrtoc8() in C++ modes if
-// __cpp_char8_t is defined or if C2X extensions are enabled. Unfortunately,
-// determining the latter depends on internal GNU libc details. If the
-// __cpp_char8_t feature test macro is not defined, then a char8_t typedef
-// will be declared as well.
-# if defined(_LIBCPP_GLIBC_PREREQ) && defined(__GLIBC_USE)
-# if _LIBCPP_GLIBC_PREREQ(2, 36) && (defined(__cpp_char8_t) || __GLIBC_USE(ISOC2X))
+// __cpp_char8_t is defined or if C2X extensions are enabled. Determining
+// the latter depends on internal GNU libc details that are not appropriate
+// to depend on here, so any declarations present when __cpp_char8_t is not
+// defined are ignored.
+# if defined(_LIBCPP_GLIBC_PREREQ)
+# if _LIBCPP_GLIBC_PREREQ(2, 36) && defined(__cpp_char8_t)
# undef _LIBCPP_HAS_NO_C8RTOMB_MBRTOC8
# endif
# endif
@@ -1250,6 +1302,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) static_assert(true, "")
#endif
+// TODO(varconst): currently, there are bugs in Clang's intrinsics when handling Objective-C++ `id`, so don't use
+// compiler intrinsics in the Objective-C++ mode.
+# ifdef __OBJC__
+# define _LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS
+# endif
+
#endif // __cplusplus
#endif // _LIBCPP___CONFIG
diff --git a/contrib/libs/cxxsupp/libcxx/include/__coroutine/coroutine_handle.h b/contrib/libs/cxxsupp/libcxx/include/__coroutine/coroutine_handle.h
index 8f7ed2ee48..0a6cc1cab6 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__coroutine/coroutine_handle.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__coroutine/coroutine_handle.h
@@ -13,8 +13,9 @@
#include <__config>
#include <__functional/hash.h>
#include <__memory/addressof.h>
+#include <__type_traits/remove_cv.h>
#include <compare>
-#include <type_traits>
+#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__coroutine/coroutine_traits.h b/contrib/libs/cxxsupp/libcxx/include/__coroutine/coroutine_traits.h
index 87eb21830a..d513075098 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__coroutine/coroutine_traits.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__coroutine/coroutine_traits.h
@@ -10,7 +10,7 @@
#define _LIBCPP___COROUTINE_COROUTINE_TRAITS_H
#include <__config>
-#include <type_traits>
+#include <__type_traits/void_t.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__debug b/contrib/libs/cxxsupp/libcxx/include/__debug
index ae0c1a5af0..140cc9142a 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__debug
+++ b/contrib/libs/cxxsupp/libcxx/include/__debug
@@ -12,8 +12,8 @@
#include <__assert>
#include <__config>
+#include <__type_traits/is_constant_evaluated.h>
#include <cstddef>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__filesystem/filesystem_error.h b/contrib/libs/cxxsupp/libcxx/include/__filesystem/filesystem_error.h
index eb5c38ad12..effe699833 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__filesystem/filesystem_error.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__filesystem/filesystem_error.h
@@ -61,7 +61,7 @@ public:
filesystem_error(const filesystem_error&) = default;
~filesystem_error() override; // key function
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL
const char* what() const noexcept override {
return __storage_->__what_.c_str();
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/__filesystem/path.h b/contrib/libs/cxxsupp/libcxx/include/__filesystem/path.h
index 7d1a784403..4e6912fcf3 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__filesystem/path.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__filesystem/path.h
@@ -619,7 +619,7 @@ public:
_EnableIfPathable<_Source> append(const _Source& __src) {
using _Traits = __is_pathable<_Source>;
using _CVT = _PathCVT<_SourceChar<_Source> >;
- bool __source_is_absolute = __is_separator(_Traits::__first_or_null(__src));
+ bool __source_is_absolute = _VSTD_FS::__is_separator(_Traits::__first_or_null(__src));
if (__source_is_absolute)
__pn_.clear();
else if (has_filename())
@@ -634,7 +634,7 @@ public:
typedef typename iterator_traits<_InputIt>::value_type _ItVal;
static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
using _CVT = _PathCVT<_ItVal>;
- if (__first != __last && __is_separator(*__first))
+ if (__first != __last && _VSTD_FS::__is_separator(*__first))
__pn_.clear();
else if (has_filename())
__pn_ += preferred_separator;
@@ -866,7 +866,7 @@ public:
using _Str = basic_string<_ECharT, _Traits, _Allocator>;
_Str __s(__a);
__s.reserve(__pn_.size());
- _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
+ _CVT()(std::back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
return __s;
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/buffer.h b/contrib/libs/cxxsupp/libcxx/include/__format/buffer.h
index 60c1f8093c..ddfe76728e 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__format/buffer.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__format/buffer.h
@@ -31,6 +31,7 @@
#include <cstddef>
#include <string_view>
#include <type_traits>
+#include <vector>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -493,6 +494,74 @@ public:
return {_VSTD::move(this->__writer_).__out_it(), this->__size_};
}
};
+
+// A dynamically growing buffer intended to be used for retargeting a context.
+//
+// P2286 Formatting ranges adds range formatting support. It allows the user to
+// specify the minimum width for the entire formatted range. The width of the
+// range is not known until the range is formatted. Formatting is done to an
+// output_iterator so there's no guarantee it would be possible to add the fill
+// to the front of the output. Instead the range is formatted to a temporary
+// buffer and that buffer is formatted as a string.
+//
+// There is an issue with that approach, the format context used in
+// std::formatter<T>::format contains the output iterator used as part of its
+// type. So using this output iterator means there needs to be a new format
+// context and the format arguments need to be retargeted to the new context.
+// This retargeting is done by a basic_format_context specialized for the
+// __iterator of this container.
+template <__fmt_char_type _CharT>
+class _LIBCPP_TEMPLATE_VIS __retarget_buffer {
+public:
+ using value_type = _CharT;
+
+ struct __iterator {
+ using difference_type = ptrdiff_t;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(__retarget_buffer& __buffer)
+ : __buffer_(std::addressof(__buffer)) {}
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator=(const _CharT& __c) {
+ __buffer_->push_back(__c);
+ return *this;
+ }
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator=(_CharT&& __c) {
+ __buffer_->push_back(__c);
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator*() { return *this; }
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() { return *this; }
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) { return *this; }
+ __retarget_buffer* __buffer_;
+ };
+
+ _LIBCPP_HIDE_FROM_ABI explicit __retarget_buffer(size_t __size_hint) { __buffer_.reserve(__size_hint); }
+
+ _LIBCPP_HIDE_FROM_ABI __iterator __make_output_iterator() { return __iterator{*this}; }
+
+ _LIBCPP_HIDE_FROM_ABI void push_back(_CharT __c) { __buffer_.push_back(__c); }
+
+ template <__fmt_char_type _InCharT>
+ _LIBCPP_HIDE_FROM_ABI void __copy(basic_string_view<_InCharT> __str) {
+ __buffer_.insert(__buffer_.end(), __str.begin(), __str.end());
+ }
+
+ template <__fmt_char_type _InCharT, class _UnaryOperation>
+ _LIBCPP_HIDE_FROM_ABI void __transform(const _InCharT* __first, const _InCharT* __last, _UnaryOperation __operation) {
+ _LIBCPP_ASSERT(__first <= __last, "not a valid range");
+ std::transform(__first, __last, std::back_inserter(__buffer_), std::move(__operation));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI void __fill(size_t __n, _CharT __value) { __buffer_.insert(__buffer_.end(), __n, __value); }
+
+ _LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT> __view() { return {__buffer_.data(), __buffer_.size()}; }
+
+private:
+ // Use vector instead of string to avoid adding zeros after every append
+ // operation. The buffer is exposed as a string_view and not as a c-string.
+ vector<_CharT> __buffer_;
+};
+
} // namespace __format
#endif //_LIBCPP_STD_VER > 17
diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/concepts.h b/contrib/libs/cxxsupp/libcxx/include/__format/concepts.h
index 5407feebf7..ba8d8e3162 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__format/concepts.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__format/concepts.h
@@ -15,6 +15,9 @@
#include <__config>
#include <__format/format_fwd.h>
#include <__format/format_parse_context.h>
+#include <__type_traits/is_specialization.h>
+#include <__utility/pair.h>
+#include <tuple>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -56,6 +59,16 @@ concept __formattable =
# if _LIBCPP_STD_VER > 20
template <class _Tp, class _CharT>
concept formattable = __formattable<_Tp, _CharT>;
+
+// [tuple.like] defines a tuple-like exposition only concept. This concept is
+// not related to that. Therefore it uses a different name for the concept.
+//
+// TODO FMT Add a test to validate we fail when using that concept after P2165
+// has been implemented.
+template <class _Tp>
+concept __fmt_pair_like =
+ __is_specialization_v<_Tp, pair> || (__is_specialization_v<_Tp, tuple> && tuple_size_v<_Tp> == 2);
+
# endif //_LIBCPP_STD_VER > 20
#endif //_LIBCPP_STD_VER > 17
diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/container_adaptor.h b/contrib/libs/cxxsupp/libcxx/include/__format/container_adaptor.h
new file mode 100644
index 0000000000..62b698186e
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__format/container_adaptor.h
@@ -0,0 +1,70 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FORMAT_CONTAINER_ADAPTOR_H
+#define _LIBCPP___FORMAT_CONTAINER_ADAPTOR_H
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#include <__availability>
+#include <__config>
+#include <__format/concepts.h>
+#include <__format/formatter.h>
+#include <__format/range_default_formatter.h>
+#include <queue>
+#include <stack>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 20
+
+// [container.adaptors.format] only specifies the library should provide the
+// formatter specializations, not which header should provide them.
+// Since <format> includes a lot of headers, add these headers here instead of
+// adding more dependencies like, locale, optinal, string, tuple, etc. to the
+// adaptor headers. To use the format functions users already include <format>.
+
+template <class _Adaptor, class _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_container_adaptor {
+private:
+ using __maybe_const_adaptor = __fmt_maybe_const<_Adaptor, _CharT>;
+ formatter<typename _Adaptor::container_type, _CharT> __underlying_;
+
+public:
+ template <class _ParseContext>
+ _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+ return __underlying_.parse(__ctx);
+ }
+
+ template <class _FormatContext>
+ _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+ format(__maybe_const_adaptor& __adaptor, _FormatContext& __ctx) const {
+ return __underlying_.format(__adaptor.__get_container(), __ctx);
+ }
+};
+
+template <class _CharT, class _Tp, formattable<_CharT> _Container>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<queue<_Tp, _Container>, _CharT>
+ : public __formatter_container_adaptor<queue<_Tp, _Container>, _CharT> {};
+
+template <class _CharT, class _Tp, class _Container, class _Compare>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<priority_queue<_Tp, _Container, _Compare>, _CharT>
+ : public __formatter_container_adaptor<priority_queue<_Tp, _Container, _Compare>, _CharT> {};
+
+template <class _CharT, class _Tp, formattable<_CharT> _Container>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<stack<_Tp, _Container>, _CharT>
+ : public __formatter_container_adaptor<stack<_Tp, _Container>, _CharT> {};
+
+#endif //_LIBCPP_STD_VER > 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FORMAT_CONTAINER_ADAPTOR_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/extended_grapheme_cluster_table.h b/contrib/libs/cxxsupp/libcxx/include/__format/extended_grapheme_cluster_table.h
index 0e00670df7..1ffcfeb549 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__format/extended_grapheme_cluster_table.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__format/extended_grapheme_cluster_table.h
@@ -111,7 +111,7 @@ enum class __property : uint8_t {
/// - https://www.unicode.org/Public/UCD/latest/ucd/emoji/emoji-data.txt
///
/// The data has 3 values
-/// - bits [0, 3] The property. One of the values generated form the datafiles
+/// - bits [0, 3] The property. One of the values generated from the datafiles
/// of \ref __property
/// - bits [4, 10] The size of the range.
/// - bits [11, 31] The lower bound code point of the range. The upper bound of
diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/format_arg.h b/contrib/libs/cxxsupp/libcxx/include/__format/format_arg.h
index 33d931ad79..771a03ff2f 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__format/format_arg.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__format/format_arg.h
@@ -161,7 +161,7 @@ public:
using _Dp = remove_cvref_t<_Tp>;
using _Formatter = typename _Context::template formatter_type<_Dp>;
constexpr bool __const_formattable =
- requires { _Formatter().format(declval<const _Dp&>(), declval<_Context&>()); };
+ requires { _Formatter().format(std::declval<const _Dp&>(), std::declval<_Context&>()); };
using _Qp = conditional_t<__const_formattable, const _Dp, _Dp>;
static_assert(__const_formattable || !is_const_v<remove_reference_t<_Tp>>, "Mandated by [format.arg]/18");
diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/format_arg_store.h b/contrib/libs/cxxsupp/libcxx/include/__format/format_arg_store.h
index 1820c0387c..6f4f4c3617 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__format/format_arg_store.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__format/format_arg_store.h
@@ -198,7 +198,7 @@ _LIBCPP_HIDE_FROM_ABI void __create_packed_storage(uint64_t& __types, __basic_fo
int __shift = 0;
(
[&] {
- basic_format_arg<_Context> __arg = __create_format_arg<_Context>(__args);
+ basic_format_arg<_Context> __arg = __format::__create_format_arg<_Context>(__args);
if (__shift != 0)
__types |= static_cast<uint64_t>(__arg.__type_) << __shift;
else
@@ -212,7 +212,7 @@ _LIBCPP_HIDE_FROM_ABI void __create_packed_storage(uint64_t& __types, __basic_fo
template <class _Context, class... _Args>
_LIBCPP_HIDE_FROM_ABI void __store_basic_format_arg(basic_format_arg<_Context>* __data, _Args&&... __args) noexcept {
- ([&] { *__data++ = __create_format_arg<_Context>(__args); }(), ...);
+ ([&] { *__data++ = __format::__create_format_arg<_Context>(__args); }(), ...);
}
template <class _Context, size_t N>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/format_context.h b/contrib/libs/cxxsupp/libcxx/include/__format/format_context.h
index 882a6049bb..85e00eb222 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__format/format_context.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__format/format_context.h
@@ -11,13 +11,19 @@
#define _LIBCPP___FORMAT_FORMAT_CONTEXT_H
#include <__availability>
+#include <__concepts/same_as.h>
#include <__config>
#include <__format/buffer.h>
+#include <__format/format_arg.h>
+#include <__format/format_arg_store.h>
#include <__format/format_args.h>
+#include <__format/format_error.h>
#include <__format/format_fwd.h>
#include <__iterator/back_insert_iterator.h>
#include <__iterator/concepts.h>
+#include <__memory/addressof.h>
#include <__utility/move.h>
+#include <__variant/monostate.h>
#include <cstddef>
#ifndef _LIBCPP_HAS_NO_LOCALIZATION
@@ -138,8 +144,78 @@ private:
: __out_it_(_VSTD::move(__out_it)), __args_(__args) {}
#endif
};
-_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_context);
+// A specialization for __retarget_buffer
+//
+// See __retarget_buffer for the motivation for this specialization.
+//
+// This context holds a reference to the instance of the basic_format_context
+// that is retargeted. It converts a formatting argument when it is requested
+// during formatting. It is expected that the usage of the arguments is rare so
+// the lookups are not expected to be used often. An alternative would be to
+// convert all elements during construction.
+//
+// The elements of the retargets context are only used when an underlying
+// formatter uses a locale specific formatting or an formatting argument is
+// part for the format spec. For example
+// format("{:256:{}}", input, 8);
+// Here the width of an element in input is determined dynamically.
+// Note when the top-level element has no width the retargeting is not needed.
+template <class _CharT>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
+ basic_format_context<typename __format::__retarget_buffer<_CharT>::__iterator, _CharT> {
+public:
+ using iterator = typename __format::__retarget_buffer<_CharT>::__iterator;
+ using char_type = _CharT;
+ template <class _Tp>
+ using formatter_type = formatter<_Tp, _CharT>;
+
+ template <class _Context>
+ _LIBCPP_HIDE_FROM_ABI explicit basic_format_context(iterator __out_it, _Context& __ctx)
+ : __out_it_(std::move(__out_it)),
+# ifndef _LIBCPP_HAS_NO_LOCALIZATION
+ __loc_([](void* __c) { return static_cast<_Context*>(__c)->locale(); }),
+# endif
+ __ctx_(std::addressof(__ctx)),
+ __arg_([](void* __c, size_t __id) {
+ return std::visit_format_arg(
+ [&](auto __arg) -> basic_format_arg<basic_format_context> {
+ if constexpr (same_as<decltype(__arg), monostate>)
+ return {};
+ else if constexpr (same_as<decltype(__arg), typename basic_format_arg<_Context>::handle>)
+ // At the moment it's not possible for formatting to use a re-targeted handle.
+ // TODO FMT add this when support is needed.
+ std::__throw_format_error("Re-targeting handle not supported");
+ else
+ return basic_format_arg<basic_format_context>{
+ __format::__determine_arg_t<basic_format_context, decltype(__arg)>(),
+ __basic_format_arg_value<basic_format_context>(__arg)};
+ },
+ static_cast<_Context*>(__c)->arg(__id));
+ }) {
+ }
+
+ _LIBCPP_HIDE_FROM_ABI basic_format_arg<basic_format_context> arg(size_t __id) const noexcept {
+ return __arg_(__ctx_, __id);
+ }
+# ifndef _LIBCPP_HAS_NO_LOCALIZATION
+ _LIBCPP_HIDE_FROM_ABI _VSTD::locale locale() { return __loc_(__ctx_); }
+# endif
+ _LIBCPP_HIDE_FROM_ABI iterator out() { return std::move(__out_it_); }
+ _LIBCPP_HIDE_FROM_ABI void advance_to(iterator __it) { __out_it_ = std::move(__it); }
+
+private:
+ iterator __out_it_;
+
+# ifndef _LIBCPP_HAS_NO_LOCALIZATION
+ std::locale (*__loc_)(void* __ctx);
+# endif
+
+ void* __ctx_;
+ basic_format_arg<basic_format_context> (*__arg_)(void* __ctx, size_t __id);
+};
+
+_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_context);
#endif //_LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/format_functions.h b/contrib/libs/cxxsupp/libcxx/include/__format/format_functions.h
index 8c8b54e808..0f0001272d 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__format/format_functions.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__format/format_functions.h
@@ -101,7 +101,7 @@ public:
// Before calling __parse the proper handler needs to be set with __enable.
// The default handler isn't a core constant expression.
_LIBCPP_HIDE_FROM_ABI constexpr __compile_time_handle()
- : __parse_([](basic_format_parse_context<_CharT>&) { __throw_format_error("Not a handle"); }) {}
+ : __parse_([](basic_format_parse_context<_CharT>&) { std::__throw_format_error("Not a handle"); }) {}
private:
void (*__parse_)(basic_format_parse_context<_CharT>&);
@@ -128,13 +128,13 @@ public:
_LIBCPP_HIDE_FROM_ABI constexpr __arg_t arg(size_t __id) const {
if (__id >= __size_)
- __throw_format_error("Argument index out of bounds");
+ std::__throw_format_error("Argument index out of bounds");
return __args_[__id];
}
_LIBCPP_HIDE_FROM_ABI constexpr const __compile_time_handle<_CharT>& __handle(size_t __id) const {
if (__id >= __size_)
- __throw_format_error("Argument index out of bounds");
+ std::__throw_format_error("Argument index out of bounds");
return __handles_[__id];
}
@@ -159,7 +159,7 @@ constexpr void __compile_time_validate_integral(__arg_t __type) {
return;
default:
- __throw_format_error("Argument isn't an integral type");
+ std::__throw_format_error("Argument isn't an integral type");
}
}
@@ -191,7 +191,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg(basic_forma
__arg_t __type) {
switch (__type) {
case __arg_t::__none:
- __throw_format_error("Invalid argument");
+ std::__throw_format_error("Invalid argument");
case __arg_t::__boolean:
return __format::__compile_time_validate_argument<_CharT, bool>(__parse_ctx, __ctx);
case __arg_t::__char_type:
@@ -204,7 +204,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg(basic_forma
# ifndef _LIBCPP_HAS_NO_INT128
return __format::__compile_time_validate_argument<_CharT, __int128_t>(__parse_ctx, __ctx);
# else
- __throw_format_error("Invalid argument");
+ std::__throw_format_error("Invalid argument");
# endif
return;
case __arg_t::__unsigned:
@@ -215,7 +215,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg(basic_forma
# ifndef _LIBCPP_HAS_NO_INT128
return __format::__compile_time_validate_argument<_CharT, __uint128_t>(__parse_ctx, __ctx);
# else
- __throw_format_error("Invalid argument");
+ std::__throw_format_error("Invalid argument");
# endif
return;
case __arg_t::__float:
@@ -231,9 +231,9 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg(basic_forma
case __arg_t::__ptr:
return __format::__compile_time_validate_argument<_CharT, const void*>(__parse_ctx, __ctx);
case __arg_t::__handle:
- __throw_format_error("Handle should use __compile_time_validate_handle_argument");
+ std::__throw_format_error("Handle should use __compile_time_validate_handle_argument");
}
- __throw_format_error("Invalid argument");
+ std::__throw_format_error("Invalid argument");
}
template <class _CharT, class _ParseCtx, class _Ctx>
@@ -253,21 +253,22 @@ __handle_replacement_field(const _CharT* __begin, const _CharT* __end,
__parse_ctx.advance_to(__r.__ptr);
break;
default:
- __throw_format_error(
- "The replacement field arg-id should terminate at a ':' or '}'");
+ std::__throw_format_error("The replacement field arg-id should terminate at a ':' or '}'");
}
if constexpr (same_as<_Ctx, __compile_time_basic_format_context<_CharT>>) {
__arg_t __type = __ctx.arg(__r.__value);
- if (__type == __arg_t::__handle)
+ if (__type == __arg_t::__none)
+ std::__throw_format_error("Argument index out of bounds");
+ else if (__type == __arg_t::__handle)
__ctx.__handle(__r.__value).__parse(__parse_ctx);
- else
- __format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type);
+ else if (__parse)
+ __format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type);
} else
_VSTD::__visit_format_arg(
[&](auto __arg) {
if constexpr (same_as<decltype(__arg), monostate>)
- __throw_format_error("Argument index out of bounds");
+ std::__throw_format_error("Argument index out of bounds");
else if constexpr (same_as<decltype(__arg), typename basic_format_arg<_Ctx>::handle>)
__arg.format(__parse_ctx, __ctx);
else {
@@ -281,7 +282,7 @@ __handle_replacement_field(const _CharT* __begin, const _CharT* __end,
__begin = __parse_ctx.begin();
if (__begin == __end || *__begin != _CharT('}'))
- __throw_format_error("The replacement field misses a terminating '}'");
+ std::__throw_format_error("The replacement field misses a terminating '}'");
return ++__begin;
}
@@ -300,12 +301,12 @@ __vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) {
case _CharT('{'):
++__begin;
if (__begin == __end)
- __throw_format_error("The format string terminates at a '{'");
+ std::__throw_format_error("The format string terminates at a '{'");
if (*__begin != _CharT('{')) [[likely]] {
__ctx.advance_to(_VSTD::move(__out_it));
__begin =
- __handle_replacement_field(__begin, __end, __parse_ctx, __ctx);
+ __format::__handle_replacement_field(__begin, __end, __parse_ctx, __ctx);
__out_it = __ctx.out();
// The output is written and __begin points to the next character. So
@@ -318,8 +319,7 @@ __vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) {
case _CharT('}'):
++__begin;
if (__begin == __end || *__begin != _CharT('}'))
- __throw_format_error(
- "The format string contains an invalid escape sequence");
+ std::__throw_format_error("The format string contains an invalid escape sequence");
break;
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/format_parse_context.h b/contrib/libs/cxxsupp/libcxx/include/__format/format_parse_context.h
index 4bcfda1138..30e3a7dfda 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__format/format_parse_context.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__format/format_parse_context.h
@@ -54,8 +54,7 @@ public:
_LIBCPP_HIDE_FROM_ABI constexpr size_t next_arg_id() {
if (__indexing_ == __manual)
- __throw_format_error("Using automatic argument numbering in manual "
- "argument numbering mode");
+ std::__throw_format_error("Using automatic argument numbering in manual argument numbering mode");
if (__indexing_ == __unknown)
__indexing_ = __automatic;
@@ -63,8 +62,7 @@ public:
}
_LIBCPP_HIDE_FROM_ABI constexpr void check_arg_id(size_t __id) {
if (__indexing_ == __automatic)
- __throw_format_error("Using manual argument numbering in automatic "
- "argument numbering mode");
+ std::__throw_format_error("Using manual argument numbering in automatic argument numbering mode");
if (__indexing_ == __unknown)
__indexing_ = __manual;
@@ -77,7 +75,7 @@ public:
// Note: the Throws clause [format.parse.ctx]/10 doesn't specify the
// behavior when id >= num_args_.
if (is_constant_evaluated() && __id >= __num_args_)
- __throw_format_error("Argument index outside the valid range");
+ std::__throw_format_error("Argument index outside the valid range");
}
private:
diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/format_string.h b/contrib/libs/cxxsupp/libcxx/include/__format/format_string.h
index 6033180d97..d9caf866a1 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__format/format_string.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__format/format_string.h
@@ -73,7 +73,7 @@ __parse_automatic(const _CharT* __begin, const _CharT*, auto& __parse_ctx) {
template <class _CharT>
_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
__parse_manual(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
- __parse_number_result<_CharT> __r = __parse_number(__begin, __end);
+ __parse_number_result<_CharT> __r = __format::__parse_number(__begin, __end);
__parse_ctx.check_arg_id(__r.__value);
return __r;
}
@@ -120,7 +120,7 @@ __parse_number(const _CharT* __begin, const _CharT* __end_input) {
if (__v > __number_max ||
(__begin != __end_input && *__begin >= _CharT('0') &&
*__begin <= _CharT('9')))
- __throw_format_error("The numeric value of the format-spec is too large");
+ std::__throw_format_error("The numeric value of the format-spec is too large");
__value = __v;
}
@@ -149,8 +149,7 @@ __parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
return __detail::__parse_automatic(__begin, __end, __parse_ctx);
}
if (*__begin < _CharT('0') || *__begin > _CharT('9'))
- __throw_format_error(
- "The arg-id of the format-spec starts with an invalid character");
+ std::__throw_format_error("The arg-id of the format-spec starts with an invalid character");
return __detail::__parse_manual(__begin, __end, __parse_ctx);
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/formatter.h b/contrib/libs/cxxsupp/libcxx/include/__format/formatter.h
index 154f8a5262..900a09af4e 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__format/formatter.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__format/formatter.h
@@ -38,7 +38,16 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter {
formatter& operator=(const formatter&) = delete;
};
-#endif //_LIBCPP_STD_VER > 17
+# if _LIBCPP_STD_VER > 20
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr void __set_debug_format(_Tp& __formatter) {
+ if constexpr (requires { __formatter.set_debug_format(); })
+ __formatter.set_debug_format();
+}
+
+# endif // _LIBCPP_STD_VER > 20
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/formatter_floating_point.h b/contrib/libs/cxxsupp/libcxx/include/__format/formatter_floating_point.h
index 29b3711ef9..ca065723e1 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__format/formatter_floating_point.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__format/formatter_floating_point.h
@@ -404,7 +404,6 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_lower_case(__float_
// In fixed mode the algorithm truncates trailing spaces and possibly the
// radix point. There's no good guess for the position of the radix point
// therefore scan the output after the first digit.
-
__result.__radix_point = _VSTD::find(__first, __result.__last, '.');
}
}
@@ -498,7 +497,7 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form(
const __float_result& __result,
_VSTD::locale __loc,
__format_spec::__parsed_specifications<_CharT> __specs) {
- const auto& __np = use_facet<numpunct<_CharT>>(__loc);
+ const auto& __np = std::use_facet<numpunct<_CharT>>(__loc);
string __grouping = __np.grouping();
char* __first = __result.__integral;
// When no radix point or exponent are present __last will be __result.__last.
@@ -665,7 +664,7 @@ __format_floating_point(_Tp __value, auto& __ctx, __format_spec::__parsed_specif
if (__result.__exponent == __result.__last)
// if P > X >= -4, the conversion is with style f or F and precision P - 1 - X.
// By including the radix point it calculates P - (1 + X)
- __p -= __result.__radix_point - __buffer.begin();
+ __p -= __result.__radix_point - __result.__integral;
else
// otherwise, the conversion is with style e or E and precision P - 1.
--__p;
diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/formatter_integral.h b/contrib/libs/cxxsupp/libcxx/include/__format/formatter_integral.h
index 87c6d559b0..fe3a06311b 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__format/formatter_integral.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__format/formatter_integral.h
@@ -217,7 +217,7 @@ _LIBCPP_HIDE_FROM_ABI auto __format_integer(
# ifndef _LIBCPP_HAS_NO_LOCALIZATION
if (__specs.__std_.__locale_specific_form_) {
- const auto& __np = use_facet<numpunct<_CharT>>(__ctx.locale());
+ const auto& __np = std::use_facet<numpunct<_CharT>>(__ctx.locale());
string __grouping = __np.grouping();
ptrdiff_t __size = __last - __first;
// Writing the grouped form has more overhead than the normal output
@@ -310,7 +310,7 @@ __format_integer(_Tp __value, auto& __ctx, __format_spec::__parsed_specification
auto __r = std::__to_unsigned_like(__value);
bool __negative = __value < 0;
if (__negative)
- __r = __complement(__r);
+ __r = std::__complement(__r);
return __formatter::__format_integer(__r, __ctx, __specs, __negative);
}
@@ -342,7 +342,7 @@ __format_bool(bool __value, auto& __ctx, __format_spec::__parsed_specifications<
-> decltype(__ctx.out()) {
# ifndef _LIBCPP_HAS_NO_LOCALIZATION
if (__specs.__std_.__locale_specific_form_) {
- const auto& __np = use_facet<numpunct<_CharT>>(__ctx.locale());
+ const auto& __np = std::use_facet<numpunct<_CharT>>(__ctx.locale());
basic_string<_CharT> __str = __value ? __np.truename() : __np.falsename();
return __formatter::__write_string_no_precision(basic_string_view<_CharT>{__str}, __ctx.out(), __specs);
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/formatter_output.h b/contrib/libs/cxxsupp/libcxx/include/__format/formatter_output.h
index 4f2c0445c0..467692559c 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__format/formatter_output.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__format/formatter_output.h
@@ -102,6 +102,10 @@ _LIBCPP_HIDE_FROM_ABI auto __copy(basic_string_view<_CharT> __str, output_iterat
if constexpr (_VSTD::same_as<decltype(__out_it), _VSTD::back_insert_iterator<__format::__output_buffer<_OutCharT>>>) {
__out_it.__get_container()->__copy(__str);
return __out_it;
+ } else if constexpr (_VSTD::same_as<decltype(__out_it),
+ typename __format::__retarget_buffer<_OutCharT>::__iterator>) {
+ __out_it.__buffer_->__copy(__str);
+ return __out_it;
} else {
return std::ranges::copy(__str, _VSTD::move(__out_it)).out;
}
@@ -132,6 +136,10 @@ __transform(const _CharT* __first,
if constexpr (_VSTD::same_as<decltype(__out_it), _VSTD::back_insert_iterator<__format::__output_buffer<_OutCharT>>>) {
__out_it.__get_container()->__transform(__first, __last, _VSTD::move(__operation));
return __out_it;
+ } else if constexpr (_VSTD::same_as<decltype(__out_it),
+ typename __format::__retarget_buffer<_OutCharT>::__iterator>) {
+ __out_it.__buffer_->__transform(__first, __last, _VSTD::move(__operation));
+ return __out_it;
} else {
return std::ranges::transform(__first, __last, _VSTD::move(__out_it), __operation).out;
}
@@ -145,6 +153,9 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, _CharT __value)
if constexpr (_VSTD::same_as<decltype(__out_it), _VSTD::back_insert_iterator<__format::__output_buffer<_CharT>>>) {
__out_it.__get_container()->__fill(__n, __value);
return __out_it;
+ } else if constexpr (_VSTD::same_as<decltype(__out_it), typename __format::__retarget_buffer<_CharT>::__iterator>) {
+ __out_it.__buffer_->__fill(__n, __value);
+ return __out_it;
} else {
return std::ranges::fill_n(_VSTD::move(__out_it), __n, __value);
}
@@ -171,7 +182,7 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators(_OutIt __out_it, c
} else {
if (__specs.__width_ > __size) {
// Determine padding and write padding.
- __padding = __padding_size(__size, __specs.__width_, __specs.__alignment_);
+ __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_);
__out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
}
@@ -285,7 +296,7 @@ _LIBCPP_HIDE_FROM_ABI auto __write_transformed(const _CharT* __first, const _Cha
if (__size >= __specs.__width_)
return __formatter::__transform(__first, __last, _VSTD::move(__out_it), __op);
- __padding_size_result __padding = __padding_size(__size, __specs.__width_, __specs.__alignment_);
+ __padding_size_result __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_);
__out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
__out_it = __formatter::__transform(__first, __last, _VSTD::move(__out_it), __op);
return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
@@ -312,7 +323,7 @@ _LIBCPP_HIDE_FROM_ABI auto __write_using_trailing_zeros(
_LIBCPP_ASSERT(__num_trailing_zeros > 0, "The overload not writing trailing zeros should have been used");
__padding_size_result __padding =
- __padding_size(__size + __num_trailing_zeros, __specs.__width_, __specs.__alignment_);
+ __formatter::__padding_size(__size + __num_trailing_zeros, __specs.__width_, __specs.__alignment_);
__out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
__out_it = __formatter::__copy(__first, __exponent, _VSTD::move(__out_it));
__out_it = __formatter::__fill(_VSTD::move(__out_it), __num_trailing_zeros, _CharT('0'));
@@ -368,15 +379,15 @@ _LIBCPP_HIDE_FROM_ABI auto __write_string(
int __size = __formatter::__truncate(__str, __specs.__precision_);
- return __write(__str.begin(), __str.end(), _VSTD::move(__out_it), __specs, __size);
+ return __formatter::__write(__str.begin(), __str.end(), _VSTD::move(__out_it), __specs, __size);
}
# if _LIBCPP_STD_VER > 20
-struct __null_sentinel {};
+struct __nul_terminator {};
template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI bool operator==(const _CharT* __cstr, __null_sentinel) {
+_LIBCPP_HIDE_FROM_ABI bool operator==(const _CharT* __cstr, __nul_terminator) {
return *__cstr == _CharT('\0');
}
@@ -384,7 +395,7 @@ template <class _CharT>
_LIBCPP_HIDE_FROM_ABI void
__write_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value, const _CharT* __prefix) {
back_insert_iterator __out_it{__str};
- std::ranges::copy(__prefix, __null_sentinel{}, __out_it);
+ std::ranges::copy(__prefix, __nul_terminator{}, __out_it);
char __buffer[8];
to_chars_result __r = std::to_chars(std::begin(__buffer), std::end(__buffer), __value, 16);
@@ -401,7 +412,7 @@ __write_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value, const _
// lower-case hexadecimal digits.
template <class _CharT>
_LIBCPP_HIDE_FROM_ABI void __write_well_formed_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value) {
- __write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\u{"));
+ __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\u{"));
}
// [format.string.escaped]/2.2.3
@@ -411,7 +422,7 @@ _LIBCPP_HIDE_FROM_ABI void __write_well_formed_escaped_code_unit(basic_string<_C
// lower-case hexadecimal digits.
template <class _CharT>
_LIBCPP_HIDE_FROM_ABI void __write_escape_ill_formed_code_unit(basic_string<_CharT>& __str, char32_t __value) {
- __write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\x{"));
+ __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\x{"));
}
template <class _CharT>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/formatter_string.h b/contrib/libs/cxxsupp/libcxx/include/__format/formatter_string.h
index d1d1379146..606fb79249 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__format/formatter_string.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__format/formatter_string.h
@@ -65,6 +65,12 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const _CharT*,
_LIBCPP_ASSERT(__str, "The basic_format_arg constructor should have "
"prevented an invalid pointer.");
+ __format_spec::__parsed_specifications<_CharT> __specs = _Base::__parser_.__get_parsed_std_specifications(__ctx);
+# if _LIBCPP_STD_VER > 20
+ if (_Base::__parser_.__type_ == __format_spec::__type::__debug)
+ return __formatter::__format_escaped_string(basic_string_view<_CharT>{__str}, __ctx.out(), __specs);
+# endif
+
// When using a center or right alignment and the width option the length
// of __str must be known to add the padding upfront. This case is handled
// by the base class by converting the argument to a basic_string_view.
@@ -76,7 +82,6 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const _CharT*,
// now these optimizations aren't implemented. Instead the base class
// handles these options.
// TODO FMT Implement these improvements.
- __format_spec::__parsed_specifications<_CharT> __specs = _Base::__parser_.__get_parsed_std_specifications(__ctx);
if (__specs.__has_width() || __specs.__has_precision())
return __formatter::__write_string(basic_string_view<_CharT>{__str}, __ctx.out(), __specs);
diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/formatter_tuple.h b/contrib/libs/cxxsupp/libcxx/include/__format/formatter_tuple.h
new file mode 100644
index 0000000000..82f5ada6e0
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__format/formatter_tuple.h
@@ -0,0 +1,178 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FORMAT_FORMATTER_TUPLE_H
+#define _LIBCPP___FORMAT_FORMATTER_TUPLE_H
+
+#include <__algorithm/ranges_copy.h>
+#include <__availability>
+#include <__chrono/statically_widen.h>
+#include <__config>
+#include <__format/concepts.h>
+#include <__format/format_args.h>
+#include <__format/format_context.h>
+#include <__format/format_error.h>
+#include <__format/format_parse_context.h>
+#include <__format/formatter.h>
+#include <__format/formatter_output.h>
+#include <__format/parser_std_format_spec.h>
+#include <__iterator/back_insert_iterator.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/integer_sequence.h>
+#include <__utility/pair.h>
+#include <string_view>
+#include <tuple>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 20
+
+template <__fmt_char_type _CharT, class _Tuple, formattable<_CharT>... _Args>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_tuple {
+ _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) {
+ __separator_ = __separator;
+ }
+ _LIBCPP_HIDE_FROM_ABI constexpr void
+ set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) {
+ __opening_bracket_ = __opening_bracket;
+ __closing_bracket_ = __closing_bracket;
+ }
+
+ template <class _ParseContext>
+ _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __parse_ctx) {
+ const _CharT* __begin = __parser_.__parse(__parse_ctx, __format_spec::__fields_tuple);
+
+ // [format.tuple]/7
+ // ... For each element e in underlying_, if e.set_debug_format()
+ // is a valid expression, calls e.set_debug_format().
+ // TODO FMT this can be removed when P2733 is accepted.
+ std::__for_each_index_sequence(make_index_sequence<sizeof...(_Args)>(), [&]<size_t _Index> {
+ std::__set_debug_format(std::get<_Index>(__underlying_));
+ });
+
+ const _CharT* __end = __parse_ctx.end();
+ if (__begin == __end)
+ return __begin;
+
+ if (*__begin == _CharT('m')) {
+ if constexpr (sizeof...(_Args) == 2) {
+ set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ": "));
+ set_brackets({}, {});
+ ++__begin;
+ } else
+ std::__throw_format_error("The format specifier m requires a pair or a two-element tuple");
+ } else if (*__begin == _CharT('n')) {
+ set_brackets({}, {});
+ ++__begin;
+ }
+
+ if (__begin != __end && *__begin != _CharT('}'))
+ std::__throw_format_error("The format-spec should consume the input or end with a '}'");
+
+ return __begin;
+ }
+
+ template <class _FormatContext>
+ typename _FormatContext::iterator _LIBCPP_HIDE_FROM_ABI
+ format(conditional_t<(formattable<const _Args, _CharT> && ...), const _Tuple&, _Tuple&> __tuple,
+ _FormatContext& __ctx) const {
+ __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx);
+
+ if (!__specs.__has_width())
+ return __format_tuple(__tuple, __ctx);
+
+ basic_string<_CharT> __str;
+
+ // Since the output is written to a different iterator a new context is
+ // created. Since the underlying formatter uses the default formatting it
+ // doesn't need a locale or the formatting arguments. So creating a new
+ // context works.
+ //
+ // This solution works for this formatter, but it will not work for the
+ // range_formatter. In that patch a generic solution is work in progress.
+ // Once that is finished it can be used here. (The range_formatter will use
+ // these features so it's easier to add it there and then port it.)
+ //
+ // TODO FMT Use formatting wrapping used in the range_formatter.
+ basic_format_context __c = std::__format_context_create(
+ back_insert_iterator{__str},
+ basic_format_args<basic_format_context<back_insert_iterator<basic_string<_CharT>>, _CharT>>{});
+
+ __format_tuple(__tuple, __c);
+
+ return __formatter::__write_string_no_precision(basic_string_view{__str}, __ctx.out(), __specs);
+ }
+
+ template <class _FormatContext>
+ _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator __format_tuple(auto&& __tuple, _FormatContext& __ctx) const {
+ __ctx.advance_to(std::ranges::copy(__opening_bracket_, __ctx.out()).out);
+
+ std::__for_each_index_sequence(make_index_sequence<sizeof...(_Args)>(), [&]<size_t _Index> {
+ if constexpr (_Index)
+ __ctx.advance_to(std::ranges::copy(__separator_, __ctx.out()).out);
+
+ // During review Victor suggested to make the exposition only
+ // __underlying_ member a local variable. Currently the Standard
+ // requires nested debug-enabled formatter specializations not to
+ // output escaped output. P2733 fixes that bug, once accepted the
+ // code below can be used.
+ // (Note when a paper allows parsing a tuple-underlying-spec the
+ // exposition only member needs to be a class member. Earlier
+ // revisions of P2286 proposed that, but this was not pursued,
+ // due to time constrains and complexity of the matter.)
+ // TODO FMT This can be updated after P2733 is accepted.
+# if 0
+ // P2286 uses an exposition only member in the formatter
+ // tuple<formatter<remove_cvref_t<_Args>, _CharT>...> __underlying_;
+ // This was used in earlier versions of the paper since
+ // __underlying_.parse(...) was called. This is no longer the case
+ // so we can reduce the scope of the formatter.
+ //
+ // It does require the underlying's parse effect to be moved here too.
+ using _Arg = tuple_element<_Index, decltype(__tuple)>;
+ formatter<remove_cvref_t<_Args>, _CharT> __underlying;
+
+ // [format.tuple]/7
+ // ... For each element e in underlying_, if e.set_debug_format()
+ // is a valid expression, calls e.set_debug_format().
+ std::__set_debug_format(__underlying);
+# else
+ __ctx.advance_to(std::get<_Index>(__underlying_).format(std::get<_Index>(__tuple), __ctx));
+# endif
+ });
+
+ return std::ranges::copy(__closing_bracket_, __ctx.out()).out;
+ }
+
+ __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__left};
+
+private:
+ tuple<formatter<remove_cvref_t<_Args>, _CharT>...> __underlying_;
+ basic_string_view<_CharT> __separator_ = _LIBCPP_STATICALLY_WIDEN(_CharT, ", ");
+ basic_string_view<_CharT> __opening_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, "(");
+ basic_string_view<_CharT> __closing_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, ")");
+};
+
+template <__fmt_char_type _CharT, formattable<_CharT>... _Args>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<pair<_Args...>, _CharT>
+ : public __formatter_tuple<_CharT, pair<_Args...>, _Args...> {};
+
+template <__fmt_char_type _CharT, formattable<_CharT>... _Args>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<tuple<_Args...>, _CharT>
+ : public __formatter_tuple<_CharT, tuple<_Args...>, _Args...> {};
+
+#endif //_LIBCPP_STD_VER > 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FORMAT_FORMATTER_TUPLE_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/parser_std_format_spec.h b/contrib/libs/cxxsupp/libcxx/include/__format/parser_std_format_spec.h
index 90c0cd184c..c03cec9796 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__format/parser_std_format_spec.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__format/parser_std_format_spec.h
@@ -19,6 +19,7 @@
#include <__algorithm/find_if.h>
#include <__algorithm/min.h>
#include <__assert>
+#include <__concepts/arithmetic.h>
#include <__concepts/same_as.h>
#include <__config>
#include <__debug>
@@ -52,12 +53,12 @@ __parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
// This function is a wrapper to call the real parser. But it does the
// validation for the pre-conditions and post-conditions.
if (__begin == __end)
- __throw_format_error("End of input while parsing format-spec arg-id");
+ std::__throw_format_error("End of input while parsing format-spec arg-id");
__format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __parse_ctx);
if (__r.__ptr == __end || *__r.__ptr != _CharT('}'))
- __throw_format_error("Invalid arg-id");
+ std::__throw_format_error("Invalid arg-id");
++__r.__ptr;
return __r;
@@ -80,22 +81,19 @@ __substitute_arg_id(basic_format_arg<_Context> __format_arg) {
if constexpr (integral<_Type>) {
if constexpr (signed_integral<_Type>) {
if (__arg < 0)
- __throw_format_error("A format-spec arg-id replacement shouldn't "
- "have a negative value");
+ std::__throw_format_error("A format-spec arg-id replacement shouldn't have a negative value");
}
using _CT = common_type_t<_Type, decltype(__format::__number_max)>;
if (static_cast<_CT>(__arg) >
static_cast<_CT>(__format::__number_max))
- __throw_format_error("A format-spec arg-id replacement exceeds "
- "the maximum supported value");
+ std::__throw_format_error("A format-spec arg-id replacement exceeds the maximum supported value");
return __arg;
} else if constexpr (same_as<_Type, monostate>)
- __throw_format_error("Argument index out of bounds");
+ std::__throw_format_error("Argument index out of bounds");
else
- __throw_format_error("A format-spec arg-id replacement argument "
- "isn't an integral type");
+ std::__throw_format_error("A format-spec arg-id replacement argument isn't an integral type");
},
__format_arg);
}
@@ -104,6 +102,7 @@ __substitute_arg_id(basic_format_arg<_Context> __format_arg) {
///
/// They default to false so when a new field is added it needs to be opted in
/// explicitly.
+// TODO FMT Use an ABI tag for this struct.
struct __fields {
uint8_t __sign_ : 1 {false};
uint8_t __alternate_form_ : 1 {false};
@@ -111,6 +110,13 @@ struct __fields {
uint8_t __precision_ : 1 {false};
uint8_t __locale_specific_form_ : 1 {false};
uint8_t __type_ : 1 {false};
+ // Determines the valid values for fill.
+ //
+ // Originally the fill could be any character except { and }. Range-based
+ // formatters use the colon to mark the beginning of the
+ // underlying-format-spec. To avoid parsing ambiguities these formatter
+ // specializations prohibit the use of the colon as a fill character.
+ uint8_t __allow_colon_in_fill_ : 1 {false};
};
// By not placing this constant in the formatter class it's not duplicated for
@@ -131,6 +137,11 @@ inline constexpr __fields __fields_floating_point{
inline constexpr __fields __fields_string{.__precision_ = true, .__type_ = true};
inline constexpr __fields __fields_pointer{.__type_ = true};
+# if _LIBCPP_STD_VER > 20
+inline constexpr __fields __fields_tuple{.__type_ = false, .__allow_colon_in_fill_ = true};
+inline constexpr __fields __fields_range{.__type_ = false, .__allow_colon_in_fill_ = true};
+# endif
+
enum class _LIBCPP_ENUM_VIS __alignment : uint8_t {
/// No alignment is set in the format string.
__default,
@@ -186,6 +197,9 @@ struct __chrono {
__alignment __alignment_ : 3;
bool __locale_specific_form_ : 1;
bool __weekday_name_ : 1;
+ bool __weekday_ : 1;
+ bool __day_of_year_ : 1;
+ bool __week_of_year_ : 1;
bool __month_name_ : 1;
};
@@ -259,7 +273,7 @@ public:
if (__begin == __end)
return __begin;
- if (__parse_fill_align(__begin, __end) && __begin == __end)
+ if (__parse_fill_align(__begin, __end, __fields.__allow_colon_in_fill_) && __begin == __end)
return __begin;
if (__fields.__sign_ && __parse_sign(__begin) && __begin == __end)
@@ -287,7 +301,7 @@ public:
// parsing. In that case that parser should do the end of format string
// validation.
if (__begin != __end && *__begin != _CharT('}'))
- __throw_format_error("The format-spec should consume the input or end with a '}'");
+ std::__throw_format_error("The format-spec should consume the input or end with a '}'");
}
return __begin;
@@ -309,10 +323,14 @@ public:
_LIBCPP_HIDE_FROM_ABI __parsed_specifications<_CharT> __get_parsed_chrono_specifications(auto& __ctx) const {
return __parsed_specifications<_CharT>{
- .__chrono_ = __chrono{.__alignment_ = __alignment_,
- .__locale_specific_form_ = __locale_specific_form_,
- .__weekday_name_ = __weekday_name_,
- .__month_name_ = __month_name_},
+ .__chrono_ =
+ __chrono{.__alignment_ = __alignment_,
+ .__locale_specific_form_ = __locale_specific_form_,
+ .__weekday_name_ = __weekday_name_,
+ .__weekday_ = __weekday_,
+ .__day_of_year_ = __day_of_year_,
+ .__week_of_year_ = __week_of_year_,
+ .__month_name_ = __month_name_},
.__width_{__get_width(__ctx)},
.__precision_{__get_precision(__ctx)},
.__fill_{__fill_}};
@@ -325,12 +343,17 @@ public:
bool __reserved_0_ : 1 {false};
__type __type_{__type::__default};
- // These two flags are used for formatting chrono. Since the struct has
+ // These flags are only used for formatting chrono. Since the struct has
// padding space left it's added to this structure.
bool __weekday_name_ : 1 {false};
+ bool __weekday_ : 1 {false};
+
+ bool __day_of_year_ : 1 {false};
+ bool __week_of_year_ : 1 {false};
+
bool __month_name_ : 1 {false};
- uint8_t __reserved_1_ : 6 {0};
+ uint8_t __reserved_1_ : 3 {0};
uint8_t __reserved_2_ : 6 {0};
// These two flags are only used internally and not part of the
// __parsed_specifications. Therefore put them at the end.
@@ -367,13 +390,17 @@ private:
return false;
}
- _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(const _CharT*& __begin, const _CharT* __end) {
+ // range-fill and tuple-fill are identical
+ _LIBCPP_HIDE_FROM_ABI constexpr bool
+ __parse_fill_align(const _CharT*& __begin, const _CharT* __end, bool __use_range_fill) {
_LIBCPP_ASSERT(__begin != __end, "when called with an empty input the function will cause "
"undefined behavior by evaluating data not in the input");
if (__begin + 1 != __end) {
if (__parse_alignment(*(__begin + 1))) {
- if (*__begin == _CharT('{') || *__begin == _CharT('}'))
- __throw_format_error("The format-spec fill field contains an invalid character");
+ if (__use_range_fill && (*__begin == _CharT('{') || *__begin == _CharT('}') || *__begin == _CharT(':')))
+ std::__throw_format_error("The format-spec range-fill field contains an invalid character");
+ else if (*__begin == _CharT('{') || *__begin == _CharT('}'))
+ std::__throw_format_error("The format-spec fill field contains an invalid character");
__fill_ = *__begin;
__begin += 2;
@@ -427,7 +454,7 @@ private:
_LIBCPP_HIDE_FROM_ABI constexpr bool __parse_width(const _CharT*& __begin, const _CharT* __end, auto& __parse_ctx) {
if (*__begin == _CharT('0'))
- __throw_format_error("A format-spec width field shouldn't have a leading zero");
+ std::__throw_format_error("A format-spec width field shouldn't have a leading zero");
if (*__begin == _CharT('{')) {
__format::__parse_number_result __r = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx);
@@ -455,7 +482,7 @@ private:
++__begin;
if (__begin == __end)
- __throw_format_error("End of input while parsing format-spec precision");
+ std::__throw_format_error("End of input while parsing format-spec precision");
if (*__begin == _CharT('{')) {
__format::__parse_number_result __arg_id = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx);
@@ -466,7 +493,7 @@ private:
}
if (*__begin < _CharT('0') || *__begin > _CharT('9'))
- __throw_format_error("The format-spec precision field doesn't contain a value or arg-id");
+ std::__throw_format_error("The format-spec precision field doesn't contain a value or arg-id");
__format::__parse_number_result __r = __format::__parse_number(__begin, __end);
__precision_ = __r.__value;
@@ -878,7 +905,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_
// unit is non-ASCII we omit the current code unit and let the Grapheme
// clustering algorithm do its work.
const _CharT* __it = __str.begin();
- if (__is_ascii(*__it)) {
+ if (__format_spec::__is_ascii(*__it)) {
do {
--__maximum;
++__it;
@@ -886,12 +913,12 @@ _LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_
return {__str.size(), __str.end()};
if (__maximum == 0) {
- if (__is_ascii(*__it))
+ if (__format_spec::__is_ascii(*__it))
return {static_cast<size_t>(__it - __str.begin()), __it};
break;
}
- } while (__is_ascii(*__it));
+ } while (__format_spec::__is_ascii(*__it));
--__it;
++__maximum;
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/range_default_formatter.h b/contrib/libs/cxxsupp/libcxx/include/__format/range_default_formatter.h
new file mode 100644
index 0000000000..774887b053
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__format/range_default_formatter.h
@@ -0,0 +1,201 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FORMAT_RANGE_DEFAULT_FORMATTER_H
+#define _LIBCPP___FORMAT_RANGE_DEFAULT_FORMATTER_H
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#include <__availability>
+#include <__chrono/statically_widen.h>
+#include <__concepts/same_as.h>
+#include <__config>
+#include <__format/concepts.h>
+#include <__format/formatter.h>
+#include <__format/range_formatter.h>
+#include <__ranges/concepts.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/pair.h>
+#include <string_view>
+#include <tuple>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 20
+
+template <class _Rp, class _CharT>
+concept __const_formattable_range =
+ ranges::input_range<const _Rp> && formattable<ranges::range_reference_t<const _Rp>, _CharT>;
+
+template <class _Rp, class _CharT>
+using __fmt_maybe_const = conditional_t<__const_formattable_range<_Rp, _CharT>, const _Rp, _Rp>;
+
+_LIBCPP_DIAGNOSTIC_PUSH
+_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wshadow")
+_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshadow")
+// This shadows map, set, and string.
+enum class range_format { disabled, map, set, sequence, string, debug_string };
+_LIBCPP_DIAGNOSTIC_POP
+
+// There is no definition of this struct, it's purely intended to be used to
+// generate diagnostics.
+template <class _Rp>
+struct _LIBCPP_TEMPLATE_VIS __instantiated_the_primary_template_of_format_kind;
+
+template <class _Rp>
+constexpr range_format format_kind = [] {
+ // [format.range.fmtkind]/1
+ // A program that instantiates the primary template of format_kind is ill-formed.
+ static_assert(sizeof(_Rp) != sizeof(_Rp), "create a template specialization of format_kind for your type");
+ return range_format::disabled;
+}();
+
+template <ranges::input_range _Rp>
+ requires same_as<_Rp, remove_cvref_t<_Rp>>
+inline constexpr range_format format_kind<_Rp> = [] {
+ // [format.range.fmtkind]/2
+
+ // 2.1 If same_as<remove_cvref_t<ranges::range_reference_t<R>>, R> is true,
+ // Otherwise format_kind<R> is range_format::disabled.
+ if constexpr (same_as<remove_cvref_t<ranges::range_reference_t<_Rp>>, _Rp>)
+ return range_format::disabled;
+ // 2.2 Otherwise, if the qualified-id R::key_type is valid and denotes a type:
+ else if constexpr (requires { typename _Rp::key_type; }) {
+ // 2.2.1 If the qualified-id R::mapped_type is valid and denotes a type ...
+ if constexpr (requires { typename _Rp::mapped_type; } &&
+ // 2.2.1 ... If either U is a specialization of pair or U is a specialization
+ // of tuple and tuple_size_v<U> == 2
+ __fmt_pair_like<remove_cvref_t<ranges::range_reference_t<_Rp>>>)
+ return range_format::map;
+ else
+ // 2.2.2 Otherwise format_kind<R> is range_format::set.
+ return range_format::set;
+ } else
+ // 2.3 Otherwise, format_kind<R> is range_format::sequence.
+ return range_format::sequence;
+}();
+
+// This is a non-standard work-around to fix instantiation of
+// formatter<const _CharT[N], _CharT>
+// const _CharT[N] satisfies the ranges::input_range concept.
+// remove_cvref_t<const _CharT[N]> is _CharT[N] so it does not satisfy the
+// requirement of the above specialization. Instead it will instantiate the
+// primary template, which is ill-formed.
+//
+// An alternative solution is to remove the offending formatter.
+//
+// https://godbolt.org/z/bqjhhaexx
+//
+// The removal is proposed in LWG3833, but use the work-around until the issue
+// has been adopted.
+// TODO FMT Implement LWG3833.
+template <class _CharT, size_t N>
+inline constexpr range_format format_kind<const _CharT[N]> = range_format::disabled;
+
+template <range_format _Kp, ranges::input_range _Rp, class _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter;
+
+// Required specializations
+
+template <ranges::input_range _Rp, class _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<range_format::sequence, _Rp, _CharT> {
+private:
+ using __maybe_const_r = __fmt_maybe_const<_Rp, _CharT>;
+ range_formatter<remove_cvref_t<ranges::range_reference_t<__maybe_const_r>>, _CharT> __underlying_;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) {
+ __underlying_.set_separator(__separator);
+ }
+ _LIBCPP_HIDE_FROM_ABI constexpr void
+ set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) {
+ __underlying_.set_brackets(__opening_bracket, __closing_bracket);
+ }
+
+ template <class _ParseContext>
+ _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+ return __underlying_.parse(__ctx);
+ }
+
+ template <class FormatContext>
+ _LIBCPP_HIDE_FROM_ABI typename FormatContext::iterator format(__maybe_const_r& __range, FormatContext& __ctx) const {
+ return __underlying_.format(__range, __ctx);
+ }
+};
+
+template <ranges::input_range _Rp, class _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<range_format::map, _Rp, _CharT> {
+private:
+ using __maybe_const_map = __fmt_maybe_const<_Rp, _CharT>;
+ using __element_type = remove_cvref_t<ranges::range_reference_t<__maybe_const_map>>;
+ range_formatter<__element_type, _CharT> __underlying_;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI constexpr __range_default_formatter()
+ requires(__fmt_pair_like<__element_type>)
+ {
+ __underlying_.set_brackets(_LIBCPP_STATICALLY_WIDEN(_CharT, "{"), _LIBCPP_STATICALLY_WIDEN(_CharT, "}"));
+ __underlying_.underlying().set_brackets({}, {});
+ __underlying_.underlying().set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ": "));
+ }
+
+ template <class _ParseContext>
+ _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+ return __underlying_.parse(__ctx);
+ }
+
+ template <class _FormatContext>
+ _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+ format(__maybe_const_map& __range, _FormatContext& __ctx) const {
+ return __underlying_.format(__range, __ctx);
+ }
+};
+
+template <ranges::input_range _Rp, class _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<range_format::set, _Rp, _CharT> {
+private:
+ using __maybe_const_set = __fmt_maybe_const<_Rp, _CharT>;
+ using __element_type = remove_cvref_t<ranges::range_reference_t<__maybe_const_set>>;
+ range_formatter<__element_type, _CharT> __underlying_;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI constexpr __range_default_formatter() {
+ __underlying_.set_brackets(_LIBCPP_STATICALLY_WIDEN(_CharT, "{"), _LIBCPP_STATICALLY_WIDEN(_CharT, "}"));
+ }
+
+ template <class _ParseContext>
+ _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+ return __underlying_.parse(__ctx);
+ }
+
+ template <class _FormatContext>
+ _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+ format(__maybe_const_set& __range, _FormatContext& __ctx) const {
+ return __underlying_.format(__range, __ctx);
+ }
+};
+
+template <range_format _Kp, ranges::input_range _Rp, class _CharT>
+ requires(_Kp == range_format::string || _Kp == range_format::debug_string)
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<_Kp, _Rp, _CharT> {
+ __range_default_formatter() = delete; // TODO FMT Implement
+};
+
+template <ranges::input_range _Rp, class _CharT>
+ requires(format_kind<_Rp> != range_format::disabled && formattable<ranges::range_reference_t<_Rp>, _CharT>)
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_Rp, _CharT>
+ : __range_default_formatter<format_kind<_Rp>, _Rp, _CharT> {};
+
+#endif //_LIBCPP_STD_VER > 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FORMAT_RANGE_DEFAULT_FORMATTER_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/range_formatter.h b/contrib/libs/cxxsupp/libcxx/include/__format/range_formatter.h
new file mode 100644
index 0000000000..9ea61a7035
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__format/range_formatter.h
@@ -0,0 +1,255 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FORMAT_RANGE_FORMATTER_H
+#define _LIBCPP___FORMAT_RANGE_FORMATTER_H
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#include <__algorithm/ranges_copy.h>
+#include <__availability>
+#include <__chrono/statically_widen.h>
+#include <__concepts/same_as.h>
+#include <__config>
+#include <__format/buffer.h>
+#include <__format/concepts.h>
+#include <__format/format_args.h>
+#include <__format/format_context.h>
+#include <__format/format_error.h>
+#include <__format/formatter.h>
+#include <__format/formatter_output.h>
+#include <__format/parser_std_format_spec.h>
+#include <__iterator/back_insert_iterator.h>
+#include <__ranges/concepts.h>
+#include <__ranges/data.h>
+#include <__ranges/size.h>
+#include <__type_traits/remove_cvref.h>
+#include <string_view>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 20
+
+template <class _Tp, class _CharT = char>
+ requires same_as<remove_cvref_t<_Tp>, _Tp> && formattable<_Tp, _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT range_formatter {
+ _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) {
+ __separator_ = __separator;
+ }
+ _LIBCPP_HIDE_FROM_ABI constexpr void
+ set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) {
+ __opening_bracket_ = __opening_bracket;
+ __closing_bracket_ = __closing_bracket;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr formatter<_Tp, _CharT>& underlying() { return __underlying_; }
+ _LIBCPP_HIDE_FROM_ABI constexpr const formatter<_Tp, _CharT>& underlying() const { return __underlying_; }
+
+ template <class _ParseContext>
+ _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __parse_ctx) {
+ const _CharT* __begin = __parser_.__parse(__parse_ctx, __format_spec::__fields_range);
+ const _CharT* __end = __parse_ctx.end();
+ if (__begin == __end)
+ return __begin;
+
+ // The n field overrides a possible m type, therefore delay applying the
+ // effect of n until the type has been procesed.
+ bool __clear_brackets = (*__begin == _CharT('n'));
+ if (__clear_brackets) {
+ ++__begin;
+ if (__begin == __end) {
+ // Since there is no more data, clear the brackets before returning.
+ set_brackets({}, {});
+ return __begin;
+ }
+ }
+
+ __parse_type(__begin, __end);
+ if (__clear_brackets)
+ set_brackets({}, {});
+ if (__begin == __end)
+ return __begin;
+
+ bool __has_range_underlying_spec = *__begin == _CharT(':');
+ if (__parser_.__type_ != __format_spec::__type::__default) {
+ // [format.range.formatter]/6
+ // If the range-type is s or ?s, then there shall be no n option and no
+ // range-underlying-spec.
+ if (__clear_brackets) {
+ if (__parser_.__type_ == __format_spec::__type::__string)
+ std::__throw_format_error("The n option and type s can't be used together");
+ std::__throw_format_error("The n option and type ?s can't be used together");
+ }
+ if (__has_range_underlying_spec) {
+ if (__parser_.__type_ == __format_spec::__type::__string)
+ std::__throw_format_error("Type s and an underlying format specification can't be used together");
+ std::__throw_format_error("Type ?s and an underlying format specification can't be used together");
+ }
+ } else if (!__has_range_underlying_spec)
+ std::__set_debug_format(__underlying_);
+
+ if (__has_range_underlying_spec) {
+ // range-underlying-spec:
+ // : format-spec
+ ++__begin;
+ if (__begin == __end)
+ return __begin;
+
+ __parse_ctx.advance_to(__begin);
+ __begin = __underlying_.parse(__parse_ctx);
+ }
+
+ if (__begin != __end && *__begin != _CharT('}'))
+ std::__throw_format_error("The format-spec should consume the input or end with a '}'");
+
+ return __begin;
+ }
+
+ template <ranges::input_range _Rp, class _FormatContext>
+ requires formattable<ranges::range_reference_t<_Rp>, _CharT> &&
+ same_as<remove_cvref_t<ranges::range_reference_t<_Rp>>, _Tp>
+ _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(_Rp&& __range, _FormatContext& __ctx) const {
+ __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx);
+
+ if (!__specs.__has_width())
+ return __format_range(__range, __ctx, __specs);
+
+ // The size of the buffer needed is:
+ // - open bracket characters
+ // - close bracket character
+ // - n elements where every element may have a different size
+ // - (n -1) separators
+ // The size of the element is hard to predict, knowing the type helps but
+ // it depends on the format-spec. As an initial estimate we guess 6
+ // characters.
+ // Typically both brackets are 1 character and the separator is 2
+ // characters. Which means there will be
+ // (n - 1) * 2 + 1 + 1 = n * 2 character
+ // So estimate 8 times the range size as buffer.
+ std::size_t __capacity_hint = 0;
+ if constexpr (std::ranges::sized_range<_Rp>)
+ __capacity_hint = 8 * ranges::size(__range);
+ __format::__retarget_buffer<_CharT> __buffer{__capacity_hint};
+ basic_format_context<typename __format::__retarget_buffer<_CharT>::__iterator, _CharT> __c{
+ __buffer.__make_output_iterator(), __ctx};
+
+ __format_range(__range, __c, __specs);
+
+ return __formatter::__write_string_no_precision(__buffer.__view(), __ctx.out(), __specs);
+ }
+
+ template <ranges::input_range _Rp, class _FormatContext>
+ typename _FormatContext::iterator _LIBCPP_HIDE_FROM_ABI
+ __format_range(_Rp&& __range, _FormatContext& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) const {
+ if constexpr (same_as<_Tp, _CharT>) {
+ switch (__specs.__std_.__type_) {
+ case __format_spec::__type::__string:
+ case __format_spec::__type::__debug:
+ return __format_as_string(__range, __ctx, __specs.__std_.__type_ == __format_spec::__type::__debug);
+ default:
+ return __format_as_sequence(__range, __ctx);
+ }
+ } else
+ return __format_as_sequence(__range, __ctx);
+ }
+
+ template <ranges::input_range _Rp, class _FormatContext>
+ _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+ __format_as_string(_Rp&& __range, _FormatContext& __ctx, bool __debug_format) const {
+ // When the range is contiguous use a basic_string_view instead to avoid a
+ // copy of the underlying data. The basic_string_view formatter
+ // specialization is the "basic" string formatter in libc++.
+ if constexpr (ranges::contiguous_range<_Rp> && std::ranges::sized_range<_Rp>) {
+ std::formatter<basic_string_view<_CharT>, _CharT> __formatter;
+ if (__debug_format)
+ __formatter.set_debug_format();
+ return __formatter.format(
+ basic_string_view<_CharT>{
+ ranges::data(__range),
+ ranges::size(__range),
+ },
+ __ctx);
+ } else {
+ std::formatter<basic_string<_CharT>, _CharT> __formatter;
+ if (__debug_format)
+ __formatter.set_debug_format();
+ // P2106's from_range has not been implemented yet. Instead use a simple
+ // copy operation.
+ // TODO FMT use basic_string's "from_range" constructor.
+ // return std::formatter<basic_string<_CharT>, _CharT>{}.format(basic_string<_CharT>{from_range, __range}, __ctx);
+ basic_string<_CharT> __str;
+ ranges::copy(__range, back_insert_iterator{__str});
+ return __formatter.format(__str, __ctx);
+ }
+ }
+
+ template <ranges::input_range _Rp, class _FormatContext>
+ _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+ __format_as_sequence(_Rp&& __range, _FormatContext& __ctx) const {
+ __ctx.advance_to(ranges::copy(__opening_bracket_, __ctx.out()).out);
+ bool __use_separator = false;
+ for (auto&& __e : __range) {
+ if (__use_separator)
+ __ctx.advance_to(ranges::copy(__separator_, __ctx.out()).out);
+ else
+ __use_separator = true;
+
+ __ctx.advance_to(__underlying_.format(__e, __ctx));
+ }
+
+ return ranges::copy(__closing_bracket_, __ctx.out()).out;
+ }
+
+ __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__left};
+
+private:
+ _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(const _CharT*& __begin, const _CharT* __end) {
+ switch (*__begin) {
+ case _CharT('m'):
+ if constexpr (__fmt_pair_like<_Tp>) {
+ set_brackets(_LIBCPP_STATICALLY_WIDEN(_CharT, "{"), _LIBCPP_STATICALLY_WIDEN(_CharT, "}"));
+ set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ", "));
+ ++__begin;
+ } else
+ std::__throw_format_error("The range-format-spec type m requires two elements for a pair or tuple");
+ break;
+
+ case _CharT('s'):
+ if constexpr (same_as<_Tp, _CharT>) {
+ __parser_.__type_ = __format_spec::__type::__string;
+ ++__begin;
+ } else
+ std::__throw_format_error("The range-format-spec type s requires formatting a character type");
+ break;
+
+ case _CharT('?'):
+ ++__begin;
+ if (__begin == __end || *__begin != _CharT('s'))
+ std::__throw_format_error("The format-spec should consume the input or end with a '}'");
+ if constexpr (same_as<_Tp, _CharT>) {
+ __parser_.__type_ = __format_spec::__type::__debug;
+ ++__begin;
+ } else
+ std::__throw_format_error("The range-format-spec type ?s requires formatting a character type");
+ }
+ }
+
+ formatter<_Tp, _CharT> __underlying_;
+ basic_string_view<_CharT> __separator_ = _LIBCPP_STATICALLY_WIDEN(_CharT, ", ");
+ basic_string_view<_CharT> __opening_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, "[");
+ basic_string_view<_CharT> __closing_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, "]");
+};
+
+#endif //_LIBCPP_STD_VER > 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FORMAT_RANGE_FORMATTER_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__format/unicode.h b/contrib/libs/cxxsupp/libcxx/include/__format/unicode.h
index fdcaff8407..4327258760 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__format/unicode.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__format/unicode.h
@@ -13,6 +13,7 @@
#include <__assert>
#include <__config>
#include <__format/extended_grapheme_cluster_table.h>
+#include <__type_traits/make_unsigned.h>
#include <__utility/unreachable.h>
#include <bit>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__functional/function.h b/contrib/libs/cxxsupp/libcxx/include/__functional/function.h
index 2d9cdc0459..9f92f61814 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__functional/function.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__functional/function.h
@@ -23,6 +23,7 @@
#include <__memory/builtin_new_allocator.h>
#include <__memory/compressed_pair.h>
#include <__memory/unique_ptr.h>
+#include <__type_traits/strip_signature.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#include <__utility/piecewise_construct.h>
@@ -261,16 +262,16 @@ class __base<_Rp(_ArgTypes...)>
__base& operator=(const __base&);
public:
_LIBCPP_INLINE_VISIBILITY __base() {}
- _LIBCPP_INLINE_VISIBILITY virtual ~__base() {}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__base() {}
virtual __base* __clone() const = 0;
virtual void __clone(__base*) const = 0;
virtual void destroy() _NOEXCEPT = 0;
virtual void destroy_deallocate() _NOEXCEPT = 0;
virtual _Rp operator()(_ArgTypes&& ...) = 0;
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
virtual const void* target(const type_info&) const _NOEXCEPT = 0;
virtual const std::type_info& target_type() const _NOEXCEPT = 0;
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
};
// __func implements __base for a given functor type.
@@ -304,10 +305,10 @@ public:
virtual void destroy() _NOEXCEPT;
virtual void destroy_deallocate() _NOEXCEPT;
virtual _Rp operator()(_ArgTypes&&... __arg);
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
virtual const void* target(const type_info&) const _NOEXCEPT;
virtual const std::type_info& target_type() const _NOEXCEPT;
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
};
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
@@ -355,7 +356,7 @@ __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
}
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
const void*
@@ -373,7 +374,7 @@ __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
return typeid(_Fp);
}
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
// __value_func creates a value-type from a __func.
@@ -381,7 +382,9 @@ template <class _Fp> class __value_func;
template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
{
+ _LIBCPP_SUPPRESS_DEPRECATED_PUSH
typename aligned_storage<3 * sizeof(void*)>::type __buf_;
+ _LIBCPP_SUPPRESS_DEPRECATED_POP
typedef __base<_Rp(_ArgTypes...)> __func;
__func* __f_;
@@ -514,7 +517,9 @@ template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
return;
if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_)
{
+ _LIBCPP_SUPPRESS_DEPRECATED_PUSH
typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
+ _LIBCPP_SUPPRESS_DEPRECATED_POP
__func* __t = __as_base(&__tempbuf);
__f_->__clone(__t);
__f_->destroy();
@@ -548,7 +553,7 @@ template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
_LIBCPP_INLINE_VISIBILITY
explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; }
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
_LIBCPP_INLINE_VISIBILITY
const std::type_info& target_type() const _NOEXCEPT
{
@@ -564,7 +569,7 @@ template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
return nullptr;
return (const _Tp*)__f_->target(typeid(_Tp));
}
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
};
// Storage for a functor object, to be used with __policy to manage copy and
@@ -611,7 +616,7 @@ struct __policy
{
static const _LIBCPP_CONSTEXPR __policy __policy_ = {nullptr, nullptr,
true,
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
&typeid(void)
#else
nullptr
@@ -637,7 +642,7 @@ struct __policy
__choose_policy(/* is_small = */ false_type) {
static const _LIBCPP_CONSTEXPR __policy __policy_ = {
&__large_clone<_Fun>, &__large_destroy<_Fun>, false,
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
&typeid(typename _Fun::_Target)
#else
nullptr
@@ -652,7 +657,7 @@ struct __policy
{
static const _LIBCPP_CONSTEXPR __policy __policy_ = {
nullptr, nullptr, false,
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
&typeid(typename _Fun::_Target)
#else
nullptr
@@ -856,7 +861,7 @@ template <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)>
return !__policy_->__is_null;
}
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
_LIBCPP_INLINE_VISIBILITY
const std::type_info& target_type() const _NOEXCEPT
{
@@ -873,7 +878,7 @@ template <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)>
else
return reinterpret_cast<const _Tp*>(&__buf_.__small);
}
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
};
#if defined(_LIBCPP_HAS_BLOCKS_RUNTIME)
@@ -940,7 +945,7 @@ public:
return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...);
}
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
virtual const void* target(type_info const& __ti) const _NOEXCEPT {
if (__ti == typeid(__func::__block_type))
return &__f_;
@@ -950,7 +955,7 @@ public:
virtual const std::type_info& target_type() const _NOEXCEPT {
return typeid(__func::__block_type);
}
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
};
#endif // _LIBCPP_HAS_EXTENSION_BLOCKS
@@ -1051,57 +1056,18 @@ public:
// function invocation:
_Rp operator()(_ArgTypes...) const;
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
// function target access:
const std::type_info& target_type() const _NOEXCEPT;
template <typename _Tp> _Tp* target() _NOEXCEPT;
template <typename _Tp> const _Tp* target() const _NOEXCEPT;
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
};
#if _LIBCPP_STD_VER >= 17
template<class _Rp, class ..._Ap>
function(_Rp(*)(_Ap...)) -> function<_Rp(_Ap...)>;
-template<class _Fp>
-struct __strip_signature;
-
-template<class _Rp, class _Gp, class ..._Ap>
-struct __strip_signature<_Rp (_Gp::*) (_Ap...)> { using type = _Rp(_Ap...); };
-template<class _Rp, class _Gp, class ..._Ap>
-struct __strip_signature<_Rp (_Gp::*) (_Ap...) const> { using type = _Rp(_Ap...); };
-template<class _Rp, class _Gp, class ..._Ap>
-struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile> { using type = _Rp(_Ap...); };
-template<class _Rp, class _Gp, class ..._Ap>
-struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile> { using type = _Rp(_Ap...); };
-
-template<class _Rp, class _Gp, class ..._Ap>
-struct __strip_signature<_Rp (_Gp::*) (_Ap...) &> { using type = _Rp(_Ap...); };
-template<class _Rp, class _Gp, class ..._Ap>
-struct __strip_signature<_Rp (_Gp::*) (_Ap...) const &> { using type = _Rp(_Ap...); };
-template<class _Rp, class _Gp, class ..._Ap>
-struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile &> { using type = _Rp(_Ap...); };
-template<class _Rp, class _Gp, class ..._Ap>
-struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile &> { using type = _Rp(_Ap...); };
-
-template<class _Rp, class _Gp, class ..._Ap>
-struct __strip_signature<_Rp (_Gp::*) (_Ap...) noexcept> { using type = _Rp(_Ap...); };
-template<class _Rp, class _Gp, class ..._Ap>
-struct __strip_signature<_Rp (_Gp::*) (_Ap...) const noexcept> { using type = _Rp(_Ap...); };
-template<class _Rp, class _Gp, class ..._Ap>
-struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile noexcept> { using type = _Rp(_Ap...); };
-template<class _Rp, class _Gp, class ..._Ap>
-struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile noexcept> { using type = _Rp(_Ap...); };
-
-template<class _Rp, class _Gp, class ..._Ap>
-struct __strip_signature<_Rp (_Gp::*) (_Ap...) & noexcept> { using type = _Rp(_Ap...); };
-template<class _Rp, class _Gp, class ..._Ap>
-struct __strip_signature<_Rp (_Gp::*) (_Ap...) const & noexcept> { using type = _Rp(_Ap...); };
-template<class _Rp, class _Gp, class ..._Ap>
-struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile & noexcept> { using type = _Rp(_Ap...); };
-template<class _Rp, class _Gp, class ..._Ap>
-struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile & noexcept> { using type = _Rp(_Ap...); };
-
template<class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type>
function(_Fp) -> function<_Stripped>;
#endif // _LIBCPP_STD_VER >= 17
@@ -1190,7 +1156,7 @@ function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
}
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
template<class _Rp, class ..._ArgTypes>
const std::type_info&
@@ -1215,7 +1181,7 @@ function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT
return __f_.template target<_Tp>();
}
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
template <class _Rp, class... _ArgTypes>
inline _LIBCPP_INLINE_VISIBILITY
diff --git a/contrib/libs/cxxsupp/libcxx/include/__functional/hash.h b/contrib/libs/cxxsupp/libcxx/include/__functional/hash.h
index 041730dfb6..39382aa9bf 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__functional/hash.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__functional/hash.h
@@ -10,9 +10,15 @@
#define _LIBCPP___FUNCTIONAL_HASH_H
#include <__config>
+#include <__functional/invoke.h>
#include <__functional/unary_function.h>
#include <__fwd/hash.h>
-#include <__tuple/sfinae_helpers.h>
+#include <__tuple_dir/sfinae_helpers.h>
+#include <__type_traits/is_copy_constructible.h>
+#include <__type_traits/is_default_constructible.h>
+#include <__type_traits/is_enum.h>
+#include <__type_traits/is_move_constructible.h>
+#include <__type_traits/underlying_type.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#include <__utility/pair.h>
@@ -21,7 +27,6 @@
#include <cstdint>
#include <cstring>
#include <limits>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -63,7 +68,7 @@ __murmur2_or_cityhash<_Size, 32>::operator()(const void* __key, _Size __len)
const unsigned char* __data = static_cast<const unsigned char*>(__key);
for (; __len >= 4; __data += 4, __len -= 4)
{
- _Size __k = __loadword<_Size>(__data);
+ _Size __k = std::__loadword<_Size>(__data);
__k *= __m;
__k ^= __k >> __r;
__k *= __m;
@@ -128,14 +133,18 @@ struct __murmur2_or_cityhash<_Size, 64>
_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
{
if (__len > 8) {
- const _Size __a = __loadword<_Size>(__s);
- const _Size __b = __loadword<_Size>(__s + __len - 8);
+ const _Size __a = std::__loadword<_Size>(__s);
+ const _Size __b = std::__loadword<_Size>(__s + __len - 8);
return __hash_len_16(__a, __rotate_by_at_least_1(__b + __len, __len)) ^ __b;
}
if (__len >= 4) {
- const uint32_t __a = __loadword<uint32_t>(__s);
- const uint32_t __b = __loadword<uint32_t>(__s + __len - 4);
+ const uint32_t __a = std::__loadword<uint32_t>(__s);
+ const uint32_t __b = std::__loadword<uint32_t>(__s + __len - 4);
+#ifdef _LIBCPP_ABI_FIX_CITYHASH_IMPLEMENTATION
return __hash_len_16(__len + (static_cast<_Size>(__a) << 3), __b);
+#else
+ return __hash_len_16(__len + (__a << 3), __b);
+#endif
}
if (__len > 0) {
const unsigned char __a = static_cast<unsigned char>(__s[0]);
@@ -152,10 +161,10 @@ struct __murmur2_or_cityhash<_Size, 64>
static _Size __hash_len_17_to_32(const char *__s, _Size __len)
_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
{
- const _Size __a = __loadword<_Size>(__s) * __k1;
- const _Size __b = __loadword<_Size>(__s + 8);
- const _Size __c = __loadword<_Size>(__s + __len - 8) * __k2;
- const _Size __d = __loadword<_Size>(__s + __len - 16) * __k0;
+ const _Size __a = std::__loadword<_Size>(__s) * __k1;
+ const _Size __b = std::__loadword<_Size>(__s + 8);
+ const _Size __c = std::__loadword<_Size>(__s + __len - 8) * __k2;
+ const _Size __d = std::__loadword<_Size>(__s + __len - 16) * __k0;
return __hash_len_16(__rotate(__a - __b, 43) + __rotate(__c, 30) + __d,
__a + __rotate(__b ^ __k3, 20) - __c + __len);
}
@@ -180,10 +189,10 @@ struct __murmur2_or_cityhash<_Size, 64>
const char* __s, _Size __a, _Size __b)
_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
{
- return __weak_hash_len_32_with_seeds(__loadword<_Size>(__s),
- __loadword<_Size>(__s + 8),
- __loadword<_Size>(__s + 16),
- __loadword<_Size>(__s + 24),
+ return __weak_hash_len_32_with_seeds(std::__loadword<_Size>(__s),
+ std::__loadword<_Size>(__s + 8),
+ std::__loadword<_Size>(__s + 16),
+ std::__loadword<_Size>(__s + 24),
__a,
__b);
}
@@ -192,23 +201,23 @@ struct __murmur2_or_cityhash<_Size, 64>
static _Size __hash_len_33_to_64(const char *__s, size_t __len)
_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
{
- _Size __z = __loadword<_Size>(__s + 24);
- _Size __a = __loadword<_Size>(__s) +
- (__len + __loadword<_Size>(__s + __len - 16)) * __k0;
+ _Size __z = std::__loadword<_Size>(__s + 24);
+ _Size __a = std::__loadword<_Size>(__s) +
+ (__len + std::__loadword<_Size>(__s + __len - 16)) * __k0;
_Size __b = __rotate(__a + __z, 52);
_Size __c = __rotate(__a, 37);
- __a += __loadword<_Size>(__s + 8);
+ __a += std::__loadword<_Size>(__s + 8);
__c += __rotate(__a, 7);
- __a += __loadword<_Size>(__s + 16);
+ __a += std::__loadword<_Size>(__s + 16);
_Size __vf = __a + __z;
_Size __vs = __b + __rotate(__a, 31) + __c;
- __a = __loadword<_Size>(__s + 16) + __loadword<_Size>(__s + __len - 32);
- __z += __loadword<_Size>(__s + __len - 8);
+ __a = std::__loadword<_Size>(__s + 16) + std::__loadword<_Size>(__s + __len - 32);
+ __z += std::__loadword<_Size>(__s + __len - 8);
__b = __rotate(__a + __z, 52);
__c = __rotate(__a, 37);
- __a += __loadword<_Size>(__s + __len - 24);
+ __a += std::__loadword<_Size>(__s + __len - 24);
__c += __rotate(__a, 7);
- __a += __loadword<_Size>(__s + __len - 16);
+ __a += std::__loadword<_Size>(__s + __len - 16);
_Size __wf = __a + __z;
_Size __ws = __b + __rotate(__a, 31) + __c;
_Size __r = __shift_mix((__vf + __ws) * __k2 + (__wf + __vs) * __k0);
@@ -234,26 +243,26 @@ __murmur2_or_cityhash<_Size, 64>::operator()(const void* __key, _Size __len)
// For strings over 64 bytes we hash the end first, and then as we
// loop we keep 56 bytes of state: v, w, x, y, and z.
- _Size __x = __loadword<_Size>(__s + __len - 40);
- _Size __y = __loadword<_Size>(__s + __len - 16) +
- __loadword<_Size>(__s + __len - 56);
- _Size __z = __hash_len_16(__loadword<_Size>(__s + __len - 48) + __len,
- __loadword<_Size>(__s + __len - 24));
+ _Size __x = std::__loadword<_Size>(__s + __len - 40);
+ _Size __y = std::__loadword<_Size>(__s + __len - 16) +
+ std::__loadword<_Size>(__s + __len - 56);
+ _Size __z = __hash_len_16(std::__loadword<_Size>(__s + __len - 48) + __len,
+ std::__loadword<_Size>(__s + __len - 24));
pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z);
pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x);
- __x = __x * __k1 + __loadword<_Size>(__s);
+ __x = __x * __k1 + std::__loadword<_Size>(__s);
// Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
__len = (__len - 1) & ~static_cast<_Size>(63);
do {
- __x = __rotate(__x + __y + __v.first + __loadword<_Size>(__s + 8), 37) * __k1;
- __y = __rotate(__y + __v.second + __loadword<_Size>(__s + 48), 42) * __k1;
+ __x = __rotate(__x + __y + __v.first + std::__loadword<_Size>(__s + 8), 37) * __k1;
+ __y = __rotate(__y + __v.second + std::__loadword<_Size>(__s + 48), 42) * __k1;
__x ^= __w.second;
- __y += __v.first + __loadword<_Size>(__s + 40);
+ __y += __v.first + std::__loadword<_Size>(__s + 40);
__z = __rotate(__z + __w.first, 33) * __k1;
__v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first);
__w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second,
- __y + __loadword<_Size>(__s + 16));
+ __y + std::__loadword<_Size>(__s + 16));
_VSTD::swap(__z, __x);
__s += 64;
__len -= 64;
diff --git a/contrib/libs/cxxsupp/libcxx/include/__functional/invoke.h b/contrib/libs/cxxsupp/libcxx/include/__functional/invoke.h
index fdbbce029e..48e6eac3ce 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__functional/invoke.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__functional/invoke.h
@@ -398,7 +398,7 @@ template <class _Ret, class _Fp, class ..._Args>
struct __invokable_r
{
template <class _XFp, class ..._XArgs>
- static decltype(std::__invoke(declval<_XFp>(), declval<_XArgs>()...)) __try_call(int);
+ static decltype(std::__invoke(std::declval<_XFp>(), std::declval<_XArgs>()...)) __try_call(int);
template <class _XFp, class ..._XArgs>
static __nat __try_call(...);
@@ -428,15 +428,23 @@ struct __nothrow_invokable_r_imp<true, false, _Ret, _Fp, _Args...>
template <class _Tp>
static void __test_noexcept(_Tp) _NOEXCEPT;
+#ifdef _LIBCPP_CXX03_LANG
+ static const bool value = false;
+#else
static const bool value = noexcept(_ThisT::__test_noexcept<_Ret>(
- _VSTD::__invoke(declval<_Fp>(), declval<_Args>()...)));
+ _VSTD::__invoke(std::declval<_Fp>(), std::declval<_Args>()...)));
+#endif
};
template <class _Ret, class _Fp, class ..._Args>
struct __nothrow_invokable_r_imp<true, true, _Ret, _Fp, _Args...>
{
+#ifdef _LIBCPP_CXX03_LANG
+ static const bool value = false;
+#else
static const bool value = noexcept(
- _VSTD::__invoke(declval<_Fp>(), declval<_Args>()...));
+ _VSTD::__invoke(std::declval<_Fp>(), std::declval<_Args>()...));
+#endif
};
template <class _Ret, class _Fp, class ..._Args>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__functional/reference_wrapper.h b/contrib/libs/cxxsupp/libcxx/include/__functional/reference_wrapper.h
index 6659825818..c377b64377 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__functional/reference_wrapper.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__functional/reference_wrapper.h
@@ -11,10 +11,13 @@
#define _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H
#include <__config>
+#include <__functional/invoke.h>
#include <__functional/weak_result_type.h>
#include <__memory/addressof.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/declval.h>
#include <__utility/forward.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -35,9 +38,9 @@ private:
static void __fun(_Tp&&) = delete;
public:
- template <class _Up, class = __enable_if_t<!__is_same_uncvref<_Up, reference_wrapper>::value, decltype(__fun(declval<_Up>())) > >
+ template <class _Up, class = __enable_if_t<!__is_same_uncvref<_Up, reference_wrapper>::value, decltype(__fun(std::declval<_Up>())) > >
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
- reference_wrapper(_Up&& __u) _NOEXCEPT_(noexcept(__fun(declval<_Up>()))) {
+ reference_wrapper(_Up&& __u) _NOEXCEPT_(noexcept(__fun(std::declval<_Up>()))) {
type& __f = static_cast<_Up&&>(__u);
__f_ = _VSTD::addressof(__f);
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/__functional/unwrap_ref.h b/contrib/libs/cxxsupp/libcxx/include/__functional/unwrap_ref.h
index f7207934e1..da000d80b8 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__functional/unwrap_ref.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__functional/unwrap_ref.h
@@ -10,6 +10,7 @@
#define _LIBCPP___FUNCTIONAL_UNWRAP_REF_H
#include <__config>
+#include <__type_traits/decay.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__functional/weak_result_type.h b/contrib/libs/cxxsupp/libcxx/include/__functional/weak_result_type.h
index 96d8cf7146..18d1bf718c 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__functional/weak_result_type.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__functional/weak_result_type.h
@@ -12,8 +12,11 @@
#include <__config>
#include <__functional/binary_function.h>
+#include <__functional/invoke.h>
#include <__functional/unary_function.h>
-#include <type_traits>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_same.h>
+#include <__utility/declval.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -283,7 +286,7 @@ struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile>
template <class _Tp, class ..._Args>
struct __invoke_return
{
- typedef decltype(_VSTD::__invoke(declval<_Tp>(), declval<_Args>()...)) type;
+ typedef decltype(_VSTD::__invoke(std::declval<_Tp>(), std::declval<_Args>()...)) type;
};
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/include/__fwd/get.h b/contrib/libs/cxxsupp/libcxx/include/__fwd/get.h
index 8162403898..ec1fab4602 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__fwd/get.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__fwd/get.h
@@ -9,11 +9,13 @@
#ifndef _LIBCPP___FWD_GET_H
#define _LIBCPP___FWD_GET_H
+#include <__concepts/copyable.h>
#include <__config>
#include <__fwd/array.h>
#include <__fwd/pair.h>
+#include <__fwd/subrange.h>
#include <__fwd/tuple.h>
-#include <__tuple/tuple_element.h>
+#include <__tuple_dir/tuple_element.h>
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -90,6 +92,24 @@ const _Tp&&
get(const array<_Tp, _Size>&&) _NOEXCEPT;
#endif
+#if _LIBCPP_STD_VER >= 20
+
+namespace ranges {
+
+template <size_t _Index, class _Iter, class _Sent, subrange_kind _Kind>
+ requires((_Index == 0 && copyable<_Iter>) || _Index == 1)
+_LIBCPP_HIDE_FROM_ABI constexpr auto get(const subrange<_Iter, _Sent, _Kind>& __subrange);
+
+template <size_t _Index, class _Iter, class _Sent, subrange_kind _Kind>
+ requires(_Index < 2)
+_LIBCPP_HIDE_FROM_ABI constexpr auto get(subrange<_Iter, _Sent, _Kind>&& __subrange);
+
+} // namespace ranges
+
+using ranges::get;
+
+#endif // _LIBCPP_STD_VER >= 20
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___FWD_GET_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__fwd/subrange.h b/contrib/libs/cxxsupp/libcxx/include/__fwd/subrange.h
new file mode 100644
index 0000000000..8f7239247e
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__fwd/subrange.h
@@ -0,0 +1,38 @@
+//===---------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FWD_SUBRANGE_H
+#define _LIBCPP___FWD_SUBRANGE_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 20
+
+#include <__iterator/concepts.h>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+enum class _LIBCPP_ENUM_VIS subrange_kind : bool { unsized, sized };
+
+template <input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent, subrange_kind _Kind>
+ requires(_Kind == subrange_kind::sized || !sized_sentinel_for<_Sent, _Iter>)
+class _LIBCPP_TEMPLATE_VIS subrange;
+
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 20
+
+#endif // _LIBCPP___FWD_SUBRANGE_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__hash_table b/contrib/libs/cxxsupp/libcxx/include/__hash_table
index d6af75e9e0..f8896c8664 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__hash_table
+++ b/contrib/libs/cxxsupp/libcxx/include/__hash_table
@@ -13,7 +13,7 @@
#include <__algorithm/max.h>
#include <__algorithm/min.h>
#include <__assert>
-#include <__bits> // __libcpp_clz
+#include <__bit/countl.h>
#include <__config>
#include <__debug>
#include <__functional/hash.h>
@@ -565,7 +565,7 @@ public:
_LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
"Attempted to increment a non-incrementable unordered container local_iterator");
__node_ = __node_->__next_;
- if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
+ if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
__node_ = nullptr;
return *this;
}
@@ -698,7 +698,7 @@ public:
_LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
"Attempted to increment a non-incrementable unordered container const_local_iterator");
__node_ = __node_->__next_;
- if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
+ if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
__node_ = nullptr;
return *this;
}
@@ -1156,11 +1156,11 @@ public:
_LIBCPP_INLINE_VISIBILITY void __rehash_multi(size_type __n) { __rehash<false>(__n); }
_LIBCPP_INLINE_VISIBILITY void __reserve_unique(size_type __n)
{
- __rehash_unique(static_cast<size_type>(ceil(__n / max_load_factor())));
+ __rehash_unique(static_cast<size_type>(std::ceil(__n / max_load_factor())));
}
_LIBCPP_INLINE_VISIBILITY void __reserve_multi(size_type __n)
{
- __rehash_multi(static_cast<size_type>(ceil(__n / max_load_factor())));
+ __rehash_multi(static_cast<size_type>(std::ceil(__n / max_load_factor())));
}
_LIBCPP_INLINE_VISIBILITY
@@ -1184,7 +1184,7 @@ public:
{
_LIBCPP_ASSERT(bucket_count() > 0,
"unordered container::bucket(key) called when bucket_count() == 0");
- return __constrain_hash(hash_function()(__k), bucket_count());
+ return std::__constrain_hash(hash_function()(__k), bucket_count());
}
template <class _Key>
@@ -1433,7 +1433,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u)
{
if (size() > 0)
{
- __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
+ __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
__p1_.first().__ptr();
__u.__p1_.first().__next_ = nullptr;
__u.size() = 0;
@@ -1457,7 +1457,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u,
{
__p1_.first().__next_ = __u.__p1_.first().__next_;
__u.__p1_.first().__next_ = nullptr;
- __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
+ __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
__p1_.first().__ptr();
size() = __u.size();
__u.size() = 0;
@@ -1574,7 +1574,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
__p1_.first().__next_ = __u.__p1_.first().__next_;
if (size() > 0)
{
- __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
+ __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
__p1_.first().__ptr();
__u.__p1_.first().__next_ = nullptr;
__u.size() = 0;
@@ -1789,12 +1789,12 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare(
if (__bc != 0)
{
- size_t __chash = __constrain_hash(__hash, __bc);
+ size_t __chash = std::__constrain_hash(__hash, __bc);
__next_pointer __ndptr = __bucket_list_[__chash];
if (__ndptr != nullptr)
{
for (__ndptr = __ndptr->__next_; __ndptr != nullptr &&
- __constrain_hash(__ndptr->__hash(), __bc) == __chash;
+ std::__constrain_hash(__ndptr->__hash(), __bc) == __chash;
__ndptr = __ndptr->__next_)
{
if (key_eq()(__ndptr->__upcast()->__value_, __value))
@@ -1804,8 +1804,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare(
}
if (size()+1 > __bc * max_load_factor() || __bc == 0)
{
- __rehash_unique(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
- size_type(ceil(float(size() + 1) / max_load_factor()))));
+ __rehash_unique(_VSTD::max<size_type>(2 * __bc + !std::__is_hash_power2(__bc),
+ size_type(std::ceil(float(size() + 1) / max_load_factor()))));
}
return nullptr;
}
@@ -1821,7 +1821,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_perform(
__node_pointer __nd) _NOEXCEPT
{
size_type __bc = bucket_count();
- size_t __chash = __constrain_hash(__nd->__hash(), __bc);
+ size_t __chash = std::__constrain_hash(__nd->__hash(), __bc);
// insert_after __bucket_list_[__chash], or __first_node if bucket is null
__next_pointer __pn = __bucket_list_[__chash];
if (__pn == nullptr)
@@ -1832,7 +1832,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_perform(
// fix up __bucket_list_
__bucket_list_[__chash] = __pn;
if (__nd->__next_ != nullptr)
- __bucket_list_[__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr();
+ __bucket_list_[std::__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr();
}
else
{
@@ -1876,16 +1876,16 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare(
size_type __bc = bucket_count();
if (size()+1 > __bc * max_load_factor() || __bc == 0)
{
- __rehash_multi(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
- size_type(ceil(float(size() + 1) / max_load_factor()))));
+ __rehash_multi(_VSTD::max<size_type>(2 * __bc + !std::__is_hash_power2(__bc),
+ size_type(std::ceil(float(size() + 1) / max_load_factor()))));
__bc = bucket_count();
}
- size_t __chash = __constrain_hash(__cp_hash, __bc);
+ size_t __chash = std::__constrain_hash(__cp_hash, __bc);
__next_pointer __pn = __bucket_list_[__chash];
if (__pn != nullptr)
{
for (bool __found = false; __pn->__next_ != nullptr &&
- __constrain_hash(__pn->__next_->__hash(), __bc) == __chash;
+ std::__constrain_hash(__pn->__next_->__hash(), __bc) == __chash;
__pn = __pn->__next_)
{
// __found key_eq() action
@@ -1917,7 +1917,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform(
__node_pointer __cp, __next_pointer __pn) _NOEXCEPT
{
size_type __bc = bucket_count();
- size_t __chash = __constrain_hash(__cp->__hash_, __bc);
+ size_t __chash = std::__constrain_hash(__cp->__hash_, __bc);
if (__pn == nullptr)
{
__pn =__p1_.first().__ptr();
@@ -1926,7 +1926,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform(
// fix up __bucket_list_
__bucket_list_[__chash] = __pn;
if (__cp->__next_ != nullptr)
- __bucket_list_[__constrain_hash(__cp->__next_->__hash(), __bc)]
+ __bucket_list_[std::__constrain_hash(__cp->__next_->__hash(), __bc)]
= __cp->__ptr();
}
else
@@ -1935,7 +1935,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform(
__pn->__next_ = __cp->__ptr();
if (__cp->__next_ != nullptr)
{
- size_t __nhash = __constrain_hash(__cp->__next_->__hash(), __bc);
+ size_t __nhash = std::__constrain_hash(__cp->__next_->__hash(), __bc);
if (__nhash != __chash)
__bucket_list_[__nhash] = __cp->__ptr();
}
@@ -1970,11 +1970,11 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(
size_type __bc = bucket_count();
if (size()+1 > __bc * max_load_factor() || __bc == 0)
{
- __rehash_multi(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
- size_type(ceil(float(size() + 1) / max_load_factor()))));
+ __rehash_multi(_VSTD::max<size_type>(2 * __bc + !std::__is_hash_power2(__bc),
+ size_type(std::ceil(float(size() + 1) / max_load_factor()))));
__bc = bucket_count();
}
- size_t __chash = __constrain_hash(__cp->__hash_, __bc);
+ size_t __chash = std::__constrain_hash(__cp->__hash_, __bc);
__next_pointer __pp = __bucket_list_[__chash];
while (__pp->__next_ != __np)
__pp = __pp->__next_;
@@ -2001,12 +2001,12 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const&
size_t __chash;
if (__bc != 0)
{
- __chash = __constrain_hash(__hash, __bc);
+ __chash = std::__constrain_hash(__hash, __bc);
__nd = __bucket_list_[__chash];
if (__nd != nullptr)
{
for (__nd = __nd->__next_; __nd != nullptr &&
- (__nd->__hash() == __hash || __constrain_hash(__nd->__hash(), __bc) == __chash);
+ (__nd->__hash() == __hash || std::__constrain_hash(__nd->__hash(), __bc) == __chash);
__nd = __nd->__next_)
{
if (key_eq()(__nd->__upcast()->__value_, __k))
@@ -2018,10 +2018,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const&
__node_holder __h = __construct_node_hash(__hash, _VSTD::forward<_Args>(__args)...);
if (size()+1 > __bc * max_load_factor() || __bc == 0)
{
- __rehash_unique(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
- size_type(ceil(float(size() + 1) / max_load_factor()))));
+ __rehash_unique(_VSTD::max<size_type>(2 * __bc + !std::__is_hash_power2(__bc),
+ size_type(std::ceil(float(size() + 1) / max_load_factor()))));
__bc = bucket_count();
- __chash = __constrain_hash(__hash, __bc);
+ __chash = std::__constrain_hash(__hash, __bc);
}
// insert_after __bucket_list_[__chash], or __first_node if bucket is null
__next_pointer __pn = __bucket_list_[__chash];
@@ -2033,7 +2033,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const&
// fix up __bucket_list_
__bucket_list_[__chash] = __pn;
if (__h->__next_ != nullptr)
- __bucket_list_[__constrain_hash(__h->__next_->__hash(), __bc)]
+ __bucket_list_[std::__constrain_hash(__h->__next_->__hash(), __bc)]
= __h.get()->__ptr();
}
else
@@ -2229,7 +2229,7 @@ _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
if (__n == 1)
__n = 2;
else if (__n & (__n - 1))
- __n = __next_prime(__n);
+ __n = std::__next_prime(__n);
size_type __bc = bucket_count();
if (__n > __bc)
__do_rehash<_UniqueKeys>(__n);
@@ -2238,8 +2238,8 @@ _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
__n = _VSTD::max<size_type>
(
__n,
- __is_hash_power2(__bc) ? __next_hash_pow2(size_t(ceil(float(size()) / max_load_factor()))) :
- __next_prime(size_t(ceil(float(size()) / max_load_factor())))
+ std::__is_hash_power2(__bc) ? std::__next_hash_pow2(size_t(std::ceil(float(size()) / max_load_factor()))) :
+ std::__next_prime(size_t(std::ceil(float(size()) / max_load_factor())))
);
if (__n < __bc)
__do_rehash<_UniqueKeys>(__n);
@@ -2264,13 +2264,13 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __nbc)
__next_pointer __cp = __pp->__next_;
if (__cp != nullptr)
{
- size_type __chash = __constrain_hash(__cp->__hash(), __nbc);
+ size_type __chash = std::__constrain_hash(__cp->__hash(), __nbc);
__bucket_list_[__chash] = __pp;
size_type __phash = __chash;
for (__pp = __cp, void(), __cp = __cp->__next_; __cp != nullptr;
__cp = __pp->__next_)
{
- __chash = __constrain_hash(__cp->__hash(), __nbc);
+ __chash = std::__constrain_hash(__cp->__hash(), __nbc);
if (__chash == __phash)
__pp = __cp;
else
@@ -2312,13 +2312,13 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k)
size_type __bc = bucket_count();
if (__bc != 0)
{
- size_t __chash = __constrain_hash(__hash, __bc);
+ size_t __chash = std::__constrain_hash(__hash, __bc);
__next_pointer __nd = __bucket_list_[__chash];
if (__nd != nullptr)
{
for (__nd = __nd->__next_; __nd != nullptr &&
(__nd->__hash() == __hash
- || __constrain_hash(__nd->__hash(), __bc) == __chash);
+ || std::__constrain_hash(__nd->__hash(), __bc) == __chash);
__nd = __nd->__next_)
{
if ((__nd->__hash() == __hash)
@@ -2339,13 +2339,13 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const
size_type __bc = bucket_count();
if (__bc != 0)
{
- size_t __chash = __constrain_hash(__hash, __bc);
+ size_t __chash = std::__constrain_hash(__hash, __bc);
__next_pointer __nd = __bucket_list_[__chash];
if (__nd != nullptr)
{
for (__nd = __nd->__next_; __nd != nullptr &&
(__hash == __nd->__hash()
- || __constrain_hash(__nd->__hash(), __bc) == __chash);
+ || std::__constrain_hash(__nd->__hash(), __bc) == __chash);
__nd = __nd->__next_)
{
if ((__nd->__hash() == __hash)
@@ -2467,7 +2467,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT
// current node
__next_pointer __cn = __p.__node_;
size_type __bc = bucket_count();
- size_t __chash = __constrain_hash(__cn->__hash(), __bc);
+ size_t __chash = std::__constrain_hash(__cn->__hash(), __bc);
// find previous node
__next_pointer __pn = __bucket_list_[__chash];
for (; __pn->__next_ != __cn; __pn = __pn->__next_)
@@ -2476,16 +2476,16 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT
// if __pn is not in same bucket (before begin is not in same bucket) &&
// if __cn->__next_ is not in same bucket (nullptr is not in same bucket)
if (__pn == __p1_.first().__ptr()
- || __constrain_hash(__pn->__hash(), __bc) != __chash)
+ || std::__constrain_hash(__pn->__hash(), __bc) != __chash)
{
if (__cn->__next_ == nullptr
- || __constrain_hash(__cn->__next_->__hash(), __bc) != __chash)
+ || std::__constrain_hash(__cn->__next_->__hash(), __bc) != __chash)
__bucket_list_[__chash] = nullptr;
}
// if __cn->__next_ is not in same bucket (nullptr is in same bucket)
if (__cn->__next_ != nullptr)
{
- size_t __nhash = __constrain_hash(__cn->__next_->__hash(), __bc);
+ size_t __nhash = std::__constrain_hash(__cn->__next_->__hash(), __bc);
if (__nhash != __chash)
__bucket_list_[__nhash] = __pn;
}
@@ -2639,10 +2639,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u)
__p2_.swap(__u.__p2_);
__p3_.swap(__u.__p3_);
if (size() > 0)
- __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
+ __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
__p1_.first().__ptr();
if (__u.size() > 0)
- __u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] =
+ __u.__bucket_list_[std::__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] =
__u.__p1_.first().__ptr();
std::__debug_db_swap(this, std::addressof(__u));
}
@@ -2659,8 +2659,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const
if (__np != nullptr)
{
for (__np = __np->__next_; __np != nullptr &&
- __constrain_hash(__np->__hash(), __bc) == __n;
- __np = __np->__next_, (void) ++__r)
+ std::__constrain_hash(__np->__hash(), __bc) == __n;
+ __np = __np->__next_, (void) ++__r)
;
}
return __r;
diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/advance.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/advance.h
index e43e41873a..870778061b 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__iterator/advance.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/advance.h
@@ -17,12 +17,14 @@
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/iterator_traits.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_integral.h>
#include <__utility/convert_to_integral.h>
+#include <__utility/declval.h>
#include <__utility/move.h>
#include <__utility/unreachable.h>
#include <cstdlib>
#include <limits>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -56,7 +58,7 @@ void __advance(_RandIter& __i, typename iterator_traits<_RandIter>::difference_t
template <
class _InputIter, class _Distance,
- class _IntegralDistance = decltype(_VSTD::__convert_to_integral(declval<_Distance>())),
+ class _IntegralDistance = decltype(_VSTD::__convert_to_integral(std::declval<_Distance>())),
class = __enable_if_t<is_integral<_IntegralDistance>::value> >
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17
void advance(_InputIter& __i, _Distance __orig_n) {
diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/bounded_iter.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/bounded_iter.h
index 071cbdac99..96d311faa3 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__iterator/bounded_iter.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/bounded_iter.h
@@ -14,8 +14,10 @@
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__memory/pointer_traits.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_convertible.h>
#include <__utility/move.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/common_iterator.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/common_iterator.h
index a1985c9287..f7883e2c37 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__iterator/common_iterator.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/common_iterator.h
@@ -25,6 +25,8 @@
#include <__iterator/iter_swap.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/readable_traits.h>
+#include <__type_traits/is_pointer.h>
+#include <__utility/declval.h>
#include <variant>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -101,14 +103,14 @@ public:
constexpr decltype(auto) operator*()
{
- _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator");
+ _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator");
return *_VSTD::__unchecked_get<_Iter>(__hold_);
}
constexpr decltype(auto) operator*() const
requires __dereferenceable<const _Iter>
{
- _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator");
+ _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator");
return *_VSTD::__unchecked_get<_Iter>(__hold_);
}
@@ -119,7 +121,7 @@ public:
is_reference_v<iter_reference_t<_I2>> ||
constructible_from<iter_value_t<_I2>, iter_reference_t<_I2>>)
{
- _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator");
+ _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator");
if constexpr (is_pointer_v<_Iter> || requires(const _Iter& __i) { __i.operator->(); }) {
return _VSTD::__unchecked_get<_Iter>(__hold_);
} else if constexpr (is_reference_v<iter_reference_t<_Iter>>) {
@@ -131,12 +133,12 @@ public:
}
common_iterator& operator++() {
- _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator");
+ _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator");
++_VSTD::__unchecked_get<_Iter>(__hold_); return *this;
}
decltype(auto) operator++(int) {
- _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator");
+ _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator");
if constexpr (forward_iterator<_Iter>) {
auto __tmp = *this;
++*this;
@@ -215,19 +217,19 @@ public:
}
_LIBCPP_HIDE_FROM_ABI friend constexpr iter_rvalue_reference_t<_Iter> iter_move(const common_iterator& __i)
- noexcept(noexcept(ranges::iter_move(declval<const _Iter&>())))
+ noexcept(noexcept(ranges::iter_move(std::declval<const _Iter&>())))
requires input_iterator<_Iter>
{
- _LIBCPP_ASSERT(holds_alternative<_Iter>(__i.__hold_), "Attempted to iter_move a non-dereferenceable common_iterator");
+ _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__i.__hold_), "Attempted to iter_move a non-dereferenceable common_iterator");
return ranges::iter_move( _VSTD::__unchecked_get<_Iter>(__i.__hold_));
}
template<indirectly_swappable<_Iter> _I2, class _S2>
_LIBCPP_HIDE_FROM_ABI friend constexpr void iter_swap(const common_iterator& __x, const common_iterator<_I2, _S2>& __y)
- noexcept(noexcept(ranges::iter_swap(declval<const _Iter&>(), declval<const _I2&>())))
+ noexcept(noexcept(ranges::iter_swap(std::declval<const _Iter&>(), std::declval<const _I2&>())))
{
- _LIBCPP_ASSERT(holds_alternative<_Iter>(__x.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator");
- _LIBCPP_ASSERT(holds_alternative<_I2>(__y.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator");
+ _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__x.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator");
+ _LIBCPP_ASSERT(std::holds_alternative<_I2>(__y.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator");
return ranges::iter_swap(_VSTD::__unchecked_get<_Iter>(__x.__hold_), _VSTD::__unchecked_get<_I2>(__y.__hold_));
}
};
@@ -255,7 +257,7 @@ struct __arrow_type_or_void {
template<class _Iter, class _Sent>
requires __common_iter_has_ptr_op<_Iter, _Sent>
struct __arrow_type_or_void<_Iter, _Sent> {
- using type = decltype(declval<const common_iterator<_Iter, _Sent>&>().operator->());
+ using type = decltype(std::declval<const common_iterator<_Iter, _Sent>&>().operator->());
};
template<input_iterator _Iter, class _Sent>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/concepts.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/concepts.h
index 246f84c7cf..d9d40a4249 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__iterator/concepts.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/concepts.h
@@ -26,13 +26,19 @@
#include <__concepts/semiregular.h>
#include <__concepts/totally_ordered.h>
#include <__config>
+#include <__functional/invoke.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/iter_move.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/readable_traits.h>
#include <__memory/pointer_traits.h>
+#include <__type_traits/add_pointer.h>
+#include <__type_traits/common_reference.h>
+#include <__type_traits/is_pointer.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/remove_cv.h>
+#include <__type_traits/remove_cvref.h>
#include <__utility/forward.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/counted_iterator.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/counted_iterator.h
index 5edd9c9422..5fdbff4b48 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__iterator/counted_iterator.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/counted_iterator.h
@@ -25,9 +25,10 @@
#include <__iterator/iterator_traits.h>
#include <__iterator/readable_traits.h>
#include <__memory/pointer_traits.h>
+#include <__type_traits/add_pointer.h>
+#include <__type_traits/conditional.h>
#include <__utility/move.h>
#include <compare>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/distance.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/distance.h
index 32e41331f6..681e20d045 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__iterator/distance.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/distance.h
@@ -17,7 +17,8 @@
#include <__ranges/access.h>
#include <__ranges/concepts.h>
#include <__ranges/size.h>
-#include <type_traits>
+#include <__type_traits/decay.h>
+#include <__type_traits/remove_cvref.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/incrementable_traits.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/incrementable_traits.h
index 6f966ec4c7..3d06dc0535 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__iterator/incrementable_traits.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/incrementable_traits.h
@@ -12,9 +12,13 @@
#include <__concepts/arithmetic.h>
#include <__config>
+#include <__type_traits/conditional.h>
+#include <__type_traits/is_object.h>
#include <__type_traits/is_primary_template.h>
+#include <__type_traits/make_signed.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/declval.h>
#include <cstddef>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -53,7 +57,7 @@ concept __has_integral_minus =
template<__has_integral_minus _Tp>
requires (!__has_member_difference_type<_Tp>)
struct incrementable_traits<_Tp> {
- using difference_type = make_signed_t<decltype(declval<_Tp>() - declval<_Tp>())>;
+ using difference_type = make_signed_t<decltype(std::declval<_Tp>() - std::declval<_Tp>())>;
};
template <class>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/iter_move.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/iter_move.h
index d8240ab9c2..a7d9413fb8 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__iterator/iter_move.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/iter_move.h
@@ -13,9 +13,11 @@
#include <__concepts/class_or_enum.h>
#include <__config>
#include <__iterator/iterator_traits.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/declval.h>
#include <__utility/forward.h>
#include <__utility/move.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -36,6 +38,7 @@ template <class _Tp>
concept __unqualified_iter_move =
__class_or_enum<remove_cvref_t<_Tp>> &&
requires (_Tp&& __t) {
+ // NOLINTNEXTLINE(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap
iter_move(std::forward<_Tp>(__t));
};
@@ -59,6 +62,7 @@ concept __just_deref =
// [iterator.cust.move]
struct __fn {
+ // NOLINTBEGIN(libcpp-robust-against-adl) iter_move ADL calls should only be made through ranges::iter_move
template<class _Ip>
requires __unqualified_iter_move<_Ip>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Ip&& __i) const
@@ -66,6 +70,7 @@ struct __fn {
{
return iter_move(std::forward<_Ip>(__i));
}
+ // NOLINTEND(libcpp-robust-against-adl)
template<class _Ip>
requires __move_deref<_Ip>
@@ -90,7 +95,7 @@ inline namespace __cpo {
template<__dereferenceable _Tp>
requires requires(_Tp& __t) { { ranges::iter_move(__t) } -> __can_reference; }
-using iter_rvalue_reference_t = decltype(ranges::iter_move(declval<_Tp&>()));
+using iter_rvalue_reference_t = decltype(ranges::iter_move(std::declval<_Tp&>()));
#endif // _LIBCPP_STD_VER > 17
diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/iter_swap.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/iter_swap.h
index 78152e2d9a..d4c0dca1f6 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__iterator/iter_swap.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/iter_swap.h
@@ -17,9 +17,10 @@
#include <__iterator/iter_move.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/readable_traits.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/declval.h>
#include <__utility/forward.h>
#include <__utility/move.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -40,6 +41,7 @@ namespace __iter_swap {
concept __unqualified_iter_swap =
(__class_or_enum<remove_cvref_t<_T1>> || __class_or_enum<remove_cvref_t<_T2>>) &&
requires (_T1&& __x, _T2&& __y) {
+ // NOLINTNEXTLINE(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap
iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y));
};
@@ -48,7 +50,9 @@ namespace __iter_swap {
indirectly_readable<_T1> && indirectly_readable<_T2> &&
swappable_with<iter_reference_t<_T1>, iter_reference_t<_T2>>;
+
struct __fn {
+ // NOLINTBEGIN(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap
template <class _T1, class _T2>
requires __unqualified_iter_swap<_T1, _T2>
_LIBCPP_HIDE_FROM_ABI
@@ -57,6 +61,7 @@ namespace __iter_swap {
{
(void)iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y));
}
+ // NOLINTEND(libcpp-robust-against-adl)
template <class _T1, class _T2>
requires (!__unqualified_iter_swap<_T1, _T2>) &&
@@ -77,7 +82,7 @@ namespace __iter_swap {
constexpr void operator()(_T1&& __x, _T2&& __y) const
noexcept(noexcept(iter_value_t<_T2>(ranges::iter_move(__y))) &&
noexcept(*__y = ranges::iter_move(__x)) &&
- noexcept(*_VSTD::forward<_T1>(__x) = declval<iter_value_t<_T2>>()))
+ noexcept(*_VSTD::forward<_T1>(__x) = std::declval<iter_value_t<_T2>>()))
{
iter_value_t<_T2> __old(ranges::iter_move(__y));
*__y = ranges::iter_move(__x);
diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/iterator_traits.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/iterator_traits.h
index b4cf072332..c9d8944bfe 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__iterator/iterator_traits.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/iterator_traits.h
@@ -21,8 +21,21 @@
#include <__fwd/pair.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/readable_traits.h>
+#include <__type_traits/add_const.h>
+#include <__type_traits/common_reference.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/disjunction.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_object.h>
+#include <__type_traits/is_primary_template.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/is_valid_expansion.h>
+#include <__type_traits/remove_const.h>
+#include <__type_traits/remove_cv.h>
+#include <__type_traits/remove_cvref.h>
+#include <__type_traits/void_t.h>
+#include <__utility/declval.h>
#include <cstddef>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -47,7 +60,7 @@ concept __dereferenceable = requires(_Tp& __t) {
// [iterator.traits]
template<__dereferenceable _Tp>
-using iter_reference_t = decltype(*declval<_Tp&>());
+using iter_reference_t = decltype(*std::declval<_Tp&>());
#endif // _LIBCPP_STD_VER > 17
@@ -260,7 +273,7 @@ struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> { using type = typ
template<class _Ip>
requires requires(_Ip& __i) { __i.operator->(); } && (!__has_member_pointer<_Ip>)
struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> {
- using type = decltype(declval<_Ip&>().operator->());
+ using type = decltype(std::declval<_Ip&>().operator->());
};
// Otherwise, `reference` names `iter-reference-t<I>`.
diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/iterator_with_data.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/iterator_with_data.h
new file mode 100644
index 0000000000..06c2fa699c
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/iterator_with_data.h
@@ -0,0 +1,100 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_ITERATOR_WITH_DATA_H
+#define _LIBCPP___ITERATOR_ITERATOR_WITH_DATA_H
+
+#include <__compare/compare_three_way_result.h>
+#include <__compare/three_way_comparable.h>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/iter_swap.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/readable_traits.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 20
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <forward_iterator _Iterator, class _Data>
+class __iterator_with_data {
+ _Iterator __iter_{};
+ _Data __data_{};
+
+public:
+ using value_type = iter_value_t<_Iterator>;
+ using difference_type = iter_difference_t<_Iterator>;
+
+ _LIBCPP_HIDE_FROM_ABI __iterator_with_data() = default;
+
+ constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data(_Iterator __iter, _Data __data)
+ : __iter_(std::move(__iter)), __data_(std::move(__data)) {}
+
+ constexpr _LIBCPP_HIDE_FROM_ABI _Iterator __get_iter() const { return __iter_; }
+
+ constexpr _LIBCPP_HIDE_FROM_ABI _Data __get_data() && { return std::move(__data_); }
+
+ friend constexpr _LIBCPP_HIDE_FROM_ABI bool
+ operator==(const __iterator_with_data& __lhs, const __iterator_with_data& __rhs) {
+ return __lhs.__iter_ == __rhs.__iter_;
+ }
+
+ constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data& operator++() {
+ ++__iter_;
+ return *this;
+ }
+
+ constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data operator++(int) {
+ auto __tmp = *this;
+ __iter_++;
+ return __tmp;
+ }
+
+ constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data& operator--()
+ requires bidirectional_iterator<_Iterator>
+ {
+ --__iter_;
+ return *this;
+ }
+
+ constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data operator--(int)
+ requires bidirectional_iterator<_Iterator>
+ {
+ auto __tmp = *this;
+ --__iter_;
+ return __tmp;
+ }
+
+ constexpr _LIBCPP_HIDE_FROM_ABI iter_reference_t<_Iterator> operator*() const { return *__iter_; }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr iter_rvalue_reference_t<_Iterator>
+ iter_move(const __iterator_with_data& __iter) noexcept(noexcept(ranges::iter_move(__iter.__iter_))) {
+ return ranges::iter_move(__iter.__iter_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr void
+ iter_swap(const __iterator_with_data& __lhs,
+ const __iterator_with_data& __rhs) noexcept(noexcept(ranges::iter_swap(__lhs.__iter_, __rhs.__iter_)))
+ requires indirectly_swappable<_Iterator>
+ {
+ return ranges::iter_swap(__lhs.__data_, __rhs.__iter_);
+ }
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 20
+
+#endif // _LIBCPP___ITERATOR_ITERATOR_WITH_DATA_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/move_iterator.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/move_iterator.h
index b4f2f9ec3d..fa806dbaf7 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__iterator/move_iterator.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/move_iterator.h
@@ -24,8 +24,16 @@
#include <__iterator/iterator_traits.h>
#include <__iterator/move_sentinel.h>
#include <__iterator/readable_traits.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_assignable.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/remove_reference.h>
+#include <__utility/declval.h>
#include <__utility/move.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -49,7 +57,7 @@ struct __move_iter_category_base<_Iter> {
template<class _Iter, class _Sent>
concept __move_iter_comparable = requires {
- { declval<const _Iter&>() == declval<_Sent>() } -> convertible_to<bool>;
+ { std::declval<const _Iter&>() == std::declval<_Sent>() } -> convertible_to<bool>;
};
#endif // _LIBCPP_STD_VER > 17
diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/move_sentinel.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/move_sentinel.h
index 5adf877b34..0d7336a1dc 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__iterator/move_sentinel.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/move_sentinel.h
@@ -50,6 +50,8 @@ private:
_Sent __last_ = _Sent();
};
+_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_sentinel);
+
#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/next.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/next.h
index 13de2f3f73..44e129e106 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__iterator/next.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/next.h
@@ -16,7 +16,7 @@
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/iterator_traits.h>
-#include <type_traits>
+#include <__type_traits/enable_if.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/prev.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/prev.h
index a1d0bc0dbb..cdd1b8ecf6 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__iterator/prev.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/prev.h
@@ -16,7 +16,7 @@
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/iterator_traits.h>
-#include <type_traits>
+#include <__type_traits/enable_if.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/projected.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/projected.h
index 3a08b58b8b..19c076b2e5 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__iterator/projected.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/projected.h
@@ -13,7 +13,7 @@
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
-#include <type_traits>
+#include <__type_traits/remove_cvref.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/readable_traits.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/readable_traits.h
index dc818d8a23..8f17757c5a 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__iterator/readable_traits.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/readable_traits.h
@@ -12,7 +12,13 @@
#include <__concepts/same_as.h>
#include <__config>
-#include <type_traits>
+#include <__type_traits/conditional.h>
+#include <__type_traits/is_array.h>
+#include <__type_traits/is_object.h>
+#include <__type_traits/is_primary_template.h>
+#include <__type_traits/remove_cv.h>
+#include <__type_traits/remove_cvref.h>
+#include <__type_traits/remove_extent.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/reverse_iterator.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/reverse_iterator.h
index 2933a29fc8..f272e03c17 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__iterator/reverse_iterator.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/reverse_iterator.h
@@ -25,12 +25,20 @@
#include <__iterator/next.h>
#include <__iterator/prev.h>
#include <__iterator/readable_traits.h>
+#include <__iterator/segmented_iterator.h>
#include <__memory/addressof.h>
#include <__ranges/access.h>
#include <__ranges/concepts.h>
#include <__ranges/subrange.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_assignable.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_nothrow_copy_constructible.h>
+#include <__type_traits/is_pointer.h>
+#include <__type_traits/is_same.h>
+#include <__utility/declval.h>
#include <__utility/move.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -177,7 +185,7 @@ public:
_LIBCPP_HIDE_FROM_ABI friend constexpr
iter_rvalue_reference_t<_Iter> iter_move(const reverse_iterator& __i)
noexcept(is_nothrow_copy_constructible_v<_Iter> &&
- noexcept(ranges::iter_move(--declval<_Iter&>()))) {
+ noexcept(ranges::iter_move(--std::declval<_Iter&>()))) {
auto __tmp = __i.base();
return ranges::iter_move(--__tmp);
}
@@ -187,7 +195,7 @@ public:
void iter_swap(const reverse_iterator& __x, const reverse_iterator<_Iter2>& __y)
noexcept(is_nothrow_copy_constructible_v<_Iter> &&
is_nothrow_copy_constructible_v<_Iter2> &&
- noexcept(ranges::iter_swap(--declval<_Iter&>(), --declval<_Iter2&>()))) {
+ noexcept(ranges::iter_swap(--std::declval<_Iter&>(), --std::declval<_Iter2&>()))) {
auto __xtmp = __x.base();
auto __ytmp = __y.base();
ranges::iter_swap(--__xtmp, --__ytmp);
@@ -195,12 +203,6 @@ public:
#endif // _LIBCPP_STD_VER > 17
};
-template <class _Iter>
-struct __is_reverse_iterator : false_type {};
-
-template <class _Iter>
-struct __is_reverse_iterator<reverse_iterator<_Iter> > : true_type {};
-
template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
bool
@@ -394,7 +396,7 @@ public:
_LIBCPP_HIDE_FROM_ABI friend constexpr
iter_rvalue_reference_t<_Iter> iter_move(const __unconstrained_reverse_iterator& __i)
noexcept(is_nothrow_copy_constructible_v<_Iter> &&
- noexcept(ranges::iter_move(--declval<_Iter&>()))) {
+ noexcept(ranges::iter_move(--std::declval<_Iter&>()))) {
auto __tmp = __i.base();
return ranges::iter_move(--__tmp);
}
@@ -478,9 +480,6 @@ public:
}
};
-template <class _Iter>
-struct __is_reverse_iterator<__unconstrained_reverse_iterator<_Iter>> : true_type {};
-
#endif // _LIBCPP_STD_VER <= 17
template <template <class> class _RevIter1, template <class> class _RevIter2, class _Iter>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/segmented_iterator.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/segmented_iterator.h
new file mode 100644
index 0000000000..c0a77ef1c4
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/segmented_iterator.h
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___SEGMENTED_ITERATOR_H
+#define _LIBCPP___SEGMENTED_ITERATOR_H
+
+// Segmented iterators are iterators over (not necessarily contiguous) sub-ranges.
+//
+// For example, std::deque stores its data into multiple blocks of contiguous memory,
+// which are not stored contiguously themselves. The concept of segmented iterators
+// allows algorithms to operate over these multi-level iterators natively, opening the
+// door to various optimizations. See http://lafstern.org/matt/segmented.pdf for details.
+//
+// If __segmented_iterator_traits can be instantiated, the following functions and associated types must be provided:
+// - Traits::__local_iterator
+// The type of iterators used to iterate inside a segment.
+//
+// - Traits::__segment_iterator
+// The type of iterators used to iterate over segments.
+// Segment iterators can be forward iterators or bidirectional iterators, depending on the
+// underlying data structure.
+//
+// - static __segment_iterator Traits::__segment(It __it)
+// Returns an iterator to the segment that the provided iterator is in.
+//
+// - static __local_iterator Traits::__local(It __it)
+// Returns the local iterator pointing to the element that the provided iterator points to.
+//
+// - static __local_iterator Traits::__begin(__segment_iterator __it)
+// Returns the local iterator to the beginning of the segment that the provided iterator is pointing into.
+//
+// - static __local_iterator Traits::__end(__segment_iterator __it)
+// Returns the one-past-the-end local iterator to the segment that the provided iterator is pointing into.
+//
+// - static It Traits::__compose(__segment_iterator, __local_iterator)
+// Returns the iterator composed of the segment iterator and local iterator.
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Iterator>
+struct __segmented_iterator_traits;
+/* exposition-only:
+{
+ using __segment_iterator = ...;
+ using __local_iterator = ...;
+
+ static __segment_iterator __segment(_Iterator);
+ static __local_iterator __local(_Iterator);
+ static __local_iterator __begin(__segment_iterator);
+ static __local_iterator __end(__segment_iterator);
+ static _Iterator __compose(__segment_iterator, __local_iterator);
+};
+*/
+
+template <class _Tp, size_t = 0>
+struct __has_specialization : false_type {};
+
+#ifndef __CUDACC__
+template <class _Tp>
+struct __has_specialization<_Tp, sizeof(_Tp) * 0> : true_type {};
+#endif
+
+template <class _Iterator>
+using __is_segmented_iterator = __has_specialization<__segmented_iterator_traits<_Iterator> >;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___SEGMENTED_ITERATOR_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/size.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/size.h
index e060134966..1452bd1d55 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__iterator/size.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/size.h
@@ -11,8 +11,9 @@
#define _LIBCPP___ITERATOR_SIZE_H
#include <__config>
+#include <__type_traits/common_type.h>
+#include <__type_traits/make_signed.h>
#include <cstddef>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__iterator/wrap_iter.h b/contrib/libs/cxxsupp/libcxx/include/__iterator/wrap_iter.h
index 80be74ef58..16defc1d8b 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__iterator/wrap_iter.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__iterator/wrap_iter.h
@@ -15,7 +15,8 @@
#include <__iterator/iterator_traits.h>
#include <__memory/addressof.h>
#include <__memory/pointer_traits.h>
-#include <type_traits>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_convertible.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__locale b/contrib/libs/cxxsupp/libcxx/include/__locale
index 0fe43dcb3e..334a8fd052 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__locale
+++ b/contrib/libs/cxxsupp/libcxx/include/__locale
@@ -841,7 +841,7 @@ inline _LIBCPP_INLINE_VISIBILITY
bool
isspace(_CharT __c, const locale& __loc)
{
- return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
+ return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
}
template <class _CharT>
@@ -849,7 +849,7 @@ inline _LIBCPP_INLINE_VISIBILITY
bool
isprint(_CharT __c, const locale& __loc)
{
- return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
+ return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
}
template <class _CharT>
@@ -857,7 +857,7 @@ inline _LIBCPP_INLINE_VISIBILITY
bool
iscntrl(_CharT __c, const locale& __loc)
{
- return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
+ return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
}
template <class _CharT>
@@ -865,7 +865,7 @@ inline _LIBCPP_INLINE_VISIBILITY
bool
isupper(_CharT __c, const locale& __loc)
{
- return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
+ return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
}
template <class _CharT>
@@ -873,7 +873,7 @@ inline _LIBCPP_INLINE_VISIBILITY
bool
islower(_CharT __c, const locale& __loc)
{
- return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
+ return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
}
template <class _CharT>
@@ -881,7 +881,7 @@ inline _LIBCPP_INLINE_VISIBILITY
bool
isalpha(_CharT __c, const locale& __loc)
{
- return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
+ return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
}
template <class _CharT>
@@ -889,7 +889,7 @@ inline _LIBCPP_INLINE_VISIBILITY
bool
isdigit(_CharT __c, const locale& __loc)
{
- return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
+ return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
}
template <class _CharT>
@@ -897,7 +897,7 @@ inline _LIBCPP_INLINE_VISIBILITY
bool
ispunct(_CharT __c, const locale& __loc)
{
- return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
+ return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
}
template <class _CharT>
@@ -905,7 +905,7 @@ inline _LIBCPP_INLINE_VISIBILITY
bool
isxdigit(_CharT __c, const locale& __loc)
{
- return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
+ return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
}
template <class _CharT>
@@ -913,7 +913,7 @@ inline _LIBCPP_INLINE_VISIBILITY
bool
isalnum(_CharT __c, const locale& __loc)
{
- return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
+ return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
}
template <class _CharT>
@@ -921,7 +921,7 @@ inline _LIBCPP_INLINE_VISIBILITY
bool
isgraph(_CharT __c, const locale& __loc)
{
- return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
+ return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
}
template <class _CharT>
@@ -929,7 +929,7 @@ inline _LIBCPP_INLINE_VISIBILITY
_CharT
toupper(_CharT __c, const locale& __loc)
{
- return use_facet<ctype<_CharT> >(__loc).toupper(__c);
+ return std::use_facet<ctype<_CharT> >(__loc).toupper(__c);
}
template <class _CharT>
@@ -937,7 +937,7 @@ inline _LIBCPP_INLINE_VISIBILITY
_CharT
tolower(_CharT __c, const locale& __loc)
{
- return use_facet<ctype<_CharT> >(__loc).tolower(__c);
+ return std::use_facet<ctype<_CharT> >(__loc).tolower(__c);
}
// codecvt_base
diff --git a/contrib/libs/cxxsupp/libcxx/include/__memory/allocate_at_least.h b/contrib/libs/cxxsupp/libcxx/include/__memory/allocate_at_least.h
index 7ce588a25d..ef205f855c 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__memory/allocate_at_least.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__memory/allocate_at_least.h
@@ -25,6 +25,7 @@ struct allocation_result {
_Pointer ptr;
size_t count;
};
+_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(allocation_result);
template <class _Alloc>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr
diff --git a/contrib/libs/cxxsupp/libcxx/include/__memory/allocator.h b/contrib/libs/cxxsupp/libcxx/include/__memory/allocator.h
index 7a930959a1..54c9b78d52 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__memory/allocator.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__memory/allocator.h
@@ -13,11 +13,14 @@
#include <__config>
#include <__memory/allocate_at_least.h>
#include <__memory/allocator_traits.h>
+#include <__type_traits/is_constant_evaluated.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_void.h>
+#include <__type_traits/is_volatile.h>
#include <__utility/forward.h>
#include <cstddef>
#include <new>
#include <stdexcept>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__memory/allocator_arg_t.h b/contrib/libs/cxxsupp/libcxx/include/__memory/allocator_arg_t.h
index 44df046ed7..15f8c98c4c 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__memory/allocator_arg_t.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__memory/allocator_arg_t.h
@@ -12,8 +12,10 @@
#include <__config>
#include <__memory/uses_allocator.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/remove_cvref.h>
#include <__utility/forward.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__memory/allocator_traits.h b/contrib/libs/cxxsupp/libcxx/include/__memory/allocator_traits.h
index 6acc14aa23..3a23b47c74 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__memory/allocator_traits.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__memory/allocator_traits.h
@@ -13,9 +13,16 @@
#include <__config>
#include <__memory/construct_at.h>
#include <__memory/pointer_traits.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_copy_constructible.h>
+#include <__type_traits/is_empty.h>
+#include <__type_traits/is_move_constructible.h>
+#include <__type_traits/make_unsigned.h>
+#include <__type_traits/remove_reference.h>
+#include <__type_traits/void_t.h>
+#include <__utility/declval.h>
#include <__utility/forward.h>
#include <limits>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -180,7 +187,7 @@ struct __has_allocate_hint : false_type { };
template <class _Alloc, class _SizeType, class _ConstVoidPtr>
struct __has_allocate_hint<_Alloc, _SizeType, _ConstVoidPtr, decltype(
- (void)declval<_Alloc>().allocate(declval<_SizeType>(), declval<_ConstVoidPtr>())
+ (void)std::declval<_Alloc>().allocate(std::declval<_SizeType>(), std::declval<_ConstVoidPtr>())
)> : true_type { };
// __has_construct
@@ -189,7 +196,7 @@ struct __has_construct_impl : false_type { };
template <class _Alloc, class ..._Args>
struct __has_construct_impl<decltype(
- (void)declval<_Alloc>().construct(declval<_Args>()...)
+ (void)std::declval<_Alloc>().construct(std::declval<_Args>()...)
), _Alloc, _Args...> : true_type { };
template <class _Alloc, class ..._Args>
@@ -201,7 +208,7 @@ struct __has_destroy : false_type { };
template <class _Alloc, class _Pointer>
struct __has_destroy<_Alloc, _Pointer, decltype(
- (void)declval<_Alloc>().destroy(declval<_Pointer>())
+ (void)std::declval<_Alloc>().destroy(std::declval<_Pointer>())
)> : true_type { };
// __has_max_size
@@ -210,7 +217,7 @@ struct __has_max_size : false_type { };
template <class _Alloc>
struct __has_max_size<_Alloc, decltype(
- (void)declval<_Alloc&>().max_size()
+ (void)std::declval<_Alloc&>().max_size()
)> : true_type { };
// __has_select_on_container_copy_construction
@@ -219,7 +226,7 @@ struct __has_select_on_container_copy_construction : false_type { };
template <class _Alloc>
struct __has_select_on_container_copy_construction<_Alloc, decltype(
- (void)declval<_Alloc>().select_on_container_copy_construction()
+ (void)std::declval<_Alloc>().select_on_container_copy_construction()
)> : true_type { };
_LIBCPP_SUPPRESS_DEPRECATED_POP
diff --git a/contrib/libs/cxxsupp/libcxx/include/__memory/assume_aligned.h b/contrib/libs/cxxsupp/libcxx/include/__memory/assume_aligned.h
index 0f12fb11fd..a1fd2441f9 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__memory/assume_aligned.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__memory/assume_aligned.h
@@ -12,9 +12,9 @@
#include <__assert>
#include <__config>
+#include <__type_traits/is_constant_evaluated.h>
#include <cstddef>
#include <cstdint>
-#include <type_traits> // for is_constant_evaluated()
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__memory/compressed_pair.h b/contrib/libs/cxxsupp/libcxx/include/__memory/compressed_pair.h
index 9dd42f8d6e..8093d7c931 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__memory/compressed_pair.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__memory/compressed_pair.h
@@ -13,12 +13,19 @@
#include <__config>
#include <__fwd/get.h>
#include <__fwd/tuple.h>
-#include <__tuple/tuple_indices.h>
+#include <__tuple_dir/tuple_indices.h>
+#include <__type_traits/decay.h>
#include <__type_traits/dependent_type.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_default_constructible.h>
+#include <__type_traits/is_empty.h>
+#include <__type_traits/is_final.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_swappable.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#include <__utility/piecewise_construct.h>
-#include <type_traits>
+#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__memory/concepts.h b/contrib/libs/cxxsupp/libcxx/include/__memory/concepts.h
index 76d2a2e729..12d7bf85ed 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__memory/concepts.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__memory/concepts.h
@@ -17,7 +17,8 @@
#include <__iterator/readable_traits.h>
#include <__ranges/access.h>
#include <__ranges/concepts.h>
-#include <type_traits>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/remove_cvref.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__memory/construct_at.h b/contrib/libs/cxxsupp/libcxx/include/__memory/construct_at.h
index a11a6ebe44..14484dd6aa 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__memory/construct_at.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__memory/construct_at.h
@@ -15,10 +15,12 @@
#include <__iterator/access.h>
#include <__memory/addressof.h>
#include <__memory/voidify.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_array.h>
+#include <__utility/declval.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#include <new>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -30,7 +32,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-template <class _Tp, class... _Args, class = decltype(::new(declval<void*>()) _Tp(declval<_Args>()...))>
+template <class _Tp, class... _Args, class = decltype(::new(std::declval<void*>()) _Tp(std::declval<_Args>()...))>
_LIBCPP_HIDE_FROM_ABI constexpr _Tp* construct_at(_Tp* __location, _Args&&... __args) {
_LIBCPP_ASSERT(__location != nullptr, "null pointer given to construct_at");
return ::new (_VSTD::__voidify(*__location)) _Tp(_VSTD::forward<_Args>(__args)...);
@@ -38,7 +40,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Tp* construct_at(_Tp* __location, _Args&&... __
#endif
-template <class _Tp, class... _Args, class = decltype(::new(declval<void*>()) _Tp(declval<_Args>()...))>
+template <class _Tp, class... _Args, class = decltype(::new(std::declval<void*>()) _Tp(std::declval<_Args>()...))>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* __construct_at(_Tp* __location, _Args&&... __args) {
#if _LIBCPP_STD_VER > 17
return std::construct_at(__location, std::forward<_Args>(__args)...);
@@ -81,6 +83,16 @@ _ForwardIterator __destroy(_ForwardIterator __first, _ForwardIterator __last) {
return __first;
}
+template <class _BidirectionalIterator>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+_BidirectionalIterator __reverse_destroy(_BidirectionalIterator __first, _BidirectionalIterator __last) {
+ while (__last != __first) {
+ --__last;
+ std::__destroy_at(std::addressof(*__last));
+ }
+ return __last;
+}
+
#if _LIBCPP_STD_VER > 14
template <class _Tp, enable_if_t<!is_array_v<_Tp>, int> = 0>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__memory/pointer_traits.h b/contrib/libs/cxxsupp/libcxx/include/__memory/pointer_traits.h
index fd52647178..c4f20def45 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__memory/pointer_traits.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__memory/pointer_traits.h
@@ -12,8 +12,15 @@
#include <__config>
#include <__memory/addressof.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/conjunction.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_class.h>
+#include <__type_traits/is_function.h>
+#include <__type_traits/is_void.h>
+#include <__type_traits/void_t.h>
+#include <__utility/declval.h>
#include <cstddef>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -172,7 +179,7 @@ struct _HasToAddress : false_type {};
template <class _Pointer>
struct _HasToAddress<_Pointer,
- decltype((void)pointer_traits<_Pointer>::to_address(declval<const _Pointer&>()))
+ decltype((void)pointer_traits<_Pointer>::to_address(std::declval<const _Pointer&>()))
> : true_type {};
template <class _Pointer, class = void>
@@ -180,7 +187,7 @@ struct _HasArrow : false_type {};
template <class _Pointer>
struct _HasArrow<_Pointer,
- decltype((void)declval<const _Pointer&>().operator->())
+ decltype((void)std::declval<const _Pointer&>().operator->())
> : true_type {};
template <class _Pointer>
@@ -193,7 +200,7 @@ template <class _Pointer, class = __enable_if_t<
_And<is_class<_Pointer>, _IsFancyPointer<_Pointer> >::value
> >
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-typename decay<decltype(__to_address_helper<_Pointer>::__call(declval<const _Pointer&>()))>::type
+typename decay<decltype(__to_address_helper<_Pointer>::__call(std::declval<const _Pointer&>()))>::type
__to_address(const _Pointer& __p) _NOEXCEPT {
return __to_address_helper<_Pointer>::__call(__p);
}
@@ -201,16 +208,16 @@ __to_address(const _Pointer& __p) _NOEXCEPT {
template <class _Pointer, class>
struct __to_address_helper {
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
- static decltype(_VSTD::__to_address(declval<const _Pointer&>().operator->()))
+ static decltype(_VSTD::__to_address(std::declval<const _Pointer&>().operator->()))
__call(const _Pointer& __p) _NOEXCEPT {
return _VSTD::__to_address(__p.operator->());
}
};
template <class _Pointer>
-struct __to_address_helper<_Pointer, decltype((void)pointer_traits<_Pointer>::to_address(declval<const _Pointer&>()))> {
+struct __to_address_helper<_Pointer, decltype((void)pointer_traits<_Pointer>::to_address(std::declval<const _Pointer&>()))> {
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
- static decltype(pointer_traits<_Pointer>::to_address(declval<const _Pointer&>()))
+ static decltype(pointer_traits<_Pointer>::to_address(std::declval<const _Pointer&>()))
__call(const _Pointer& __p) _NOEXCEPT {
return pointer_traits<_Pointer>::to_address(__p);
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/__memory/ranges_construct_at.h b/contrib/libs/cxxsupp/libcxx/include/__memory/ranges_construct_at.h
index 19cd0ff7e8..e63585d1ab 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__memory/ranges_construct_at.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__memory/ranges_construct_at.h
@@ -39,7 +39,7 @@ namespace __construct_at {
struct __fn {
template<class _Tp, class... _Args, class = decltype(
- ::new (declval<void*>()) _Tp(declval<_Args>()...)
+ ::new (std::declval<void*>()) _Tp(std::declval<_Args>()...)
)>
_LIBCPP_HIDE_FROM_ABI
constexpr _Tp* operator()(_Tp* __location, _Args&& ...__args) const {
diff --git a/contrib/libs/cxxsupp/libcxx/include/__memory/ranges_uninitialized_algorithms.h b/contrib/libs/cxxsupp/libcxx/include/__memory/ranges_uninitialized_algorithms.h
index 7d2ac3af03..15c78e20ba 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__memory/ranges_uninitialized_algorithms.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__memory/ranges_uninitialized_algorithms.h
@@ -23,9 +23,9 @@
#include <__ranges/access.h>
#include <__ranges/concepts.h>
#include <__ranges/dangling.h>
+#include <__type_traits/remove_reference.h>
#include <__utility/move.h>
#include <new>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -256,7 +256,7 @@ struct __fn {
sentinel_for<_InputIterator> _Sentinel1,
__nothrow_forward_iterator _OutputIterator,
__nothrow_sentinel_for<_OutputIterator> _Sentinel2>
- requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>>
+ requires constructible_from<iter_value_t<_OutputIterator>, iter_rvalue_reference_t<_InputIterator>>
uninitialized_move_result<_InputIterator, _OutputIterator>
operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const {
using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
@@ -267,7 +267,7 @@ struct __fn {
}
template <input_range _InputRange, __nothrow_forward_range _OutputRange>
- requires constructible_from<range_value_t<_OutputRange>, range_reference_t<_InputRange>>
+ requires constructible_from<range_value_t<_OutputRange>, range_rvalue_reference_t<_InputRange>>
uninitialized_move_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>>
operator()(_InputRange&& __in_range, _OutputRange&& __out_range) const {
return (*this)(ranges::begin(__in_range), ranges::end(__in_range),
@@ -292,7 +292,7 @@ struct __fn {
template <input_iterator _InputIterator,
__nothrow_forward_iterator _OutputIterator,
__nothrow_sentinel_for<_OutputIterator> _Sentinel>
- requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>>
+ requires constructible_from<iter_value_t<_OutputIterator>, iter_rvalue_reference_t<_InputIterator>>
uninitialized_move_n_result<_InputIterator, _OutputIterator>
operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n,
_OutputIterator __ofirst, _Sentinel __olast) const {
diff --git a/contrib/libs/cxxsupp/libcxx/include/__memory/shared_ptr.h b/contrib/libs/cxxsupp/libcxx/include/__memory/shared_ptr.h
index bab8c8c15c..46c0534c3d 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__memory/shared_ptr.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__memory/shared_ptr.h
@@ -37,7 +37,6 @@
#include <iosfwd>
#include <new>
#include <stdexcept>
-#include <type_traits>
#include <typeinfo>
#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
# include <atomic>
@@ -246,7 +245,7 @@ public:
__shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a)
: __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTD::move(__d)), _VSTD::move(__a)) {}
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
const void* __get_deleter(const type_info&) const _NOEXCEPT override;
#endif
@@ -255,7 +254,7 @@ private:
void __on_zero_shared_weak() _NOEXCEPT override;
};
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
template <class _Tp, class _Dp, class _Alloc>
const void*
@@ -264,7 +263,7 @@ __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) cons
return __t == typeid(_Dp) ? _VSTD::addressof(__data_.first().second()) : nullptr;
}
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
template <class _Tp, class _Dp, class _Alloc>
void
@@ -287,6 +286,11 @@ __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
__a.deallocate(_PTraits::pointer_to(*this), 1);
}
+// This tag is used to instantiate an allocator type. The various shared_ptr control blocks
+// detect that the allocator has been instantiated for this type and perform alternative
+// initialization/destruction based on that.
+struct __for_overwrite_tag {};
+
template <class _Tp, class _Alloc>
struct __shared_ptr_emplace
: __shared_weak_count
@@ -296,10 +300,15 @@ struct __shared_ptr_emplace
explicit __shared_ptr_emplace(_Alloc __a, _Args&& ...__args)
: __storage_(_VSTD::move(__a))
{
-#if _LIBCPP_STD_VER > 17
- using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
- _TpAlloc __tmp(*__get_alloc());
- allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), _VSTD::forward<_Args>(__args)...);
+#if _LIBCPP_STD_VER >= 20
+ if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
+ static_assert(sizeof...(_Args) == 0, "No argument should be provided to the control block when using _for_overwrite");
+ ::new ((void*)__get_elem()) _Tp;
+ } else {
+ using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
+ _TpAlloc __tmp(*__get_alloc());
+ allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), _VSTD::forward<_Args>(__args)...);
+ }
#else
::new ((void*)__get_elem()) _Tp(_VSTD::forward<_Args>(__args)...);
#endif
@@ -314,9 +323,13 @@ struct __shared_ptr_emplace
private:
void __on_zero_shared() _NOEXCEPT override {
#if _LIBCPP_STD_VER > 17
- using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
- _TpAlloc __tmp(*__get_alloc());
- allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem());
+ if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
+ __get_elem()->~_Tp();
+ } else {
+ using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
+ _TpAlloc __tmp(*__get_alloc());
+ allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem());
+ }
#else
__get_elem()->~_Tp();
#endif
@@ -382,40 +395,84 @@ public:
template<class _Tp> class _LIBCPP_TEMPLATE_VIS enable_shared_from_this;
-template<class _Tp, class _Up>
+// http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.general-6
+// A pointer type Y* is said to be compatible with a pointer type T*
+// when either Y* is convertible to T* or Y is U[N] and T is cv U[].
+#if _LIBCPP_STD_VER >= 17
+template <class _Yp, class _Tp>
+struct __bounded_convertible_to_unbounded : false_type {};
+
+template <class _Up, std::size_t _Np, class _Tp>
+struct __bounded_convertible_to_unbounded<_Up[_Np], _Tp>
+ : is_same<__remove_cv_t<_Tp>, _Up[]> {};
+
+template <class _Yp, class _Tp>
struct __compatible_with
-#if _LIBCPP_STD_VER > 14
- : is_convertible<remove_extent_t<_Tp>*, remove_extent_t<_Up>*> {};
+ : _Or<
+ is_convertible<_Yp*, _Tp*>,
+ __bounded_convertible_to_unbounded<_Yp, _Tp>
+ > {};
#else
- : is_convertible<_Tp*, _Up*> {};
-#endif // _LIBCPP_STD_VER > 14
+template <class _Yp, class _Tp>
+struct __compatible_with
+ : is_convertible<_Yp*, _Tp*> {};
+#endif // _LIBCPP_STD_VER >= 17
+
+// Constructors that take raw pointers have a different set of "compatible" constraints
+// http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.const-9.1
+// - If T is an array type, then either T is U[N] and Y(*)[N] is convertible to T*,
+// or T is U[] and Y(*)[] is convertible to T*.
+// - If T is not an array type, then Y* is convertible to T*.
+#if _LIBCPP_STD_VER >= 17
+template <class _Yp, class _Tp, class = void>
+struct __raw_pointer_compatible_with : _And<
+ _Not<is_array<_Tp>>,
+ is_convertible<_Yp*, _Tp*>
+ > {};
+
+template <class _Yp, class _Up, std::size_t _Np>
+struct __raw_pointer_compatible_with<_Yp, _Up[_Np], __enable_if_t<
+ is_convertible<_Yp(*)[_Np], _Up(*)[_Np]>::value> >
+ : true_type {};
+
+template <class _Yp, class _Up>
+struct __raw_pointer_compatible_with<_Yp, _Up[], __enable_if_t<
+ is_convertible<_Yp(*)[], _Up(*)[]>::value> >
+ : true_type {};
+
+#else
+template <class _Yp, class _Tp>
+struct __raw_pointer_compatible_with
+ : is_convertible<_Yp*, _Tp*> {};
+#endif // _LIBCPP_STD_VER >= 17
+
template <class _Ptr, class = void>
struct __is_deletable : false_type { };
template <class _Ptr>
-struct __is_deletable<_Ptr, decltype(delete declval<_Ptr>())> : true_type { };
+struct __is_deletable<_Ptr, decltype(delete std::declval<_Ptr>())> : true_type { };
template <class _Ptr, class = void>
struct __is_array_deletable : false_type { };
template <class _Ptr>
-struct __is_array_deletable<_Ptr, decltype(delete[] declval<_Ptr>())> : true_type { };
+struct __is_array_deletable<_Ptr, decltype(delete[] std::declval<_Ptr>())> : true_type { };
template <class _Dp, class _Pt,
- class = decltype(declval<_Dp>()(declval<_Pt>()))>
+ class = decltype(std::declval<_Dp>()(std::declval<_Pt>()))>
static true_type __well_formed_deleter_test(int);
template <class, class>
static false_type __well_formed_deleter_test(...);
template <class _Dp, class _Pt>
-struct __well_formed_deleter : decltype(__well_formed_deleter_test<_Dp, _Pt>(0)) {};
+struct __well_formed_deleter : decltype(std::__well_formed_deleter_test<_Dp, _Pt>(0)) {};
-template<class _Dp, class _Tp, class _Yp>
+template<class _Dp, class _Yp, class _Tp>
struct __shared_ptr_deleter_ctor_reqs
{
- static const bool value = __compatible_with<_Tp, _Yp>::value &&
+ static const bool value = __raw_pointer_compatible_with<_Yp, _Tp>::value &&
is_move_constructible<_Dp>::value &&
- __well_formed_deleter<_Dp, _Tp*>::value;
+ __well_formed_deleter<_Dp, _Yp*>::value;
};
#if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI)
@@ -454,7 +511,7 @@ public:
template<class _Yp, class = __enable_if_t<
_And<
- __compatible_with<_Yp, _Tp>
+ __raw_pointer_compatible_with<_Yp, _Tp>
// In C++03 we get errors when trying to do SFINAE with the
// delete operator, so we always pretend that it's deletable.
// The same happens on GCC.
@@ -472,7 +529,7 @@ public:
__enable_weak_this(__p, __p);
}
- template<class _Yp, class _Dp, class = __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value> >
+ template<class _Yp, class _Dp, class = __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value> >
_LIBCPP_HIDE_FROM_ABI
shared_ptr(_Yp* __p, _Dp __d)
: __ptr_(__p)
@@ -499,7 +556,7 @@ public:
#endif // _LIBCPP_NO_EXCEPTIONS
}
- template<class _Yp, class _Dp, class _Alloc, class = __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value> >
+ template<class _Yp, class _Dp, class _Alloc, class = __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value> >
_LIBCPP_HIDE_FROM_ABI
shared_ptr(_Yp* __p, _Dp __d, _Alloc __a)
: __ptr_(__p)
@@ -661,6 +718,7 @@ public:
template <class _Yp, class _Dp, class = __enable_if_t<
!is_lvalue_reference<_Dp>::value &&
+ __compatible_with<_Yp, _Tp>::value &&
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value
> >
_LIBCPP_HIDE_FROM_ABI
@@ -683,6 +741,7 @@ public:
template <class _Yp, class _Dp, class = void, class = __enable_if_t<
is_lvalue_reference<_Dp>::value &&
+ __compatible_with<_Yp, _Tp>::value &&
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value
> >
_LIBCPP_HIDE_FROM_ABI
@@ -755,9 +814,10 @@ public:
}
#endif
- template <class _Yp, class _Dp, class = __enable_if_t<
- is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value
- > >
+ template <class _Yp, class _Dp, class = __enable_if_t<_And<
+ __compatible_with<_Yp, _Tp>,
+ is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>
+ >::value> >
_LIBCPP_HIDE_FROM_ABI
shared_ptr<_Tp>& operator=(unique_ptr<_Yp, _Dp>&& __r)
{
@@ -779,7 +839,7 @@ public:
}
template<class _Yp, class = __enable_if_t<
- __compatible_with<_Yp, _Tp>::value
+ __raw_pointer_compatible_with<_Yp, _Tp>::value
> >
_LIBCPP_HIDE_FROM_ABI
void reset(_Yp* __p)
@@ -788,8 +848,7 @@ public:
}
template<class _Yp, class _Dp, class = __enable_if_t<
- __compatible_with<_Yp, _Tp>::value
- > >
+ __shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value> >
_LIBCPP_HIDE_FROM_ABI
void reset(_Yp* __p, _Dp __d)
{
@@ -797,8 +856,7 @@ public:
}
template<class _Yp, class _Dp, class _Alloc, class = __enable_if_t<
- __compatible_with<_Yp, _Tp>::value
- > >
+ __shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value> >
_LIBCPP_HIDE_FROM_ABI
void reset(_Yp* __p, _Dp __d, _Alloc __a)
{
@@ -873,7 +931,7 @@ public:
}
#endif
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
template <class _Dp>
_LIBCPP_HIDE_FROM_ABI
_Dp* __get_deleter() const _NOEXCEPT
@@ -882,7 +940,7 @@ public:
? const_cast<void *>(__cntrl_->__get_deleter(typeid(_Dp)))
: nullptr);
}
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
template<class _Yp, class _CntrlBlk>
_LIBCPP_HIDE_FROM_ABI
@@ -972,6 +1030,26 @@ shared_ptr<_Tp> make_shared(_Args&& ...__args)
return _VSTD::allocate_shared<_Tp>(allocator<_Tp>(), _VSTD::forward<_Args>(__args)...);
}
+#if _LIBCPP_STD_VER >= 20
+
+template<class _Tp, class _Alloc, __enable_if_t<!is_array<_Tp>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI
+shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a)
+{
+ using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
+ _ForOverwriteAllocator __alloc(__a);
+ return std::allocate_shared<_Tp>(__alloc);
+}
+
+template<class _Tp, __enable_if_t<!is_array<_Tp>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI
+shared_ptr<_Tp> make_shared_for_overwrite()
+{
+ return std::allocate_shared_for_overwrite<_Tp>(allocator<_Tp>());
+}
+
+#endif // _LIBCPP_STD_VER >= 20
+
#if _LIBCPP_STD_VER > 14
template <size_t _Alignment>
@@ -992,14 +1070,24 @@ struct __unbounded_array_control_block<_Tp[], _Alloc> : __shared_weak_count
explicit __unbounded_array_control_block(_Alloc const& __alloc, size_t __count, _Tp const& __arg)
: __alloc_(__alloc), __count_(__count)
{
- std::__uninitialized_allocator_fill_n(__alloc_, std::begin(__data_), __count_, __arg);
+ std::__uninitialized_allocator_fill_n_multidimensional(__alloc_, std::begin(__data_), __count_, __arg);
}
_LIBCPP_HIDE_FROM_ABI
explicit __unbounded_array_control_block(_Alloc const& __alloc, size_t __count)
: __alloc_(__alloc), __count_(__count)
{
- std::__uninitialized_allocator_value_construct_n(__alloc_, std::begin(__data_), __count_);
+#if _LIBCPP_STD_VER >= 20
+ if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
+ // We are purposefully not using an allocator-aware default construction because the spec says so.
+ // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
+ std::uninitialized_default_construct_n(std::begin(__data_), __count_);
+ } else {
+ std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::begin(__data_), __count_);
+ }
+#else
+ std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::begin(__data_), __count_);
+#endif
}
// Returns the number of bytes required to store a control block followed by the given number
@@ -1018,13 +1106,22 @@ struct __unbounded_array_control_block<_Tp[], _Alloc> : __shared_weak_count
return (__bytes + __align - 1) & ~(__align - 1);
}
- _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL
~__unbounded_array_control_block() override { } // can't be `= default` because of the sometimes-non-trivial union member __data_
private:
void __on_zero_shared() _NOEXCEPT override {
+#if _LIBCPP_STD_VER >= 20
+ if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
+ std::__reverse_destroy(__data_, __data_ + __count_);
+ } else {
+ __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
+ std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + __count_);
+ }
+#else
__allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + __count_);
+#endif
}
void __on_zero_shared_weak() _NOEXCEPT override {
@@ -1077,21 +1174,40 @@ struct __bounded_array_control_block<_Tp[_Count], _Alloc>
_LIBCPP_HIDE_FROM_ABI
explicit __bounded_array_control_block(_Alloc const& __alloc, _Tp const& __arg) : __alloc_(__alloc) {
- std::__uninitialized_allocator_fill_n(__alloc_, std::addressof(__data_[0]), _Count, __arg);
+ std::__uninitialized_allocator_fill_n_multidimensional(__alloc_, std::addressof(__data_[0]), _Count, __arg);
}
_LIBCPP_HIDE_FROM_ABI
explicit __bounded_array_control_block(_Alloc const& __alloc) : __alloc_(__alloc) {
- std::__uninitialized_allocator_value_construct_n(__alloc_, std::addressof(__data_[0]), _Count);
+#if _LIBCPP_STD_VER >= 20
+ if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
+ // We are purposefully not using an allocator-aware default construction because the spec says so.
+ // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
+ std::uninitialized_default_construct_n(std::addressof(__data_[0]), _Count);
+ } else {
+ std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::addressof(__data_[0]), _Count);
+ }
+#else
+ std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::addressof(__data_[0]), _Count);
+#endif
}
- _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL
~__bounded_array_control_block() override { } // can't be `= default` because of the sometimes-non-trivial union member __data_
private:
void __on_zero_shared() _NOEXCEPT override {
+#if _LIBCPP_STD_VER >= 20
+ if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
+ std::__reverse_destroy(__data_, __data_ + _Count);
+ } else {
+ __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
+ std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + _Count);
+ }
+#else
__allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + _Count);
+#endif
}
void __on_zero_shared_weak() _NOEXCEPT override {
@@ -1128,6 +1244,7 @@ shared_ptr<_Array> __allocate_shared_bounded_array(const _Alloc& __a, _Arg&& ...
#if _LIBCPP_STD_VER > 17
+// bounded array variants
template<class _Tp, class _Alloc, class = __enable_if_t<is_bounded_array<_Tp>::value>>
_LIBCPP_HIDE_FROM_ABI
shared_ptr<_Tp> allocate_shared(const _Alloc& __a)
@@ -1142,18 +1259,13 @@ shared_ptr<_Tp> allocate_shared(const _Alloc& __a, const remove_extent_t<_Tp>& _
return std::__allocate_shared_bounded_array<_Tp>(__a, __u);
}
-template<class _Tp, class _Alloc, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
-_LIBCPP_HIDE_FROM_ABI
-shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n)
-{
- return std::__allocate_shared_unbounded_array<_Tp>(__a, __n);
-}
-
-template<class _Tp, class _Alloc, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
+template<class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI
-shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n, const remove_extent_t<_Tp>& __u)
+shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a)
{
- return std::__allocate_shared_unbounded_array<_Tp>(__a, __n, __u);
+ using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
+ _ForOverwriteAllocator __alloc(__a);
+ return std::__allocate_shared_bounded_array<_Tp>(__alloc);
}
template<class _Tp, class = __enable_if_t<is_bounded_array<_Tp>::value>>
@@ -1170,6 +1282,37 @@ shared_ptr<_Tp> make_shared(const remove_extent_t<_Tp>& __u)
return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>(), __u);
}
+template<class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI
+shared_ptr<_Tp> make_shared_for_overwrite()
+{
+ return std::__allocate_shared_bounded_array<_Tp>(allocator<__for_overwrite_tag>());
+}
+
+// unbounded array variants
+template<class _Tp, class _Alloc, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
+_LIBCPP_HIDE_FROM_ABI
+shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n)
+{
+ return std::__allocate_shared_unbounded_array<_Tp>(__a, __n);
+}
+
+template<class _Tp, class _Alloc, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
+_LIBCPP_HIDE_FROM_ABI
+shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n, const remove_extent_t<_Tp>& __u)
+{
+ return std::__allocate_shared_unbounded_array<_Tp>(__a, __n, __u);
+}
+
+template<class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI
+shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a, size_t __n)
+{
+ using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
+ _ForOverwriteAllocator __alloc(__a);
+ return std::__allocate_shared_unbounded_array<_Tp>(__alloc, __n);
+}
+
template<class _Tp, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
_LIBCPP_HIDE_FROM_ABI
shared_ptr<_Tp> make_shared(size_t __n)
@@ -1184,6 +1327,13 @@ shared_ptr<_Tp> make_shared(size_t __n, const remove_extent_t<_Tp>& __u)
return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n, __u);
}
+template<class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI
+shared_ptr<_Tp> make_shared_for_overwrite(size_t __n)
+{
+ return std::__allocate_shared_unbounded_array<_Tp>(allocator<__for_overwrite_tag>(), __n);
+}
+
#endif // _LIBCPP_STD_VER > 17
template<class _Tp, class _Up>
@@ -1407,7 +1557,7 @@ reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
typename shared_ptr<_Tp>::element_type*>(__r.get()));
}
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
template<class _Dp, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
@@ -1417,7 +1567,7 @@ get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT
return __p.template __get_deleter<_Dp>();
}
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
template<class _Tp>
class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
@@ -1836,7 +1986,7 @@ _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
atomic_load(const shared_ptr<_Tp>* __p)
{
- __sp_mut& __m = __get_sp_mut(__p);
+ __sp_mut& __m = std::__get_sp_mut(__p);
__m.lock();
shared_ptr<_Tp> __q = *__p;
__m.unlock();
@@ -1849,7 +1999,7 @@ _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
shared_ptr<_Tp>
atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order)
{
- return atomic_load(__p);
+ return std::atomic_load(__p);
}
template <class _Tp>
@@ -1857,7 +2007,7 @@ _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
_LIBCPP_HIDE_FROM_ABI void
atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
{
- __sp_mut& __m = __get_sp_mut(__p);
+ __sp_mut& __m = std::__get_sp_mut(__p);
__m.lock();
__p->swap(__r);
__m.unlock();
@@ -1869,7 +2019,7 @@ _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
void
atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
{
- atomic_store(__p, __r);
+ std::atomic_store(__p, __r);
}
template <class _Tp>
@@ -1877,7 +2027,7 @@ _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
{
- __sp_mut& __m = __get_sp_mut(__p);
+ __sp_mut& __m = std::__get_sp_mut(__p);
__m.lock();
__p->swap(__r);
__m.unlock();
@@ -1890,7 +2040,7 @@ _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
shared_ptr<_Tp>
atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
{
- return atomic_exchange(__p, __r);
+ return std::atomic_exchange(__p, __r);
}
template <class _Tp>
@@ -1899,7 +2049,7 @@ _LIBCPP_HIDE_FROM_ABI bool
atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
{
shared_ptr<_Tp> __temp;
- __sp_mut& __m = __get_sp_mut(__p);
+ __sp_mut& __m = std::__get_sp_mut(__p);
__m.lock();
if (__p->__owner_equivalent(*__v))
{
@@ -1920,7 +2070,7 @@ _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
bool
atomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
{
- return atomic_compare_exchange_strong(__p, __v, __w);
+ return std::atomic_compare_exchange_strong(__p, __v, __w);
}
template <class _Tp>
@@ -1930,7 +2080,7 @@ bool
atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
shared_ptr<_Tp> __w, memory_order, memory_order)
{
- return atomic_compare_exchange_strong(__p, __v, __w);
+ return std::atomic_compare_exchange_strong(__p, __v, __w);
}
template <class _Tp>
@@ -1940,7 +2090,7 @@ bool
atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
shared_ptr<_Tp> __w, memory_order, memory_order)
{
- return atomic_compare_exchange_weak(__p, __v, __w);
+ return std::atomic_compare_exchange_weak(__p, __v, __w);
}
#endif // !defined(_LIBCPP_HAS_NO_THREADS)
diff --git a/contrib/libs/cxxsupp/libcxx/include/__memory/uninitialized_algorithms.h b/contrib/libs/cxxsupp/libcxx/include/__memory/uninitialized_algorithms.h
index 948774d53f..fa4881e0be 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__memory/uninitialized_algorithms.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__memory/uninitialized_algorithms.h
@@ -20,12 +20,21 @@
#include <__memory/construct_at.h>
#include <__memory/pointer_traits.h>
#include <__memory/voidify.h>
+#include <__type_traits/extent.h>
+#include <__type_traits/is_array.h>
#include <__type_traits/is_constant_evaluated.h>
+#include <__type_traits/is_trivially_copy_assignable.h>
+#include <__type_traits/is_trivially_copy_constructible.h>
+#include <__type_traits/is_trivially_move_assignable.h>
+#include <__type_traits/is_trivially_move_constructible.h>
+#include <__type_traits/is_unbounded_array.h>
+#include <__type_traits/negation.h>
+#include <__type_traits/remove_const.h>
+#include <__type_traits/remove_extent.h>
+#include <__utility/exception_guard.h>
#include <__utility/move.h>
#include <__utility/pair.h>
-#include <__utility/transaction.h>
#include <new>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -284,7 +293,7 @@ template <class _ForwardIterator, class _Size>
inline _LIBCPP_HIDE_FROM_ABI
_ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) {
using _ValueType = typename iterator_traits<_ForwardIterator>::value_type;
- return __uninitialized_value_construct_n<_ValueType>(_VSTD::move(__first), __n);
+ return std::__uninitialized_value_construct_n<_ValueType>(_VSTD::move(__first), __n);
}
// uninitialized_move
@@ -401,7 +410,7 @@ constexpr void __allocator_destroy_multidimensional(_Alloc& __alloc, _BidirIter
// This function assumes that the allocator is bound to the correct type.
template<class _Alloc, class _Tp>
_LIBCPP_HIDE_FROM_ABI
-constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc) {
+constexpr void __allocator_construct_at_multidimensional(_Alloc& __alloc, _Tp* __loc) {
static_assert(is_same_v<typename allocator_traits<_Alloc>::value_type, _Tp>,
"The allocator should already be rebound to the correct type");
@@ -412,9 +421,12 @@ constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc) {
_Tp& __array = *__loc;
// If an exception is thrown, destroy what we have constructed so far in reverse order.
- __transaction __guard([&]() { std::__allocator_destroy_multidimensional(__elem_alloc, __array, __array + __i); });
+ auto __guard = std::__make_exception_guard([&]() {
+ std::__allocator_destroy_multidimensional(__elem_alloc, __array, __array + __i);
+ });
+
for (; __i != extent_v<_Tp>; ++__i) {
- std::__allocator_construct_at(__elem_alloc, std::addressof(__array[__i]));
+ std::__allocator_construct_at_multidimensional(__elem_alloc, std::addressof(__array[__i]));
}
__guard.__complete();
} else {
@@ -434,13 +446,13 @@ constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc) {
// This function assumes that the allocator is bound to the correct type.
template<class _Alloc, class _Tp, class _Arg>
_LIBCPP_HIDE_FROM_ABI
-constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc, _Arg const& __arg) {
+constexpr void __allocator_construct_at_multidimensional(_Alloc& __alloc, _Tp* __loc, _Arg const& __arg) {
static_assert(is_same_v<typename allocator_traits<_Alloc>::value_type, _Tp>,
"The allocator should already be rebound to the correct type");
if constexpr (is_array_v<_Tp>) {
static_assert(is_array_v<_Arg>,
- "Provided non-array initialization argument to __allocator_construct_at when "
+ "Provided non-array initialization argument to __allocator_construct_at_multidimensional when "
"trying to construct an array.");
using _Element = remove_extent_t<_Tp>;
@@ -449,9 +461,11 @@ constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc, _Arg const&
_Tp& __array = *__loc;
// If an exception is thrown, destroy what we have constructed so far in reverse order.
- __transaction __guard([&]() { std::__allocator_destroy_multidimensional(__elem_alloc, __array, __array + __i); });
+ auto __guard = std::__make_exception_guard([&]() {
+ std::__allocator_destroy_multidimensional(__elem_alloc, __array, __array + __i);
+ });
for (; __i != extent_v<_Tp>; ++__i) {
- std::__allocator_construct_at(__elem_alloc, std::addressof(__array[__i]), __arg[__i]);
+ std::__allocator_construct_at_multidimensional(__elem_alloc, std::addressof(__array[__i]), __arg[__i]);
}
__guard.__complete();
} else {
@@ -467,33 +481,33 @@ constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc, _Arg const&
// initialization using allocator_traits destruction. If the elements in the range are C-style
// arrays, they are initialized element-wise using allocator construction, and recursively so.
template<class _Alloc, class _BidirIter, class _Tp, class _Size = typename iterator_traits<_BidirIter>::difference_type>
-_LIBCPP_HIDE_FROM_ABI
-constexpr void __uninitialized_allocator_fill_n(_Alloc& __alloc, _BidirIter __it, _Size __n, _Tp const& __value) {
+_LIBCPP_HIDE_FROM_ABI constexpr void
+__uninitialized_allocator_fill_n_multidimensional(_Alloc& __alloc, _BidirIter __it, _Size __n, _Tp const& __value) {
using _ValueType = typename iterator_traits<_BidirIter>::value_type;
__allocator_traits_rebind_t<_Alloc, _ValueType> __value_alloc(__alloc);
_BidirIter __begin = __it;
// If an exception is thrown, destroy what we have constructed so far in reverse order.
- __transaction __guard([&]() { std::__allocator_destroy_multidimensional(__value_alloc, __begin, __it); });
+ auto __guard = std::__make_exception_guard([&]() { std::__allocator_destroy_multidimensional(__value_alloc, __begin, __it); });
for (; __n != 0; --__n, ++__it) {
- std::__allocator_construct_at(__value_alloc, std::addressof(*__it), __value);
+ std::__allocator_construct_at_multidimensional(__value_alloc, std::addressof(*__it), __value);
}
__guard.__complete();
}
-// Same as __uninitialized_allocator_fill_n, but doesn't pass any initialization argument
+// Same as __uninitialized_allocator_fill_n_multidimensional, but doesn't pass any initialization argument
// to the allocator's construct method, which results in value initialization.
-template<class _Alloc, class _BidirIter, class _Size = typename iterator_traits<_BidirIter>::difference_type>
-_LIBCPP_HIDE_FROM_ABI
-constexpr void __uninitialized_allocator_value_construct_n(_Alloc& __alloc, _BidirIter __it, _Size __n) {
+template <class _Alloc, class _BidirIter, class _Size = typename iterator_traits<_BidirIter>::difference_type>
+_LIBCPP_HIDE_FROM_ABI constexpr void
+__uninitialized_allocator_value_construct_n_multidimensional(_Alloc& __alloc, _BidirIter __it, _Size __n) {
using _ValueType = typename iterator_traits<_BidirIter>::value_type;
__allocator_traits_rebind_t<_Alloc, _ValueType> __value_alloc(__alloc);
_BidirIter __begin = __it;
// If an exception is thrown, destroy what we have constructed so far in reverse order.
- __transaction __guard([&]() { std::__allocator_destroy_multidimensional(__value_alloc, __begin, __it); });
+ auto __guard = std::__make_exception_guard([&]() { std::__allocator_destroy_multidimensional(__value_alloc, __begin, __it); });
for (; __n != 0; --__n, ++__it) {
- std::__allocator_construct_at(__value_alloc, std::addressof(*__it));
+ std::__allocator_construct_at_multidimensional(__value_alloc, std::addressof(*__it));
}
__guard.__complete();
}
@@ -532,21 +546,15 @@ private:
template <class _Alloc, class _Iter1, class _Sent1, class _Iter2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter2
__uninitialized_allocator_copy(_Alloc& __alloc, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2) {
-#ifndef _LIBCPP_NO_EXCEPTIONS
auto __destruct_first = __first2;
- try {
-#endif
+ auto __guard =
+ std::__make_exception_guard(_AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2));
while (__first1 != __last1) {
allocator_traits<_Alloc>::construct(__alloc, std::__to_address(__first2), *__first1);
++__first1;
++__first2;
}
-#ifndef _LIBCPP_NO_EXCEPTIONS
- } catch (...) {
- _AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2)();
- throw;
- }
-#endif
+ __guard.__complete();
return __first2;
}
@@ -590,10 +598,9 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter2 __uninitialized_alloc
_Alloc& __alloc, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2) {
static_assert(__is_cpp17_move_insertable<_Alloc>::value,
"The specified type does not meet the requirements of Cpp17MoveInsertable");
-#ifndef _LIBCPP_NO_EXCEPTIONS
auto __destruct_first = __first2;
- try {
-#endif
+ auto __guard =
+ std::__make_exception_guard(_AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2));
while (__first1 != __last1) {
#ifndef _LIBCPP_NO_EXCEPTIONS
allocator_traits<_Alloc>::construct(__alloc, std::__to_address(__first2), std::move_if_noexcept(*__first1));
@@ -603,12 +610,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter2 __uninitialized_alloc
++__first1;
++__first2;
}
-#ifndef _LIBCPP_NO_EXCEPTIONS
- } catch (...) {
- _AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2)();
- throw;
- }
-#endif
+ __guard.__complete();
return __first2;
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/__memory/unique_ptr.h b/contrib/libs/cxxsupp/libcxx/include/__memory/unique_ptr.h
index 2230d934be..333691f715 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__memory/unique_ptr.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__memory/unique_ptr.h
@@ -19,11 +19,27 @@
#include <__memory/allocator_traits.h> // __pointer
#include <__memory/auto_ptr.h>
#include <__memory/compressed_pair.h>
+#include <__type_traits/add_lvalue_reference.h>
+#include <__type_traits/common_type.h>
+#include <__type_traits/dependent_type.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_array.h>
+#include <__type_traits/is_assignable.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_default_constructible.h>
+#include <__type_traits/is_function.h>
+#include <__type_traits/is_pointer.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_swappable.h>
+#include <__type_traits/is_void.h>
+#include <__type_traits/remove_extent.h>
+#include <__type_traits/type_identity.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#include <cstddef>
#include <stlfwd>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -684,6 +700,25 @@ template<class _Tp, class... _Args>
#endif // _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 20
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_single
+make_unique_for_overwrite() {
+ return unique_ptr<_Tp>(new _Tp);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_array_unknown_bound
+make_unique_for_overwrite(size_t __n) {
+ return unique_ptr<_Tp>(new __remove_extent_t<_Tp>[__n]);
+}
+
+template<class _Tp, class... _Args>
+typename __unique_if<_Tp>::__unique_array_known_bound make_unique_for_overwrite(_Args&&...) = delete;
+
+#endif // _LIBCPP_STD_VER >= 20
+
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash;
template <class _Tp, class _Dp>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__memory/uses_allocator.h b/contrib/libs/cxxsupp/libcxx/include/__memory/uses_allocator.h
index 4a07a4a521..fe89704027 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__memory/uses_allocator.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__memory/uses_allocator.h
@@ -11,8 +11,8 @@
#define _LIBCPP___MEMORY_USES_ALLOCATOR_H
#include <__config>
+#include <__type_traits/is_convertible.h>
#include <cstddef>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__memory/uses_allocator_construction.h b/contrib/libs/cxxsupp/libcxx/include/__memory/uses_allocator_construction.h
index 02e0668d12..0f63b080da 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__memory/uses_allocator_construction.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__memory/uses_allocator_construction.h
@@ -14,6 +14,8 @@
#include <__memory/uses_allocator.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_same.h>
+#include <__type_traits/remove_cv.h>
+#include <__utility/declval.h>
#include <__utility/pair.h>
#include <tuple>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__memory_resource/monotonic_buffer_resource.h b/contrib/libs/cxxsupp/libcxx/include/__memory_resource/monotonic_buffer_resource.h
index 5c35a62b16..5b0d246258 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__memory_resource/monotonic_buffer_resource.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__memory_resource/monotonic_buffer_resource.h
@@ -69,7 +69,7 @@ public:
: __res_(__upstream) {
__initial_.__start_ = static_cast<char*>(__buffer);
if (__buffer != nullptr) {
- __initial_.__cur_ = static_cast<char*>(__buffer);
+ __initial_.__cur_ = static_cast<char*>(__buffer) + __buffer_size;
__initial_.__end_ = static_cast<char*>(__buffer) + __buffer_size;
} else {
__initial_.__cur_ = nullptr;
@@ -80,12 +80,13 @@ public:
monotonic_buffer_resource(const monotonic_buffer_resource&) = delete;
- _LIBCPP_HIDE_FROM_ABI ~monotonic_buffer_resource() override { release(); }
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~monotonic_buffer_resource() override { release(); }
monotonic_buffer_resource& operator=(const monotonic_buffer_resource&) = delete;
_LIBCPP_HIDE_FROM_ABI void release() {
- __initial_.__cur_ = __initial_.__start_;
+ if (__initial_.__start_ != nullptr)
+ __initial_.__cur_ = __initial_.__end_;
while (__chunks_ != nullptr) {
__chunk_footer* __next = __chunks_->__next_;
__res_->deallocate(__chunks_->__start_, __chunks_->__allocation_size(), __chunks_->__align_);
@@ -98,9 +99,9 @@ public:
protected:
void* do_allocate(size_t __bytes, size_t __alignment) override; // key function
- _LIBCPP_HIDE_FROM_ABI void do_deallocate(void*, size_t, size_t) override {}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL void do_deallocate(void*, size_t, size_t) override {}
- _LIBCPP_HIDE_FROM_ABI bool do_is_equal(const memory_resource& __other) const _NOEXCEPT override {
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL bool do_is_equal(const memory_resource& __other) const _NOEXCEPT override {
return this == std::addressof(__other);
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/__memory_resource/polymorphic_allocator.h b/contrib/libs/cxxsupp/libcxx/include/__memory_resource/polymorphic_allocator.h
index a5ca39b57e..f7b9a0b408 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__memory_resource/polymorphic_allocator.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__memory_resource/polymorphic_allocator.h
@@ -12,6 +12,7 @@
#include <__assert>
#include <__config>
#include <__memory_resource/memory_resource.h>
+#include <__utility/exception_guard.h>
#include <cstddef>
#include <limits>
#include <new>
@@ -33,8 +34,13 @@ namespace pmr {
// [mem.poly.allocator.class]
-template <class _ValueType>
+template <class _ValueType
+# if _LIBCPP_STD_VER >= 20
+ = byte
+# endif
+ >
class _LIBCPP_TEMPLATE_VIS polymorphic_allocator {
+
public:
using value_type = _ValueType;
@@ -66,6 +72,46 @@ public:
__res_->deallocate(__p, __n * sizeof(_ValueType), alignof(_ValueType));
}
+# if _LIBCPP_STD_VER >= 20
+
+ [[nodiscard]] [[using __gnu__: __alloc_size__(2), __alloc_align__(3)]] void*
+ allocate_bytes(size_t __nbytes, size_t __alignment = alignof(max_align_t)) {
+ return __res_->allocate(__nbytes, __alignment);
+ }
+
+ void deallocate_bytes(void* __ptr, size_t __nbytes, size_t __alignment = alignof(max_align_t)) {
+ __res_->deallocate(__ptr, __nbytes, __alignment);
+ }
+
+ template <class _Type>
+ [[nodiscard]] _Type* allocate_object(size_t __n = 1) {
+ if (numeric_limits<size_t>::max() / sizeof(_Type) < __n)
+ std::__throw_bad_array_new_length();
+ return static_cast<_Type*>(allocate_bytes(__n * sizeof(_Type), alignof(_Type)));
+ }
+
+ template <class _Type>
+ void deallocate_object(_Type* __ptr, size_t __n = 1) {
+ deallocate_bytes(__ptr, __n * sizeof(_Type), alignof(_Type));
+ }
+
+ template <class _Type, class... _CtorArgs>
+ [[nodiscard]] _Type* new_object(_CtorArgs&&... __ctor_args) {
+ _Type* __ptr = allocate_object<_Type>();
+ auto __guard = std::__make_exception_guard([&] { deallocate_object(__ptr); });
+ construct(__ptr, std::forward<_CtorArgs>(__ctor_args)...);
+ __guard.__complete();
+ return __ptr;
+ }
+
+ template <class _Type>
+ void delete_object(_Type* __ptr) {
+ destroy(__ptr);
+ deallocate_object(__ptr);
+ }
+
+# endif // _LIBCPP_STD_VER >= 20
+
template <class _Tp, class... _Ts>
_LIBCPP_HIDE_FROM_ABI void construct(_Tp* __p, _Ts&&... __args) {
std::__user_alloc_construct_impl(
diff --git a/contrib/libs/cxxsupp/libcxx/include/__memory_resource/synchronized_pool_resource.h b/contrib/libs/cxxsupp/libcxx/include/__memory_resource/synchronized_pool_resource.h
index 550223c7d9..1877147ca1 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__memory_resource/synchronized_pool_resource.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__memory_resource/synchronized_pool_resource.h
@@ -62,14 +62,14 @@ public:
_LIBCPP_HIDE_FROM_ABI pool_options options() const { return __unsync_.options(); }
protected:
- _LIBCPP_HIDE_FROM_ABI void* do_allocate(size_t __bytes, size_t __align) override {
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL void* do_allocate(size_t __bytes, size_t __align) override {
# if !defined(_LIBCPP_HAS_NO_THREADS)
unique_lock<mutex> __lk(__mut_);
# endif
return __unsync_.allocate(__bytes, __align);
}
- _LIBCPP_HIDE_FROM_ABI void do_deallocate(void* __p, size_t __bytes, size_t __align) override {
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL void do_deallocate(void* __p, size_t __bytes, size_t __align) override {
# if !defined(_LIBCPP_HAS_NO_THREADS)
unique_lock<mutex> __lk(__mut_);
# endif
diff --git a/contrib/libs/cxxsupp/libcxx/include/__memory_resource/unsynchronized_pool_resource.h b/contrib/libs/cxxsupp/libcxx/include/__memory_resource/unsynchronized_pool_resource.h
index 7270cf19e2..91d38aac0d 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__memory_resource/unsynchronized_pool_resource.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__memory_resource/unsynchronized_pool_resource.h
@@ -70,7 +70,7 @@ public:
unsynchronized_pool_resource(const unsynchronized_pool_resource&) = delete;
- _LIBCPP_HIDE_FROM_ABI ~unsynchronized_pool_resource() override { release(); }
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~unsynchronized_pool_resource() override { release(); }
unsynchronized_pool_resource& operator=(const unsynchronized_pool_resource&) = delete;
@@ -85,7 +85,7 @@ protected:
void do_deallocate(void* __p, size_t __bytes, size_t __align) override;
- _LIBCPP_HIDE_FROM_ABI bool do_is_equal(const memory_resource& __other) const _NOEXCEPT override {
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL bool do_is_equal(const memory_resource& __other) const _NOEXCEPT override {
return &__other == this;
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/__numeric/gcd_lcm.h b/contrib/libs/cxxsupp/libcxx/include/__numeric/gcd_lcm.h
index b3d776b3a4..5a3f81b695 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__numeric/gcd_lcm.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__numeric/gcd_lcm.h
@@ -12,8 +12,12 @@
#include <__assert>
#include <__config>
+#include <__type_traits/common_type.h>
+#include <__type_traits/is_integral.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_signed.h>
+#include <__type_traits/make_unsigned.h>
#include <limits>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__numeric/midpoint.h b/contrib/libs/cxxsupp/libcxx/include/__numeric/midpoint.h
index d8cce7929b..bac3642cbd 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__numeric/midpoint.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__numeric/midpoint.h
@@ -11,8 +11,18 @@
#define _LIBCPP___NUMERIC_MIDPOINT_H
#include <__config>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_floating_point.h>
+#include <__type_traits/is_integral.h>
+#include <__type_traits/is_null_pointer.h>
+#include <__type_traits/is_object.h>
+#include <__type_traits/is_pointer.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_void.h>
+#include <__type_traits/make_unsigned.h>
+#include <__type_traits/remove_pointer.h>
+#include <cstddef>
#include <limits>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -69,10 +79,10 @@ midpoint(_Fp __a, _Fp __b) noexcept
{
constexpr _Fp __lo = numeric_limits<_Fp>::min()*2;
constexpr _Fp __hi = numeric_limits<_Fp>::max()/2;
- return __fp_abs(__a) <= __hi && __fp_abs(__b) <= __hi ? // typical case: overflow is impossible
+ return std::__fp_abs(__a) <= __hi && std::__fp_abs(__b) <= __hi ? // typical case: overflow is impossible
(__a + __b)/2 : // always correctly rounded
- __fp_abs(__a) < __lo ? __a + __b/2 : // not safe to halve a
- __fp_abs(__b) < __lo ? __a/2 + __b : // not safe to halve b
+ std::__fp_abs(__a) < __lo ? __a + __b/2 : // not safe to halve a
+ std::__fp_abs(__b) < __lo ? __a/2 + __b : // not safe to halve b
__a/2 + __b/2; // otherwise correctly rounded
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/__random/binomial_distribution.h b/contrib/libs/cxxsupp/libcxx/include/__random/binomial_distribution.h
index 28f176e14f..7b0f055d50 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__random/binomial_distribution.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__random/binomial_distribution.h
@@ -133,9 +133,9 @@ binomial_distribution<_IntType>::param_type::param_type(result_type __t, double
if (0 < __p_ && __p_ < 1)
{
__r0_ = static_cast<result_type>((__t_ + 1) * __p_);
- __pr_ = _VSTD::exp(__libcpp_lgamma(__t_ + 1.) -
- __libcpp_lgamma(__r0_ + 1.) -
- __libcpp_lgamma(__t_ - __r0_ + 1.) + __r0_ * _VSTD::log(__p_) +
+ __pr_ = _VSTD::exp(std::__libcpp_lgamma(__t_ + 1.) -
+ std::__libcpp_lgamma(__r0_ + 1.) -
+ std::__libcpp_lgamma(__t_ - __r0_ + 1.) + __r0_ * _VSTD::log(__p_) +
(__t_ - __r0_) * _VSTD::log(1 - __p_));
__odds_ratio_ = __p_ / (1 - __p_);
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/__random/is_valid.h b/contrib/libs/cxxsupp/libcxx/include/__random/is_valid.h
index be3b61b8dc..1d65de00fb 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__random/is_valid.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__random/is_valid.h
@@ -53,7 +53,7 @@ template<> struct __libcpp_random_is_valid_inttype<__uint128_t> : true_type {};
template<class, class = void> struct __libcpp_random_is_valid_urng : false_type {};
template<class _Gp> struct __libcpp_random_is_valid_urng<_Gp, __enable_if_t<
is_unsigned<typename _Gp::result_type>::value &&
- _IsSame<decltype(declval<_Gp&>()()), typename _Gp::result_type>::value
+ _IsSame<decltype(std::declval<_Gp&>()()), typename _Gp::result_type>::value
> > : true_type {};
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/include/__random/uniform_int_distribution.h b/contrib/libs/cxxsupp/libcxx/include/__random/uniform_int_distribution.h
index e9930e8575..b7db8a3f9c 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__random/uniform_int_distribution.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__random/uniform_int_distribution.h
@@ -9,7 +9,6 @@
#ifndef _LIBCPP___RANDOM_UNIFORM_INT_DISTRIBUTION_H
#define _LIBCPP___RANDOM_UNIFORM_INT_DISTRIBUTION_H
-#include <__bits>
#include <__config>
#include <__random/is_valid.h>
#include <__random/log2.h>
@@ -242,7 +241,7 @@ _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
typedef __independent_bits_engine<_URNG, _UIntType> _Eng;
if (_Rp == 0)
return static_cast<result_type>(_Eng(__g, _Dt)());
- size_t __w = _Dt - __countl_zero(_Rp) - 1;
+ size_t __w = _Dt - std::__countl_zero(_Rp) - 1;
if ((_Rp & (numeric_limits<_UIntType>::max() >> (_Dt - __w))) != 0)
++__w;
_Eng __e(__g, __w);
diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/access.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/access.h
index 87392a163e..e48a71adf7 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__ranges/access.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/access.h
@@ -15,8 +15,13 @@
#include <__iterator/concepts.h>
#include <__iterator/readable_traits.h>
#include <__ranges/enable_borrowed_range.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/remove_cvref.h>
+#include <__type_traits/remove_reference.h>
#include <__utility/auto_cast.h>
-#include <type_traits>
+#include <__utility/declval.h>
+#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -100,7 +105,7 @@ inline namespace __cpo {
namespace ranges {
template <class _Tp>
- using iterator_t = decltype(ranges::begin(declval<_Tp&>()));
+ using iterator_t = decltype(ranges::begin(std::declval<_Tp&>()));
} // namespace ranges
// [range.access.end]
diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/all.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/all.h
index c30c9e32e4..511f7b3b46 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__ranges/all.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/all.h
@@ -73,7 +73,7 @@ inline namespace __cpo {
} // namespace __cpo
template<ranges::viewable_range _Range>
-using all_t = decltype(views::all(declval<_Range>()));
+using all_t = decltype(views::all(std::declval<_Range>()));
} // namespace ranges::views
diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/as_rvalue_view.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/as_rvalue_view.h
new file mode 100644
index 0000000000..422d8a8e08
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/as_rvalue_view.h
@@ -0,0 +1,137 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___RANGES_AS_RVALUE_H
+#define _LIBCPP___RANGES_AS_RVALUE_H
+
+#include <__concepts/constructible.h>
+#include <__concepts/same_as.h>
+#include <__config>
+#include <__iterator/move_iterator.h>
+#include <__iterator/move_sentinel.h>
+#include <__ranges/access.h>
+#include <__ranges/all.h>
+#include <__ranges/concepts.h>
+#include <__ranges/enable_borrowed_range.h>
+#include <__ranges/range_adaptor.h>
+#include <__ranges/size.h>
+#include <__ranges/view_interface.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 23
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+template <view _View>
+ requires input_range<_View>
+class as_rvalue_view : public view_interface<as_rvalue_view<_View>> {
+ _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
+
+public:
+ _LIBCPP_HIDE_FROM_ABI as_rvalue_view()
+ requires default_initializable<_View>
+ = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit as_rvalue_view(_View __base) : __base_(std::move(__base)) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
+ requires copy_constructible<_View>
+ {
+ return __base_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
+ requires(!__simple_view<_View>)
+ {
+ return move_iterator(ranges::begin(__base_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
+ requires range<const _View>
+ {
+ return move_iterator(ranges::begin(__base_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end()
+ requires(!__simple_view<_View>)
+ {
+ if constexpr (common_range<_View>) {
+ return move_iterator(ranges::end(__base_));
+ } else {
+ return move_sentinel(ranges::end(__base_));
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
+ requires range<const _View>
+ {
+ if constexpr (common_range<const _View>) {
+ return move_iterator(ranges::end(__base_));
+ } else {
+ return move_sentinel(ranges::end(__base_));
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto size()
+ requires sized_range<_View>
+ {
+ return ranges::size(__base_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
+ requires sized_range<const _View>
+ {
+ return ranges::size(__base_);
+ }
+};
+
+template <class _Range>
+as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
+
+template <class _View>
+inline constexpr bool enable_borrowed_range<as_rvalue_view<_View>> = enable_borrowed_range<_View>;
+
+namespace views {
+namespace __as_rvalue {
+struct __fn : __range_adaptor_closure<__fn> {
+ template <class _Range>
+ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
+ noexcept(noexcept(/**/ as_rvalue_view(std::forward<_Range>(__range))))
+ -> decltype(/*--*/ as_rvalue_view(std::forward<_Range>(__range))) {
+ return /*-------------*/ as_rvalue_view(std::forward<_Range>(__range));
+ }
+
+ template <class _Range>
+ requires same_as<range_rvalue_reference_t<_Range>, range_reference_t<_Range>>
+ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
+ noexcept(noexcept(/**/ views::all(std::forward<_Range>(__range))))
+ -> decltype(/*--*/ views::all(std::forward<_Range>(__range))) {
+ return /*-------------*/ views::all(std::forward<_Range>(__range));
+ }
+};
+} // namespace __as_rvalue
+
+inline namespace __cpo {
+constexpr auto as_rvalue = __as_rvalue::__fn{};
+} // namespace __cpo
+} // namespace views
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 23
+
+#endif // _LIBCPP___RANGES_AS_RVALUE_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/concepts.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/concepts.h
index 739e14184a..e34c545578 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__ranges/concepts.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/concepts.h
@@ -24,8 +24,12 @@
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/enable_view.h>
#include <__ranges/size.h>
+#include <__type_traits/add_pointer.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/remove_cvref.h>
+#include <__type_traits/remove_reference.h>
+#include <__utility/declval.h>
#include <initializer_list>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -55,7 +59,7 @@ namespace ranges {
// `iterator_t` defined in <__ranges/access.h>
template <range _Rp>
- using sentinel_t = decltype(ranges::end(declval<_Rp&>()));
+ using sentinel_t = decltype(ranges::end(std::declval<_Rp&>()));
template <range _Rp>
using range_difference_t = iter_difference_t<iterator_t<_Rp>>;
@@ -74,7 +78,7 @@ namespace ranges {
concept sized_range = range<_Tp> && requires(_Tp& __t) { ranges::size(__t); };
template<sized_range _Rp>
- using range_size_t = decltype(ranges::size(declval<_Rp&>()));
+ using range_size_t = decltype(ranges::size(std::declval<_Rp&>()));
// `disable_sized_range` defined in `<__ranges/size.h>`
diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/dangling.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/dangling.h
index 525b5ff0aa..c10453454d 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__ranges/dangling.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/dangling.h
@@ -13,7 +13,7 @@
#include <__config>
#include <__ranges/access.h>
#include <__ranges/concepts.h>
-#include <type_traits>
+#include <__type_traits/conditional.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/data.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/data.h
index cadbfc8cf3..0ac25b52c7 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__ranges/data.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/data.h
@@ -16,8 +16,13 @@
#include <__iterator/iterator_traits.h>
#include <__memory/pointer_traits.h>
#include <__ranges/access.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_object.h>
+#include <__type_traits/is_pointer.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/remove_pointer.h>
+#include <__type_traits/remove_reference.h>
#include <__utility/auto_cast.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/elements_view.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/elements_view.h
new file mode 100644
index 0000000000..997380ee9c
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/elements_view.h
@@ -0,0 +1,413 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___RANGES_ELEMENTS_VIEW_H
+#define _LIBCPP___RANGES_ELEMENTS_VIEW_H
+
+#include <__compare/three_way_comparable.h>
+#include <__concepts/constructible.h>
+#include <__concepts/convertible_to.h>
+#include <__concepts/derived_from.h>
+#include <__concepts/equality_comparable.h>
+#include <__config>
+#include <__fwd/get.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__ranges/access.h>
+#include <__ranges/all.h>
+#include <__ranges/concepts.h>
+#include <__ranges/enable_borrowed_range.h>
+#include <__ranges/range_adaptor.h>
+#include <__ranges/size.h>
+#include <__ranges/view_interface.h>
+#include <__tuple_dir/tuple_element.h>
+#include <__tuple_dir/tuple_like.h>
+#include <__tuple_dir/tuple_size.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/maybe_const.h>
+#include <__type_traits/remove_cv.h>
+#include <__type_traits/remove_cvref.h>
+#include <__type_traits/remove_reference.h>
+#include <__utility/declval.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+namespace ranges {
+
+template <class _Tp, size_t _Np>
+concept __has_tuple_element = __tuple_like<_Tp> && _Np < tuple_size<_Tp>::value;
+
+template <class _Tp, size_t _Np>
+concept __returnable_element = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Np, _Tp>>;
+
+template <input_range _View, size_t _Np>
+ requires view<_View> && __has_tuple_element<range_value_t<_View>, _Np> &&
+ __has_tuple_element<remove_reference_t<range_reference_t<_View>>, _Np> &&
+ __returnable_element<range_reference_t<_View>, _Np>
+class elements_view : public view_interface<elements_view<_View, _Np>> {
+private:
+ template <bool>
+ class __iterator;
+
+ template <bool>
+ class __sentinel;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI elements_view()
+ requires default_initializable<_View>
+ = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit elements_view(_View __base) : __base_(std::move(__base)) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
+ requires copy_constructible<_View>
+ {
+ return __base_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
+ requires(!__simple_view<_View>)
+ {
+ return __iterator</*_Const=*/false>(ranges::begin(__base_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
+ requires range<const _View>
+ {
+ return __iterator</*_Const=*/true>(ranges::begin(__base_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end()
+ requires(!__simple_view<_View> && !common_range<_View>)
+ {
+ return __sentinel</*_Const=*/false>{ranges::end(__base_)};
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end()
+ requires(!__simple_view<_View> && common_range<_View>)
+ {
+ return __iterator</*_Const=*/false>{ranges::end(__base_)};
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
+ requires range<const _View>
+ {
+ return __sentinel</*_Const=*/true>{ranges::end(__base_)};
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
+ requires common_range<const _View>
+ {
+ return __iterator</*_Const=*/true>{ranges::end(__base_)};
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto size()
+ requires sized_range<_View>
+ {
+ return ranges::size(__base_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
+ requires sized_range<const _View>
+ {
+ return ranges::size(__base_);
+ }
+
+private:
+ _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
+};
+
+template <class, size_t>
+struct __elements_view_iterator_category_base {};
+
+template <forward_range _Base, size_t _Np>
+struct __elements_view_iterator_category_base<_Base, _Np> {
+ static consteval auto __get_iterator_category() {
+ using _Result = decltype(std::get<_Np>(*std::declval<iterator_t<_Base>>()));
+ using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
+
+ if constexpr (!is_lvalue_reference_v<_Result>) {
+ return input_iterator_tag{};
+ } else if constexpr (derived_from<_Cat, random_access_iterator_tag>) {
+ return random_access_iterator_tag{};
+ } else {
+ return _Cat{};
+ }
+ }
+
+ using iterator_category = decltype(__get_iterator_category());
+};
+
+template <input_range _View, size_t _Np>
+ requires view<_View> && __has_tuple_element<range_value_t<_View>, _Np> &&
+ __has_tuple_element<remove_reference_t<range_reference_t<_View>>, _Np> &&
+ __returnable_element<range_reference_t<_View>, _Np>
+template <bool _Const>
+class elements_view<_View, _Np>::__iterator
+ : public __elements_view_iterator_category_base<__maybe_const<_Const, _View>, _Np> {
+ template <bool>
+ friend class __iterator;
+
+ template <bool>
+ friend class __sentinel;
+
+ using _Base = __maybe_const<_Const, _View>;
+
+ iterator_t<_Base> __current_ = iterator_t<_Base>();
+
+ _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __get_element(const iterator_t<_Base>& __i) {
+ if constexpr (is_reference_v<range_reference_t<_Base>>) {
+ return std::get<_Np>(*__i);
+ } else {
+ using _Element = remove_cv_t<tuple_element_t<_Np, range_reference_t<_Base>>>;
+ return static_cast<_Element>(std::get<_Np>(*__i));
+ }
+ }
+
+ static consteval auto __get_iterator_concept() {
+ if constexpr (random_access_range<_Base>) {
+ return random_access_iterator_tag{};
+ } else if constexpr (bidirectional_range<_Base>) {
+ return bidirectional_iterator_tag{};
+ } else if constexpr (forward_range<_Base>) {
+ return forward_iterator_tag{};
+ } else {
+ return input_iterator_tag{};
+ }
+ }
+
+public:
+ using iterator_concept = decltype(__get_iterator_concept());
+ using value_type = remove_cvref_t<tuple_element_t<_Np, range_value_t<_Base>>>;
+ using difference_type = range_difference_t<_Base>;
+
+ _LIBCPP_HIDE_FROM_ABI __iterator()
+ requires default_initializable<iterator_t<_Base>>
+ = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(iterator_t<_Base> __current) : __current_(std::move(__current)) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator<!_Const> __i)
+ requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>>
+ : __current_(std::move(__i.__current_)) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr const iterator_t<_Base>& base() const& noexcept { return __current_; }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() && { return std::move(__current_); }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { return __get_element(__current_); }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
+ ++__current_;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++__current_; }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int)
+ requires forward_range<_Base>
+ {
+ auto temp = *this;
+ ++__current_;
+ return temp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--()
+ requires bidirectional_range<_Base>
+ {
+ --__current_;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int)
+ requires bidirectional_range<_Base>
+ {
+ auto temp = *this;
+ --__current_;
+ return temp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n)
+ requires random_access_range<_Base>
+ {
+ __current_ += __n;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __n)
+ requires random_access_range<_Base>
+ {
+ __current_ -= __n;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](difference_type __n) const
+ requires random_access_range<_Base>
+ {
+ return __get_element(__current_ + __n);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
+ requires equality_comparable<iterator_t<_Base>>
+ {
+ return __x.__current_ == __y.__current_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
+ requires random_access_range<_Base>
+ {
+ return __x.__current_ < __y.__current_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
+ requires random_access_range<_Base>
+ {
+ return __y < __x;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
+ requires random_access_range<_Base>
+ {
+ return !(__y < __x);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
+ requires random_access_range<_Base>
+ {
+ return !(__x < __y);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
+ requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
+ {
+ return __x.__current_ <=> __y.__current_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(const __iterator& __x, difference_type __y)
+ requires random_access_range<_Base>
+ {
+ return __iterator{__x} += __y;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __x, const __iterator& __y)
+ requires random_access_range<_Base>
+ {
+ return __y + __x;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(const __iterator& __x, difference_type __y)
+ requires random_access_range<_Base>
+ {
+ return __iterator{__x} -= __y;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
+ requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
+ {
+ return __x.__current_ - __y.__current_;
+ }
+};
+
+template <input_range _View, size_t _Np>
+ requires view<_View> && __has_tuple_element<range_value_t<_View>, _Np> &&
+ __has_tuple_element<remove_reference_t<range_reference_t<_View>>, _Np> &&
+ __returnable_element<range_reference_t<_View>, _Np>
+template <bool _Const>
+class elements_view<_View, _Np>::__sentinel {
+private:
+ using _Base = __maybe_const<_Const, _View>;
+ _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>();
+
+ template <bool>
+ friend class __sentinel;
+
+ template <bool _AnyConst>
+ _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __get_current(const __iterator<_AnyConst>& __iter) {
+ return (__iter.__current_);
+ }
+
+public:
+ _LIBCPP_HIDE_FROM_ABI __sentinel() = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __other)
+ requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
+ : __end_(std::move(__other.__end_)) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Base> base() const { return __end_; }
+
+ template <bool _OtherConst>
+ requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
+ return __get_current(__x) == __y.__end_;
+ }
+
+ template <bool _OtherConst>
+ requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
+ _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
+ operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
+ return __get_current(__x) - __y.__end_;
+ }
+
+ template <bool _OtherConst>
+ requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
+ _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
+ operator-(const __sentinel& __x, const __iterator<_OtherConst>& __y) {
+ return __x.__end_ - __get_current(__y);
+ }
+};
+
+template <class _Tp, size_t _Np>
+inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Np>> = enable_borrowed_range<_Tp>;
+
+template <class _Tp>
+using keys_view = elements_view<_Tp, 0>;
+template <class _Tp>
+using values_view = elements_view<_Tp, 1>;
+
+namespace views {
+namespace __elements {
+
+template <size_t _Np>
+struct __fn : __range_adaptor_closure<__fn<_Np>> {
+ template <class _Range>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
+ /**/ noexcept(noexcept(elements_view<all_t<_Range&&>, _Np>(std::forward<_Range>(__range))))
+ /*------*/ -> decltype(elements_view<all_t<_Range&&>, _Np>(std::forward<_Range>(__range))) {
+ /*-------------*/ return elements_view<all_t<_Range&&>, _Np>(std::forward<_Range>(__range));
+ }
+};
+} // namespace __elements
+
+inline namespace __cpo {
+template <size_t _Np>
+inline constexpr auto elements = __elements::__fn<_Np>{};
+inline constexpr auto keys = elements<0>;
+inline constexpr auto values = elements<1>;
+} // namespace __cpo
+} // namespace views
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_ELEMENTS_VIEW_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/empty.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/empty.h
index 2370f1373c..8a1c75c0ba 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__ranges/empty.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/empty.h
@@ -15,7 +15,6 @@
#include <__iterator/concepts.h>
#include <__ranges/access.h>
#include <__ranges/size.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/enable_view.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/enable_view.h
index 2dc4752ff4..c85064b915 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__ranges/enable_view.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/enable_view.h
@@ -13,7 +13,9 @@
#include <__concepts/derived_from.h>
#include <__concepts/same_as.h>
#include <__config>
-#include <type_traits>
+#include <__type_traits/is_class.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/remove_cv.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/filter_view.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/filter_view.h
index 0622da54ef..e14a9abeb9 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__ranges/filter_view.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/filter_view.h
@@ -120,6 +120,7 @@ namespace ranges {
template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
requires view<_View> && is_object_v<_Pred>
class filter_view<_View, _Pred>::__iterator : public __filter_iterator_category<_View> {
+
public:
_LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_View> __current_ = iterator_t<_View>();
_LIBCPP_NO_UNIQUE_ADDRESS filter_view* __parent_ = nullptr;
@@ -224,8 +225,8 @@ namespace ranges {
_LIBCPP_HIDE_FROM_ABI
constexpr sentinel_t<_View> base() const { return __end_; }
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(__iterator const& __x, __sentinel const& __y) {
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool
+ operator==(__iterator const& __x, __sentinel const& __y) {
return __x.__current_ == __y.__end_;
}
};
diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/istream_view.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/istream_view.h
index 4113b329b2..66cd915276 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__ranges/istream_view.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/istream_view.h
@@ -39,6 +39,8 @@ concept __stream_extractable = requires(basic_istream<_CharT, _Traits>& __is, _V
template <movable _Val, class _CharT, class _Traits = char_traits<_CharT>>
requires default_initializable<_Val> && __stream_extractable<_Val, _CharT, _Traits>
class basic_istream_view : public view_interface<basic_istream_view<_Val, _CharT, _Traits>> {
+ class __iterator;
+
public:
_LIBCPP_HIDE_FROM_ABI constexpr explicit basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
: __stream_(std::addressof(__stream)) {}
@@ -51,8 +53,6 @@ public:
_LIBCPP_HIDE_FROM_ABI constexpr default_sentinel_t end() const noexcept { return default_sentinel; }
private:
- class __iterator;
-
basic_istream<_CharT, _Traits>* __stream_;
_LIBCPP_NO_UNIQUE_ADDRESS _Val __value_ = _Val();
};
@@ -65,7 +65,8 @@ public:
using difference_type = ptrdiff_t;
using value_type = _Val;
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(basic_istream_view& __parent) noexcept
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(
+ basic_istream_view<_Val, _CharT, _Traits>& __parent) noexcept
: __parent_(std::addressof(__parent)) {}
__iterator(const __iterator&) = delete;
@@ -88,7 +89,7 @@ public:
}
private:
- basic_istream_view* __parent_;
+ basic_istream_view<_Val, _CharT, _Traits>* __parent_;
_LIBCPP_HIDE_FROM_ABI constexpr basic_istream<_CharT, _Traits>* __get_parent_stream() const {
return __parent_->__stream_;
@@ -98,10 +99,10 @@ private:
template <class _Val>
using istream_view = basic_istream_view<_Val, char>;
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <class _Val>
using wistream_view = basic_istream_view<_Val, wchar_t>;
-#endif
+# endif
namespace views {
namespace __istream {
@@ -127,7 +128,7 @@ struct __fn {
inline namespace __cpo {
template <class _Tp>
- inline constexpr auto istream = __istream::__fn<_Tp>{};
+inline constexpr auto istream = __istream::__fn<_Tp>{};
} // namespace __cpo
} // namespace views
diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/join_view.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/join_view.h
index 293926cc12..b5a4c4e733 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__ranges/join_view.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/join_view.h
@@ -20,9 +20,12 @@
#include <__iterator/iter_move.h>
#include <__iterator/iter_swap.h>
#include <__iterator/iterator_traits.h>
+#include <__iterator/iterator_with_data.h>
+#include <__iterator/segmented_iterator.h>
#include <__ranges/access.h>
#include <__ranges/all.h>
#include <__ranges/concepts.h>
+#include <__ranges/empty.h>
#include <__ranges/non_propagating_cache.h>
#include <__ranges/range_adaptor.h>
#include <__ranges/view_interface.h>
@@ -37,6 +40,9 @@
_LIBCPP_BEGIN_NAMESPACE_STD
+// Note: `join_view` is still marked experimental because there is an ABI-breaking change that affects `join_view` in
+// the pipeline (https://isocpp.org/files/papers/D2770R0.html).
+// TODO: make `join_view` non-experimental once D2770 is implemented.
#if _LIBCPP_STD_VER > 17
namespace ranges {
@@ -71,8 +77,12 @@ namespace ranges {
using _InnerRange = range_reference_t<_View>;
template<bool> struct __iterator;
+
template<bool> struct __sentinel;
+ template <class>
+ friend struct std::__segmented_iterator_traits;
+
static constexpr bool _UseCache = !is_reference_v<_InnerRange>;
using _Cache = _If<_UseCache, __non_propagating_cache<remove_cvref_t<_InnerRange>>, __empty_cache>;
_LIBCPP_NO_UNIQUE_ADDRESS _Cache __cache_;
@@ -141,11 +151,13 @@ namespace ranges {
template<input_range _View>
requires view<_View> && input_range<range_reference_t<_View>>
- template<bool _Const> struct join_view<_View>::__sentinel {
- template<bool> friend struct __sentinel;
+ template<bool _Const>
+ struct join_view<_View>::__sentinel {
+ template<bool>
+ friend struct __sentinel;
private:
- using _Parent = __maybe_const<_Const, join_view>;
+ using _Parent = __maybe_const<_Const, join_view<_View>>;
using _Base = __maybe_const<_Const, _View>;
sentinel_t<_Base> __end_ = sentinel_t<_Base>();
@@ -170,18 +182,29 @@ namespace ranges {
}
};
+ // https://reviews.llvm.org/D142811#inline-1383022
+ // To simplify the segmented iterator traits specialization,
+ // make the iterator `final`
template<input_range _View>
requires view<_View> && input_range<range_reference_t<_View>>
- template<bool _Const> struct join_view<_View>::__iterator
+ template<bool _Const>
+ struct join_view<_View>::__iterator final
: public __join_view_iterator_category<__maybe_const<_Const, _View>> {
- template<bool> friend struct __iterator;
+ template<bool>
+ friend struct __iterator;
+
+ template <class>
+ friend struct std::__segmented_iterator_traits;
+
+ static constexpr bool __is_join_view_iterator = true;
private:
- using _Parent = __maybe_const<_Const, join_view>;
+ using _Parent = __maybe_const<_Const, join_view<_View>>;
using _Base = __maybe_const<_Const, _View>;
using _Outer = iterator_t<_Base>;
using _Inner = iterator_t<range_reference_t<_Base>>;
+ using _InnerRange = range_reference_t<_View>;
static constexpr bool __ref_is_glvalue = is_reference_v<range_reference_t<_Base>>;
@@ -210,6 +233,9 @@ namespace ranges {
__inner_.reset();
}
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator(_Parent* __parent, _Outer __outer, _Inner __inner)
+ : __outer_(std::move(__outer)), __inner_(std::move(__inner)), __parent_(__parent) {}
+
public:
using iterator_concept = _If<
__ref_is_glvalue && bidirectional_range<_Base> && bidirectional_range<range_reference_t<_Base>> &&
@@ -365,7 +391,51 @@ inline namespace __cpo {
} // namespace views
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17
+template <class _JoinViewIterator>
+ requires(_JoinViewIterator::__is_join_view_iterator &&
+ ranges::common_range<typename _JoinViewIterator::_Parent> &&
+ __is_cpp17_random_access_iterator<typename _JoinViewIterator::_Outer>::value &&
+ __is_cpp17_random_access_iterator<typename _JoinViewIterator::_Inner>::value)
+struct __segmented_iterator_traits<_JoinViewIterator> {
+
+ using __segment_iterator =
+ _LIBCPP_NODEBUG __iterator_with_data<typename _JoinViewIterator::_Outer, typename _JoinViewIterator::_Parent*>;
+ using __local_iterator = typename _JoinViewIterator::_Inner;
+
+ // TODO: Would it make sense to enable the optimization for other iterator types?
+
+ static constexpr _LIBCPP_HIDE_FROM_ABI __segment_iterator __segment(_JoinViewIterator __iter) {
+ if (ranges::empty(__iter.__parent_->__base_))
+ return {};
+ if (!__iter.__inner_.has_value())
+ return __segment_iterator(--__iter.__outer_, __iter.__parent_);
+ return __segment_iterator(__iter.__outer_, __iter.__parent_);
+ }
+
+ static constexpr _LIBCPP_HIDE_FROM_ABI __local_iterator __local(_JoinViewIterator __iter) {
+ if (ranges::empty(__iter.__parent_->__base_))
+ return {};
+ if (!__iter.__inner_.has_value())
+ return ranges::end(*--__iter.__outer_);
+ return *__iter.__inner_;
+ }
+
+ static constexpr _LIBCPP_HIDE_FROM_ABI __local_iterator __begin(__segment_iterator __iter) {
+ return ranges::begin(*__iter.__get_iter());
+ }
+
+ static constexpr _LIBCPP_HIDE_FROM_ABI __local_iterator __end(__segment_iterator __iter) {
+ return ranges::end(*__iter.__get_iter());
+ }
+
+ static constexpr _LIBCPP_HIDE_FROM_ABI _JoinViewIterator
+ __compose(__segment_iterator __seg_iter, __local_iterator __local_iter) {
+ return _JoinViewIterator(
+ std::move(__seg_iter).__get_data(), std::move(__seg_iter).__get_iter(), std::move(__local_iter));
+ }
+};
+
+#endif // #if _LIBCPP_STD_VER > 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/ref_view.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/ref_view.h
index e949f75344..1e5f7466f3 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__ranges/ref_view.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/ref_view.h
@@ -47,7 +47,7 @@ namespace ranges {
public:
template<class _Tp>
requires __different_from<_Tp, ref_view> &&
- convertible_to<_Tp, _Range&> && requires { __fun(declval<_Tp>()); }
+ convertible_to<_Tp, _Range&> && requires { __fun(std::declval<_Tp>()); }
_LIBCPP_HIDE_FROM_ABI
constexpr ref_view(_Tp&& __t)
: __range_(std::addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/size.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/size.h
index 720e3d4fd2..0ac8d63063 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__ranges/size.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/size.h
@@ -16,9 +16,13 @@
#include <__iterator/concepts.h>
#include <__iterator/iterator_traits.h>
#include <__ranges/access.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/make_signed.h>
+#include <__type_traits/make_unsigned.h>
+#include <__type_traits/remove_cvref.h>
#include <__utility/auto_cast.h>
+#include <__utility/declval.h>
#include <cstddef>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -67,7 +71,7 @@ concept __difference =
__class_or_enum<remove_cvref_t<_Tp>> &&
requires(_Tp&& __t) {
{ ranges::begin(__t) } -> forward_iterator;
- { ranges::end(__t) } -> sized_sentinel_for<decltype(ranges::begin(declval<_Tp>()))>;
+ { ranges::end(__t) } -> sized_sentinel_for<decltype(ranges::begin(std::declval<_Tp>()))>;
};
struct __fn {
diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/split_view.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/split_view.h
new file mode 100644
index 0000000000..6ebe5a43ed
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/split_view.h
@@ -0,0 +1,226 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___RANGES_SPLIT_VIEW_H
+#define _LIBCPP___RANGES_SPLIT_VIEW_H
+
+#include <__algorithm/ranges_search.h>
+#include <__concepts/constructible.h>
+#include <__config>
+#include <__functional/bind_back.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/indirectly_comparable.h>
+#include <__iterator/iterator_traits.h>
+#include <__memory/addressof.h>
+#include <__ranges/access.h>
+#include <__ranges/all.h>
+#include <__ranges/concepts.h>
+#include <__ranges/empty.h>
+#include <__ranges/non_propagating_cache.h>
+#include <__ranges/range_adaptor.h>
+#include <__ranges/single_view.h>
+#include <__ranges/subrange.h>
+#include <__ranges/view_interface.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+namespace ranges {
+
+template <forward_range _View, forward_range _Pattern>
+ requires view<_View> && view<_Pattern> &&
+ indirectly_comparable<iterator_t<_View>, iterator_t<_Pattern>, ranges::equal_to>
+class split_view : public view_interface<split_view<_View, _Pattern>> {
+private:
+ _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
+ _LIBCPP_NO_UNIQUE_ADDRESS _Pattern __pattern_ = _Pattern();
+ using _Cache = __non_propagating_cache<subrange<iterator_t<_View>>>;
+ _Cache __cached_begin_ = _Cache();
+
+ template <class, class>
+ friend struct __iterator;
+
+ template <class, class>
+ friend struct __sentinel;
+
+ struct __iterator;
+ struct __sentinel;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr subrange<iterator_t<_View>> __find_next(iterator_t<_View> __it) {
+ auto [__begin, __end] = ranges::search(subrange(__it, ranges::end(__base_)), __pattern_);
+ if (__begin != ranges::end(__base_) && ranges::empty(__pattern_)) {
+ ++__begin;
+ ++__end;
+ }
+ return {__begin, __end};
+ }
+
+public:
+ _LIBCPP_HIDE_FROM_ABI split_view()
+ requires default_initializable<_View> && default_initializable<_Pattern>
+ = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr split_view(_View __base, _Pattern __pattern)
+ : __base_(std::move(__base)), __pattern_(std::move((__pattern))) {}
+
+ template <forward_range _Range>
+ requires constructible_from<_View, views::all_t<_Range>> &&
+ constructible_from<_Pattern, single_view<range_value_t<_Range>>>
+ _LIBCPP_HIDE_FROM_ABI constexpr split_view(_Range&& __range, range_value_t<_Range> __elem)
+ : __base_(views::all(std::forward<_Range>(__range))), __pattern_(views::single(std::move(__elem))) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
+ requires copy_constructible<_View>
+ {
+ return __base_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() {
+ if (!__cached_begin_.__has_value()) {
+ __cached_begin_.__emplace(__find_next(ranges::begin(__base_)));
+ }
+ return {*this, ranges::begin(__base_), *__cached_begin_};
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end() {
+ if constexpr (common_range<_View>) {
+ return __iterator{*this, ranges::end(__base_), {}};
+ } else {
+ return __sentinel{*this};
+ }
+ }
+};
+
+template <class _Range, class _Pattern>
+split_view(_Range&&, _Pattern&&) -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
+
+template <forward_range _Range>
+split_view(_Range&&, range_value_t<_Range>) -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
+
+template <forward_range _View, forward_range _Pattern>
+ requires view<_View> && view<_Pattern> &&
+ indirectly_comparable<iterator_t<_View>, iterator_t<_Pattern>, ranges::equal_to>
+struct split_view<_View, _Pattern>::__iterator {
+private:
+ split_view* __parent_ = nullptr;
+ _LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_View> __cur_ = iterator_t<_View>();
+ _LIBCPP_NO_UNIQUE_ADDRESS subrange<iterator_t<_View>> __next_ = subrange<iterator_t<_View>>();
+ bool __trailing_empty_ = false;
+
+ friend struct __sentinel;
+
+public:
+ using iterator_concept = forward_iterator_tag;
+ using iterator_category = input_iterator_tag;
+ using value_type = subrange<iterator_t<_View>>;
+ using difference_type = range_difference_t<_View>;
+
+ _LIBCPP_HIDE_FROM_ABI __iterator() = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator(
+ split_view<_View, _Pattern>& __parent, iterator_t<_View> __current, subrange<iterator_t<_View>> __next)
+ : __parent_(std::addressof(__parent)), __cur_(std::move(__current)), __next_(std::move(__next)) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> base() const { return __cur_; }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr value_type operator*() const { return {__cur_, __next_.begin()}; }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
+ __cur_ = __next_.begin();
+ if (__cur_ != ranges::end(__parent_->__base_)) {
+ __cur_ = __next_.end();
+ if (__cur_ == ranges::end(__parent_->__base_)) {
+ __trailing_empty_ = true;
+ __next_ = {__cur_, __cur_};
+ } else {
+ __next_ = __parent_->__find_next(__cur_);
+ }
+ } else {
+ __trailing_empty_ = false;
+ }
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) {
+ auto __tmp = *this;
+ ++*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) {
+ return __x.__cur_ == __y.__cur_ && __x.__trailing_empty_ == __y.__trailing_empty_;
+ }
+};
+
+template <forward_range _View, forward_range _Pattern>
+ requires view<_View> && view<_Pattern> &&
+ indirectly_comparable<iterator_t<_View>, iterator_t<_Pattern>, ranges::equal_to>
+struct split_view<_View, _Pattern>::__sentinel {
+private:
+ _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_View> __end_ = sentinel_t<_View>();
+
+ _LIBCPP_HIDE_FROM_ABI static constexpr bool __equals(const __iterator& __x, const __sentinel& __y) {
+ return __x.__cur_ == __y.__end_ && !__x.__trailing_empty_;
+ }
+
+public:
+ _LIBCPP_HIDE_FROM_ABI __sentinel() = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(split_view<_View, _Pattern>& __parent)
+ : __end_(ranges::end(__parent.__base_)) {}
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) {
+ return __equals(__x, __y);
+ }
+};
+
+namespace views {
+namespace __split_view {
+struct __fn : __range_adaptor_closure<__fn> {
+ // clang-format off
+ template <class _Range, class _Pattern>
+ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Range&& __range, _Pattern&& __pattern) const
+ noexcept(noexcept(split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern))))
+ -> decltype( split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern)))
+ { return split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern)); }
+ // clang-format on
+
+ template <class _Pattern>
+ requires constructible_from<decay_t<_Pattern>, _Pattern>
+ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Pattern&& __pattern) const
+ noexcept(is_nothrow_constructible_v<decay_t<_Pattern>, _Pattern>) {
+ return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Pattern>(__pattern)));
+ }
+};
+} // namespace __split_view
+
+inline namespace __cpo {
+inline constexpr auto split = __split_view::__fn{};
+} // namespace __cpo
+} // namespace views
+
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_SPLIT_VIEW_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/subrange.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/subrange.h
index 3efcd9602a..2d9e4cc7e5 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__ranges/subrange.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/subrange.h
@@ -18,6 +18,7 @@
#include <__concepts/different_from.h>
#include <__config>
#include <__fwd/get.h>
+#include <__fwd/subrange.h>
#include <__iterator/advance.h>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
@@ -28,10 +29,18 @@
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/size.h>
#include <__ranges/view_interface.h>
-#include <__tuple/tuple_element.h>
-#include <__tuple/tuple_size.h>
+#include <__tuple_dir/pair_like.h>
+#include <__tuple_dir/tuple_element.h>
+#include <__tuple_dir/tuple_size.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_pointer.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/make_unsigned.h>
+#include <__type_traits/remove_const.h>
+#include <__type_traits/remove_pointer.h>
#include <__utility/move.h>
-#include <type_traits>
+#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -52,17 +61,6 @@ namespace ranges {
convertible_to<_From, _To> &&
!__uses_nonqualification_pointer_conversion<decay_t<_From>, decay_t<_To>>;
- template<class _Tp>
- concept __pair_like =
- !is_reference_v<_Tp> && requires(_Tp __t) {
- typename tuple_size<_Tp>::type; // Ensures `tuple_size<T>` is complete.
- requires derived_from<tuple_size<_Tp>, integral_constant<size_t, 2>>;
- typename tuple_element_t<0, remove_const_t<_Tp>>;
- typename tuple_element_t<1, remove_const_t<_Tp>>;
- { std::get<0>(__t) } -> convertible_to<const tuple_element_t<0, _Tp>&>;
- { std::get<1>(__t) } -> convertible_to<const tuple_element_t<1, _Tp>&>;
- };
-
template<class _Pair, class _Iter, class _Sent>
concept __pair_like_convertible_from =
!range<_Pair> && __pair_like<_Pair> &&
@@ -70,8 +68,6 @@ namespace ranges {
__convertible_to_non_slicing<_Iter, tuple_element_t<0, _Pair>> &&
convertible_to<_Sent, tuple_element_t<1, _Pair>>;
- enum class _LIBCPP_ENUM_VIS subrange_kind : bool { unsized, sized };
-
template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent = _Iter,
subrange_kind _Kind = sized_sentinel_for<_Sent, _Iter>
? subrange_kind::sized
diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/take_view.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/take_view.h
index 546e898aec..bea3862cd7 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__ranges/take_view.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/take_view.h
@@ -12,6 +12,7 @@
#include <__algorithm/min.h>
#include <__algorithm/ranges_min.h>
+#include <__assert>
#include <__concepts/constructible.h>
#include <__concepts/convertible_to.h>
#include <__config>
@@ -63,9 +64,10 @@ public:
_LIBCPP_HIDE_FROM_ABI
take_view() requires default_initializable<_View> = default;
- _LIBCPP_HIDE_FROM_ABI
- constexpr take_view(_View __base, range_difference_t<_View> __count)
- : __base_(std::move(__base)), __count_(__count) {}
+ _LIBCPP_HIDE_FROM_ABI constexpr take_view(_View __base, range_difference_t<_View> __count)
+ : __base_(std::move(__base)), __count_(__count) {
+ _LIBCPP_ASSERT(__count >= 0, "count has to be greater than or equal to zero");
+ }
_LIBCPP_HIDE_FROM_ABI
constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/view_interface.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/view_interface.h
index b89ee999f8..5581eb9c73 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__ranges/view_interface.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/view_interface.h
@@ -21,7 +21,9 @@
#include <__ranges/access.h>
#include <__ranges/concepts.h>
#include <__ranges/empty.h>
-#include <type_traits>
+#include <__type_traits/is_class.h>
+#include <__type_traits/make_unsigned.h>
+#include <__type_traits/remove_cv.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -100,7 +102,7 @@ public:
constexpr auto size()
requires forward_range<_D2> && sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>>
{
- return ranges::end(__derived()) - ranges::begin(__derived());
+ return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived()));
}
template<class _D2 = _Derived>
@@ -108,7 +110,7 @@ public:
constexpr auto size() const
requires forward_range<const _D2> && sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>>
{
- return ranges::end(__derived()) - ranges::begin(__derived());
+ return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived()));
}
template<class _D2 = _Derived>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__ranges/zip_view.h b/contrib/libs/cxxsupp/libcxx/include/__ranges/zip_view.h
index 6eb0ffdf84..5624726e13 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__ranges/zip_view.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__ranges/zip_view.h
@@ -403,15 +403,15 @@ public:
_LIBCPP_HIDE_FROM_ABI
friend constexpr auto iter_move(const __iterator& __i) noexcept(
- (noexcept(ranges::iter_move(declval<const iterator_t<__maybe_const<_Const, _Views>>&>())) && ...) &&
+ (noexcept(ranges::iter_move(std::declval<const iterator_t<__maybe_const<_Const, _Views>>&>())) && ...) &&
(is_nothrow_move_constructible_v<range_rvalue_reference_t<__maybe_const<_Const, _Views>>> && ...)) {
return ranges::__tuple_transform(ranges::iter_move, __i.__current_);
}
_LIBCPP_HIDE_FROM_ABI
friend constexpr void iter_swap(const __iterator& __l, const __iterator& __r) noexcept(
- (noexcept(ranges::iter_swap(declval<const iterator_t<__maybe_const<_Const, _Views>>&>(),
- declval<const iterator_t<__maybe_const<_Const, _Views>>&>())) &&
+ (noexcept(ranges::iter_swap(std::declval<const iterator_t<__maybe_const<_Const, _Views>>&>(),
+ std::declval<const iterator_t<__maybe_const<_Const, _Views>>&>())) &&
...))
requires(indirectly_swappable<iterator_t<__maybe_const<_Const, _Views>>> && ...) {
ranges::__tuple_zip_for_each(ranges::iter_swap, __l.__current_, __r.__current_);
diff --git a/contrib/libs/cxxsupp/libcxx/include/__split_buffer b/contrib/libs/cxxsupp/libcxx/include/__split_buffer
index 5750a71531..4855089bcf 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__split_buffer
+++ b/contrib/libs/cxxsupp/libcxx/include/__split_buffer
@@ -507,7 +507,7 @@ __split_buffer<_Tp, _Allocator>::push_front(const_reference __x)
}
else
{
- size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
+ size_type __c = std::max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
__split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc());
__t.__construct_at_end(move_iterator<pointer>(__begin_),
move_iterator<pointer>(__end_));
@@ -537,7 +537,7 @@ __split_buffer<_Tp, _Allocator>::push_front(value_type&& __x)
}
else
{
- size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
+ size_type __c = std::max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
__split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc());
__t.__construct_at_end(move_iterator<pointer>(__begin_),
move_iterator<pointer>(__end_));
@@ -569,7 +569,7 @@ __split_buffer<_Tp, _Allocator>::push_back(const_reference __x)
}
else
{
- size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
+ size_type __c = std::max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
__split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());
__t.__construct_at_end(move_iterator<pointer>(__begin_),
move_iterator<pointer>(__end_));
@@ -599,7 +599,7 @@ __split_buffer<_Tp, _Allocator>::push_back(value_type&& __x)
}
else
{
- size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
+ size_type __c = std::max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
__split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());
__t.__construct_at_end(move_iterator<pointer>(__begin_),
move_iterator<pointer>(__end_));
@@ -631,7 +631,7 @@ __split_buffer<_Tp, _Allocator>::emplace_back(_Args&&... __args)
}
else
{
- size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
+ size_type __c = std::max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
__split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());
__t.__construct_at_end(move_iterator<pointer>(__begin_),
move_iterator<pointer>(__end_));
diff --git a/contrib/libs/cxxsupp/libcxx/include/__string/char_traits.h b/contrib/libs/cxxsupp/libcxx/include/__string/char_traits.h
index dc9afbd336..622ee224f1 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__string/char_traits.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__string/char_traits.h
@@ -210,25 +210,22 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char>
static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
{return (unsigned char)__c1 < (unsigned char)__c2;}
- static _LIBCPP_CONSTEXPR_SINCE_CXX17
- int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
+ static _LIBCPP_CONSTEXPR_SINCE_CXX17 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
+ if (__n == 0)
+ return 0;
+ return std::__constexpr_memcmp(__s1, __s2, __n);
+ }
- static inline size_t _LIBCPP_CONSTEXPR_SINCE_CXX17 length(const char_type* __s) _NOEXCEPT {
- // GCC currently does not support __builtin_strlen during constant evaluation.
- // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70816
-#ifdef _LIBCPP_COMPILER_GCC
- if (__libcpp_is_constant_evaluated()) {
- size_t __i = 0;
- for (; __s[__i] != char_type('\0'); ++__i)
- ;
- return __i;
- }
-#endif
- return __builtin_strlen(__s);
- }
+ static inline size_t _LIBCPP_CONSTEXPR_SINCE_CXX17 length(const char_type* __s) _NOEXCEPT {
+ return std::__constexpr_strlen(__s);
+ }
- static _LIBCPP_CONSTEXPR_SINCE_CXX17
- const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
+ static _LIBCPP_CONSTEXPR_SINCE_CXX17
+ const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
+ if (__n == 0)
+ return nullptr;
+ return std::__constexpr_char_memchr(__s, static_cast<int>(__a), __n);
+ }
static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
@@ -261,49 +258,6 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char>
{return int_type(EOF);}
};
-inline _LIBCPP_CONSTEXPR_SINCE_CXX17
-int
-char_traits<char>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
-{
- if (__n == 0)
- return 0;
-#if __has_feature(cxx_constexpr_string_builtins)
- return __builtin_memcmp(__s1, __s2, __n);
-#elif _LIBCPP_STD_VER <= 14
- return _VSTD::memcmp(__s1, __s2, __n);
-#else
- for (; __n; --__n, ++__s1, ++__s2)
- {
- if (lt(*__s1, *__s2))
- return -1;
- if (lt(*__s2, *__s1))
- return 1;
- }
- return 0;
-#endif
-}
-
-inline _LIBCPP_CONSTEXPR_SINCE_CXX17
-const char*
-char_traits<char>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
-{
- if (__n == 0)
- return nullptr;
-#if __has_feature(cxx_constexpr_string_builtins) && !defined(__CUDACC__)
- return __builtin_char_memchr(__s, to_int_type(__a), __n);
-#elif _LIBCPP_STD_VER <= 14
- return (const char_type*) _VSTD::memchr(__s, to_int_type(__a), __n);
-#else
- for (; __n; --__n)
- {
- if (eq(*__s, __a))
- return __s;
- ++__s;
- }
- return nullptr;
-#endif
-}
-
// char_traits<wchar_t>
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
@@ -326,12 +280,22 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t>
static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
{return __c1 < __c2;}
- static _LIBCPP_CONSTEXPR_SINCE_CXX17
- int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
- static _LIBCPP_CONSTEXPR_SINCE_CXX17
- size_t length(const char_type* __s) _NOEXCEPT;
- static _LIBCPP_CONSTEXPR_SINCE_CXX17
- const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
+ static _LIBCPP_CONSTEXPR_SINCE_CXX17 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
+ if (__n == 0)
+ return 0;
+ return std::__constexpr_wmemcmp(__s1, __s2, __n);
+ }
+
+ static _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length(const char_type* __s) _NOEXCEPT {
+ return std::__constexpr_wcslen(__s);
+ }
+
+ static _LIBCPP_CONSTEXPR_SINCE_CXX17
+ const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
+ if (__n == 0)
+ return nullptr;
+ return std::__constexpr_wmemchr(__s, __a, __n);
+ }
static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
@@ -363,65 +327,6 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t>
static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
{return int_type(WEOF);}
};
-
-inline _LIBCPP_CONSTEXPR_SINCE_CXX17
-int
-char_traits<wchar_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
-{
- if (__n == 0)
- return 0;
-#if __has_feature(cxx_constexpr_string_builtins) && !defined(__CUDACC__)
- return __builtin_wmemcmp(__s1, __s2, __n);
-#elif _LIBCPP_STD_VER <= 14
- return _VSTD::wmemcmp(__s1, __s2, __n);
-#else
- for (; __n; --__n, ++__s1, ++__s2)
- {
- if (lt(*__s1, *__s2))
- return -1;
- if (lt(*__s2, *__s1))
- return 1;
- }
- return 0;
-#endif
-}
-
-inline _LIBCPP_CONSTEXPR_SINCE_CXX17
-size_t
-char_traits<wchar_t>::length(const char_type* __s) _NOEXCEPT
-{
-#if __has_feature(cxx_constexpr_string_builtins) && !defined(__CUDACC__)
- return __builtin_wcslen(__s);
-#elif _LIBCPP_STD_VER <= 14
- return _VSTD::wcslen(__s);
-#else
- size_t __len = 0;
- for (; !eq(*__s, char_type(0)); ++__s)
- ++__len;
- return __len;
-#endif
-}
-
-inline _LIBCPP_CONSTEXPR_SINCE_CXX17
-const wchar_t*
-char_traits<wchar_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
-{
- if (__n == 0)
- return nullptr;
-#if __has_feature(cxx_constexpr_string_builtins) && !defined(__CUDACC__)
- return __builtin_wmemchr(__s, __a, __n);
-#elif _LIBCPP_STD_VER <= 14
- return _VSTD::wmemchr(__s, __a, __n);
-#else
- for (; __n; --__n)
- {
- if (eq(*__s, __a))
- return __s;
- ++__s;
- }
- return nullptr;
-#endif
-}
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
#ifndef _LIBCPP_HAS_NO_CHAR8_T
@@ -445,8 +350,10 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
static inline constexpr bool lt(char_type __c1, char_type __c2) noexcept
{return __c1 < __c2;}
- static constexpr
- int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
+ static _LIBCPP_HIDE_FROM_ABI constexpr int
+ compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
+ return std::__constexpr_memcmp(__s1, __s2, __n);
+ }
static constexpr
size_t length(const char_type* __s) _NOEXCEPT;
@@ -496,24 +403,6 @@ char_traits<char8_t>::length(const char_type* __s) _NOEXCEPT
return __len;
}
-inline constexpr
-int
-char_traits<char8_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
-{
-#if __has_feature(cxx_constexpr_string_builtins)
- return __builtin_memcmp(__s1, __s2, __n);
-#else
- for (; __n; --__n, ++__s1, ++__s2)
- {
- if (lt(*__s1, *__s2))
- return -1;
- if (lt(*__s2, *__s1))
- return 1;
- }
- return 0;
-#endif
-}
-
// TODO use '__builtin_char_memchr' if it ever supports char8_t ??
inline constexpr
const char8_t*
@@ -782,7 +671,7 @@ __str_find(const _CharT *__p, _SizeT __sz,
if (__n == 0) // There is nothing to search, just return __pos.
return __pos;
- const _CharT *__r = __search_substring<_CharT, _Traits>(
+ const _CharT *__r = std::__search_substring<_CharT, _Traits>(
__p + __pos, __p + __sz, __s, __s + __n);
if (__r == __p + __sz)
diff --git a/contrib/libs/cxxsupp/libcxx/include/__support/android/locale_bionic.h b/contrib/libs/cxxsupp/libcxx/include/__support/android/locale_bionic.h
index 5f4a89a7c6..30e345cf9e 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__support/android/locale_bionic.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__support/android/locale_bionic.h
@@ -46,18 +46,15 @@ extern "C" {
extern "C" {
#endif
-inline _LIBCPP_HIDE_FROM_ABI float
-strtof_l(const char* __nptr, char** __endptr, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C float strtof_l(const char* __nptr, char** __endptr, locale_t) {
return ::strtof(__nptr, __endptr);
}
-inline _LIBCPP_HIDE_FROM_ABI double
-strtod_l(const char* __nptr, char** __endptr, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C double strtod_l(const char* __nptr, char** __endptr, locale_t) {
return ::strtod(__nptr, __endptr);
}
-inline _LIBCPP_HIDE_FROM_ABI long
-strtol_l(const char* __nptr, char** __endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C long strtol_l(const char* __nptr, char** __endptr, int __base, locale_t) {
return ::strtol(__nptr, __endptr, __base);
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/__support/musl/xlocale.h b/contrib/libs/cxxsupp/libcxx/include/__support/musl/xlocale.h
index 675ba93e11..fe1dcf61a5 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__support/musl/xlocale.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__support/musl/xlocale.h
@@ -24,28 +24,24 @@
extern "C" {
#endif
-inline _LIBCPP_HIDE_FROM_ABI long long
-strtoll_l(const char *__nptr, char **__endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C long long strtoll_l(const char* __nptr, char** __endptr, int __base, locale_t) {
return ::strtoll(__nptr, __endptr, __base);
}
-inline _LIBCPP_HIDE_FROM_ABI unsigned long long
-strtoull_l(const char *__nptr, char **__endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C unsigned long long
+strtoull_l(const char* __nptr, char** __endptr, int __base, locale_t) {
return ::strtoull(__nptr, __endptr, __base);
}
-inline _LIBCPP_HIDE_FROM_ABI long long
-wcstoll_l(const wchar_t *__nptr, wchar_t **__endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C long long wcstoll_l(const wchar_t* __nptr, wchar_t** __endptr, int __base, locale_t) {
return ::wcstoll(__nptr, __endptr, __base);
}
-inline _LIBCPP_HIDE_FROM_ABI long long
-wcstoull_l(const wchar_t *__nptr, wchar_t **__endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C long long wcstoull_l(const wchar_t* __nptr, wchar_t** __endptr, int __base, locale_t) {
return ::wcstoull(__nptr, __endptr, __base);
}
-inline _LIBCPP_HIDE_FROM_ABI long double
-wcstold_l(const wchar_t *__nptr, wchar_t **__endptr, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C long double wcstold_l(const wchar_t* __nptr, wchar_t** __endptr, locale_t) {
return ::wcstold(__nptr, __endptr);
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/__support/openbsd/xlocale.h b/contrib/libs/cxxsupp/libcxx/include/__support/openbsd/xlocale.h
index 0269e8133b..b969ae9d10 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__support/openbsd/xlocale.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__support/openbsd/xlocale.h
@@ -20,18 +20,14 @@
extern "C" {
#endif
-
-inline _LIBCPP_HIDE_FROM_ABI long
-strtol_l(const char *__nptr, char **__endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C long strtol_l(const char* __nptr, char** __endptr, int __base, locale_t) {
return ::strtol(__nptr, __endptr, __base);
}
-inline _LIBCPP_HIDE_FROM_ABI unsigned long
-strtoul_l(const char *__nptr, char **__endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C unsigned long strtoul_l(const char* __nptr, char** __endptr, int __base, locale_t) {
return ::strtoul(__nptr, __endptr, __base);
}
-
#ifdef __cplusplus
}
#endif
diff --git a/contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__nop_locale_mgmt.h b/contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__nop_locale_mgmt.h
index 23727a5a3b..4b3caa895f 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__nop_locale_mgmt.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__nop_locale_mgmt.h
@@ -19,24 +19,13 @@ extern "C" {
// Patch over lack of extended locale support
typedef void *locale_t;
-inline _LIBCPP_HIDE_FROM_ABI locale_t
-duplocale(locale_t) {
- return NULL;
-}
-
-inline _LIBCPP_HIDE_FROM_ABI void
-freelocale(locale_t) {
-}
-
-inline _LIBCPP_HIDE_FROM_ABI locale_t
-newlocale(int, const char *, locale_t) {
- return NULL;
-}
-
-inline _LIBCPP_HIDE_FROM_ABI locale_t
-uselocale(locale_t) {
- return NULL;
-}
+inline _LIBCPP_HIDE_FROM_ABI_C locale_t duplocale(locale_t) { return NULL; }
+
+inline _LIBCPP_HIDE_FROM_ABI_C void freelocale(locale_t) {}
+
+inline _LIBCPP_HIDE_FROM_ABI_C locale_t newlocale(int, const char*, locale_t) { return NULL; }
+
+inline _LIBCPP_HIDE_FROM_ABI_C locale_t uselocale(locale_t) { return NULL; }
#define LC_COLLATE_MASK (1 << LC_COLLATE)
#define LC_CTYPE_MASK (1 << LC_CTYPE)
diff --git a/contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__posix_l_fallback.h b/contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__posix_l_fallback.h
index 8196c2362c..774081a8a4 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__posix_l_fallback.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__posix_l_fallback.h
@@ -27,144 +27,83 @@
extern "C" {
#endif
-inline _LIBCPP_HIDE_FROM_ABI int isalnum_l(int __c, locale_t) {
- return ::isalnum(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int isalnum_l(int __c, locale_t) { return ::isalnum(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int isalpha_l(int __c, locale_t) {
- return ::isalpha(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int isalpha_l(int __c, locale_t) { return ::isalpha(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int isblank_l(int __c, locale_t) {
- return ::isblank(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int isblank_l(int __c, locale_t) { return ::isblank(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iscntrl_l(int __c, locale_t) {
- return ::iscntrl(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iscntrl_l(int __c, locale_t) { return ::iscntrl(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int isdigit_l(int __c, locale_t) {
- return ::isdigit(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int isdigit_l(int __c, locale_t) { return ::isdigit(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int isgraph_l(int __c, locale_t) {
- return ::isgraph(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int isgraph_l(int __c, locale_t) { return ::isgraph(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int islower_l(int __c, locale_t) {
- return ::islower(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int islower_l(int __c, locale_t) { return ::islower(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int isprint_l(int __c, locale_t) {
- return ::isprint(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int isprint_l(int __c, locale_t) { return ::isprint(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int ispunct_l(int __c, locale_t) {
- return ::ispunct(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int ispunct_l(int __c, locale_t) { return ::ispunct(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int isspace_l(int __c, locale_t) {
- return ::isspace(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int isspace_l(int __c, locale_t) { return ::isspace(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int isupper_l(int __c, locale_t) {
- return ::isupper(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int isupper_l(int __c, locale_t) { return ::isupper(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int isxdigit_l(int __c, locale_t) {
- return ::isxdigit(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int isxdigit_l(int __c, locale_t) { return ::isxdigit(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int toupper_l(int __c, locale_t) {
- return ::toupper(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int toupper_l(int __c, locale_t) { return ::toupper(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int tolower_l(int __c, locale_t) {
- return ::tolower(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int tolower_l(int __c, locale_t) { return ::tolower(__c); }
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-inline _LIBCPP_HIDE_FROM_ABI int iswalnum_l(wint_t __c, locale_t) {
- return ::iswalnum(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswalnum_l(wint_t __c, locale_t) { return ::iswalnum(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswalpha_l(wint_t __c, locale_t) {
- return ::iswalpha(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswalpha_l(wint_t __c, locale_t) { return ::iswalpha(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswblank_l(wint_t __c, locale_t) {
- return ::iswblank(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswblank_l(wint_t __c, locale_t) { return ::iswblank(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswcntrl_l(wint_t __c, locale_t) {
- return ::iswcntrl(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswcntrl_l(wint_t __c, locale_t) { return ::iswcntrl(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswdigit_l(wint_t __c, locale_t) {
- return ::iswdigit(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswdigit_l(wint_t __c, locale_t) { return ::iswdigit(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswgraph_l(wint_t __c, locale_t) {
- return ::iswgraph(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswgraph_l(wint_t __c, locale_t) { return ::iswgraph(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswlower_l(wint_t __c, locale_t) {
- return ::iswlower(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswlower_l(wint_t __c, locale_t) { return ::iswlower(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswprint_l(wint_t __c, locale_t) {
- return ::iswprint(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswprint_l(wint_t __c, locale_t) { return ::iswprint(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswpunct_l(wint_t __c, locale_t) {
- return ::iswpunct(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswpunct_l(wint_t __c, locale_t) { return ::iswpunct(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswspace_l(wint_t __c, locale_t) {
- return ::iswspace(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswspace_l(wint_t __c, locale_t) { return ::iswspace(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswupper_l(wint_t __c, locale_t) {
- return ::iswupper(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswupper_l(wint_t __c, locale_t) { return ::iswupper(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswxdigit_l(wint_t __c, locale_t) {
- return ::iswxdigit(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswxdigit_l(wint_t __c, locale_t) { return ::iswxdigit(__c); }
-inline _LIBCPP_HIDE_FROM_ABI wint_t towupper_l(wint_t __c, locale_t) {
- return ::towupper(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C wint_t towupper_l(wint_t __c, locale_t) { return ::towupper(__c); }
-inline _LIBCPP_HIDE_FROM_ABI wint_t towlower_l(wint_t __c, locale_t) {
- return ::towlower(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C wint_t towlower_l(wint_t __c, locale_t) { return ::towlower(__c); }
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
-inline _LIBCPP_HIDE_FROM_ABI int
-strcoll_l(const char *__s1, const char *__s2, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C int strcoll_l(const char* __s1, const char* __s2, locale_t) {
return ::strcoll(__s1, __s2);
}
-inline _LIBCPP_HIDE_FROM_ABI size_t
-strxfrm_l(char *__dest, const char *__src, size_t __n, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C size_t strxfrm_l(char* __dest, const char* __src, size_t __n, locale_t) {
return ::strxfrm(__dest, __src, __n);
}
-inline _LIBCPP_HIDE_FROM_ABI size_t
-strftime_l(char *__s, size_t __max, const char *__format, const struct tm *__tm,
- locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C size_t
+strftime_l(char* __s, size_t __max, const char* __format, const struct tm* __tm, locale_t) {
return ::strftime(__s, __max, __format, __tm);
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-inline _LIBCPP_HIDE_FROM_ABI int
-wcscoll_l(const wchar_t *__ws1, const wchar_t *__ws2, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C int wcscoll_l(const wchar_t* __ws1, const wchar_t* __ws2, locale_t) {
return ::wcscoll(__ws1, __ws2);
}
-inline _LIBCPP_HIDE_FROM_ABI size_t
-wcsxfrm_l(wchar_t *__dest, const wchar_t *__src, size_t __n, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C size_t wcsxfrm_l(wchar_t* __dest, const wchar_t* __src, size_t __n, locale_t) {
return ::wcsxfrm(__dest, __src, __n);
}
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
diff --git a/contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__strtonum_fallback.h b/contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__strtonum_fallback.h
index d1ef8aaa83..ae8e13a758 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__strtonum_fallback.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__support/xlocale/__strtonum_fallback.h
@@ -26,44 +26,38 @@
extern "C" {
#endif
-inline _LIBCPP_HIDE_FROM_ABI float
-strtof_l(const char *__nptr, char **__endptr, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C float strtof_l(const char* __nptr, char** __endptr, locale_t) {
return ::strtof(__nptr, __endptr);
}
-inline _LIBCPP_HIDE_FROM_ABI double
-strtod_l(const char *__nptr, char **__endptr, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C double strtod_l(const char* __nptr, char** __endptr, locale_t) {
return ::strtod(__nptr, __endptr);
}
-inline _LIBCPP_HIDE_FROM_ABI long double
-strtold_l(const char *__nptr, char **__endptr, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C long double strtold_l(const char* __nptr, char** __endptr, locale_t) {
return ::strtold(__nptr, __endptr);
}
-inline _LIBCPP_HIDE_FROM_ABI long long
-strtoll_l(const char *__nptr, char **__endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C long long strtoll_l(const char* __nptr, char** __endptr, int __base, locale_t) {
return ::strtoll(__nptr, __endptr, __base);
}
-inline _LIBCPP_HIDE_FROM_ABI unsigned long long
-strtoull_l(const char *__nptr, char **__endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C unsigned long long
+strtoull_l(const char* __nptr, char** __endptr, int __base, locale_t) {
return ::strtoull(__nptr, __endptr, __base);
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-inline _LIBCPP_HIDE_FROM_ABI long long
-wcstoll_l(const wchar_t *__nptr, wchar_t **__endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C long long wcstoll_l(const wchar_t* __nptr, wchar_t** __endptr, int __base, locale_t) {
return ::wcstoll(__nptr, __endptr, __base);
}
-inline _LIBCPP_HIDE_FROM_ABI unsigned long long
-wcstoull_l(const wchar_t *__nptr, wchar_t **__endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C unsigned long long
+wcstoull_l(const wchar_t* __nptr, wchar_t** __endptr, int __base, locale_t) {
return ::wcstoull(__nptr, __endptr, __base);
}
-inline _LIBCPP_HIDE_FROM_ABI long double
-wcstold_l(const wchar_t *__nptr, wchar_t **__endptr, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C long double wcstold_l(const wchar_t* __nptr, wchar_t** __endptr, locale_t) {
return ::wcstold(__nptr, __endptr);
}
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
diff --git a/contrib/libs/cxxsupp/libcxx/include/__tree b/contrib/libs/cxxsupp/libcxx/include/__tree
index 05a3da1580..f5d9d595b4 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__tree
+++ b/contrib/libs/cxxsupp/libcxx/include/__tree
@@ -14,6 +14,7 @@
#include <__assert>
#include <__config>
#include <__debug>
+#include <__functional/invoke.h>
#include <__iterator/distance.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/next.h>
@@ -23,6 +24,17 @@
#include <__memory/swap_allocator.h>
#include <__memory/unique_ptr.h>
#include <__type_traits/can_extract_key.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/is_const.h>
+#include <__type_traits/is_nothrow_copy_constructible.h>
+#include <__type_traits/is_nothrow_default_constructible.h>
+#include <__type_traits/is_nothrow_move_assignable.h>
+#include <__type_traits/is_nothrow_move_constructible.h>
+#include <__type_traits/is_pointer.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_swappable.h>
+#include <__type_traits/remove_const_ref.h>
+#include <__type_traits/remove_cvref.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#include <__utility/pair.h>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__tuple/apply_cv.h b/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/apply_cv.h
index 296755a1d5..296755a1d5 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__tuple/apply_cv.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/apply_cv.h
diff --git a/contrib/libs/cxxsupp/libcxx/include/__tuple/make_tuple_types.h b/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/make_tuple_types.h
index 38e2547d13..913ff9bbd6 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__tuple/make_tuple_types.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/make_tuple_types.h
@@ -12,11 +12,11 @@
#include <__config>
#include <__fwd/array.h>
#include <__fwd/tuple.h>
-#include <__tuple/apply_cv.h>
-#include <__tuple/tuple_element.h>
-#include <__tuple/tuple_indices.h>
-#include <__tuple/tuple_size.h>
-#include <__tuple/tuple_types.h>
+#include <__tuple_dir/apply_cv.h>
+#include <__tuple_dir/tuple_element.h>
+#include <__tuple_dir/tuple_indices.h>
+#include <__tuple_dir/tuple_size.h>
+#include <__tuple_dir/tuple_types.h>
#include <__type_traits/remove_cv.h>
#include <__type_traits/remove_reference.h>
#include <cstddef>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/pair_like.h b/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/pair_like.h
new file mode 100644
index 0000000000..87407ad95b
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/pair_like.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TUPLE_PAIR_LIKE_H
+#define _LIBCPP___TUPLE_PAIR_LIKE_H
+
+#include <__config>
+#include <__tuple_dir/tuple_like.h>
+#include <__tuple_dir/tuple_size.h>
+#include <__type_traits/remove_cvref.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+template <class _Tp>
+concept __pair_like = __tuple_like<_Tp> && tuple_size<remove_cvref_t<_Tp>>::value == 2;
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TUPLE_PAIR_LIKE_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__tuple/sfinae_helpers.h b/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/sfinae_helpers.h
index ebe1e07a00..bedb62b6c7 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__tuple/sfinae_helpers.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/sfinae_helpers.h
@@ -11,11 +11,11 @@
#include <__config>
#include <__fwd/tuple.h>
-#include <__tuple/make_tuple_types.h>
-#include <__tuple/tuple_element.h>
-#include <__tuple/tuple_like.h>
-#include <__tuple/tuple_size.h>
-#include <__tuple/tuple_types.h>
+#include <__tuple_dir/make_tuple_types.h>
+#include <__tuple_dir/tuple_element.h>
+#include <__tuple_dir/tuple_like_ext.h>
+#include <__tuple_dir/tuple_size.h>
+#include <__tuple_dir/tuple_types.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/integral_constant.h>
#include <__type_traits/is_assignable.h>
@@ -58,8 +58,8 @@ struct __tuple_sfinae_base {
// __tuple_convertible
-template <class _Tp, class _Up, bool = __tuple_like<__libcpp_remove_reference_t<_Tp> >::value,
- bool = __tuple_like<_Up>::value,
+template <class _Tp, class _Up, bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value,
+ bool = __tuple_like_ext<_Up>::value,
class = void>
struct __tuple_convertible
: public false_type {};
@@ -75,8 +75,8 @@ struct __tuple_convertible<_Tp, _Up, true, true,
// __tuple_constructible
-template <class _Tp, class _Up, bool = __tuple_like<__libcpp_remove_reference_t<_Tp> >::value,
- bool = __tuple_like<_Up>::value>
+template <class _Tp, class _Up, bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value,
+ bool = __tuple_like_ext<_Up>::value>
struct __tuple_constructible
: public false_type {};
@@ -90,8 +90,8 @@ struct __tuple_constructible<_Tp, _Up, true, true>
// __tuple_assignable
-template <class _Tp, class _Up, bool = __tuple_like<__libcpp_remove_reference_t<_Tp> >::value,
- bool = __tuple_like<_Up>::value>
+template <class _Tp, class _Up, bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value,
+ bool = __tuple_like_ext<_Up>::value>
struct __tuple_assignable
: public false_type {};
@@ -119,7 +119,7 @@ struct __tuple_like_with_size_imp<true, _SizeTrait, _Expected>
template <class _Tuple, size_t _ExpectedSize, class _RawTuple = __libcpp_remove_reference_t<_Tuple> >
using __tuple_like_with_size _LIBCPP_NODEBUG = __tuple_like_with_size_imp<
- __tuple_like<_RawTuple>::value,
+ __tuple_like_ext<_RawTuple>::value,
tuple_size<_RawTuple>, _ExpectedSize
>;
diff --git a/contrib/libs/cxxsupp/libcxx/include/__tuple/tuple_element.h b/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_element.h
index 2e9d9c738e..1ed996e80f 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__tuple/tuple_element.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_element.h
@@ -10,8 +10,8 @@
#define _LIBCPP___TUPLE_TUPLE_ELEMENT_H
#include <__config>
-#include <__tuple/tuple_indices.h>
-#include <__tuple/tuple_types.h>
+#include <__tuple_dir/tuple_indices.h>
+#include <__tuple_dir/tuple_types.h>
#include <__type_traits/add_const.h>
#include <__type_traits/add_cv.h>
#include <__type_traits/add_volatile.h>
@@ -73,7 +73,6 @@ using __type_pack_element _LIBCPP_NODEBUG = typename decltype(
typename __make_tuple_indices<sizeof...(_Types)>::type
>{})
)::type;
-
#else // !defined(__CUDACC__) || !defined(_MSC_VER)
template <size_t _Idx, class ..._Types>
struct __y_type_pack_element {
diff --git a/contrib/libs/cxxsupp/libcxx/include/__tuple/tuple_indices.h b/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_indices.h
index 18666d5948..18666d5948 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__tuple/tuple_indices.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_indices.h
diff --git a/contrib/libs/cxxsupp/libcxx/include/__tuple/tuple_like.h b/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_like.h
index 3b596916a6..dab395be61 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__tuple/tuple_like.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_like.h
@@ -12,9 +12,10 @@
#include <__config>
#include <__fwd/array.h>
#include <__fwd/pair.h>
+#include <__fwd/subrange.h>
#include <__fwd/tuple.h>
-#include <__tuple/tuple_types.h>
#include <__type_traits/integral_constant.h>
+#include <__type_traits/remove_cvref.h>
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -23,21 +24,27 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Tp> struct __tuple_like : false_type {};
+#if _LIBCPP_STD_VER >= 20
-template <class _Tp> struct __tuple_like<const _Tp> : public __tuple_like<_Tp> {};
-template <class _Tp> struct __tuple_like<volatile _Tp> : public __tuple_like<_Tp> {};
-template <class _Tp> struct __tuple_like<const volatile _Tp> : public __tuple_like<_Tp> {};
+template <class _Tp>
+struct __tuple_like_impl : false_type {};
-#ifndef _LIBCPP_CXX03_LANG
-template <class... _Tp> struct __tuple_like<tuple<_Tp...> > : true_type {};
-#endif
+template <class... _Tp>
+struct __tuple_like_impl<tuple<_Tp...> > : true_type {};
+
+template <class _T1, class _T2>
+struct __tuple_like_impl<pair<_T1, _T2> > : true_type {};
+
+template <class _Tp, size_t _Size>
+struct __tuple_like_impl<array<_Tp, _Size> > : true_type {};
-template <class _T1, class _T2> struct __tuple_like<pair<_T1, _T2> > : true_type {};
+template <class _Ip, class _Sp, ranges::subrange_kind _Kp>
+struct __tuple_like_impl<ranges::subrange<_Ip, _Sp, _Kp> > : true_type {};
-template <class _Tp, size_t _Size> struct __tuple_like<array<_Tp, _Size> > : true_type {};
+template <class _Tp>
+concept __tuple_like = __tuple_like_impl<remove_cvref_t<_Tp>>::value;
-template <class... _Tp> struct __tuple_like<__tuple_types<_Tp...> > : true_type {};
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_like_ext.h b/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_like_ext.h
new file mode 100644
index 0000000000..bf98696112
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_like_ext.h
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TUPLE_TUPLE_LIKE_EXT_H
+#define _LIBCPP___TUPLE_TUPLE_LIKE_EXT_H
+
+#include <__config>
+#include <__fwd/array.h>
+#include <__fwd/pair.h>
+#include <__fwd/tuple.h>
+#include <__tuple_dir/tuple_types.h>
+#include <__type_traits/integral_constant.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct __tuple_like_ext : false_type {};
+
+template <class _Tp> struct __tuple_like_ext<const _Tp> : public __tuple_like_ext<_Tp> {};
+template <class _Tp> struct __tuple_like_ext<volatile _Tp> : public __tuple_like_ext<_Tp> {};
+template <class _Tp> struct __tuple_like_ext<const volatile _Tp> : public __tuple_like_ext<_Tp> {};
+
+#ifndef _LIBCPP_CXX03_LANG
+template <class... _Tp> struct __tuple_like_ext<tuple<_Tp...> > : true_type {};
+#endif
+
+template <class _T1, class _T2> struct __tuple_like_ext<pair<_T1, _T2> > : true_type {};
+
+template <class _Tp, size_t _Size> struct __tuple_like_ext<array<_Tp, _Size> > : true_type {};
+
+template <class... _Tp> struct __tuple_like_ext<__tuple_types<_Tp...> > : true_type {};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TUPLE_TUPLE_LIKE_EXT_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__tuple/tuple_size.h b/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_size.h
index 26f9d9725d..d551b2258c 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__tuple/tuple_size.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_size.h
@@ -11,7 +11,7 @@
#include <__config>
#include <__fwd/tuple.h>
-#include <__tuple/tuple_types.h>
+#include <__tuple_dir/tuple_types.h>
#include <__type_traits/is_const.h>
#include <__type_traits/is_volatile.h>
#include <cstddef>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__tuple/tuple_types.h b/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_types.h
index c5be81cce8..c5be81cce8 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__tuple/tuple_types.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__tuple_dir/tuple_types.h
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/add_pointer.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/add_pointer.h
index 9d0c201007..1af5eca65c 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/add_pointer.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/add_pointer.h
@@ -22,7 +22,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_builtin(__add_pointer)
+#if !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__add_pointer)
template <class _Tp>
using __add_pointer_t = __add_pointer(_Tp);
@@ -39,7 +39,7 @@ template <class _Tp> struct __add_pointer_impl<_Tp, false>
template <class _Tp>
using __add_pointer_t = typename __add_pointer_impl<_Tp>::type;
-#endif // __has_builtin(__add_pointer)
+#endif // !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__add_pointer)
template <class _Tp>
struct add_pointer {
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/aligned_storage.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/aligned_storage.h
index a9f1244ed3..c564d58245 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/aligned_storage.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/aligned_storage.h
@@ -83,7 +83,7 @@ struct __find_max_align<__type_list<_Hp, _Tp>, _Len>
: public integral_constant<size_t, __select_align<_Len, _Hp::value, __find_max_align<_Tp, _Len>::value>::value> {};
template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
-struct _LIBCPP_TEMPLATE_VIS aligned_storage
+struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS aligned_storage
{
typedef typename __find_pod<__all_types, _Align>::type _Aligner;
union type
@@ -94,13 +94,17 @@ struct _LIBCPP_TEMPLATE_VIS aligned_storage
};
#if _LIBCPP_STD_VER > 11
+
+ _LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
- using aligned_storage_t = typename aligned_storage<_Len, _Align>::type;
+ using aligned_storage_t _LIBCPP_DEPRECATED_IN_CXX23 = typename aligned_storage<_Len, _Align>::type;
+ _LIBCPP_SUPPRESS_DEPRECATED_POP
+
#endif
#define _CREATE_ALIGNED_STORAGE_SPECIALIZATION(n) \
template <size_t _Len>\
-struct _LIBCPP_TEMPLATE_VIS aligned_storage<_Len, n>\
+struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS aligned_storage<_Len, n>\
{\
struct _ALIGNAS(n) type\
{\
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/aligned_union.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/aligned_union.h
index 31eb9353a9..2c64130da3 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/aligned_union.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/aligned_union.h
@@ -37,7 +37,7 @@ struct __static_max<_I0, _I1, _In...>
};
template <size_t _Len, class _Type0, class ..._Types>
-struct aligned_union
+struct _LIBCPP_DEPRECATED_IN_CXX23 aligned_union
{
static const size_t alignment_value = __static_max<_LIBCPP_PREFERRED_ALIGNOF(_Type0),
_LIBCPP_PREFERRED_ALIGNOF(_Types)...>::value;
@@ -47,7 +47,8 @@ struct aligned_union
};
#if _LIBCPP_STD_VER > 11
-template <size_t _Len, class ..._Types> using aligned_union_t = typename aligned_union<_Len, _Types...>::type;
+template <size_t _Len, class... _Types>
+using aligned_union_t _LIBCPP_DEPRECATED_IN_CXX23 = typename aligned_union<_Len, _Types...>::type;
#endif
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/common_reference.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/common_reference.h
index 559d39858e..f9195865c8 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/common_reference.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/common_reference.h
@@ -31,7 +31,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// Let COND_RES(X, Y) be:
template <class _Xp, class _Yp>
using __cond_res =
- decltype(false ? declval<_Xp(&)()>()() : declval<_Yp(&)()>()());
+ decltype(false ? std::declval<_Xp(&)()>()() : std::declval<_Yp(&)()>()());
// Let `XREF(A)` denote a unary alias template `T` such that `T<U>` denotes the same type as `U`
// with the addition of `A`'s cv and reference qualifiers, for a non-reference cv-unqualified type
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/common_type.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/common_type.h
index 8009142dfe..6d2df6c9b3 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/common_type.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/common_type.h
@@ -26,7 +26,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
// Let COND_RES(X, Y) be:
template <class _Tp, class _Up>
-using __cond_type = decltype(false ? declval<_Tp>() : declval<_Up>());
+using __cond_type = decltype(false ? std::declval<_Tp>() : std::declval<_Up>());
template <class _Tp, class _Up, class = void>
struct __common_type3 {};
@@ -47,10 +47,10 @@ struct __common_type2_imp {};
// sub-bullet 3 - "if decay_t<decltype(false ? declval<D1>() : declval<D2>())> ..."
template <class _Tp, class _Up>
-struct __common_type2_imp<_Tp, _Up, __void_t<decltype(true ? declval<_Tp>() : declval<_Up>())> >
+struct __common_type2_imp<_Tp, _Up, __void_t<decltype(true ? std::declval<_Tp>() : std::declval<_Up>())> >
{
typedef _LIBCPP_NODEBUG typename decay<decltype(
- true ? declval<_Tp>() : declval<_Up>()
+ true ? std::declval<_Tp>() : std::declval<_Up>()
)>::type type;
};
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/conjunction.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/conjunction.h
index 2802d28452..0d95347e99 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/conjunction.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/conjunction.h
@@ -35,7 +35,7 @@ false_type __and_helper(...);
// be instantiated) since it is an alias, unlike `conjunction<_Pred...>`, which is a struct.
// If you want to defer the evaluation of `_And<_Pred...>` itself, use `_Lazy<_And, _Pred...>`.
template <class... _Pred>
-using _And _LIBCPP_NODEBUG = decltype(__and_helper<_Pred...>(0));
+using _And _LIBCPP_NODEBUG = decltype(std::__and_helper<_Pred...>(0));
#if _LIBCPP_STD_VER > 14
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/enable_if.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/enable_if.h
index c5e8df45ea..706386deb1 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/enable_if.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/enable_if.h
@@ -26,6 +26,12 @@ template <bool _Bp, class _Tp = void> using __enable_if_t _LIBCPP_NODEBUG = type
template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp, _Tp>::type;
#endif
+// CUDA headers use libc++ internals.
+#ifdef __CUDACC__
+template <bool _Cond, class _Ret = void>
+using __lazy_enable_if _LIBCPP_NODEBUG = __enable_if_t<_Cond, _Ret>;
+#endif
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___TYPE_TRAITS_ENABLE_IF_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_allocator.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_allocator.h
index 53401e9f4f..ee4154d7e4 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_allocator.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_allocator.h
@@ -27,7 +27,7 @@ struct __is_allocator : false_type {};
template<typename _Alloc>
struct __is_allocator<_Alloc,
__void_t<typename _Alloc::value_type>,
- __void_t<decltype(declval<_Alloc&>().allocate(size_t(0)))>
+ __void_t<decltype(std::declval<_Alloc&>().allocate(size_t(0)))>
>
: true_type {};
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_always_bitcastable.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_always_bitcastable.h
new file mode 100644
index 0000000000..63304eb492
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_always_bitcastable.h
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_ALWAYS_BITCASTABLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_ALWAYS_BITCASTABLE_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_integral.h>
+#include <__type_traits/is_object.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_trivially_copyable.h>
+#include <__type_traits/remove_cv.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// Checks whether an object of type `From` can always be bit-cast to an object of type `To` and represent a valid value
+// of type `To`. In other words, `From` and `To` have the same value representation and the set of values of `From` is
+// a subset of the set of values of `To`.
+//
+// Note that types that cannot be assigned to each other using built-in assignment (e.g. arrays) might still be
+// considered bit-castable.
+template <class _From, class _To>
+struct __is_always_bitcastable {
+ using _UnqualFrom = __remove_cv_t<_From>;
+ using _UnqualTo = __remove_cv_t<_To>;
+
+ static const bool value =
+ // First, the simple case -- `From` and `To` are the same object type.
+ (is_same<_UnqualFrom, _UnqualTo>::value && is_trivially_copyable<_UnqualFrom>::value) ||
+
+ // Beyond the simple case, we say that one type is "always bit-castable" to another if:
+ // - (1) `From` and `To` have the same value representation, and in addition every possible value of `From` has
+ // a corresponding value in the `To` type (in other words, the set of values of `To` is a superset of the set of
+ // values of `From`);
+ // - (2) When the corresponding values are not the same value (as, for example, between an unsigned and a signed
+ // integer, where a large positive value of the unsigned integer corresponds to a negative value in the signed
+ // integer type), the value of `To` that results from a bitwise copy of `From` is the same what would be produced
+ // by the built-in assignment (if it were defined for the two types, to which there are minor exceptions, e.g.
+ // built-in arrays).
+ //
+ // In practice, that means:
+ // - all integral types (except `bool`, see below) -- that is, character types and `int` types, both signed and
+ // unsigned...
+ // - as well as arrays of such types...
+ // - ...that have the same size.
+ //
+ // Other trivially-copyable types can't be validly bit-cast outside of their own type:
+ // - floating-point types normally have different sizes and thus aren't bit-castable between each other (fails #1);
+ // - integral types and floating-point types use different representations, so for example bit-casting an integral
+ // `1` to `float` results in a very small less-than-one value, unlike built-in assignment that produces `1.0`
+ // (fails #2);
+ // - booleans normally use only a single bit of their object representation; bit-casting an integer to a boolean
+ // will result in a boolean object with an incorrect representation, which is undefined behavior (fails #2).
+ // Bit-casting from a boolean into an integer, however, is valid;
+ // - enumeration types may have different ranges of possible values (fails #1);
+ // - for pointers, it is not guaranteed that pointers to different types use the same set of values to represent
+ // addresses, and the conversion results are explicitly unspecified for types with different alignments
+ // (fails #1);
+ // - for structs and unions it is impossible to determine whether the set of values of one of them is a subset of
+ // the other (fails #1);
+ // - there is no need to consider `nullptr_t` for practical purposes.
+ (
+ sizeof(_From) == sizeof(_To) &&
+ is_integral<_From>::value &&
+ is_integral<_To>::value &&
+ !is_same<_UnqualTo, bool>::value
+ );
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_ALWAYS_BITCASTABLE_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_callable.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_callable.h
index 73f894dce9..445373c43b 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_callable.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_callable.h
@@ -25,7 +25,7 @@ template<class...>
false_type __is_callable_helper(...);
template<class _Func, class... _Args>
-struct __is_callable : decltype(__is_callable_helper<_Func, _Args...>(0)) {};
+struct __is_callable : decltype(std::__is_callable_helper<_Func, _Args...>(0)) {};
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_convertible.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_convertible.h
index 1085d632a5..5f77fd4d70 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_convertible.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_convertible.h
@@ -40,7 +40,7 @@ struct __is_convertible_test : public false_type {};
template <class _From, class _To>
struct __is_convertible_test<_From, _To,
- decltype(__is_convertible_imp::__test_convert<_To>(declval<_From>()))> : public true_type
+ decltype(__is_convertible_imp::__test_convert<_To>(std::declval<_From>()))> : public true_type
{};
template <class _Tp, bool _IsArray = is_array<_Tp>::value,
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_destructible.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_destructible.h
index 700b8d591a..87a68bfce2 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_destructible.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_destructible.h
@@ -48,7 +48,7 @@ template <typename _Tp>
struct __is_destructor_wellformed {
template <typename _Tp1>
static true_type __test (
- typename __is_destructible_apply<decltype(declval<_Tp1&>().~_Tp1())>::type
+ typename __is_destructible_apply<decltype(std::declval<_Tp1&>().~_Tp1())>::type
);
template <typename _Tp1>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_implicitly_default_constructible.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_implicitly_default_constructible.h
index 3643897a2d..b77f94845f 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_implicitly_default_constructible.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_implicitly_default_constructible.h
@@ -33,12 +33,12 @@ struct __is_implicitly_default_constructible
{ };
template <class _Tp>
-struct __is_implicitly_default_constructible<_Tp, decltype(__test_implicit_default_constructible<_Tp const&>({})), true_type>
+struct __is_implicitly_default_constructible<_Tp, decltype(std::__test_implicit_default_constructible<_Tp const&>({})), true_type>
: true_type
{ };
template <class _Tp>
-struct __is_implicitly_default_constructible<_Tp, decltype(__test_implicit_default_constructible<_Tp const&>({})), false_type>
+struct __is_implicitly_default_constructible<_Tp, decltype(std::__test_implicit_default_constructible<_Tp const&>({})), false_type>
: false_type
{ };
#endif // !C++03
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_member_pointer.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_member_pointer.h
index 2c453c8dc6..23b2288fda 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_member_pointer.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_member_pointer.h
@@ -11,6 +11,7 @@
#include <__config>
#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_member_function_pointer.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_nothrow_constructible.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_nothrow_constructible.h
index da116a95db..20c6199521 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_nothrow_constructible.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_nothrow_constructible.h
@@ -11,6 +11,10 @@
#include <__config>
#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_reference.h>
+#include <__utility/declval.h>
+#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -30,7 +34,7 @@ template <bool, bool, class _Tp, class... _Args> struct __libcpp_is_nothrow_cons
template <class _Tp, class... _Args>
struct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/false, _Tp, _Args...>
- : public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))>
+ : public integral_constant<bool, noexcept(_Tp(std::declval<_Args>()...))>
{
};
@@ -39,7 +43,7 @@ void __implicit_conversion_to(_Tp) noexcept { }
template <class _Tp, class _Arg>
struct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/true, _Tp, _Arg>
- : public integral_constant<bool, noexcept(_VSTD::__implicit_conversion_to<_Tp>(declval<_Arg>()))>
+ : public integral_constant<bool, noexcept(_VSTD::__implicit_conversion_to<_Tp>(std::declval<_Arg>()))>
{
};
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_nothrow_convertible.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_nothrow_convertible.h
index 712b6f2cf4..a8ca1c4c41 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_nothrow_convertible.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_nothrow_convertible.h
@@ -30,7 +30,7 @@ template <typename _Tp>
static void __test_noexcept(_Tp) noexcept;
template<typename _Fm, typename _To>
-static bool_constant<noexcept(_VSTD::__test_noexcept<_To>(declval<_Fm>()))>
+static bool_constant<noexcept(_VSTD::__test_noexcept<_To>(std::declval<_Fm>()))>
__is_nothrow_convertible_test();
template <typename _Fm, typename _To>
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_nothrow_destructible.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_nothrow_destructible.h
index 050362f9f4..03ebf44049 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_nothrow_destructible.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_nothrow_destructible.h
@@ -36,7 +36,7 @@ struct __libcpp_is_nothrow_destructible<false, _Tp>
template <class _Tp>
struct __libcpp_is_nothrow_destructible<true, _Tp>
- : public integral_constant<bool, noexcept(declval<_Tp>().~_Tp()) >
+ : public integral_constant<bool, noexcept(std::declval<_Tp>().~_Tp()) >
{
};
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_scalar.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_scalar.h
index b72da1806b..6bd80ed3f2 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_scalar.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_scalar.h
@@ -14,6 +14,7 @@
#include <__type_traits/is_arithmetic.h>
#include <__type_traits/is_enum.h>
#include <__type_traits/is_member_pointer.h>
+#include <__type_traits/is_null_pointer.h>
#include <__type_traits/is_pointer.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_signed.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_signed.h
index 92a45e3536..99e5ea00c0 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_signed.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_signed.h
@@ -11,6 +11,8 @@
#include <__config>
#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_arithmetic.h>
+#include <__type_traits/is_integral.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_specialization.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_specialization.h
new file mode 100644
index 0000000000..0cc3667425
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_specialization.h
@@ -0,0 +1,45 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_SPECIALIZATION
+#define _LIBCPP___TYPE_TRAITS_IS_SPECIALIZATION
+
+// This contains parts of P2098R1 but is based on MSVC STL's implementation.
+//
+// The paper has been rejected
+// We will not pursue P2098R0 (std::is_specialization_of) at this time; we'd
+// like to see a solution to this problem, but it requires language evolution
+// too.
+//
+// Since it is expected a real solution will be provided in the future only the
+// minimal part is implemented.
+//
+// Note a cvref qualified _Tp is never considered a specialization.
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 14
+
+template <class _Tp, template <class...> class _Template>
+inline constexpr bool __is_specialization_v = false; // true if and only if _Tp is a specialization of _Template
+
+template <template <class...> class _Template, class... _Args>
+inline constexpr bool __is_specialization_v<_Template<_Args...>, _Template> = true;
+
+#endif // _LIBCPP_STD_VER > 14
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_SPECIALIZATION
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_swappable.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_swappable.h
index a131182282..3821de17f6 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_swappable.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_swappable.h
@@ -64,7 +64,7 @@ template <class _Tp, class _Up = _Tp,
struct __swappable_with
{
template <class _LHS, class _RHS>
- static decltype(swap(declval<_LHS>(), declval<_RHS>()))
+ static decltype(swap(std::declval<_LHS>(), std::declval<_RHS>()))
__test_swap(int);
template <class, class>
static __nat __test_swap(long);
@@ -84,8 +84,8 @@ template <class _Tp, class _Up = _Tp, bool _Swappable = __swappable_with<_Tp, _U
struct __nothrow_swappable_with {
static const bool value =
#ifndef _LIBCPP_HAS_NO_NOEXCEPT
- noexcept(swap(declval<_Tp>(), declval<_Up>()))
- && noexcept(swap(declval<_Up>(), declval<_Tp>()));
+ noexcept(swap(std::declval<_Tp>(), std::declval<_Up>()))
+ && noexcept(swap(std::declval<_Up>(), std::declval<_Tp>()));
#else
false;
#endif
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_trivially_destructible.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_trivially_destructible.h
index 2d1c28bd31..2a79840e3c 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_trivially_destructible.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_trivially_destructible.h
@@ -11,6 +11,7 @@
#include <__config>
#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_destructible.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_valid_expansion.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_valid_expansion.h
index c45db7509e..db7d7e5f1d 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_valid_expansion.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_valid_expansion.h
@@ -24,7 +24,7 @@ template <template <class...> class, class ...>
false_type __sfinae_test_impl(...);
template <template <class ...> class _Templ, class ..._Args>
-using _IsValidExpansion _LIBCPP_NODEBUG = decltype(__sfinae_test_impl<_Templ, _Args...>(0));
+using _IsValidExpansion _LIBCPP_NODEBUG = decltype(std::__sfinae_test_impl<_Templ, _Args...>(0));
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_void.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_void.h
index a82c2cb442..c626a19814 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_void.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/is_void.h
@@ -11,6 +11,8 @@
#include <__config>
#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/remove_cv.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/promote.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/promote.h
index e647dff469..c2af327c64 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/promote.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/promote.h
@@ -40,7 +40,7 @@ struct __numeric_type
static double __test(double);
static long double __test(long double);
- typedef decltype(__test(declval<_Tp>())) type;
+ typedef decltype(__test(std::declval<_Tp>())) type;
static const bool value = _IsNotSame<type, void>::value;
};
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/remove_pointer.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/remove_pointer.h
index 33ddb7103f..2f810ba666 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__type_traits/remove_pointer.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/remove_pointer.h
@@ -17,7 +17,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_builtin(__remove_pointer)
+#if !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__remove_pointer)
template <class _Tp>
struct remove_pointer {
using type _LIBCPP_NODEBUG = __remove_pointer(_Tp);
@@ -34,7 +34,7 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* const volat
template <class _Tp>
using __remove_pointer_t = typename remove_pointer<_Tp>::type;
-#endif // __has_builtin(__remove_pointer)
+#endif // !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__remove_pointer)
#if _LIBCPP_STD_VER > 11
template <class _Tp> using remove_pointer_t = __remove_pointer_t<_Tp>;
diff --git a/contrib/libs/cxxsupp/libcxx/include/__type_traits/strip_signature.h b/contrib/libs/cxxsupp/libcxx/include/__type_traits/strip_signature.h
new file mode 100644
index 0000000000..2bb7393c1e
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__type_traits/strip_signature.h
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_STRIP_SIGNATURE_H
+#define _LIBCPP___TYPE_TRAITS_STRIP_SIGNATURE_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template<class _Fp>
+struct __strip_signature;
+
+# if defined(__cpp_static_call_operator) && __cpp_static_call_operator >= 202207L
+
+template <class _Rp, class... _Args>
+struct __strip_signature<_Rp(*)(_Args...)> {
+ using type = _Rp(_Args...);
+};
+
+template <class _Rp, class... _Args>
+struct __strip_signature<_Rp(*)(_Args...) noexcept> {
+ using type = _Rp(_Args...);
+};
+
+# endif // defined(__cpp_static_call_operator) && __cpp_static_call_operator >= 202207L
+
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...)> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) const> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile> { using type = _Rp(_Ap...); };
+
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) &> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) const &> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile &> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile &> { using type = _Rp(_Ap...); };
+
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) noexcept> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) const noexcept> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile noexcept> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile noexcept> { using type = _Rp(_Ap...); };
+
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) & noexcept> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) const & noexcept> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile & noexcept> { using type = _Rp(_Ap...); };
+template<class _Rp, class _Gp, class ..._Ap>
+struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile & noexcept> { using type = _Rp(_Ap...); };
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___TYPE_TRAITS_STRIP_SIGNATURE_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__utility/as_const.h b/contrib/libs/cxxsupp/libcxx/include/__utility/as_const.h
index e28d7bc1a2..d4a72f43d4 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__utility/as_const.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__utility/as_const.h
@@ -10,9 +10,9 @@
#define _LIBCPP___UTILITY_AS_CONST_H
#include <__config>
+#include <__type_traits/add_const.h>
#include <__utility/forward.h>
#include <__utility/move.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__utility/auto_cast.h b/contrib/libs/cxxsupp/libcxx/include/__utility/auto_cast.h
index e907944395..381ed0c205 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__utility/auto_cast.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__utility/auto_cast.h
@@ -11,7 +11,7 @@
#define _LIBCPP___UTILITY_AUTO_CAST_H
#include <__config>
-#include <type_traits>
+#include <__type_traits/decay.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__utility/cmp.h b/contrib/libs/cxxsupp/libcxx/include/__utility/cmp.h
index 3cfd981067..d448a1d084 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__utility/cmp.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__utility/cmp.h
@@ -10,10 +10,14 @@
#define _LIBCPP___UTILITY_CMP_H
#include <__config>
+#include <__type_traits/disjunction.h>
+#include <__type_traits/is_integral.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_signed.h>
+#include <__type_traits/make_unsigned.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#include <limits>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__utility/declval.h b/contrib/libs/cxxsupp/libcxx/include/__utility/declval.h
index 97fd1eba91..c2f4bec132 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__utility/declval.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__utility/declval.h
@@ -27,7 +27,7 @@ _Tp __declval(long);
_LIBCPP_SUPPRESS_DEPRECATED_POP
template <class _Tp>
-decltype(__declval<_Tp>(0)) declval() _NOEXCEPT;
+decltype(std::__declval<_Tp>(0)) declval() _NOEXCEPT;
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/include/__utility/exception_guard.h b/contrib/libs/cxxsupp/libcxx/include/__utility/exception_guard.h
new file mode 100644
index 0000000000..46f9359a5c
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/__utility/exception_guard.h
@@ -0,0 +1,139 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___UTILITY_TRANSACTION_H
+#define _LIBCPP___UTILITY_TRANSACTION_H
+
+#include <__assert>
+#include <__config>
+#include <__type_traits/is_nothrow_move_constructible.h>
+#include <__utility/exchange.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// __exception_guard is a helper class for writing code with the strong exception guarantee.
+//
+// When writing code that can throw an exception, one can store rollback instructions in an
+// exception guard so that if an exception is thrown at any point during the lifetime of the
+// exception guard, it will be rolled back automatically. When the exception guard is done, one
+// must mark it as being complete so it isn't rolled back when the exception guard is destroyed.
+//
+// Exception guards are not default constructible, they can't be copied or assigned to, but
+// they can be moved around for convenience.
+//
+// __exception_guard is a no-op in -fno-exceptions mode to produce better code-gen. This means
+// that we don't provide the strong exception guarantees. However, Clang doesn't generate cleanup
+// code with exceptions disabled, so even if we wanted to provide the strong exception guarantees
+// we couldn't. This is also only relevant for constructs with a stack of
+// -fexceptions > -fno-exceptions > -fexceptions code, since the exception can't be caught where
+// exceptions are disabled. While -fexceptions > -fno-exceptions is quite common
+// (e.g. libc++.dylib > -fno-exceptions), having another layer with exceptions enabled seems a lot
+// less common, especially one that tries to catch an exception through -fno-exceptions code.
+//
+// __exception_guard can help greatly simplify code that would normally be cluttered by
+// `#if _LIBCPP_NO_EXCEPTIONS`. For example:
+//
+// template <class Iterator, class Size, class OutputIterator>
+// Iterator uninitialized_copy_n(Iterator iter, Size n, OutputIterator out) {
+// typedef typename iterator_traits<Iterator>::value_type value_type;
+// __exception_guard guard([start=out, &out] {
+// std::destroy(start, out);
+// });
+//
+// for (; n > 0; ++iter, ++out, --n) {
+// ::new ((void*)std::addressof(*out)) value_type(*iter);
+// }
+// guard.__complete();
+// return out;
+// }
+//
+
+#ifndef _LIBCPP_NO_EXCEPTIONS
+template <class _Rollback>
+struct __exception_guard_exceptions {
+ __exception_guard_exceptions() = delete;
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __exception_guard_exceptions(_Rollback __rollback)
+ : __rollback_(std::move(__rollback)), __completed_(false) {}
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+ __exception_guard_exceptions(__exception_guard_exceptions&& __other)
+ _NOEXCEPT_(is_nothrow_move_constructible<_Rollback>::value)
+ : __rollback_(std::move(__other.__rollback_)), __completed_(__other.__completed_) {
+ __other.__completed_ = true;
+ }
+
+ __exception_guard_exceptions(__exception_guard_exceptions const&) = delete;
+ __exception_guard_exceptions& operator=(__exception_guard_exceptions const&) = delete;
+ __exception_guard_exceptions& operator=(__exception_guard_exceptions&&) = delete;
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __complete() _NOEXCEPT { __completed_ = true; }
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__exception_guard_exceptions() {
+ if (!__completed_)
+ __rollback_();
+ }
+
+private:
+ _Rollback __rollback_;
+ bool __completed_;
+};
+
+_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__exception_guard_exceptions);
+
+template <class _Rollback>
+using __exception_guard = __exception_guard_exceptions<_Rollback>;
+#else // _LIBCPP_NO_EXCEPTIONS
+template <class _Rollback>
+struct __exception_guard_noexceptions {
+ __exception_guard_noexceptions() = delete;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+ _LIBCPP_NODEBUG explicit __exception_guard_noexceptions(_Rollback) {}
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NODEBUG
+ __exception_guard_noexceptions(__exception_guard_noexceptions&& __other)
+ _NOEXCEPT_(is_nothrow_move_constructible<_Rollback>::value)
+ : __completed_(__other.__completed_) {
+ __other.__completed_ = true;
+ }
+
+ __exception_guard_noexceptions(__exception_guard_noexceptions const&) = delete;
+ __exception_guard_noexceptions& operator=(__exception_guard_noexceptions const&) = delete;
+ __exception_guard_noexceptions& operator=(__exception_guard_noexceptions&&) = delete;
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NODEBUG void __complete() _NOEXCEPT {
+ __completed_ = true;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NODEBUG ~__exception_guard_noexceptions() {
+ _LIBCPP_ASSERT(__completed_, "__exception_guard not completed with exceptions disabled");
+ }
+
+private:
+ bool __completed_ = false;
+};
+
+_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__exception_guard_noexceptions);
+
+template <class _Rollback>
+using __exception_guard = __exception_guard_noexceptions<_Rollback>;
+#endif // _LIBCPP_NO_EXCEPTIONS
+
+template <class _Rollback>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __exception_guard<_Rollback> __make_exception_guard(_Rollback __rollback) {
+ return __exception_guard<_Rollback>(std::move(__rollback));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___UTILITY_TRANSACTION_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__utility/exchange.h b/contrib/libs/cxxsupp/libcxx/include/__utility/exchange.h
index 6838fc8c62..8df71a17b1 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__utility/exchange.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__utility/exchange.h
@@ -10,9 +10,10 @@
#define _LIBCPP___UTILITY_EXCHANGE_H
#include <__config>
+#include <__type_traits/is_nothrow_assignable.h>
+#include <__type_traits/is_nothrow_move_constructible.h>
#include <__utility/forward.h>
#include <__utility/move.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__utility/forward.h b/contrib/libs/cxxsupp/libcxx/include/__utility/forward.h
index 4e254e0fa0..010f2362bd 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__utility/forward.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__utility/forward.h
@@ -21,14 +21,14 @@
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp>
-_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR _Tp&&
-forward(__libcpp_remove_reference_t<_Tp>& __t) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp&&
+forward(_LIBCPP_LIFETIMEBOUND __libcpp_remove_reference_t<_Tp>& __t) _NOEXCEPT {
return static_cast<_Tp&&>(__t);
}
template <class _Tp>
-_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR _Tp&&
-forward(__libcpp_remove_reference_t<_Tp>&& __t) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp&&
+forward(_LIBCPP_LIFETIMEBOUND __libcpp_remove_reference_t<_Tp>&& __t) _NOEXCEPT {
static_assert(!is_lvalue_reference<_Tp>::value, "cannot forward an rvalue as an lvalue");
return static_cast<_Tp&&>(__t);
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/__utility/forward_like.h b/contrib/libs/cxxsupp/libcxx/include/__utility/forward_like.h
index 1446964da5..7bb0d7d203 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__utility/forward_like.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__utility/forward_like.h
@@ -34,7 +34,8 @@ template <class _Ap, class _Bp>
using _ForwardLike = _OverrideRef<_Ap&&, _CopyConst<remove_reference_t<_Ap>, remove_reference_t<_Bp>>>;
template <class _Tp, class _Up>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto forward_like(_Up&& __ux) noexcept -> _ForwardLike<_Tp, _Up> {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto forward_like(_LIBCPP_LIFETIMEBOUND _Up&& __ux) noexcept
+ -> _ForwardLike<_Tp, _Up> {
return static_cast<_ForwardLike<_Tp, _Up>>(__ux);
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/__utility/in_place.h b/contrib/libs/cxxsupp/libcxx/include/__utility/in_place.h
index bedd9e1e00..a3518455e2 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__utility/in_place.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__utility/in_place.h
@@ -10,7 +10,8 @@
#define _LIBCPP___UTILITY_IN_PLACE_H
#include <__config>
-#include <type_traits>
+#include <__type_traits/remove_cvref.h>
+#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__utility/integer_sequence.h b/contrib/libs/cxxsupp/libcxx/include/__utility/integer_sequence.h
index 87c76e9d92..257b4301c0 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__utility/integer_sequence.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__utility/integer_sequence.h
@@ -10,7 +10,8 @@
#define _LIBCPP___UTILITY_INTEGER_SEQUENCE_H
#include <__config>
-#include <type_traits>
+#include <__type_traits/is_integral.h>
+#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -137,6 +138,14 @@ template<size_t _Np>
template<class... _Tp>
using index_sequence_for = make_index_sequence<sizeof...(_Tp)>;
+# if _LIBCPP_STD_VER > 17
+// Executes __func for every element in an index_sequence.
+template <size_t... _Index, class _Function>
+_LIBCPP_HIDE_FROM_ABI constexpr void __for_each_index_sequence(index_sequence<_Index...>, _Function __func) {
+ (__func.template operator()<_Index>(), ...);
+}
+# endif // _LIBCPP_STD_VER > 17
+
#endif // _LIBCPP_STD_VER > 11
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/include/__utility/move.h b/contrib/libs/cxxsupp/libcxx/include/__utility/move.h
index 522673005b..4859c39e8b 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__utility/move.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__utility/move.h
@@ -11,7 +11,10 @@
#define _LIBCPP___UTILITY_MOVE_H
#include <__config>
-#include <type_traits>
+#include <__type_traits/conditional.h>
+#include <__type_traits/is_copy_constructible.h>
+#include <__type_traits/is_nothrow_move_constructible.h>
+#include <__type_traits/remove_reference.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -20,8 +23,8 @@
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp>
-_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __libcpp_remove_reference_t<_Tp>&&
-move(_Tp&& __t) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __libcpp_remove_reference_t<_Tp>&&
+move(_LIBCPP_LIFETIMEBOUND _Tp&& __t) _NOEXCEPT {
typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tp> _Up;
return static_cast<_Up&&>(__t);
}
@@ -31,9 +34,9 @@ using __move_if_noexcept_result_t =
__conditional_t<!is_nothrow_move_constructible<_Tp>::value && is_copy_constructible<_Tp>::value, const _Tp&, _Tp&&>;
template <class _Tp>
-_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 __move_if_noexcept_result_t<_Tp>
-move_if_noexcept(_Tp& __x) _NOEXCEPT {
- return _VSTD::move(__x);
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __move_if_noexcept_result_t<_Tp>
+move_if_noexcept(_LIBCPP_LIFETIMEBOUND _Tp& __x) _NOEXCEPT {
+ return std::move(__x);
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/include/__utility/pair.h b/contrib/libs/cxxsupp/libcxx/include/__utility/pair.h
index d928689118..8151674bcc 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__utility/pair.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__utility/pair.h
@@ -15,16 +15,33 @@
#include <__functional/unwrap_ref.h>
#include <__fwd/get.h>
#include <__fwd/tuple.h>
-#include <__tuple/sfinae_helpers.h>
-#include <__tuple/tuple_element.h>
-#include <__tuple/tuple_indices.h>
-#include <__tuple/tuple_size.h>
+#include <__tuple_dir/sfinae_helpers.h>
+#include <__tuple_dir/tuple_element.h>
+#include <__tuple_dir/tuple_indices.h>
+#include <__tuple_dir/tuple_size.h>
+#include <__type_traits/common_reference.h>
+#include <__type_traits/common_type.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/is_assignable.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_copy_assignable.h>
+#include <__type_traits/is_default_constructible.h>
#include <__type_traits/is_implicitly_default_constructible.h>
+#include <__type_traits/is_move_assignable.h>
+#include <__type_traits/is_nothrow_assignable.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_nothrow_copy_assignable.h>
+#include <__type_traits/is_nothrow_copy_constructible.h>
+#include <__type_traits/is_nothrow_default_constructible.h>
+#include <__type_traits/is_nothrow_move_assignable.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_swappable.h>
+#include <__type_traits/nat.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#include <__utility/piecewise_construct.h>
#include <cstddef>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__utility/rel_ops.h b/contrib/libs/cxxsupp/libcxx/include/__utility/rel_ops.h
index 2577e94e91..5f8d42c0b2 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__utility/rel_ops.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__utility/rel_ops.h
@@ -10,9 +10,6 @@
#define _LIBCPP___UTILITY_REL_OPS_H
#include <__config>
-#include <__utility/forward.h>
-#include <__utility/move.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__utility/swap.h b/contrib/libs/cxxsupp/libcxx/include/__utility/swap.h
index 545614aeca..0843b35a8b 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__utility/swap.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__utility/swap.h
@@ -10,10 +10,14 @@
#define _LIBCPP___UTILITY_SWAP_H
#include <__config>
+#include <__type_traits/is_move_assignable.h>
+#include <__type_traits/is_move_constructible.h>
+#include <__type_traits/is_nothrow_move_assignable.h>
+#include <__type_traits/is_nothrow_move_constructible.h>
+#include <__type_traits/is_swappable.h>
#include <__utility/declval.h>
#include <__utility/move.h>
#include <cstddef>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__utility/to_underlying.h b/contrib/libs/cxxsupp/libcxx/include/__utility/to_underlying.h
index 3428406e8d..a194d3ef28 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__utility/to_underlying.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__utility/to_underlying.h
@@ -11,7 +11,7 @@
#define _LIBCPP___UTILITY_TO_UNDERLYING_H
#include <__config>
-#include <type_traits>
+#include <__type_traits/underlying_type.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/__utility/transaction.h b/contrib/libs/cxxsupp/libcxx/include/__utility/transaction.h
deleted file mode 100644
index dc65c349d1..0000000000
--- a/contrib/libs/cxxsupp/libcxx/include/__utility/transaction.h
+++ /dev/null
@@ -1,97 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___UTILITY_TRANSACTION_H
-#define _LIBCPP___UTILITY_TRANSACTION_H
-
-#include <__config>
-#include <__utility/exchange.h>
-#include <__utility/move.h>
-#include <type_traits>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-// __transaction is a helper class for writing code with the strong exception guarantee.
-//
-// When writing code that can throw an exception, one can store rollback instructions in a
-// transaction so that if an exception is thrown at any point during the lifetime of the
-// transaction, it will be rolled back automatically. When the transaction is done, one
-// must mark it as being complete so it isn't rolled back when the transaction is destroyed.
-//
-// Transactions are not default constructible, they can't be copied or assigned to, but
-// they can be moved around for convenience.
-//
-// __transaction can help greatly simplify code that would normally be cluttered by
-// `#if _LIBCPP_NO_EXCEPTIONS`. For example:
-//
-// template <class Iterator, class Size, class OutputIterator>
-// Iterator uninitialized_copy_n(Iterator iter, Size n, OutputIterator out) {
-// typedef typename iterator_traits<Iterator>::value_type value_type;
-// __transaction transaction([start=out, &out] {
-// std::destroy(start, out);
-// });
-//
-// for (; n > 0; ++iter, ++out, --n) {
-// ::new ((void*)std::addressof(*out)) value_type(*iter);
-// }
-// transaction.__complete();
-// return out;
-// }
-//
-template <class _Rollback>
-struct __transaction {
- __transaction() = delete;
-
- _LIBCPP_HIDE_FROM_ABI
- _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __transaction(_Rollback __rollback)
- : __rollback_(_VSTD::move(__rollback))
- , __completed_(false)
- { }
-
- _LIBCPP_HIDE_FROM_ABI
- _LIBCPP_CONSTEXPR_SINCE_CXX20 __transaction(__transaction&& __other)
- _NOEXCEPT_(is_nothrow_move_constructible<_Rollback>::value)
- : __rollback_(_VSTD::move(__other.__rollback_))
- , __completed_(__other.__completed_)
- {
- __other.__completed_ = true;
- }
-
- __transaction(__transaction const&) = delete;
- __transaction& operator=(__transaction const&) = delete;
- __transaction& operator=(__transaction&&) = delete;
-
- _LIBCPP_HIDE_FROM_ABI
- _LIBCPP_CONSTEXPR_SINCE_CXX20 void __complete() _NOEXCEPT {
- __completed_ = true;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__transaction() {
- if (!__completed_)
- __rollback_();
- }
-
-private:
- _Rollback __rollback_;
- bool __completed_;
-};
-_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__transaction);
-
-template <class _Rollback>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __transaction<_Rollback> __make_transaction(_Rollback __rollback) {
- return __transaction<_Rollback>(std::move(__rollback));
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP___UTILITY_TRANSACTION_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__utility/unreachable.h b/contrib/libs/cxxsupp/libcxx/include/__utility/unreachable.h
index 485edb227c..d93e60b10b 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__utility/unreachable.h
+++ b/contrib/libs/cxxsupp/libcxx/include/__utility/unreachable.h
@@ -9,8 +9,8 @@
#ifndef _LIBCPP___UTILITY_UNREACHABLE_H
#define _LIBCPP___UTILITY_UNREACHABLE_H
+#include <__assert>
#include <__config>
-#include <cstdlib>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -18,21 +18,17 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI inline void __libcpp_unreachable()
-{
-#if __has_builtin(__builtin_unreachable)
- __builtin_unreachable();
-#else
- std::abort();
-#endif
+_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI inline void __libcpp_unreachable() {
+ _LIBCPP_ASSERT(false, "std::unreachable() was reached");
+ __builtin_unreachable();
}
#if _LIBCPP_STD_VER > 20
[[noreturn]] _LIBCPP_HIDE_FROM_ABI inline void unreachable() { __libcpp_unreachable(); }
-#endif // _LIBCPP_STD_VER > 20
+#endif
_LIBCPP_END_NAMESPACE_STD
-#endif
+#endif // _LIBCPP___UTILITY_UNREACHABLE_H
diff --git a/contrib/libs/cxxsupp/libcxx/include/__verbose_abort b/contrib/libs/cxxsupp/libcxx/include/__verbose_abort
index fddef4900e..a16d75d5ac 100644
--- a/contrib/libs/cxxsupp/libcxx/include/__verbose_abort
+++ b/contrib/libs/cxxsupp/libcxx/include/__verbose_abort
@@ -17,35 +17,41 @@
# pragma GCC system_header
#endif
-// Provide a default implementation of __libcpp_verbose_abort if we know that neither the built
-// library nor the user is providing one. Otherwise, just declare it and use the one from the
-// built library or the one provided by the user.
-//
-// We can't provide a great implementation because it needs to be pretty much
-// dependency-free (this is included everywhere else in the library).
-#if defined(_LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY) && !defined(_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED)
-
-extern "C" void abort();
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-_LIBCPP_NORETURN _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) _LIBCPP_HIDE_FROM_ABI inline
-void __libcpp_verbose_abort(const char *, ...) {
- ::abort();
- __builtin_unreachable(); // never reached, but needed to tell the compiler that the function never returns
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#else
-
_LIBCPP_BEGIN_NAMESPACE_STD
+// This function should never be called directly from the code -- it should only be called through
+// the _LIBCPP_VERBOSE_ABORT macro.
_LIBCPP_NORETURN _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2)
void __libcpp_verbose_abort(const char *__format, ...);
-_LIBCPP_END_NAMESPACE_STD
+// _LIBCPP_VERBOSE_ABORT(format, args...)
+//
+// This macro is used to abort the program abnormally while providing additional diagnostic information.
+//
+// The first argument is a printf-style format string, and the remaining arguments are values to format
+// into the format-string. This macro can be customized by users to provide fine-grained control over
+// how verbose termination is triggered.
+//
+// If the user does not supply their own version of the _LIBCPP_VERBOSE_ABORT macro, we pick the default
+// behavior based on whether we know the built library we're running against provides support for the
+// verbose termination handler or not. If it does, we call it. If it doesn't, we call __builtin_abort to
+// make sure that the program terminates but without taking any complex dependencies in this header.
+#if !defined(_LIBCPP_VERBOSE_ABORT)
+
+// Support _LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED until LLVM 18, but tell people
+// to move to customizing _LIBCPP_VERBOSE_ABORT instead.
+# if defined(_LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY) && defined(_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED)
+# undef _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY
+# warning _LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED is deprecated, please customize _LIBCPP_VERBOSE_ABORT instead
+# endif
+
+# if defined(_LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY)
+# define _LIBCPP_VERBOSE_ABORT(...) __builtin_abort()
+# else
+# define _LIBCPP_VERBOSE_ABORT(...) ::std::__libcpp_verbose_abort(__VA_ARGS__)
+# endif
+#endif // !defined(_LIBCPP_VERBOSE_ABORT)
-#endif
+_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___VERBOSE_ABORT
diff --git a/contrib/libs/cxxsupp/libcxx/include/algorithm b/contrib/libs/cxxsupp/libcxx/include/algorithm
index 85639ec448..a4351eaf9c 100644
--- a/contrib/libs/cxxsupp/libcxx/include/algorithm
+++ b/contrib/libs/cxxsupp/libcxx/include/algorithm
@@ -1704,11 +1704,9 @@ template <class BidirectionalIterator, class Compare>
*/
#include <__assert> // all public C++ headers provide the assertion handler
-#include <__bits>
#include <__config>
#include <__debug>
#include <cstddef>
-#include <cstring>
#include <type_traits>
#include <version>
@@ -1918,6 +1916,7 @@ template <class BidirectionalIterator, class Compare>
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <atomic>
# include <concepts>
+# include <cstring>
# include <iterator>
# include <memory>
# include <stdexcept>
diff --git a/contrib/libs/cxxsupp/libcxx/include/any b/contrib/libs/cxxsupp/libcxx/include/any
index ec5171ff71..50a44d7f4d 100644
--- a/contrib/libs/cxxsupp/libcxx/include/any
+++ b/contrib/libs/cxxsupp/libcxx/include/any
@@ -138,7 +138,9 @@ add_pointer_t<_ValueType> any_cast(any *) _NOEXCEPT;
namespace __any_imp
{
+ _LIBCPP_SUPPRESS_DEPRECATED_PUSH
using _Buffer = aligned_storage_t<3*sizeof(void*), alignment_of<void*>::value>;
+ _LIBCPP_SUPPRESS_DEPRECATED_POP
template <class _Tp>
using _IsSmallObject = integral_constant<bool
@@ -173,7 +175,7 @@ namespace __any_imp
inline _LIBCPP_INLINE_VISIBILITY
bool __compare_typeid(type_info const* __id, const void* __fallback_id)
{
-#if !defined(_LIBCPP_NO_RTTI)
+#if !defined(_LIBCPP_HAS_NO_RTTI)
if (__id && *__id == typeid(_Tp))
return true;
#endif
@@ -292,7 +294,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
bool has_value() const _NOEXCEPT { return __h_ != nullptr; }
-#if !defined(_LIBCPP_NO_RTTI)
+#if !defined(_LIBCPP_HAS_NO_RTTI)
_LIBCPP_INLINE_VISIBILITY
const type_info & type() const _NOEXCEPT {
if (__h_) {
@@ -424,7 +426,7 @@ namespace __any_imp
_LIBCPP_INLINE_VISIBILITY
static void* __type_info()
{
-#if !defined(_LIBCPP_NO_RTTI)
+#if !defined(_LIBCPP_HAS_NO_RTTI)
return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
#else
return nullptr;
@@ -512,7 +514,7 @@ namespace __any_imp
_LIBCPP_INLINE_VISIBILITY
static void* __type_info()
{
-#if !defined(_LIBCPP_NO_RTTI)
+#if !defined(_LIBCPP_HAS_NO_RTTI)
return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
#else
return nullptr;
@@ -678,7 +680,7 @@ any_cast(any * __any) _NOEXCEPT
typedef add_pointer_t<_ValueType> _ReturnType;
if (__any && __any->__h_) {
void *__p = __any->__call(_Action::_Get, nullptr,
-#if !defined(_LIBCPP_NO_RTTI)
+#if !defined(_LIBCPP_HAS_NO_RTTI)
&typeid(_ValueType),
#else
nullptr,
diff --git a/contrib/libs/cxxsupp/libcxx/include/array b/contrib/libs/cxxsupp/libcxx/include/array
index cb1a6d1202..068a6bd4cc 100644
--- a/contrib/libs/cxxsupp/libcxx/include/array
+++ b/contrib/libs/cxxsupp/libcxx/include/array
@@ -115,7 +115,7 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce
#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__iterator/reverse_iterator.h>
-#include <__tuple/sfinae_helpers.h>
+#include <__tuple_dir/sfinae_helpers.h>
#include <__utility/integer_sequence.h>
#include <__utility/move.h>
#include <__utility/unreachable.h>
@@ -137,8 +137,8 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce
#include <initializer_list>
// [tuple.helper]
-#include <__tuple/tuple_element.h>
-#include <__tuple/tuple_size.h>
+#include <__tuple_dir/tuple_element.h>
+#include <__tuple_dir/tuple_size.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/atomic b/contrib/libs/cxxsupp/libcxx/include/atomic
index fac146537d..d0d682da62 100644
--- a/contrib/libs/cxxsupp/libcxx/include/atomic
+++ b/contrib/libs/cxxsupp/libcxx/include/atomic
@@ -377,23 +377,23 @@ template<class T>
memory_order) noexcept;
template<class T>
- void atomic_wait(const volatile atomic<T>*, atomic<T>::value_type);
+ void atomic_wait(const volatile atomic<T>*, atomic<T>::value_type) noexcept;
template<class T>
- void atomic_wait(const atomic<T>*, atomic<T>::value_type);
+ void atomic_wait(const atomic<T>*, atomic<T>::value_type) noexcept;
template<class T>
void atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type,
- memory_order);
+ memory_order) noexcept;
template<class T>
void atomic_wait_explicit(const atomic<T>*, atomic<T>::value_type,
- memory_order);
+ memory_order) noexcept;
template<class T>
- void atomic_notify_one(volatile atomic<T>*);
+ void atomic_notify_one(volatile atomic<T>*) noexcept;
template<class T>
- void atomic_notify_one(atomic<T>*);
+ void atomic_notify_one(atomic<T>*) noexcept;
template<class T>
- void atomic_notify_all(volatile atomic<T>*);
+ void atomic_notify_all(volatile atomic<T>*) noexcept;
template<class T>
- void atomic_notify_all(atomic<T>*);
+ void atomic_notify_all(atomic<T>*) noexcept;
// Atomics for standard typedef types
@@ -524,10 +524,19 @@ template <class T>
#include <__config>
#include <__thread/poll_with_backoff.h>
#include <__thread/timed_backoff_policy.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_assignable.h>
+#include <__type_traits/is_function.h>
+#include <__type_traits/is_nothrow_default_constructible.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_trivially_copyable.h>
+#include <__type_traits/remove_const.h>
+#include <__type_traits/remove_pointer.h>
+#include <__type_traits/underlying_type.h>
#include <cstddef>
#include <cstdint>
#include <cstring>
-#include <type_traits>
#include <version>
#ifndef _LIBCPP_HAS_NO_THREADS
@@ -1452,10 +1461,10 @@ struct __libcpp_atomic_wait_backoff_impl {
{
if(__elapsed > chrono::microseconds(64))
{
- auto const __monitor = __libcpp_atomic_monitor(__a);
+ auto const __monitor = std::__libcpp_atomic_monitor(__a);
if(__test_fn())
return true;
- __libcpp_atomic_wait(__a, __monitor);
+ std::__libcpp_atomic_wait(__a, __monitor);
}
else if(__elapsed > chrono::microseconds(4))
__libcpp_thread_yield();
@@ -1470,7 +1479,7 @@ _LIBCPP_AVAILABILITY_SYNC
_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn)
{
__libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn};
- return __libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
+ return std::__libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
}
#else // _LIBCPP_HAS_NO_THREADS
@@ -1494,7 +1503,7 @@ struct __cxx_atomic_wait_test_fn_impl {
memory_order __order;
_LIBCPP_INLINE_VISIBILITY bool operator()() const
{
- return !__cxx_nonatomic_compare_equal(__cxx_atomic_load(__a, __order), __val);
+ return !std::__cxx_nonatomic_compare_equal(std::__cxx_atomic_load(__a, __order), __val);
}
};
@@ -1503,7 +1512,7 @@ _LIBCPP_AVAILABILITY_SYNC
_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order)
{
__cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
- return __cxx_atomic_wait(__a, __test_fn);
+ return std::__cxx_atomic_wait(__a, __test_fn);
}
// general atomic<T>
@@ -1526,78 +1535,78 @@ struct __atomic_base // false
_LIBCPP_INLINE_VISIBILITY
void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
_LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
- {__cxx_atomic_store(&__a_, __d, __m);}
+ {std::__cxx_atomic_store(&__a_, __d, __m);}
_LIBCPP_INLINE_VISIBILITY
void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
_LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
- {__cxx_atomic_store(&__a_, __d, __m);}
+ {std::__cxx_atomic_store(&__a_, __d, __m);}
_LIBCPP_INLINE_VISIBILITY
_Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
- {return __cxx_atomic_load(&__a_, __m);}
+ {return std::__cxx_atomic_load(&__a_, __m);}
_LIBCPP_INLINE_VISIBILITY
_Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
- {return __cxx_atomic_load(&__a_, __m);}
+ {return std::__cxx_atomic_load(&__a_, __m);}
_LIBCPP_INLINE_VISIBILITY
operator _Tp() const volatile _NOEXCEPT {return load();}
_LIBCPP_INLINE_VISIBILITY
operator _Tp() const _NOEXCEPT {return load();}
_LIBCPP_INLINE_VISIBILITY
_Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
- {return __cxx_atomic_exchange(&__a_, __d, __m);}
+ {return std::__cxx_atomic_exchange(&__a_, __d, __m);}
_LIBCPP_INLINE_VISIBILITY
_Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
- {return __cxx_atomic_exchange(&__a_, __d, __m);}
+ {return std::__cxx_atomic_exchange(&__a_, __d, __m);}
_LIBCPP_INLINE_VISIBILITY
bool compare_exchange_weak(_Tp& __e, _Tp __d,
memory_order __s, memory_order __f) volatile _NOEXCEPT
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
- {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
+ {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
_LIBCPP_INLINE_VISIBILITY
bool compare_exchange_weak(_Tp& __e, _Tp __d,
memory_order __s, memory_order __f) _NOEXCEPT
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
- {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
+ {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
_LIBCPP_INLINE_VISIBILITY
bool compare_exchange_strong(_Tp& __e, _Tp __d,
memory_order __s, memory_order __f) volatile _NOEXCEPT
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
- {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
+ {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
_LIBCPP_INLINE_VISIBILITY
bool compare_exchange_strong(_Tp& __e, _Tp __d,
memory_order __s, memory_order __f) _NOEXCEPT
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
- {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
+ {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
_LIBCPP_INLINE_VISIBILITY
bool compare_exchange_weak(_Tp& __e, _Tp __d,
memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
- {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
+ {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
_LIBCPP_INLINE_VISIBILITY
bool compare_exchange_weak(_Tp& __e, _Tp __d,
memory_order __m = memory_order_seq_cst) _NOEXCEPT
- {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
+ {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
_LIBCPP_INLINE_VISIBILITY
bool compare_exchange_strong(_Tp& __e, _Tp __d,
memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
- {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
+ {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
_LIBCPP_INLINE_VISIBILITY
bool compare_exchange_strong(_Tp& __e, _Tp __d,
memory_order __m = memory_order_seq_cst) _NOEXCEPT
- {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
+ {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
- {__cxx_atomic_wait(&__a_, __v, __m);}
+ {std::__cxx_atomic_wait(&__a_, __v, __m);}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
- {__cxx_atomic_wait(&__a_, __v, __m);}
+ {std::__cxx_atomic_wait(&__a_, __v, __m);}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT
- {__cxx_atomic_notify_one(&__a_);}
+ {std::__cxx_atomic_notify_one(&__a_);}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT
- {__cxx_atomic_notify_one(&__a_);}
+ {std::__cxx_atomic_notify_one(&__a_);}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT
- {__cxx_atomic_notify_all(&__a_);}
+ {std::__cxx_atomic_notify_all(&__a_);}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT
- {__cxx_atomic_notify_all(&__a_);}
+ {std::__cxx_atomic_notify_all(&__a_);}
#if _LIBCPP_STD_VER > 17
_LIBCPP_INLINE_VISIBILITY constexpr
@@ -1634,34 +1643,34 @@ struct __atomic_base<_Tp, true>
_LIBCPP_INLINE_VISIBILITY
_Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
- {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
+ {return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);}
_LIBCPP_INLINE_VISIBILITY
_Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
- {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
+ {return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);}
_LIBCPP_INLINE_VISIBILITY
_Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
- {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
+ {return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
_LIBCPP_INLINE_VISIBILITY
_Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
- {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
+ {return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
_LIBCPP_INLINE_VISIBILITY
_Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
- {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
+ {return std::__cxx_atomic_fetch_and(&this->__a_, __op, __m);}
_LIBCPP_INLINE_VISIBILITY
_Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
- {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
+ {return std::__cxx_atomic_fetch_and(&this->__a_, __op, __m);}
_LIBCPP_INLINE_VISIBILITY
_Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
- {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
+ {return std::__cxx_atomic_fetch_or(&this->__a_, __op, __m);}
_LIBCPP_INLINE_VISIBILITY
_Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
- {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
+ {return std::__cxx_atomic_fetch_or(&this->__a_, __op, __m);}
_LIBCPP_INLINE_VISIBILITY
_Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
- {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
+ {return std::__cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
_LIBCPP_INLINE_VISIBILITY
_Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
- {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
+ {return std::__cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
_LIBCPP_INLINE_VISIBILITY
_Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));}
@@ -1760,28 +1769,28 @@ struct atomic<_Tp*>
_Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
// __atomic_fetch_add accepts function pointers, guard against them.
static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
- return __cxx_atomic_fetch_add(&this->__a_, __op, __m);
+ return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);
}
_LIBCPP_INLINE_VISIBILITY
_Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
// __atomic_fetch_add accepts function pointers, guard against them.
static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
- return __cxx_atomic_fetch_add(&this->__a_, __op, __m);
+ return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);
}
_LIBCPP_INLINE_VISIBILITY
_Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
// __atomic_fetch_add accepts function pointers, guard against them.
static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
- return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);
+ return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);
}
_LIBCPP_INLINE_VISIBILITY
_Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
// __atomic_fetch_add accepts function pointers, guard against them.
static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
- return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);
+ return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);
}
_LIBCPP_INLINE_VISIBILITY
@@ -1838,7 +1847,7 @@ _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
void
atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
{
- __cxx_atomic_init(&__o->__a_, __d);
+ std::__cxx_atomic_init(&__o->__a_, __d);
}
template <class _Tp>
@@ -1846,7 +1855,7 @@ _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
void
atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
{
- __cxx_atomic_init(&__o->__a_, __d);
+ std::__cxx_atomic_init(&__o->__a_, __d);
}
// atomic_store
@@ -2099,7 +2108,7 @@ void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
__o->notify_one();
}
-// atomic_notify_one
+// atomic_notify_all
template <class _Tp>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
@@ -2655,13 +2664,10 @@ typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
_LIBCPP_END_NAMESPACE_STD
-#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17
-# include <chrono>
-#endif
-
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <cmath>
# include <compare>
+# include <type_traits>
#endif
#endif // _LIBCPP_ATOMIC
diff --git a/contrib/libs/cxxsupp/libcxx/include/barrier b/contrib/libs/cxxsupp/libcxx/include/barrier
index a2f753677b..2e8906b713 100644
--- a/contrib/libs/cxxsupp/libcxx/include/barrier
+++ b/contrib/libs/cxxsupp/libcxx/include/barrier
@@ -125,7 +125,7 @@ public:
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
__barrier_base(ptrdiff_t __expected, _CompletionF __completion = _CompletionF())
- : __expected_(__expected), __base_(__construct_barrier_algorithm_base(this->__expected_),
+ : __expected_(__expected), __base_(std::__construct_barrier_algorithm_base(this->__expected_),
&__destroy_barrier_algorithm_base),
__expected_adjustment_(0), __completion_(std::move(__completion)), __phase_(0)
{
@@ -150,7 +150,7 @@ public:
auto const __test_fn = [this, __old_phase]() -> bool {
return __phase_.load(memory_order_acquire) != __old_phase;
};
- __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy());
+ std::__libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy());
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void arrive_and_drop()
diff --git a/contrib/libs/cxxsupp/libcxx/include/bit b/contrib/libs/cxxsupp/libcxx/include/bit
index d2061d3e6f..d17a6e45f0 100644
--- a/contrib/libs/cxxsupp/libcxx/include/bit
+++ b/contrib/libs/cxxsupp/libcxx/include/bit
@@ -63,193 +63,29 @@ namespace std {
#include <__assert> // all public C++ headers provide the assertion handler
#include <__bit/bit_cast.h>
+#include <__bit/bit_ceil.h>
+#include <__bit/bit_floor.h>
+#include <__bit/bit_log2.h>
+#include <__bit/bit_width.h>
+#include <__bit/blsr.h>
#include <__bit/byteswap.h>
-#include <__bits> // __libcpp_clz
-#include <__concepts/arithmetic.h>
+#include <__bit/countl.h>
+#include <__bit/countr.h>
+#include <__bit/endian.h>
+#include <__bit/has_single_bit.h>
+#include <__bit/popcount.h>
+#include <__bit/rotate.h>
#include <__config>
-#include <limits>
-#include <type_traits>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template<class _Tp>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
-_Tp __rotr(_Tp __t, unsigned int __cnt) _NOEXCEPT
-{
- static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotr requires an unsigned integer type");
- const unsigned int __dig = numeric_limits<_Tp>::digits;
- if ((__cnt % __dig) == 0)
- return __t;
- return (__t >> (__cnt % __dig)) | (__t << (__dig - (__cnt % __dig)));
-}
-
-template<class _Tp>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
-int __countl_zero(_Tp __t) _NOEXCEPT
-{
- static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countl_zero requires an unsigned integer type");
- if (__t == 0)
- return numeric_limits<_Tp>::digits;
-
- if (sizeof(_Tp) <= sizeof(unsigned int))
- return std::__libcpp_clz(static_cast<unsigned int>(__t))
- - (numeric_limits<unsigned int>::digits - numeric_limits<_Tp>::digits);
- else if (sizeof(_Tp) <= sizeof(unsigned long))
- return std::__libcpp_clz(static_cast<unsigned long>(__t))
- - (numeric_limits<unsigned long>::digits - numeric_limits<_Tp>::digits);
- else if (sizeof(_Tp) <= sizeof(unsigned long long))
- return std::__libcpp_clz(static_cast<unsigned long long>(__t))
- - (numeric_limits<unsigned long long>::digits - numeric_limits<_Tp>::digits);
- else
- {
- int __ret = 0;
- int __iter = 0;
- const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits;
- while (true) {
- __t = std::__rotr(__t, __ulldigits);
- if ((__iter = std::__countl_zero(static_cast<unsigned long long>(__t))) != __ulldigits)
- break;
- __ret += __iter;
- }
- return __ret + __iter;
- }
-}
-
-#if _LIBCPP_STD_VER > 17
-
-template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, unsigned int __cnt) noexcept {
- const unsigned int __dig = numeric_limits<_Tp>::digits;
- if ((__cnt % __dig) == 0)
- return __t;
- return (__t << (__cnt % __dig)) | (__t >> (__dig - (__cnt % __dig)));
-}
-
-template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, unsigned int __cnt) noexcept {
- return std::__rotr(__t, __cnt);
-}
-
-template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr int countl_zero(_Tp __t) noexcept {
- return std::__countl_zero(__t);
-}
-
-template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept {
- return __t != numeric_limits<_Tp>::max() ? std::countl_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits;
-}
-
-template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept {
- if (__t == 0)
- return numeric_limits<_Tp>::digits;
-
- if (sizeof(_Tp) <= sizeof(unsigned int))
- return std::__libcpp_ctz(static_cast<unsigned int>(__t));
- else if (sizeof(_Tp) <= sizeof(unsigned long))
- return std::__libcpp_ctz(static_cast<unsigned long>(__t));
- else if (sizeof(_Tp) <= sizeof(unsigned long long))
- return std::__libcpp_ctz(static_cast<unsigned long long>(__t));
- else {
- int __ret = 0;
- const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits;
- while (static_cast<unsigned long long>(__t) == 0uLL) {
- __ret += __ulldigits;
- __t >>= __ulldigits;
- }
- return __ret + std::__libcpp_ctz(static_cast<unsigned long long>(__t));
- }
-}
-
-template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept {
- return __t != numeric_limits<_Tp>::max() ? std::countr_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits;
-}
-
-template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept {
- if (sizeof(_Tp) <= sizeof(unsigned int))
- return std::__libcpp_popcount(static_cast<unsigned int>(__t));
- else if (sizeof(_Tp) <= sizeof(unsigned long))
- return std::__libcpp_popcount(static_cast<unsigned long>(__t));
- else if (sizeof(_Tp) <= sizeof(unsigned long long))
- return std::__libcpp_popcount(static_cast<unsigned long long>(__t));
- else {
- int __ret = 0;
- while (__t != 0) {
- __ret += std::__libcpp_popcount(static_cast<unsigned long long>(__t));
- __t >>= numeric_limits<unsigned long long>::digits;
- }
- return __ret;
- }
-}
-
-template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept {
- return __t != 0 && (((__t & (__t - 1)) == 0));
-}
-
-// integral log base 2
-template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr _Tp __bit_log2(_Tp __t) noexcept {
- return numeric_limits<_Tp>::digits - 1 - std::countl_zero(__t);
-}
-
-template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_floor(_Tp __t) noexcept {
- return __t == 0 ? 0 : _Tp{1} << std::__bit_log2(__t);
-}
-
-template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_ceil(_Tp __t) noexcept {
- if (__t < 2)
- return 1;
- const unsigned __n = numeric_limits<_Tp>::digits - std::countl_zero((_Tp)(__t - 1u));
- _LIBCPP_ASSERT(__n != numeric_limits<_Tp>::digits, "Bad input to bit_ceil");
-
- if constexpr (sizeof(_Tp) >= sizeof(unsigned))
- return _Tp{1} << __n;
- else {
- const unsigned __extra = numeric_limits<unsigned>::digits - numeric_limits<_Tp>::digits;
- const unsigned __retVal = 1u << (__n + __extra);
- return (_Tp)(__retVal >> __extra);
- }
-}
-
-template <__libcpp_unsigned_integer _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr int bit_width(_Tp __t) noexcept {
- return __t == 0 ? 0 : std::__bit_log2(__t) + 1;
-}
-
-enum class endian {
- little = 0xDEAD,
- big = 0xFACE,
-# if defined(_LIBCPP_LITTLE_ENDIAN)
- native = little
-# elif defined(_LIBCPP_BIG_ENDIAN)
- native = big
-# else
- native = 0xCAFE
-# endif
-};
-
-#endif // _LIBCPP_STD_VER > 17
-
-_LIBCPP_END_NAMESPACE_STD
-
-_LIBCPP_POP_MACROS
-
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <iosfwd>
+# include <limits>
+# include <type_traits>
#endif
#endif // _LIBCPP_BIT
diff --git a/contrib/libs/cxxsupp/libcxx/include/charconv b/contrib/libs/cxxsupp/libcxx/include/charconv
index 4063117b30..9c74ce3c69 100644
--- a/contrib/libs/cxxsupp/libcxx/include/charconv
+++ b/contrib/libs/cxxsupp/libcxx/include/charconv
@@ -80,7 +80,7 @@ namespace std {
#include <__algorithm/copy_n.h>
#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
-#include <__bits>
+#include <__bit/countl.h>
#include <__charconv/chars_format.h>
#include <__charconv/from_chars_result.h>
#include <__charconv/tables.h>
@@ -231,7 +231,7 @@ template <typename _Tp, typename _Up>
inline _LIBCPP_HIDE_FROM_ABI bool
_LIBCPP_CONSTEXPR_SINCE_CXX23 __mul_overflowed(_Tp __a, _Up __b, _Tp& __r)
{
- return __mul_overflowed(__a, static_cast<_Tp>(__b), __r);
+ return __itoa::__mul_overflowed(__a, static_cast<_Tp>(__b), __r);
}
template <typename _Tp>
@@ -257,7 +257,7 @@ struct _LIBCPP_HIDDEN __traits : __traits_base<_Tp>
__a = __inner_product(__cprod + __i + 1, __cprod + __j, __pow() + 1,
__cprod[__i]);
- if (__mul_overflowed(__cprod[__j], __pow()[__j - __i], __b))
+ if (__itoa::__mul_overflowed(__cprod[__j], __pow()[__j - __i], __b))
--__p;
return __p;
}
@@ -284,16 +284,20 @@ __complement(_Tp __x)
template <typename _Tp>
inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
+__to_chars_itoa(char* __first, char* __last, _Tp __value, false_type);
+
+template <typename _Tp>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
__to_chars_itoa(char* __first, char* __last, _Tp __value, true_type)
{
- auto __x = __to_unsigned_like(__value);
+ auto __x = std::__to_unsigned_like(__value);
if (__value < 0 && __first != __last)
{
*__first++ = '-';
- __x = __complement(__x);
+ __x = std::__complement(__x);
}
- return __to_chars_itoa(__first, __last, __x, false_type());
+ return std::__to_chars_itoa(__first, __last, __x, false_type());
}
template <typename _Tp>
@@ -331,19 +335,23 @@ __to_chars_itoa(char* __first, char* __last, __uint128_t __value, false_type)
}
#endif
+template <class _Tp>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
+__to_chars_integral(char* __first, char* __last, _Tp __value, int __base, false_type);
+
template <typename _Tp>
inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
__to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
true_type)
{
- auto __x = __to_unsigned_like(__value);
+ auto __x = std::__to_unsigned_like(__value);
if (__value < 0 && __first != __last)
{
*__first++ = '-';
- __x = __complement(__x);
+ __x = std::__complement(__x);
}
- return __to_chars_integral(__first, __last, __x, __base, false_type());
+ return std::__to_chars_integral(__first, __last, __x, __base, false_type());
}
namespace __itoa {
@@ -521,19 +529,19 @@ __to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
false_type)
{
if (__base == 10) [[likely]]
- return __to_chars_itoa(__first, __last, __value, false_type());
+ return std::__to_chars_itoa(__first, __last, __value, false_type());
switch (__base) {
case 2:
- return __to_chars_integral<2>(__first, __last, __value);
+ return std::__to_chars_integral<2>(__first, __last, __value);
case 8:
- return __to_chars_integral<8>(__first, __last, __value);
+ return std::__to_chars_integral<8>(__first, __last, __value);
case 16:
- return __to_chars_integral<16>(__first, __last, __value);
+ return std::__to_chars_integral<16>(__first, __last, __value);
}
ptrdiff_t __cap = __last - __first;
- int __n = __to_chars_integral_width(__value, __base);
+ int __n = std::__to_chars_integral_width(__value, __base);
if (__n > __cap)
return {__last, errc::value_too_large};
@@ -571,7 +579,7 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
__sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args)
{
using __tl = numeric_limits<_Tp>;
- decltype(__to_unsigned_like(__value)) __x;
+ decltype(std::__to_unsigned_like(__value)) __x;
bool __neg = (__first != __last && *__first == '-');
auto __r = __f(__neg ? __first + 1 : __first, __last, __x, __args...);
@@ -587,16 +595,16 @@ __sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args)
if (__neg)
{
- if (__x <= __complement(__to_unsigned_like(__tl::min())))
+ if (__x <= std::__complement(std::__to_unsigned_like(__tl::min())))
{
- __x = __complement(__x);
+ __x = std::__complement(__x);
std::copy_n(std::addressof(__x), 1, std::addressof(__value));
return __r;
}
}
else
{
- if (__x <= __to_unsigned_like(__tl::max()))
+ if (__x <= std::__to_unsigned_like(__tl::max()))
{
__value = __x;
return __r;
@@ -627,7 +635,7 @@ __in_pattern(_Tp __c, int __base)
{
if (__base <= 10)
return {'0' <= __c && __c < '0' + __base, __c - '0'};
- else if (__in_pattern(__c))
+ else if (std::__in_pattern(__c))
return {true, __c - '0'};
else if ('a' <= __c && __c < 'a' + __base - 10)
return {true, __c - 'a' + 10};
@@ -648,7 +656,7 @@ __subject_seq_combinator(_It __first, _It __last, _Tp& __value, _Fn __f,
};
auto __p = __find_non_zero(__first, __last);
- if (__p == __last || !__in_pattern(*__p, __args...))
+ if (__p == __last || !std::__in_pattern(*__p, __args...))
{
if (__p == __first)
return {__first, errc::invalid_argument};
@@ -664,7 +672,7 @@ __subject_seq_combinator(_It __first, _It __last, _Tp& __value, _Fn __f,
{
for (; __r.ptr != __last; ++__r.ptr)
{
- if (!__in_pattern(*__r.ptr, __args...))
+ if (!std::__in_pattern(*__r.ptr, __args...))
break;
}
}
@@ -679,13 +687,13 @@ __from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
using __tx = __itoa::__traits<_Tp>;
using __output_type = typename __tx::type;
- return __subject_seq_combinator(
+ return std::__subject_seq_combinator(
__first, __last, __value,
[](const char* __f, const char* __l,
_Tp& __val) -> from_chars_result {
__output_type __a, __b;
auto __p = __tx::__read(__f, __l, __a, __b);
- if (__p == __l || !__in_pattern(*__p))
+ if (__p == __l || !std::__in_pattern(*__p))
{
__output_type __m = numeric_limits<_Tp>::max();
if (__m >= __a && __m - __a >= __b)
@@ -702,8 +710,8 @@ template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0
inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
__from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
{
- using __t = decltype(__to_unsigned_like(__value));
- return __sign_combinator(__first, __last, __value, __from_chars_atoi<__t>);
+ using __t = decltype(std::__to_unsigned_like(__value));
+ return std::__sign_combinator(__first, __last, __value, __from_chars_atoi<__t>);
}
@@ -731,9 +739,9 @@ __from_chars_integral(const char* __first, const char* __last, _Tp& __value,
int __base)
{
if (__base == 10)
- return __from_chars_atoi(__first, __last, __value);
+ return std::__from_chars_atoi(__first, __last, __value);
- return __subject_seq_combinator(
+ return std::__subject_seq_combinator(
__first, __last, __value,
[](const char* __p, const char* __lastp, _Tp& __val,
int __b) -> from_chars_result {
@@ -778,16 +786,16 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
__from_chars_integral(const char* __first, const char* __last, _Tp& __value,
int __base)
{
- using __t = decltype(__to_unsigned_like(__value));
- return __sign_combinator(__first, __last, __value,
- __from_chars_integral<__t>, __base);
+ using __t = decltype(std::__to_unsigned_like(__value));
+ return std::__sign_combinator(__first, __last, __value,
+ __from_chars_integral<__t>, __base);
}
template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
from_chars(const char* __first, const char* __last, _Tp& __value)
{
- return __from_chars_atoi(__first, __last, __value);
+ return std::__from_chars_atoi(__first, __last, __value);
}
template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
@@ -795,7 +803,7 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
from_chars(const char* __first, const char* __last, _Tp& __value, int __base)
{
_LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]");
- return __from_chars_integral(__first, __last, __value, __base);
+ return std::__from_chars_integral(__first, __last, __value, __base);
}
_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
diff --git a/contrib/libs/cxxsupp/libcxx/include/chrono b/contrib/libs/cxxsupp/libcxx/include/chrono
index 40fea6f336..604fdf3a3c 100644
--- a/contrib/libs/cxxsupp/libcxx/include/chrono
+++ b/contrib/libs/cxxsupp/libcxx/include/chrono
@@ -385,18 +385,29 @@ class weekday_indexed;
constexpr bool operator==(const weekday_indexed& x, const weekday_indexed& y) noexcept;
constexpr bool operator!=(const weekday_indexed& x, const weekday_indexed& y) noexcept;
+template<class charT, class traits>
+ basic_ostream<charT, traits>&
+ operator<<(basic_ostream<charT, traits>& os, const weekday_indexed& wdi);
+
// 25.8.8, class weekday_last // C++20
class weekday_last;
constexpr bool operator==(const weekday_last& x, const weekday_last& y) noexcept;
constexpr bool operator!=(const weekday_last& x, const weekday_last& y) noexcept;
+template<class charT, class traits>
+ basic_ostream<charT, traits>&
+ operator<<(basic_ostream<charT, traits>& os, const weekday_last& wdl);
+
// 25.8.9, class month_day // C++20
class month_day;
constexpr bool operator==(const month_day& x, const month_day& y) noexcept;
constexpr strong_ordering operator<=>(const month_day& x, const month_day& y) noexcept;
+template<class charT, class traits>
+ basic_ostream<charT, traits>&
+ operator<<(basic_ostream<charT, traits>& os, const month_day& md);
// 25.8.10, class month_day_last // C++20
class month_day_last;
@@ -404,18 +415,30 @@ class month_day_last;
constexpr bool operator==(const month_day_last& x, const month_day_last& y) noexcept;
constexpr strong_ordering operator<=>(const month_day_last& x, const month_day_last& y) noexcept;
+template<class charT, class traits>
+ basic_ostream<charT, traits>&
+ operator<<(basic_ostream<charT, traits>& os, const month_day_last& mdl);
+
// 25.8.11, class month_weekday // C++20
class month_weekday;
constexpr bool operator==(const month_weekday& x, const month_weekday& y) noexcept;
constexpr bool operator!=(const month_weekday& x, const month_weekday& y) noexcept;
+template<class charT, class traits>
+ basic_ostream<charT, traits>&
+ operator<<(basic_ostream<charT, traits>& os, const month_weekday& mwd);
+
// 25.8.12, class month_weekday_last // C++20
class month_weekday_last;
constexpr bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept;
constexpr bool operator!=(const month_weekday_last& x, const month_weekday_last& y) noexcept;
+template<class charT, class traits>
+ basic_ostream<charT, traits>&
+ operator<<(basic_ostream<charT, traits>& os, const month_weekday_last& mwdl);
+
// 25.8.13, class year_month // C++20
class year_month;
@@ -431,6 +454,10 @@ constexpr year_month operator+(const year_month& ym, const years& dy) noexcept;
constexpr year_month operator+(const years& dy, const year_month& ym) noexcept;
constexpr year_month operator-(const year_month& ym, const years& dy) noexcept;
+template<class charT, class traits>
+ basic_ostream<charT, traits>&
+ operator<<(basic_ostream<charT, traits>& os, const year_month& ym);
+
// 25.8.14, class year_month_day class // C++20
year_month_day;
@@ -444,6 +471,9 @@ constexpr year_month_day operator+(const years& dy, const year_month_day& ymd) n
constexpr year_month_day operator-(const year_month_day& ymd, const months& dm) noexcept;
constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept;
+template<class charT, class traits>
+ basic_ostream<charT, traits>&
+ operator<<(basic_ostream<charT, traits>& os, const year_month_day& ymd);
// 25.8.15, class year_month_day_last // C++20
class year_month_day_last;
@@ -464,6 +494,10 @@ constexpr year_month_day_last
constexpr year_month_day_last
operator-(const year_month_day_last& ymdl, const years& dy) noexcept;
+template<class charT, class traits>
+ basic_ostream<charT, traits>&
+ operator<<(basic_ostream<charT, traits>& os, const year_month_day_last& ymdl);
+
// 25.8.16, class year_month_weekday // C++20
class year_month_weekday;
@@ -485,6 +519,10 @@ constexpr year_month_weekday
constexpr year_month_weekday
operator-(const year_month_weekday& ymwd, const years& dy) noexcept;
+template<class charT, class traits>
+ basic_ostream<charT, traits>&
+ operator<<(basic_ostream<charT, traits>& os, const year_month_weekday& ymwd);
+
// 25.8.17, class year_month_weekday_last // C++20
class year_month_weekday_last;
@@ -505,6 +543,10 @@ constexpr year_month_weekday_last
constexpr year_month_weekday_last
operator-(const year_month_weekday_last& ymwdl, const years& dy) noexcept;
+template<class charT, class traits>
+ basic_ostream<charT, traits>&
+ operator<<(basic_ostream<charT, traits>& os, const year_month_weekday_last& ymwdl);
+
// 25.8.18, civil calendar conventional syntax operators // C++20
constexpr year_month
operator/(const year& y, const month& m) noexcept;
@@ -638,6 +680,17 @@ namespace std {
template<class charT> struct formatter<chrono::month, charT>; // C++20
template<class charT> struct formatter<chrono::year, charT>; // C++20
template<class charT> struct formatter<chrono::weekday, charT>; // C++20
+ template<class charT> struct formatter<chrono::weekday_indexed, charT>; // C++20
+ template<class charT> struct formatter<chrono::weekday_last, charT>; // C++20
+ template<class charT> struct formatter<chrono::month_day, charT>; // C++20
+ template<class charT> struct formatter<chrono::month_day_last, charT>; // C++20
+ template<class charT> struct formatter<chrono::month_weekday, charT>; // C++20
+ template<class charT> struct formatter<chrono::month_weekday_last, charT>; // C++20
+ template<class charT> struct formatter<chrono::year_month, charT>; // C++20
+ template<class charT> struct formatter<chrono::year_month_day, charT>; // C++20
+ template<class charT> struct formatter<chrono::year_month_day_last, charT>; // C++20
+ template<class charT> struct formatter<chrono::year_month_weekday, charT>; // C++20
+ template<class charT> struct formatter<chrono::year_month_weekday_last, charT>; // C++20
} // namespace std
namespace chrono {
diff --git a/contrib/libs/cxxsupp/libcxx/include/cmath b/contrib/libs/cxxsupp/libcxx/include/cmath
index ef3a67843e..a27d0ebceb 100644
--- a/contrib/libs/cxxsupp/libcxx/include/cmath
+++ b/contrib/libs/cxxsupp/libcxx/include/cmath
@@ -306,7 +306,12 @@ constexpr long double lerp(long double a, long double b, long double t) noexcept
#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
-#include <type_traits>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_arithmetic.h>
+#include <__type_traits/is_constant_evaluated.h>
+#include <__type_traits/is_floating_point.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/remove_cv.h>
#include <version>
#include <math.h>
@@ -558,14 +563,14 @@ hypot(_A1 __lcpp_x, _A2 __lcpp_y, _A3 __lcpp_z) _NOEXCEPT
static_assert((!(is_same<_A1, __result_type>::value &&
is_same<_A2, __result_type>::value &&
is_same<_A3, __result_type>::value)), "");
- return hypot((__result_type)__lcpp_x, (__result_type)__lcpp_y, (__result_type)__lcpp_z);
+ return std::hypot((__result_type)__lcpp_x, (__result_type)__lcpp_y, (__result_type)__lcpp_z);
}
#endif
template <class _A1>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR typename enable_if<is_floating_point<_A1>::value, bool>::type
-__libcpp_isnan_or_builtin(_A1 __lcpp_x) _NOEXCEPT
+__constexpr_isnan(_A1 __lcpp_x) _NOEXCEPT
{
#if __has_builtin(__builtin_isnan)
return __builtin_isnan(__lcpp_x);
@@ -577,15 +582,15 @@ __libcpp_isnan_or_builtin(_A1 __lcpp_x) _NOEXCEPT
template <class _A1>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR typename enable_if<!is_floating_point<_A1>::value, bool>::type
-__libcpp_isnan_or_builtin(_A1 __lcpp_x) _NOEXCEPT
+__constexpr_isnan(_A1 __lcpp_x) _NOEXCEPT
{
- return isnan(__lcpp_x);
+ return std::isnan(__lcpp_x);
}
template <class _A1>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR typename enable_if<is_floating_point<_A1>::value, bool>::type
-__libcpp_isinf_or_builtin(_A1 __lcpp_x) _NOEXCEPT
+__constexpr_isinf(_A1 __lcpp_x) _NOEXCEPT
{
#if __has_builtin(__builtin_isinf)
return __builtin_isinf(__lcpp_x);
@@ -597,15 +602,15 @@ __libcpp_isinf_or_builtin(_A1 __lcpp_x) _NOEXCEPT
template <class _A1>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR typename enable_if<!is_floating_point<_A1>::value, bool>::type
-__libcpp_isinf_or_builtin(_A1 __lcpp_x) _NOEXCEPT
+__constexpr_isinf(_A1 __lcpp_x) _NOEXCEPT
{
- return isinf(__lcpp_x);
+ return std::isinf(__lcpp_x);
}
template <class _A1>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR typename enable_if<is_floating_point<_A1>::value, bool>::type
-__libcpp_isfinite_or_builtin(_A1 __lcpp_x) _NOEXCEPT
+__constexpr_isfinite(_A1 __lcpp_x) _NOEXCEPT
{
#if __has_builtin(__builtin_isfinite)
return __builtin_isfinite(__lcpp_x);
@@ -617,9 +622,164 @@ __libcpp_isfinite_or_builtin(_A1 __lcpp_x) _NOEXCEPT
template <class _A1>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR typename enable_if<!is_floating_point<_A1>::value, bool>::type
-__libcpp_isfinite_or_builtin(_A1 __lcpp_x) _NOEXCEPT
+__constexpr_isfinite(_A1 __lcpp_x) _NOEXCEPT
{
- return isfinite(__lcpp_x);
+ return __builtin_isfinite(__lcpp_x);
+}
+
+_LIBCPP_CONSTEXPR inline _LIBCPP_HIDE_FROM_ABI float __constexpr_copysign(float __x, float __y) _NOEXCEPT {
+ return __builtin_copysignf(__x, __y);
+}
+
+_LIBCPP_CONSTEXPR inline _LIBCPP_HIDE_FROM_ABI double __constexpr_copysign(double __x, double __y) _NOEXCEPT {
+ return __builtin_copysign(__x, __y);
+}
+
+_LIBCPP_CONSTEXPR inline _LIBCPP_HIDE_FROM_ABI long double
+__constexpr_copysign(long double __x, long double __y) _NOEXCEPT {
+ return __builtin_copysignl(__x, __y);
+}
+
+template <class _A1, class _A2>
+_LIBCPP_CONSTEXPR inline _LIBCPP_HIDE_FROM_ABI
+ typename std::__enable_if_t<std::is_arithmetic<_A1>::value && std::is_arithmetic<_A2>::value,
+ std::__promote<_A1, _A2> >::type
+ __constexpr_copysign(_A1 __x, _A2 __y) _NOEXCEPT {
+ typedef typename std::__promote<_A1, _A2>::type __result_type;
+ static_assert((!(std::_IsSame<_A1, __result_type>::value && std::_IsSame<_A2, __result_type>::value)), "");
+ return __builtin_copysign((__result_type)__x, (__result_type)__y);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR float __constexpr_fabs(float __x) _NOEXCEPT {
+ return __builtin_fabsf(__x);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR double __constexpr_fabs(double __x) _NOEXCEPT {
+ return __builtin_fabs(__x);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR long double __constexpr_fabs(long double __x) _NOEXCEPT {
+ return __builtin_fabsl(__x);
+}
+
+template <class _Tp, __enable_if_t<is_integral<_Tp>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR double __constexpr_fabs(_Tp __x) _NOEXCEPT {
+ return __builtin_fabs(static_cast<double>(__x));
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 float __constexpr_fmax(float __x, float __y) _NOEXCEPT {
+#if !__has_constexpr_builtin(__builtin_fmaxf)
+ if (__libcpp_is_constant_evaluated()) {
+ if (std::__constexpr_isnan(__x))
+ return __y;
+ if (std::__constexpr_isnan(__y))
+ return __x;
+ return __x < __y ? __y : __x;
+ }
+#endif
+ return __builtin_fmaxf(__x, __y);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 double __constexpr_fmax(double __x, double __y) _NOEXCEPT {
+#if !__has_constexpr_builtin(__builtin_fmax)
+ if (__libcpp_is_constant_evaluated()) {
+ if (std::__constexpr_isnan(__x))
+ return __y;
+ if (std::__constexpr_isnan(__y))
+ return __x;
+ return __x < __y ? __y : __x;
+ }
+#endif
+ return __builtin_fmax(__x, __y);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 long double
+__constexpr_fmax(long double __x, long double __y) _NOEXCEPT {
+#if !__has_constexpr_builtin(__builtin_fmaxl)
+ if (__libcpp_is_constant_evaluated()) {
+ if (std::__constexpr_isnan(__x))
+ return __y;
+ if (std::__constexpr_isnan(__y))
+ return __x;
+ return __x < __y ? __y : __x;
+ }
+#endif
+ return __builtin_fmaxl(__x, __y);
+}
+
+template <class _Tp, class _Up, __enable_if_t<is_arithmetic<_Tp>::value && is_arithmetic<_Up>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename __promote<_Tp, _Up>::type
+__constexpr_fmax(_Tp __x, _Up __y) _NOEXCEPT {
+ using __result_type = typename __promote<_Tp, _Up>::type;
+ return std::__constexpr_fmax(static_cast<__result_type>(__x), static_cast<__result_type>(__y));
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __constexpr_logb(_Tp __x) {
+#if !__has_constexpr_builtin(__builtin_logb)
+ if (__libcpp_is_constant_evaluated()) {
+ if (__x == _Tp(0)) {
+ // raise FE_DIVBYZERO
+ return -numeric_limits<_Tp>::infinity();
+ }
+
+ if (std::__constexpr_isinf(__x))
+ return numeric_limits<_Tp>::infinity();
+
+ if (std::__constexpr_isnan(__x))
+ return numeric_limits<_Tp>::quiet_NaN();
+
+ __x = std::__constexpr_fabs(__x);
+ unsigned long long __exp = 0;
+ while (__x >= numeric_limits<_Tp>::radix) {
+ __x /= numeric_limits<_Tp>::radix;
+ __exp += 1;
+ }
+ return _Tp(__exp);
+ }
+#endif // !__has_constexpr_builtin(__builtin_logb)
+ return __builtin_logb(__x);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp __constexpr_scalbn(_Tp __x, int __exp) {
+#if !__has_constexpr_builtin(__builtin_scalbln)
+ if (__libcpp_is_constant_evaluated()) {
+ if (__x == _Tp(0))
+ return __x;
+
+ if (std::__constexpr_isinf(__x))
+ return __x;
+
+ if (__exp == _Tp(0))
+ return __x;
+
+ if (std::__constexpr_isnan(__x))
+ return numeric_limits<_Tp>::quiet_NaN();
+
+ _Tp __mult(1);
+ if (__exp > 0) {
+ __mult = numeric_limits<_Tp>::radix;
+ --__exp;
+ } else {
+ ++__exp;
+ __exp = -__exp;
+ __mult /= numeric_limits<_Tp>::radix;
+ }
+
+ while (__exp > 0) {
+ if (!(__exp & 1)) {
+ __mult *= __mult;
+ __exp >>= 1;
+ } else {
+ __x *= __mult;
+ --__exp;
+ }
+ }
+ return __x;
+ }
+#endif // !__has_constexpr_builtin(__builtin_scalbln)
+ return __builtin_scalbn(__x, __exp);
}
#if _LIBCPP_STD_VER > 17
@@ -661,7 +821,7 @@ lerp(_A1 __a, _A2 __b, _A3 __t) noexcept
static_assert(!(_IsSame<_A1, __result_type>::value &&
_IsSame<_A2, __result_type>::value &&
_IsSame<_A3, __result_type>::value));
- return __lerp((__result_type)__a, (__result_type)__b, (__result_type)__t);
+ return std::__lerp((__result_type)__a, (__result_type)__b, (__result_type)__t);
}
#endif // _LIBCPP_STD_VER > 17
@@ -669,4 +829,8 @@ _LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
+#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+# include <type_traits>
+#endif
+
#endif // _LIBCPP_CMATH
diff --git a/contrib/libs/cxxsupp/libcxx/include/compare b/contrib/libs/cxxsupp/libcxx/include/compare
index 6aa1abefd3..9272dbf62b 100644
--- a/contrib/libs/cxxsupp/libcxx/include/compare
+++ b/contrib/libs/cxxsupp/libcxx/include/compare
@@ -160,4 +160,8 @@ namespace std {
# pragma GCC system_header
#endif
+#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+# include <type_traits>
+#endif
+
#endif // _LIBCPP_COMPARE
diff --git a/contrib/libs/cxxsupp/libcxx/include/complex b/contrib/libs/cxxsupp/libcxx/include/complex
index 293ec3d439..cac901af46 100644
--- a/contrib/libs/cxxsupp/libcxx/include/complex
+++ b/contrib/libs/cxxsupp/libcxx/include/complex
@@ -29,21 +29,21 @@ public:
T real() const; // constexpr in C++14
T imag() const; // constexpr in C++14
- void real(T);
- void imag(T);
-
- complex<T>& operator= (const T&);
- complex<T>& operator+=(const T&);
- complex<T>& operator-=(const T&);
- complex<T>& operator*=(const T&);
- complex<T>& operator/=(const T&);
-
- complex& operator=(const complex&);
- template<class X> complex<T>& operator= (const complex<X>&);
- template<class X> complex<T>& operator+=(const complex<X>&);
- template<class X> complex<T>& operator-=(const complex<X>&);
- template<class X> complex<T>& operator*=(const complex<X>&);
- template<class X> complex<T>& operator/=(const complex<X>&);
+ void real(T); // constexpr in C++20
+ void imag(T); // constexpr in C++20
+
+ complex<T>& operator= (const T&); // constexpr in C++20
+ complex<T>& operator+=(const T&); // constexpr in C++20
+ complex<T>& operator-=(const T&); // constexpr in C++20
+ complex<T>& operator*=(const T&); // constexpr in C++20
+ complex<T>& operator/=(const T&); // constexpr in C++20
+
+ complex& operator=(const complex&); // constexpr in C++20
+ template<class X> complex<T>& operator= (const complex<X>&); // constexpr in C++20
+ template<class X> complex<T>& operator+=(const complex<X>&); // constexpr in C++20
+ template<class X> complex<T>& operator-=(const complex<X>&); // constexpr in C++20
+ template<class X> complex<T>& operator*=(const complex<X>&); // constexpr in C++20
+ template<class X> complex<T>& operator/=(const complex<X>&); // constexpr in C++20
};
template<>
@@ -57,22 +57,22 @@ public:
explicit constexpr complex(const complex<long double>&);
constexpr float real() const;
- void real(float);
+ void real(float); // constexpr in C++20
constexpr float imag() const;
- void imag(float);
-
- complex<float>& operator= (float);
- complex<float>& operator+=(float);
- complex<float>& operator-=(float);
- complex<float>& operator*=(float);
- complex<float>& operator/=(float);
-
- complex<float>& operator=(const complex<float>&);
- template<class X> complex<float>& operator= (const complex<X>&);
- template<class X> complex<float>& operator+=(const complex<X>&);
- template<class X> complex<float>& operator-=(const complex<X>&);
- template<class X> complex<float>& operator*=(const complex<X>&);
- template<class X> complex<float>& operator/=(const complex<X>&);
+ void imag(float); // constexpr in C++20
+
+ complex<float>& operator= (float); // constexpr in C++20
+ complex<float>& operator+=(float); // constexpr in C++20
+ complex<float>& operator-=(float); // constexpr in C++20
+ complex<float>& operator*=(float); // constexpr in C++20
+ complex<float>& operator/=(float); // constexpr in C++20
+
+ complex<float>& operator=(const complex<float>&); // constexpr in C++20
+ template<class X> complex<float>& operator= (const complex<X>&); // constexpr in C++20
+ template<class X> complex<float>& operator+=(const complex<X>&); // constexpr in C++20
+ template<class X> complex<float>& operator-=(const complex<X>&); // constexpr in C++20
+ template<class X> complex<float>& operator*=(const complex<X>&); // constexpr in C++20
+ template<class X> complex<float>& operator/=(const complex<X>&); // constexpr in C++20
};
template<>
@@ -86,22 +86,22 @@ public:
explicit constexpr complex(const complex<long double>&);
constexpr double real() const;
- void real(double);
+ void real(double); // constexpr in C++20
constexpr double imag() const;
- void imag(double);
-
- complex<double>& operator= (double);
- complex<double>& operator+=(double);
- complex<double>& operator-=(double);
- complex<double>& operator*=(double);
- complex<double>& operator/=(double);
- complex<double>& operator=(const complex<double>&);
-
- template<class X> complex<double>& operator= (const complex<X>&);
- template<class X> complex<double>& operator+=(const complex<X>&);
- template<class X> complex<double>& operator-=(const complex<X>&);
- template<class X> complex<double>& operator*=(const complex<X>&);
- template<class X> complex<double>& operator/=(const complex<X>&);
+ void imag(double); // constexpr in C++20
+
+ complex<double>& operator= (double); // constexpr in C++20
+ complex<double>& operator+=(double); // constexpr in C++20
+ complex<double>& operator-=(double); // constexpr in C++20
+ complex<double>& operator*=(double); // constexpr in C++20
+ complex<double>& operator/=(double); // constexpr in C++20
+ complex<double>& operator=(const complex<double>&); // constexpr in C++20
+
+ template<class X> complex<double>& operator= (const complex<X>&); // constexpr in C++20
+ template<class X> complex<double>& operator+=(const complex<X>&); // constexpr in C++20
+ template<class X> complex<double>& operator-=(const complex<X>&); // constexpr in C++20
+ template<class X> complex<double>& operator*=(const complex<X>&); // constexpr in C++20
+ template<class X> complex<double>& operator/=(const complex<X>&); // constexpr in C++20
};
template<>
@@ -115,39 +115,39 @@ public:
constexpr complex(const complex<double>&);
constexpr long double real() const;
- void real(long double);
+ void real(long double); // constexpr in C++20
constexpr long double imag() const;
- void imag(long double);
-
- complex<long double>& operator=(const complex<long double>&);
- complex<long double>& operator= (long double);
- complex<long double>& operator+=(long double);
- complex<long double>& operator-=(long double);
- complex<long double>& operator*=(long double);
- complex<long double>& operator/=(long double);
-
- template<class X> complex<long double>& operator= (const complex<X>&);
- template<class X> complex<long double>& operator+=(const complex<X>&);
- template<class X> complex<long double>& operator-=(const complex<X>&);
- template<class X> complex<long double>& operator*=(const complex<X>&);
- template<class X> complex<long double>& operator/=(const complex<X>&);
+ void imag(long double); // constexpr in C++20
+
+ complex<long double>& operator=(const complex<long double>&); // constexpr in C++20
+ complex<long double>& operator= (long double); // constexpr in C++20
+ complex<long double>& operator+=(long double); // constexpr in C++20
+ complex<long double>& operator-=(long double); // constexpr in C++20
+ complex<long double>& operator*=(long double); // constexpr in C++20
+ complex<long double>& operator/=(long double); // constexpr in C++20
+
+ template<class X> complex<long double>& operator= (const complex<X>&); // constexpr in C++20
+ template<class X> complex<long double>& operator+=(const complex<X>&); // constexpr in C++20
+ template<class X> complex<long double>& operator-=(const complex<X>&); // constexpr in C++20
+ template<class X> complex<long double>& operator*=(const complex<X>&); // constexpr in C++20
+ template<class X> complex<long double>& operator/=(const complex<X>&); // constexpr in C++20
};
// 26.3.6 operators:
-template<class T> complex<T> operator+(const complex<T>&, const complex<T>&);
-template<class T> complex<T> operator+(const complex<T>&, const T&);
-template<class T> complex<T> operator+(const T&, const complex<T>&);
-template<class T> complex<T> operator-(const complex<T>&, const complex<T>&);
-template<class T> complex<T> operator-(const complex<T>&, const T&);
-template<class T> complex<T> operator-(const T&, const complex<T>&);
-template<class T> complex<T> operator*(const complex<T>&, const complex<T>&);
-template<class T> complex<T> operator*(const complex<T>&, const T&);
-template<class T> complex<T> operator*(const T&, const complex<T>&);
-template<class T> complex<T> operator/(const complex<T>&, const complex<T>&);
-template<class T> complex<T> operator/(const complex<T>&, const T&);
-template<class T> complex<T> operator/(const T&, const complex<T>&);
-template<class T> complex<T> operator+(const complex<T>&);
-template<class T> complex<T> operator-(const complex<T>&);
+template<class T> complex<T> operator+(const complex<T>&, const complex<T>&); // constexpr in C++20
+template<class T> complex<T> operator+(const complex<T>&, const T&); // constexpr in C++20
+template<class T> complex<T> operator+(const T&, const complex<T>&); // constexpr in C++20
+template<class T> complex<T> operator-(const complex<T>&, const complex<T>&); // constexpr in C++20
+template<class T> complex<T> operator-(const complex<T>&, const T&); // constexpr in C++20
+template<class T> complex<T> operator-(const T&, const complex<T>&); // constexpr in C++20
+template<class T> complex<T> operator*(const complex<T>&, const complex<T>&); // constexpr in C++20
+template<class T> complex<T> operator*(const complex<T>&, const T&); // constexpr in C++20
+template<class T> complex<T> operator*(const T&, const complex<T>&); // constexpr in C++20
+template<class T> complex<T> operator/(const complex<T>&, const complex<T>&); // constexpr in C++20
+template<class T> complex<T> operator/(const complex<T>&, const T&); // constexpr in C++20
+template<class T> complex<T> operator/(const T&, const complex<T>&); // constexpr in C++20
+template<class T> complex<T> operator+(const complex<T>&); // constexpr in C++20
+template<class T> complex<T> operator-(const complex<T>&); // constexpr in C++20
template<class T> bool operator==(const complex<T>&, const complex<T>&); // constexpr in C++14
template<class T> bool operator==(const complex<T>&, const T&); // constexpr in C++14
template<class T> bool operator==(const T&, const complex<T>&); // constexpr in C++14
@@ -184,17 +184,17 @@ template<class T> T arg(const complex<T>&);
template<Integral T> double arg(T);
float arg(float);
-template<class T> T norm(const complex<T>&);
- long double norm(long double);
- double norm(double);
-template<Integral T> double norm(T);
- float norm(float);
+template<class T> T norm(const complex<T>&); // constexpr in C++20
+ long double norm(long double); // constexpr in C++20
+ double norm(double); // constexpr in C++20
+template<Integral T> double norm(T); // constexpr in C++20
+ float norm(float); // constexpr in C++20
-template<class T> complex<T> conj(const complex<T>&);
- complex<long double> conj(long double);
- complex<double> conj(double);
-template<Integral T> complex<double> conj(T);
- complex<float> conj(float);
+template<class T> complex<T> conj(const complex<T>&); // constexpr in C++20
+ complex<long double> conj(long double); // constexpr in C++20
+ complex<double> conj(double); // constexpr in C++20
+template<Integral T> complex<double> conj(T); // constexpr in C++20
+ complex<float> conj(float); // constexpr in C++20
template<class T> complex<T> proj(const complex<T>&);
complex<long double> proj(long double);
@@ -251,8 +251,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template<class _Tp> class _LIBCPP_TEMPLATE_VIS complex;
-template<class _Tp> _LIBCPP_HIDE_FROM_ABI complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w);
-template<class _Tp> _LIBCPP_HIDE_FROM_ABI complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y);
+template<class _Tp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w);
+template<class _Tp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y);
template<class _Tp>
class _LIBCPP_TEMPLATE_VIS complex
@@ -273,40 +273,40 @@ public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 value_type real() const {return __re_;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 value_type imag() const {return __im_;}
- _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
- _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) {__re_ = __re;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) {__im_ = __im;}
- _LIBCPP_INLINE_VISIBILITY complex& operator= (const value_type& __re)
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (const value_type& __re)
{__re_ = __re; __im_ = value_type(); return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator+=(const value_type& __re) {__re_ += __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator-=(const value_type& __re) {__re_ -= __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator*=(const value_type& __re) {__re_ *= __re; __im_ *= __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const value_type& __re) {__re_ += __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const value_type& __re) {__re_ -= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const value_type& __re) {__re_ *= __re; __im_ *= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
+ template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (const complex<_Xp>& __c)
{
__re_ = __c.real();
__im_ = __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
+ template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c)
{
__re_ += __c.real();
__im_ += __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
+ template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c)
{
__re_ -= __c.real();
__im_ -= __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
+ template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c)
{
*this = *this * complex(__c.real(), __c.imag());
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
+ template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c)
{
*this = *this / complex(__c.real(), __c.imag());
return *this;
@@ -334,40 +334,40 @@ public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float real() const {return __re_;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float imag() const {return __im_;}
- _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
- _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) {__re_ = __re;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) {__im_ = __im;}
- _LIBCPP_INLINE_VISIBILITY complex& operator= (float __re)
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (float __re)
{__re_ = __re; __im_ = value_type(); return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator+=(float __re) {__re_ += __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator-=(float __re) {__re_ -= __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator*=(float __re) {__re_ *= __re; __im_ *= __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator/=(float __re) {__re_ /= __re; __im_ /= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(float __re) {__re_ += __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(float __re) {__re_ -= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(float __re) {__re_ *= __re; __im_ *= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(float __re) {__re_ /= __re; __im_ /= __re; return *this;}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
+ template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (const complex<_Xp>& __c)
{
__re_ = __c.real();
__im_ = __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
+ template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c)
{
__re_ += __c.real();
__im_ += __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
+ template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c)
{
__re_ -= __c.real();
__im_ -= __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
+ template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c)
{
*this = *this * complex(__c.real(), __c.imag());
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
+ template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c)
{
*this = *this / complex(__c.real(), __c.imag());
return *this;
@@ -392,40 +392,40 @@ public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double real() const {return __re_;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double imag() const {return __im_;}
- _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
- _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) {__re_ = __re;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) {__im_ = __im;}
- _LIBCPP_INLINE_VISIBILITY complex& operator= (double __re)
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (double __re)
{__re_ = __re; __im_ = value_type(); return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator+=(double __re) {__re_ += __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator-=(double __re) {__re_ -= __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(double __re) {__re_ += __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(double __re) {__re_ -= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
+ template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (const complex<_Xp>& __c)
{
__re_ = __c.real();
__im_ = __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
+ template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c)
{
__re_ += __c.real();
__im_ += __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
+ template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c)
{
__re_ -= __c.real();
__im_ -= __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
+ template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c)
{
*this = *this * complex(__c.real(), __c.imag());
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
+ template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c)
{
*this = *this / complex(__c.real(), __c.imag());
return *this;
@@ -450,40 +450,40 @@ public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double real() const {return __re_;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double imag() const {return __im_;}
- _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
- _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) {__re_ = __re;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) {__im_ = __im;}
- _LIBCPP_INLINE_VISIBILITY complex& operator= (long double __re)
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (long double __re)
{__re_ = __re; __im_ = value_type(); return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator+=(long double __re) {__re_ += __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator-=(long double __re) {__re_ -= __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator*=(long double __re) {__re_ *= __re; __im_ *= __re; return *this;}
- _LIBCPP_INLINE_VISIBILITY complex& operator/=(long double __re) {__re_ /= __re; __im_ /= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(long double __re) {__re_ += __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(long double __re) {__re_ -= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(long double __re) {__re_ *= __re; __im_ *= __re; return *this;}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(long double __re) {__re_ /= __re; __im_ /= __re; return *this;}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
+ template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (const complex<_Xp>& __c)
{
__re_ = __c.real();
__im_ = __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
+ template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c)
{
__re_ += __c.real();
__im_ += __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
+ template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c)
{
__re_ -= __c.real();
__im_ -= __c.imag();
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
+ template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c)
{
*this = *this * complex(__c.real(), __c.imag());
return *this;
}
- template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
+ template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c)
{
*this = *this / complex(__c.real(), __c.imag());
return *this;
@@ -523,7 +523,7 @@ complex<long double>::complex(const complex<double>& __c)
// 26.3.6 operators:
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
complex<_Tp>
operator+(const complex<_Tp>& __x, const complex<_Tp>& __y)
{
@@ -533,7 +533,7 @@ operator+(const complex<_Tp>& __x, const complex<_Tp>& __y)
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
complex<_Tp>
operator+(const complex<_Tp>& __x, const _Tp& __y)
{
@@ -543,7 +543,7 @@ operator+(const complex<_Tp>& __x, const _Tp& __y)
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
complex<_Tp>
operator+(const _Tp& __x, const complex<_Tp>& __y)
{
@@ -553,7 +553,7 @@ operator+(const _Tp& __x, const complex<_Tp>& __y)
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
complex<_Tp>
operator-(const complex<_Tp>& __x, const complex<_Tp>& __y)
{
@@ -563,7 +563,7 @@ operator-(const complex<_Tp>& __x, const complex<_Tp>& __y)
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
complex<_Tp>
operator-(const complex<_Tp>& __x, const _Tp& __y)
{
@@ -573,7 +573,7 @@ operator-(const complex<_Tp>& __x, const _Tp& __y)
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
complex<_Tp>
operator-(const _Tp& __x, const complex<_Tp>& __y)
{
@@ -583,53 +583,86 @@ operator-(const _Tp& __x, const complex<_Tp>& __y)
}
template<class _Tp>
-_LIBCPP_HIDE_FROM_ABI complex<_Tp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
operator*(const complex<_Tp>& __z, const complex<_Tp>& __w)
{
_Tp __a = __z.real();
_Tp __b = __z.imag();
_Tp __c = __w.real();
_Tp __d = __w.imag();
+
+ // Avoid floating point operations that are invalid during constant evaluation
+ if (__libcpp_is_constant_evaluated()) {
+ bool __z_zero = __a == _Tp(0) && __b == _Tp(0);
+ bool __w_zero = __c == _Tp(0) && __d == _Tp(0);
+ bool __z_inf = std::__constexpr_isinf(__a) || std::__constexpr_isinf(__b);
+ bool __w_inf = std::__constexpr_isinf(__c) || std::__constexpr_isinf(__d);
+ bool __z_nan = !__z_inf && (
+ (std::__constexpr_isnan(__a) && std::__constexpr_isnan(__b))
+ || (std::__constexpr_isnan(__a) && __b == _Tp(0))
+ || (__a == _Tp(0) && std::__constexpr_isnan(__b))
+ );
+ bool __w_nan = !__w_inf && (
+ (std::__constexpr_isnan(__c) && std::__constexpr_isnan(__d))
+ || (std::__constexpr_isnan(__c) && __d == _Tp(0))
+ || (__c == _Tp(0) && std::__constexpr_isnan(__d))
+ );
+ if (__z_nan || __w_nan) {
+ return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));
+ }
+ if (__z_inf || __w_inf) {
+ if (__z_zero || __w_zero) {
+ return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));
+ }
+ return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity()));
+ }
+ bool __z_nonzero_nan = !__z_inf && !__z_nan && (std::__constexpr_isnan(__a) || std::__constexpr_isnan(__b));
+ bool __w_nonzero_nan = !__w_inf && !__w_nan && (std::__constexpr_isnan(__c) || std::__constexpr_isnan(__d));
+ if (__z_nonzero_nan || __w_nonzero_nan) {
+ return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));
+ }
+ }
+
_Tp __ac = __a * __c;
_Tp __bd = __b * __d;
_Tp __ad = __a * __d;
_Tp __bc = __b * __c;
_Tp __x = __ac - __bd;
_Tp __y = __ad + __bc;
- if (__libcpp_isnan_or_builtin(__x) && __libcpp_isnan_or_builtin(__y))
+ if (std::__constexpr_isnan(__x) && std::__constexpr_isnan(__y))
{
bool __recalc = false;
- if (__libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b))
+ if (std::__constexpr_isinf(__a) || std::__constexpr_isinf(__b))
{
- __a = copysign(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a);
- __b = copysign(__libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b);
- if (__libcpp_isnan_or_builtin(__c))
- __c = copysign(_Tp(0), __c);
- if (__libcpp_isnan_or_builtin(__d))
- __d = copysign(_Tp(0), __d);
+ __a = std::__constexpr_copysign(std::__constexpr_isinf(__a) ? _Tp(1) : _Tp(0), __a);
+ __b = std::__constexpr_copysign(std::__constexpr_isinf(__b) ? _Tp(1) : _Tp(0), __b);
+ if (std::__constexpr_isnan(__c))
+ __c = std::__constexpr_copysign(_Tp(0), __c);
+ if (std::__constexpr_isnan(__d))
+ __d = std::__constexpr_copysign(_Tp(0), __d);
__recalc = true;
}
- if (__libcpp_isinf_or_builtin(__c) || __libcpp_isinf_or_builtin(__d))
+ if (std::__constexpr_isinf(__c) || std::__constexpr_isinf(__d))
{
- __c = copysign(__libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c);
- __d = copysign(__libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d);
- if (__libcpp_isnan_or_builtin(__a))
- __a = copysign(_Tp(0), __a);
- if (__libcpp_isnan_or_builtin(__b))
- __b = copysign(_Tp(0), __b);
+ __c = std::__constexpr_copysign(std::__constexpr_isinf(__c) ? _Tp(1) : _Tp(0), __c);
+ __d = std::__constexpr_copysign(std::__constexpr_isinf(__d) ? _Tp(1) : _Tp(0), __d);
+ if (std::__constexpr_isnan(__a))
+ __a = std::__constexpr_copysign(_Tp(0), __a);
+ if (std::__constexpr_isnan(__b))
+ __b = std::__constexpr_copysign(_Tp(0), __b);
__recalc = true;
}
- if (!__recalc && (__libcpp_isinf_or_builtin(__ac) || __libcpp_isinf_or_builtin(__bd) ||
- __libcpp_isinf_or_builtin(__ad) || __libcpp_isinf_or_builtin(__bc)))
+ if (!__recalc && (std::__constexpr_isinf(__ac) || std::__constexpr_isinf(__bd) ||
+ std::__constexpr_isinf(__ad) || std::__constexpr_isinf(__bc)))
{
- if (__libcpp_isnan_or_builtin(__a))
- __a = copysign(_Tp(0), __a);
- if (__libcpp_isnan_or_builtin(__b))
- __b = copysign(_Tp(0), __b);
- if (__libcpp_isnan_or_builtin(__c))
- __c = copysign(_Tp(0), __c);
- if (__libcpp_isnan_or_builtin(__d))
- __d = copysign(_Tp(0), __d);
+ if (std::__constexpr_isnan(__a))
+ __a = std::__constexpr_copysign(_Tp(0), __a);
+ if (std::__constexpr_isnan(__b))
+ __b = std::__constexpr_copysign(_Tp(0), __b);
+ if (std::__constexpr_isnan(__c))
+ __c = std::__constexpr_copysign(_Tp(0), __c);
+ if (std::__constexpr_isnan(__d))
+ __d = std::__constexpr_copysign(_Tp(0), __d);
__recalc = true;
}
if (__recalc)
@@ -642,7 +675,7 @@ operator*(const complex<_Tp>& __z, const complex<_Tp>& __w)
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
complex<_Tp>
operator*(const complex<_Tp>& __x, const _Tp& __y)
{
@@ -652,7 +685,7 @@ operator*(const complex<_Tp>& __x, const _Tp& __y)
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
complex<_Tp>
operator*(const _Tp& __x, const complex<_Tp>& __y)
{
@@ -662,7 +695,7 @@ operator*(const _Tp& __x, const complex<_Tp>& __y)
}
template<class _Tp>
-_LIBCPP_HIDE_FROM_ABI complex<_Tp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
operator/(const complex<_Tp>& __z, const complex<_Tp>& __w)
{
int __ilogbw = 0;
@@ -670,34 +703,74 @@ operator/(const complex<_Tp>& __z, const complex<_Tp>& __w)
_Tp __b = __z.imag();
_Tp __c = __w.real();
_Tp __d = __w.imag();
- _Tp __logbw = logb(fmax(fabs(__c), fabs(__d)));
- if (__libcpp_isfinite_or_builtin(__logbw))
+ _Tp __logbw = std::__constexpr_logb(std::__constexpr_fmax(std::__constexpr_fabs(__c), std::__constexpr_fabs(__d)));
+ if (std::__constexpr_isfinite(__logbw))
{
__ilogbw = static_cast<int>(__logbw);
- __c = scalbn(__c, -__ilogbw);
- __d = scalbn(__d, -__ilogbw);
+ __c = std::__constexpr_scalbn(__c, -__ilogbw);
+ __d = std::__constexpr_scalbn(__d, -__ilogbw);
}
+
+ // Avoid floating point operations that are invalid during constant evaluation
+ if (__libcpp_is_constant_evaluated()) {
+ bool __z_zero = __a == _Tp(0) && __b == _Tp(0);
+ bool __w_zero = __c == _Tp(0) && __d == _Tp(0);
+ bool __z_inf = std::__constexpr_isinf(__a) || std::__constexpr_isinf(__b);
+ bool __w_inf = std::__constexpr_isinf(__c) || std::__constexpr_isinf(__d);
+ bool __z_nan = !__z_inf && (
+ (std::__constexpr_isnan(__a) && std::__constexpr_isnan(__b))
+ || (std::__constexpr_isnan(__a) && __b == _Tp(0))
+ || (__a == _Tp(0) && std::__constexpr_isnan(__b))
+ );
+ bool __w_nan = !__w_inf && (
+ (std::__constexpr_isnan(__c) && std::__constexpr_isnan(__d))
+ || (std::__constexpr_isnan(__c) && __d == _Tp(0))
+ || (__c == _Tp(0) && std::__constexpr_isnan(__d))
+ );
+ if ((__z_nan || __w_nan) || (__z_inf && __w_inf)) {
+ return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));
+ }
+ bool __z_nonzero_nan = !__z_inf && !__z_nan && (std::__constexpr_isnan(__a) || std::__constexpr_isnan(__b));
+ bool __w_nonzero_nan = !__w_inf && !__w_nan && (std::__constexpr_isnan(__c) || std::__constexpr_isnan(__d));
+ if (__z_nonzero_nan || __w_nonzero_nan) {
+ if (__w_zero) {
+ return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity()));
+ }
+ return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));
+ }
+ if (__w_inf) {
+ return complex<_Tp>(_Tp(0), _Tp(0));
+ }
+ if (__z_inf) {
+ return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity()));
+ }
+ if (__w_zero) {
+ if (__z_zero) {
+ return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));
+ }
+ return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity()));
+ }
+ }
+
_Tp __denom = __c * __c + __d * __d;
- _Tp __x = scalbn((__a * __c + __b * __d) / __denom, -__ilogbw);
- _Tp __y = scalbn((__b * __c - __a * __d) / __denom, -__ilogbw);
- if (__libcpp_isnan_or_builtin(__x) && __libcpp_isnan_or_builtin(__y))
+ _Tp __x = std::__constexpr_scalbn((__a * __c + __b * __d) / __denom, -__ilogbw);
+ _Tp __y = std::__constexpr_scalbn((__b * __c - __a * __d) / __denom, -__ilogbw);
+ if (std::__constexpr_isnan(__x) && std::__constexpr_isnan(__y))
{
- if ((__denom == _Tp(0)) && (!__libcpp_isnan_or_builtin(__a) || !__libcpp_isnan_or_builtin(__b)))
- {
- __x = copysign(_Tp(INFINITY), __c) * __a;
- __y = copysign(_Tp(INFINITY), __c) * __b;
- }
- else if ((__libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b)) && __libcpp_isfinite_or_builtin(__c) && __libcpp_isfinite_or_builtin(__d))
+ if ((__denom == _Tp(0)) && (!std::__constexpr_isnan(__a) || !std::__constexpr_isnan(__b)))
{
- __a = copysign(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a);
- __b = copysign(__libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b);
+ __x = std::__constexpr_copysign(_Tp(INFINITY), __c) * __a;
+ __y = std::__constexpr_copysign(_Tp(INFINITY), __c) * __b;
+ } else if ((std::__constexpr_isinf(__a) || std::__constexpr_isinf(__b)) && std::__constexpr_isfinite(__c) &&
+ std::__constexpr_isfinite(__d)) {
+ __a = std::__constexpr_copysign(std::__constexpr_isinf(__a) ? _Tp(1) : _Tp(0), __a);
+ __b = std::__constexpr_copysign(std::__constexpr_isinf(__b) ? _Tp(1) : _Tp(0), __b);
__x = _Tp(INFINITY) * (__a * __c + __b * __d);
__y = _Tp(INFINITY) * (__b * __c - __a * __d);
- }
- else if (__libcpp_isinf_or_builtin(__logbw) && __logbw > _Tp(0) && __libcpp_isfinite_or_builtin(__a) && __libcpp_isfinite_or_builtin(__b))
- {
- __c = copysign(__libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c);
- __d = copysign(__libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d);
+ } else if (std::__constexpr_isinf(__logbw) && __logbw > _Tp(0) && std::__constexpr_isfinite(__a) &&
+ std::__constexpr_isfinite(__b)) {
+ __c = std::__constexpr_copysign(std::__constexpr_isinf(__c) ? _Tp(1) : _Tp(0), __c);
+ __d = std::__constexpr_copysign(std::__constexpr_isinf(__d) ? _Tp(1) : _Tp(0), __d);
__x = _Tp(0) * (__a * __c + __b * __d);
__y = _Tp(0) * (__b * __c - __a * __d);
}
@@ -706,7 +779,7 @@ operator/(const complex<_Tp>& __z, const complex<_Tp>& __w)
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
complex<_Tp>
operator/(const complex<_Tp>& __x, const _Tp& __y)
{
@@ -714,7 +787,7 @@ operator/(const complex<_Tp>& __x, const _Tp& __y)
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
complex<_Tp>
operator/(const _Tp& __x, const complex<_Tp>& __y)
{
@@ -724,7 +797,7 @@ operator/(const _Tp& __x, const complex<_Tp>& __y)
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
complex<_Tp>
operator+(const complex<_Tp>& __x)
{
@@ -732,7 +805,7 @@ operator+(const complex<_Tp>& __x)
}
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
complex<_Tp>
operator-(const complex<_Tp>& __x)
{
@@ -853,7 +926,7 @@ inline _LIBCPP_INLINE_VISIBILITY
_Tp
abs(const complex<_Tp>& __c)
{
- return hypot(__c.real(), __c.imag());
+ return std::hypot(__c.real(), __c.imag());
}
// arg
@@ -863,7 +936,7 @@ inline _LIBCPP_INLINE_VISIBILITY
_Tp
arg(const complex<_Tp>& __c)
{
- return atan2(__c.imag(), __c.real());
+ return std::atan2(__c.imag(), __c.real());
}
template <class _Tp>
@@ -874,7 +947,7 @@ typename enable_if<
>::type
arg(_Tp __re)
{
- return atan2l(0.L, __re);
+ return std::atan2l(0.L, __re);
}
template<class _Tp>
@@ -886,7 +959,7 @@ typename enable_if
>::type
arg(_Tp __re)
{
- return atan2(0., __re);
+ return std::atan2(0., __re);
}
template <class _Tp>
@@ -897,25 +970,25 @@ typename enable_if<
>::type
arg(_Tp __re)
{
- return atan2f(0.F, __re);
+ return std::atan2f(0.F, __re);
}
// norm
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
_Tp
norm(const complex<_Tp>& __c)
{
- if (__libcpp_isinf_or_builtin(__c.real()))
- return abs(__c.real());
- if (__libcpp_isinf_or_builtin(__c.imag()))
- return abs(__c.imag());
+ if (std::__constexpr_isinf(__c.real()))
+ return std::abs(__c.real());
+ if (std::__constexpr_isinf(__c.imag()))
+ return std::abs(__c.imag());
return __c.real() * __c.real() + __c.imag() * __c.imag();
}
template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
typename __libcpp_complex_overload_traits<_Tp>::_ValueType
norm(_Tp __re)
{
@@ -926,7 +999,7 @@ norm(_Tp __re)
// conj
template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
complex<_Tp>
conj(const complex<_Tp>& __c)
{
@@ -934,7 +1007,7 @@ conj(const complex<_Tp>& __c)
}
template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
typename __libcpp_complex_overload_traits<_Tp>::_ComplexType
conj(_Tp __re)
{
@@ -952,8 +1025,8 @@ complex<_Tp>
proj(const complex<_Tp>& __c)
{
complex<_Tp> __r = __c;
- if (__libcpp_isinf_or_builtin(__c.real()) || __libcpp_isinf_or_builtin(__c.imag()))
- __r = complex<_Tp>(INFINITY, copysign(_Tp(0), __c.imag()));
+ if (std::__constexpr_isinf(__c.real()) || std::__constexpr_isinf(__c.imag()))
+ __r = complex<_Tp>(INFINITY, std::copysign(_Tp(0), __c.imag()));
return __r;
}
@@ -966,8 +1039,8 @@ typename enable_if
>::type
proj(_Tp __re)
{
- if (__libcpp_isinf_or_builtin(__re))
- __re = abs(__re);
+ if (std::__constexpr_isinf(__re))
+ __re = std::abs(__re);
return complex<_Tp>(__re);
}
@@ -990,25 +1063,25 @@ template<class _Tp>
_LIBCPP_HIDE_FROM_ABI complex<_Tp>
polar(const _Tp& __rho, const _Tp& __theta = _Tp())
{
- if (__libcpp_isnan_or_builtin(__rho) || signbit(__rho))
+ if (std::__constexpr_isnan(__rho) || std::signbit(__rho))
return complex<_Tp>(_Tp(NAN), _Tp(NAN));
- if (__libcpp_isnan_or_builtin(__theta))
+ if (std::__constexpr_isnan(__theta))
{
- if (__libcpp_isinf_or_builtin(__rho))
+ if (std::__constexpr_isinf(__rho))
return complex<_Tp>(__rho, __theta);
return complex<_Tp>(__theta, __theta);
}
- if (__libcpp_isinf_or_builtin(__theta))
+ if (std::__constexpr_isinf(__theta))
{
- if (__libcpp_isinf_or_builtin(__rho))
+ if (std::__constexpr_isinf(__rho))
return complex<_Tp>(__rho, _Tp(NAN));
return complex<_Tp>(_Tp(NAN), _Tp(NAN));
}
- _Tp __x = __rho * cos(__theta);
- if (__libcpp_isnan_or_builtin(__x))
+ _Tp __x = __rho * std::cos(__theta);
+ if (std::__constexpr_isnan(__x))
__x = 0;
- _Tp __y = __rho * sin(__theta);
- if (__libcpp_isnan_or_builtin(__y))
+ _Tp __y = __rho * std::sin(__theta);
+ if (std::__constexpr_isnan(__y))
__y = 0;
return complex<_Tp>(__x, __y);
}
@@ -1020,7 +1093,7 @@ inline _LIBCPP_INLINE_VISIBILITY
complex<_Tp>
log(const complex<_Tp>& __x)
{
- return complex<_Tp>(log(abs(__x)), arg(__x));
+ return complex<_Tp>(std::log(std::abs(__x)), std::arg(__x));
}
// log10
@@ -1030,7 +1103,7 @@ inline _LIBCPP_INLINE_VISIBILITY
complex<_Tp>
log10(const complex<_Tp>& __x)
{
- return log(__x) / log(_Tp(10));
+ return std::log(__x) / std::log(_Tp(10));
}
// sqrt
@@ -1039,15 +1112,15 @@ template<class _Tp>
_LIBCPP_HIDE_FROM_ABI complex<_Tp>
sqrt(const complex<_Tp>& __x)
{
- if (__libcpp_isinf_or_builtin(__x.imag()))
+ if (std::__constexpr_isinf(__x.imag()))
return complex<_Tp>(_Tp(INFINITY), __x.imag());
- if (__libcpp_isinf_or_builtin(__x.real()))
+ if (std::__constexpr_isinf(__x.real()))
{
if (__x.real() > _Tp(0))
- return complex<_Tp>(__x.real(), __libcpp_isnan_or_builtin(__x.imag()) ? __x.imag() : copysign(_Tp(0), __x.imag()));
- return complex<_Tp>(__libcpp_isnan_or_builtin(__x.imag()) ? __x.imag() : _Tp(0), copysign(__x.real(), __x.imag()));
+ return complex<_Tp>(__x.real(), std::__constexpr_isnan(__x.imag()) ? __x.imag() : std::copysign(_Tp(0), __x.imag()));
+ return complex<_Tp>(std::__constexpr_isnan(__x.imag()) ? __x.imag() : _Tp(0), std::copysign(__x.real(), __x.imag()));
}
- return polar(sqrt(abs(__x)), arg(__x) / _Tp(2));
+ return std::polar(std::sqrt(std::abs(__x)), std::arg(__x) / _Tp(2));
}
// exp
@@ -1058,24 +1131,24 @@ exp(const complex<_Tp>& __x)
{
_Tp __i = __x.imag();
if (__i == 0) {
- return complex<_Tp>(exp(__x.real()), copysign(_Tp(0), __x.imag()));
+ return complex<_Tp>(std::exp(__x.real()), std::copysign(_Tp(0), __x.imag()));
}
- if (__libcpp_isinf_or_builtin(__x.real()))
+ if (std::__constexpr_isinf(__x.real()))
{
if (__x.real() < _Tp(0))
{
- if (!__libcpp_isfinite_or_builtin(__i))
+ if (!std::__constexpr_isfinite(__i))
__i = _Tp(1);
}
- else if (__i == 0 || !__libcpp_isfinite_or_builtin(__i))
+ else if (__i == 0 || !std::__constexpr_isfinite(__i))
{
- if (__libcpp_isinf_or_builtin(__i))
+ if (std::__constexpr_isinf(__i))
__i = _Tp(NAN);
return complex<_Tp>(__x.real(), __i);
}
}
- _Tp __e = exp(__x.real());
- return complex<_Tp>(__e * cos(__i), __e * sin(__i));
+ _Tp __e = std::exp(__x.real());
+ return complex<_Tp>(__e * std::cos(__i), __e * std::sin(__i));
}
// pow
@@ -1085,7 +1158,7 @@ inline _LIBCPP_INLINE_VISIBILITY
complex<_Tp>
pow(const complex<_Tp>& __x, const complex<_Tp>& __y)
{
- return exp(__y * log(__x));
+ return std::exp(__y * std::log(__x));
}
template<class _Tp, class _Up>
@@ -1141,26 +1214,26 @@ _LIBCPP_HIDE_FROM_ABI complex<_Tp>
asinh(const complex<_Tp>& __x)
{
const _Tp __pi(atan2(+0., -0.));
- if (__libcpp_isinf_or_builtin(__x.real()))
+ if (std::__constexpr_isinf(__x.real()))
{
- if (__libcpp_isnan_or_builtin(__x.imag()))
+ if (std::__constexpr_isnan(__x.imag()))
return __x;
- if (__libcpp_isinf_or_builtin(__x.imag()))
- return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag()));
- return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag()));
+ if (std::__constexpr_isinf(__x.imag()))
+ return complex<_Tp>(__x.real(), std::copysign(__pi * _Tp(0.25), __x.imag()));
+ return complex<_Tp>(__x.real(), std::copysign(_Tp(0), __x.imag()));
}
- if (__libcpp_isnan_or_builtin(__x.real()))
+ if (std::__constexpr_isnan(__x.real()))
{
- if (__libcpp_isinf_or_builtin(__x.imag()))
+ if (std::__constexpr_isinf(__x.imag()))
return complex<_Tp>(__x.imag(), __x.real());
if (__x.imag() == 0)
return __x;
return complex<_Tp>(__x.real(), __x.real());
}
- if (__libcpp_isinf_or_builtin(__x.imag()))
- return complex<_Tp>(copysign(__x.imag(), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
- complex<_Tp> __z = log(__x + sqrt(__sqr(__x) + _Tp(1)));
- return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag()));
+ if (std::__constexpr_isinf(__x.imag()))
+ return complex<_Tp>(std::copysign(__x.imag(), __x.real()), std::copysign(__pi/_Tp(2), __x.imag()));
+ complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) + _Tp(1)));
+ return complex<_Tp>(std::copysign(__z.real(), __x.real()), std::copysign(__z.imag(), __x.imag()));
}
// acosh
@@ -1170,31 +1243,31 @@ _LIBCPP_HIDE_FROM_ABI complex<_Tp>
acosh(const complex<_Tp>& __x)
{
const _Tp __pi(atan2(+0., -0.));
- if (__libcpp_isinf_or_builtin(__x.real()))
+ if (std::__constexpr_isinf(__x.real()))
{
- if (__libcpp_isnan_or_builtin(__x.imag()))
- return complex<_Tp>(abs(__x.real()), __x.imag());
- if (__libcpp_isinf_or_builtin(__x.imag()))
+ if (std::__constexpr_isnan(__x.imag()))
+ return complex<_Tp>(std::abs(__x.real()), __x.imag());
+ if (std::__constexpr_isinf(__x.imag()))
{
if (__x.real() > 0)
- return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag()));
+ return complex<_Tp>(__x.real(), std::copysign(__pi * _Tp(0.25), __x.imag()));
else
- return complex<_Tp>(-__x.real(), copysign(__pi * _Tp(0.75), __x.imag()));
+ return complex<_Tp>(-__x.real(), std::copysign(__pi * _Tp(0.75), __x.imag()));
}
if (__x.real() < 0)
- return complex<_Tp>(-__x.real(), copysign(__pi, __x.imag()));
- return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag()));
+ return complex<_Tp>(-__x.real(), std::copysign(__pi, __x.imag()));
+ return complex<_Tp>(__x.real(), std::copysign(_Tp(0), __x.imag()));
}
- if (__libcpp_isnan_or_builtin(__x.real()))
+ if (std::__constexpr_isnan(__x.real()))
{
- if (__libcpp_isinf_or_builtin(__x.imag()))
- return complex<_Tp>(abs(__x.imag()), __x.real());
+ if (std::__constexpr_isinf(__x.imag()))
+ return complex<_Tp>(std::abs(__x.imag()), __x.real());
return complex<_Tp>(__x.real(), __x.real());
}
- if (__libcpp_isinf_or_builtin(__x.imag()))
- return complex<_Tp>(abs(__x.imag()), copysign(__pi/_Tp(2), __x.imag()));
- complex<_Tp> __z = log(__x + sqrt(__sqr(__x) - _Tp(1)));
- return complex<_Tp>(copysign(__z.real(), _Tp(0)), copysign(__z.imag(), __x.imag()));
+ if (std::__constexpr_isinf(__x.imag()))
+ return complex<_Tp>(std::abs(__x.imag()), std::copysign(__pi/_Tp(2), __x.imag()));
+ complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) - _Tp(1)));
+ return complex<_Tp>(std::copysign(__z.real(), _Tp(0)), std::copysign(__z.imag(), __x.imag()));
}
// atanh
@@ -1204,30 +1277,30 @@ _LIBCPP_HIDE_FROM_ABI complex<_Tp>
atanh(const complex<_Tp>& __x)
{
const _Tp __pi(atan2(+0., -0.));
- if (__libcpp_isinf_or_builtin(__x.imag()))
+ if (std::__constexpr_isinf(__x.imag()))
{
- return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
+ return complex<_Tp>(std::copysign(_Tp(0), __x.real()), std::copysign(__pi/_Tp(2), __x.imag()));
}
- if (__libcpp_isnan_or_builtin(__x.imag()))
+ if (std::__constexpr_isnan(__x.imag()))
{
- if (__libcpp_isinf_or_builtin(__x.real()) || __x.real() == 0)
- return complex<_Tp>(copysign(_Tp(0), __x.real()), __x.imag());
+ if (std::__constexpr_isinf(__x.real()) || __x.real() == 0)
+ return complex<_Tp>(std::copysign(_Tp(0), __x.real()), __x.imag());
return complex<_Tp>(__x.imag(), __x.imag());
}
- if (__libcpp_isnan_or_builtin(__x.real()))
+ if (std::__constexpr_isnan(__x.real()))
{
return complex<_Tp>(__x.real(), __x.real());
}
- if (__libcpp_isinf_or_builtin(__x.real()))
+ if (std::__constexpr_isinf(__x.real()))
{
- return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
+ return complex<_Tp>(std::copysign(_Tp(0), __x.real()), std::copysign(__pi/_Tp(2), __x.imag()));
}
- if (abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0))
+ if (std::abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0))
{
- return complex<_Tp>(copysign(_Tp(INFINITY), __x.real()), copysign(_Tp(0), __x.imag()));
+ return complex<_Tp>(std::copysign(_Tp(INFINITY), __x.real()), std::copysign(_Tp(0), __x.imag()));
}
- complex<_Tp> __z = log((_Tp(1) + __x) / (_Tp(1) - __x)) / _Tp(2);
- return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag()));
+ complex<_Tp> __z = std::log((_Tp(1) + __x) / (_Tp(1) - __x)) / _Tp(2);
+ return complex<_Tp>(std::copysign(__z.real(), __x.real()), std::copysign(__z.imag(), __x.imag()));
}
// sinh
@@ -1236,13 +1309,13 @@ template<class _Tp>
_LIBCPP_HIDE_FROM_ABI complex<_Tp>
sinh(const complex<_Tp>& __x)
{
- if (__libcpp_isinf_or_builtin(__x.real()) && !__libcpp_isfinite_or_builtin(__x.imag()))
+ if (std::__constexpr_isinf(__x.real()) && !std::__constexpr_isfinite(__x.imag()))
return complex<_Tp>(__x.real(), _Tp(NAN));
- if (__x.real() == 0 && !__libcpp_isfinite_or_builtin(__x.imag()))
+ if (__x.real() == 0 && !std::__constexpr_isfinite(__x.imag()))
return complex<_Tp>(__x.real(), _Tp(NAN));
- if (__x.imag() == 0 && !__libcpp_isfinite_or_builtin(__x.real()))
+ if (__x.imag() == 0 && !std::__constexpr_isfinite(__x.real()))
return __x;
- return complex<_Tp>(sinh(__x.real()) * cos(__x.imag()), cosh(__x.real()) * sin(__x.imag()));
+ return complex<_Tp>(std::sinh(__x.real()) * std::cos(__x.imag()), std::cosh(__x.real()) * std::sin(__x.imag()));
}
// cosh
@@ -1251,15 +1324,15 @@ template<class _Tp>
_LIBCPP_HIDE_FROM_ABI complex<_Tp>
cosh(const complex<_Tp>& __x)
{
- if (__libcpp_isinf_or_builtin(__x.real()) && !__libcpp_isfinite_or_builtin(__x.imag()))
- return complex<_Tp>(abs(__x.real()), _Tp(NAN));
- if (__x.real() == 0 && !__libcpp_isfinite_or_builtin(__x.imag()))
+ if (std::__constexpr_isinf(__x.real()) && !std::__constexpr_isfinite(__x.imag()))
+ return complex<_Tp>(std::abs(__x.real()), _Tp(NAN));
+ if (__x.real() == 0 && !std::__constexpr_isfinite(__x.imag()))
return complex<_Tp>(_Tp(NAN), __x.real());
if (__x.real() == 0 && __x.imag() == 0)
return complex<_Tp>(_Tp(1), __x.imag());
- if (__x.imag() == 0 && !__libcpp_isfinite_or_builtin(__x.real()))
- return complex<_Tp>(abs(__x.real()), __x.imag());
- return complex<_Tp>(cosh(__x.real()) * cos(__x.imag()), sinh(__x.real()) * sin(__x.imag()));
+ if (__x.imag() == 0 && !std::__constexpr_isfinite(__x.real()))
+ return complex<_Tp>(std::abs(__x.real()), __x.imag());
+ return complex<_Tp>(std::cosh(__x.real()) * std::cos(__x.imag()), std::sinh(__x.real()) * std::sin(__x.imag()));
}
// tanh
@@ -1268,22 +1341,22 @@ template<class _Tp>
_LIBCPP_HIDE_FROM_ABI complex<_Tp>
tanh(const complex<_Tp>& __x)
{
- if (__libcpp_isinf_or_builtin(__x.real()))
+ if (std::__constexpr_isinf(__x.real()))
{
- if (!__libcpp_isfinite_or_builtin(__x.imag()))
- return complex<_Tp>(copysign(_Tp(1), __x.real()), _Tp(0));
- return complex<_Tp>(copysign(_Tp(1), __x.real()), copysign(_Tp(0), sin(_Tp(2) * __x.imag())));
+ if (!std::__constexpr_isfinite(__x.imag()))
+ return complex<_Tp>(std::copysign(_Tp(1), __x.real()), _Tp(0));
+ return complex<_Tp>(std::copysign(_Tp(1), __x.real()), std::copysign(_Tp(0), std::sin(_Tp(2) * __x.imag())));
}
- if (__libcpp_isnan_or_builtin(__x.real()) && __x.imag() == 0)
+ if (std::__constexpr_isnan(__x.real()) && __x.imag() == 0)
return __x;
_Tp __2r(_Tp(2) * __x.real());
_Tp __2i(_Tp(2) * __x.imag());
- _Tp __d(cosh(__2r) + cos(__2i));
- _Tp __2rsh(sinh(__2r));
- if (__libcpp_isinf_or_builtin(__2rsh) && __libcpp_isinf_or_builtin(__d))
+ _Tp __d(std::cosh(__2r) + std::cos(__2i));
+ _Tp __2rsh(std::sinh(__2r));
+ if (std::__constexpr_isinf(__2rsh) && std::__constexpr_isinf(__d))
return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1),
__2i > _Tp(0) ? _Tp(0) : _Tp(-0.));
- return complex<_Tp>(__2rsh/__d, sin(__2i)/__d);
+ return complex<_Tp>(__2rsh/__d, std::sin(__2i)/__d);
}
// asin
@@ -1292,7 +1365,7 @@ template<class _Tp>
_LIBCPP_HIDE_FROM_ABI complex<_Tp>
asin(const complex<_Tp>& __x)
{
- complex<_Tp> __z = asinh(complex<_Tp>(-__x.imag(), __x.real()));
+ complex<_Tp> __z = std::asinh(complex<_Tp>(-__x.imag(), __x.real()));
return complex<_Tp>(__z.imag(), -__z.real());
}
@@ -1303,34 +1376,35 @@ _LIBCPP_HIDE_FROM_ABI complex<_Tp>
acos(const complex<_Tp>& __x)
{
const _Tp __pi(atan2(+0., -0.));
- if (__libcpp_isinf_or_builtin(__x.real()))
+ if (std::__constexpr_isinf(__x.real()))
{
- if (__libcpp_isnan_or_builtin(__x.imag()))
+ if (std::__constexpr_isnan(__x.imag()))
return complex<_Tp>(__x.imag(), __x.real());
- if (__libcpp_isinf_or_builtin(__x.imag()))
+ if (std::__constexpr_isinf(__x.imag()))
{
if (__x.real() < _Tp(0))
return complex<_Tp>(_Tp(0.75) * __pi, -__x.imag());
return complex<_Tp>(_Tp(0.25) * __pi, -__x.imag());
}
if (__x.real() < _Tp(0))
- return complex<_Tp>(__pi, signbit(__x.imag()) ? -__x.real() : __x.real());
- return complex<_Tp>(_Tp(0), signbit(__x.imag()) ? __x.real() : -__x.real());
+ return complex<_Tp>(__pi, std::signbit(__x.imag()) ? -__x.real() : __x.real());
+ return complex<_Tp>(_Tp(0), std::signbit(__x.imag()) ? __x.real() : -__x.real());
}
- if (__libcpp_isnan_or_builtin(__x.real()))
+ if (std::__constexpr_isnan(__x.real()))
{
- if (__libcpp_isinf_or_builtin(__x.imag()))
+ if (std::__constexpr_isinf(__x.imag()))
return complex<_Tp>(__x.real(), -__x.imag());
return complex<_Tp>(__x.real(), __x.real());
}
- if (__libcpp_isinf_or_builtin(__x.imag()))
+ if (std::__constexpr_isinf(__x.imag()))
return complex<_Tp>(__pi/_Tp(2), -__x.imag());
- if (__x.real() == 0 && (__x.imag() == 0 || isnan(__x.imag())))
+ // Somehow isnan can be a macro, so we use __constexpr_isnan
+ if (__x.real() == 0 && (__x.imag() == 0 || std::__constexpr_isnan(__x.imag())))
return complex<_Tp>(__pi/_Tp(2), -__x.imag());
- complex<_Tp> __z = log(__x + sqrt(__sqr(__x) - _Tp(1)));
- if (signbit(__x.imag()))
- return complex<_Tp>(abs(__z.imag()), abs(__z.real()));
- return complex<_Tp>(abs(__z.imag()), -abs(__z.real()));
+ complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) - _Tp(1)));
+ if (std::signbit(__x.imag()))
+ return complex<_Tp>(std::abs(__z.imag()), std::abs(__z.real()));
+ return complex<_Tp>(std::abs(__z.imag()), -std::abs(__z.real()));
}
// atan
@@ -1339,7 +1413,7 @@ template<class _Tp>
_LIBCPP_HIDE_FROM_ABI complex<_Tp>
atan(const complex<_Tp>& __x)
{
- complex<_Tp> __z = atanh(complex<_Tp>(-__x.imag(), __x.real()));
+ complex<_Tp> __z = std::atanh(complex<_Tp>(-__x.imag(), __x.real()));
return complex<_Tp>(__z.imag(), -__z.real());
}
@@ -1349,7 +1423,7 @@ template<class _Tp>
_LIBCPP_HIDE_FROM_ABI complex<_Tp>
sin(const complex<_Tp>& __x)
{
- complex<_Tp> __z = sinh(complex<_Tp>(-__x.imag(), __x.real()));
+ complex<_Tp> __z = std::sinh(complex<_Tp>(-__x.imag(), __x.real()));
return complex<_Tp>(__z.imag(), -__z.real());
}
@@ -1360,7 +1434,7 @@ inline _LIBCPP_INLINE_VISIBILITY
complex<_Tp>
cos(const complex<_Tp>& __x)
{
- return cosh(complex<_Tp>(-__x.imag(), __x.real()));
+ return std::cosh(complex<_Tp>(-__x.imag(), __x.real()));
}
// tan
@@ -1369,17 +1443,18 @@ template<class _Tp>
_LIBCPP_HIDE_FROM_ABI complex<_Tp>
tan(const complex<_Tp>& __x)
{
- complex<_Tp> __z = tanh(complex<_Tp>(-__x.imag(), __x.real()));
+ complex<_Tp> __z = std::tanh(complex<_Tp>(-__x.imag(), __x.real()));
return complex<_Tp>(__z.imag(), -__z.real());
}
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
template<class _Tp, class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
{
if (__is.good())
{
- ws(__is);
+ std::ws(__is);
if (__is.peek() == _CharT('('))
{
__is.get();
@@ -1387,7 +1462,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
__is >> __r;
if (!__is.fail())
{
- ws(__is);
+ std::ws(__is);
_CharT __c = __is.peek();
if (__c == _CharT(','))
{
@@ -1396,7 +1471,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
__is >> __i;
if (!__is.fail())
{
- ws(__is);
+ std::ws(__is);
__c = __is.peek();
if (__c == _CharT(')'))
{
@@ -1435,7 +1510,6 @@ operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
return __is;
}
-#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
template<class _Tp, class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x)
diff --git a/contrib/libs/cxxsupp/libcxx/include/concepts b/contrib/libs/cxxsupp/libcxx/include/concepts
index 301256ca7e..196fa2e0ea 100644
--- a/contrib/libs/cxxsupp/libcxx/include/concepts
+++ b/contrib/libs/cxxsupp/libcxx/include/concepts
@@ -155,6 +155,10 @@ namespace std {
#include <__config>
#include <version>
+#if _LIBCPP_STD_VER <= 20 && !defined(_LIPCPP_REMOVE_TRANSITIVE_INCLUDES)
+# include <type_traits>
+#endif
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
diff --git a/contrib/libs/cxxsupp/libcxx/include/condition_variable b/contrib/libs/cxxsupp/libcxx/include/condition_variable
index 6b4d506939..f13df1c012 100644
--- a/contrib/libs/cxxsupp/libcxx/include/condition_variable
+++ b/contrib/libs/cxxsupp/libcxx/include/condition_variable
@@ -270,6 +270,7 @@ _LIBCPP_END_NAMESPACE_STD
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <concepts>
+# include <type_traits>
#endif
#endif // _LIBCPP_CONDITION_VARIABLE
diff --git a/contrib/libs/cxxsupp/libcxx/include/coroutine b/contrib/libs/cxxsupp/libcxx/include/coroutine
index e0ce323843..f264570128 100644
--- a/contrib/libs/cxxsupp/libcxx/include/coroutine
+++ b/contrib/libs/cxxsupp/libcxx/include/coroutine
@@ -57,6 +57,7 @@ struct suspend_always;
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <iosfwd>
+# include <type_traits>
#endif
#endif // _LIBCPP_COROUTINE
diff --git a/contrib/libs/cxxsupp/libcxx/include/cstring b/contrib/libs/cxxsupp/libcxx/include/cstring
index 42bbe73924..c88d97739f 100644
--- a/contrib/libs/cxxsupp/libcxx/include/cstring
+++ b/contrib/libs/cxxsupp/libcxx/include/cstring
@@ -58,6 +58,7 @@ size_t strlen(const char* s);
#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
+#include <__type_traits/is_constant_evaluated.h>
#include <string.h>
@@ -99,6 +100,53 @@ using ::memset _LIBCPP_USING_IF_EXISTS;
using ::strerror _LIBCPP_USING_IF_EXISTS;
using ::strlen _LIBCPP_USING_IF_EXISTS;
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 size_t __constexpr_strlen(const char* __str) {
+ // GCC currently doesn't support __builtin_strlen for heap-allocated memory during constant evaluation.
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70816
+#ifdef _LIBCPP_COMPILER_GCC
+ if (__libcpp_is_constant_evaluated()) {
+ size_t __i = 0;
+ for (; __str[__i] != '\0'; ++__i)
+ ;
+ return __i;
+ }
+#endif
+ return __builtin_strlen(__str);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int
+__constexpr_memcmp(const _Tp* __lhs, const _Tp* __rhs, size_t __count) {
+#ifdef _LIBCPP_COMPILER_GCC
+ if (__libcpp_is_constant_evaluated()) {
+ for (; __count; --__count, ++__lhs, ++__rhs) {
+ if (*__lhs < *__rhs)
+ return -1;
+ if (*__rhs < *__lhs)
+ return 1;
+ }
+ return 0;
+ }
+#endif
+ return __builtin_memcmp(__lhs, __rhs, __count);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const char*
+__constexpr_char_memchr(const char* __str, int __char, size_t __count) {
+#if __has_builtin(__builtin_char_memchr)
+ return __builtin_char_memchr(__str, __char, __count);
+#else
+ if (!__libcpp_is_constant_evaluated())
+ return static_cast<const char*>(std::memchr(__str, __char, __count));
+ for (; __count; --__count) {
+ if (*__str == __char)
+ return __str;
+ ++__str;
+ }
+ return nullptr;
+#endif
+}
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_CSTRING
diff --git a/contrib/libs/cxxsupp/libcxx/include/cwchar b/contrib/libs/cxxsupp/libcxx/include/cwchar
index 220c817072..fb7b92b760 100644
--- a/contrib/libs/cxxsupp/libcxx/include/cwchar
+++ b/contrib/libs/cxxsupp/libcxx/include/cwchar
@@ -104,6 +104,7 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len,
#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
+#include <__type_traits/is_constant_evaluated.h>
#include <cwctype>
#include <wchar.h>
@@ -189,6 +190,55 @@ using ::putwchar _LIBCPP_USING_IF_EXISTS;
using ::vwprintf _LIBCPP_USING_IF_EXISTS;
using ::wprintf _LIBCPP_USING_IF_EXISTS;
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 size_t __constexpr_wcslen(const wchar_t* __str) {
+#if __has_builtin(__builtin_wcslen)
+ return __builtin_wcslen(__str);
+#else
+ if (!__libcpp_is_constant_evaluated())
+ return std::wcslen(__str);
+
+ size_t __len = 0;
+ for (; *__str != L'\0'; ++__str)
+ ++__len;
+ return __len;
+#endif
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int
+__constexpr_wmemcmp(const wchar_t* __lhs, const wchar_t* __rhs, size_t __count) {
+#if __has_builtin(__builtin_wmemcmp)
+ return __builtin_wmemcmp(__lhs, __rhs, __count);
+#else
+ if (!__libcpp_is_constant_evaluated())
+ return std::wmemcmp(__lhs, __rhs, __count);
+
+ for (; __count; --__count, ++__lhs, ++__rhs) {
+ if (*__lhs < *__rhs)
+ return -1;
+ if (*__rhs < *__lhs)
+ return 1;
+ }
+ return 0;
+#endif
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const wchar_t*
+__constexpr_wmemchr(const wchar_t* __str, wchar_t __char, size_t __count) {
+#if __has_feature(cxx_constexpr_string_builtins)
+ return __builtin_wmemchr(__str, __char, __count);
+#else
+ if (!__libcpp_is_constant_evaluated())
+ return std::wmemchr(__str, __char, __count);
+
+ for (; __count; --__count) {
+ if (*__str == __char)
+ return __str;
+ ++__str;
+ }
+ return nullptr;
+#endif
+}
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_CWCHAR
diff --git a/contrib/libs/cxxsupp/libcxx/include/deque b/contrib/libs/cxxsupp/libcxx/include/deque
index 40b9eff155..0cd09040a8 100644
--- a/contrib/libs/cxxsupp/libcxx/include/deque
+++ b/contrib/libs/cxxsupp/libcxx/include/deque
@@ -176,6 +176,7 @@ template <class T, class Allocator, class Predicate>
#include <__iterator/next.h>
#include <__iterator/prev.h>
#include <__iterator/reverse_iterator.h>
+#include <__iterator/segmented_iterator.h>
#include <__memory/allocator_destructor.h>
#include <__memory/pointer_traits.h>
#include <__memory/temp_value.h>
@@ -216,98 +217,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp, class _Allocator = allocator<_Tp> > class _LIBCPP_TEMPLATE_VIS deque;
-template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
- class _DiffType, _DiffType _BlockSize>
-class _LIBCPP_TEMPLATE_VIS __deque_iterator;
-
-template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-copy(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
-_LIBCPP_HIDE_FROM_ABI _OutputIterator
-copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r);
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
-
-template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-copy_backward(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
-_LIBCPP_HIDE_FROM_ABI _OutputIterator
-copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r);
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
-
-template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-move(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
-_LIBCPP_HIDE_FROM_ABI _OutputIterator
-move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r);
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
-
-template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-move_backward(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
-_LIBCPP_HIDE_FROM_ABI _OutputIterator
-move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r);
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
-
template <class _ValueType, class _DiffType>
struct __deque_block_size {
static const _DiffType __buf_size = 64 * sizeof(void*);
@@ -480,464 +389,43 @@ private:
template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp>
friend class _LIBCPP_TEMPLATE_VIS __deque_iterator;
- template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
- friend
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
- copy(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*);
-
- template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
- friend
- _OutputIterator
- copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r);
-
- template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
- friend
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
- copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
-
- template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
- friend
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
- copy_backward(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*);
-
- template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
- friend
- _OutputIterator
- copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r);
-
- template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
- friend
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
- copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
-
- template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
- friend
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
- move(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*);
-
- template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
- friend
- _OutputIterator
- move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r);
-
- template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
- friend
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
- move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
-
- template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
- friend
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
- move_backward(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*);
-
- template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
- friend
- _OutputIterator
- move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r);
-
- template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
- friend
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
- move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
+ template <class>
+ friend struct __segmented_iterator_traits;
};
-template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
- class _DiffType, _DiffType _BlockSize>
-const _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer,
- _DiffType, _BlockSize>::__block_size =
- __deque_block_size<_ValueType, _DiffType>::value;
-
-// copy
-
-template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-copy(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
-{
- typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
- typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
- const difference_type __block_size = __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::__block_size;
- while (__f != __l)
- {
- pointer __rb = __r.__ptr_;
- pointer __re = *__r.__m_iter_ + __block_size;
- difference_type __bs = __re - __rb;
- difference_type __n = __l - __f;
- _RAIter __m = __l;
- if (__n > __bs)
- {
- __n = __bs;
- __m = __f + __n;
- }
- _VSTD::copy(__f, __m, __rb);
- __f = __m;
- __r += __n;
- }
- return __r;
-}
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
-_LIBCPP_HIDE_FROM_ABI _OutputIterator
-copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r)
-{
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
- const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
- difference_type __n = __l - __f;
- while (__n > 0)
- {
- pointer __fb = __f.__ptr_;
- pointer __fe = *__f.__m_iter_ + __block_size;
- difference_type __bs = __fe - __fb;
- if (__bs > __n)
- {
- __bs = __n;
- __fe = __fb + __bs;
- }
- __r = _VSTD::copy(__fb, __fe, __r);
- __n -= __bs;
- __f += __bs;
- }
- return __r;
-}
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
-{
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
- const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
- difference_type __n = __l - __f;
- while (__n > 0)
- {
- pointer __fb = __f.__ptr_;
- pointer __fe = *__f.__m_iter_ + __block_size;
- difference_type __bs = __fe - __fb;
- if (__bs > __n)
- {
- __bs = __n;
- __fe = __fb + __bs;
- }
- __r = _VSTD::copy(__fb, __fe, __r);
- __n -= __bs;
- __f += __bs;
- }
- return __r;
-}
-
-// copy_backward
-
-template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-copy_backward(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
-{
- typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
- typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
- while (__f != __l)
- {
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _VSTD::prev(__r);
- pointer __rb = *__rp.__m_iter_;
- pointer __re = __rp.__ptr_ + 1;
- difference_type __bs = __re - __rb;
- difference_type __n = __l - __f;
- _RAIter __m = __f;
- if (__n > __bs)
- {
- __n = __bs;
- __m = __l - __n;
- }
- _VSTD::copy_backward(__m, __l, __re);
- __l = __m;
- __r -= __n;
- }
- return __r;
-}
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
-_LIBCPP_HIDE_FROM_ABI _OutputIterator
-copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r)
-{
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
- difference_type __n = __l - __f;
- while (__n > 0)
- {
- --__l;
- pointer __lb = *__l.__m_iter_;
- pointer __le = __l.__ptr_ + 1;
- difference_type __bs = __le - __lb;
- if (__bs > __n)
- {
- __bs = __n;
- __lb = __le - __bs;
- }
- __r = _VSTD::copy_backward(__lb, __le, __r);
- __n -= __bs;
- __l -= __bs - 1;
- }
- return __r;
-}
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
-{
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
- difference_type __n = __l - __f;
- while (__n > 0)
- {
- --__l;
- pointer __lb = *__l.__m_iter_;
- pointer __le = __l.__ptr_ + 1;
- difference_type __bs = __le - __lb;
- if (__bs > __n)
- {
- __bs = __n;
- __lb = __le - __bs;
- }
- __r = _VSTD::copy_backward(__lb, __le, __r);
- __n -= __bs;
- __l -= __bs - 1;
- }
- return __r;
-}
-
-// move
-
-template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-move(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
-{
- typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
- typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
- const difference_type __block_size = __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::__block_size;
- while (__f != __l)
- {
- pointer __rb = __r.__ptr_;
- pointer __re = *__r.__m_iter_ + __block_size;
- difference_type __bs = __re - __rb;
- difference_type __n = __l - __f;
- _RAIter __m = __l;
- if (__n > __bs)
- {
- __n = __bs;
- __m = __f + __n;
- }
- _VSTD::move(__f, __m, __rb);
- __f = __m;
- __r += __n;
- }
- return __r;
-}
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
-_LIBCPP_HIDE_FROM_ABI _OutputIterator
-move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r)
-{
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
- const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
- difference_type __n = __l - __f;
- while (__n > 0)
- {
- pointer __fb = __f.__ptr_;
- pointer __fe = *__f.__m_iter_ + __block_size;
- difference_type __bs = __fe - __fb;
- if (__bs > __n)
- {
- __bs = __n;
- __fe = __fb + __bs;
- }
- __r = _VSTD::move(__fb, __fe, __r);
- __n -= __bs;
- __f += __bs;
- }
- return __r;
-}
+template <class _ValueType, class _Pointer, class _Reference, class _MapPointer, class _DiffType, _DiffType _BlockSize>
+struct __segmented_iterator_traits<
+ __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize> > {
+private:
+ using _Iterator = __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>;
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
-{
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
- const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
- difference_type __n = __l - __f;
- while (__n > 0)
- {
- pointer __fb = __f.__ptr_;
- pointer __fe = *__f.__m_iter_ + __block_size;
- difference_type __bs = __fe - __fb;
- if (__bs > __n)
- {
- __bs = __n;
- __fe = __fb + __bs;
- }
- __r = _VSTD::move(__fb, __fe, __r);
- __n -= __bs;
- __f += __bs;
- }
- return __r;
-}
+public:
+ using __is_segmented_iterator = true_type;
+ using __segment_iterator = _MapPointer;
+ using __local_iterator = _Pointer;
-// move_backward
+ static _LIBCPP_HIDE_FROM_ABI __segment_iterator __segment(_Iterator __iter) { return __iter.__m_iter_; }
+ static _LIBCPP_HIDE_FROM_ABI __local_iterator __local(_Iterator __iter) { return __iter.__ptr_; }
+ static _LIBCPP_HIDE_FROM_ABI __local_iterator __begin(__segment_iterator __iter) { return *__iter; }
-template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-move_backward(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
-{
- typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
- typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
- while (__f != __l)
- {
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _VSTD::prev(__r);
- pointer __rb = *__rp.__m_iter_;
- pointer __re = __rp.__ptr_ + 1;
- difference_type __bs = __re - __rb;
- difference_type __n = __l - __f;
- _RAIter __m = __f;
- if (__n > __bs)
- {
- __n = __bs;
- __m = __l - __n;
- }
- _VSTD::move_backward(__m, __l, __re);
- __l = __m;
- __r -= __n;
- }
- return __r;
-}
+ static _LIBCPP_HIDE_FROM_ABI __local_iterator __end(__segment_iterator __iter) {
+ return *__iter + _Iterator::__block_size;
+ }
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
-_LIBCPP_HIDE_FROM_ABI _OutputIterator
-move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r)
-{
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
- difference_type __n = __l - __f;
- while (__n > 0)
- {
- --__l;
- pointer __lb = *__l.__m_iter_;
- pointer __le = __l.__ptr_ + 1;
- difference_type __bs = __le - __lb;
- if (__bs > __n)
- {
- __bs = __n;
- __lb = __le - __bs;
+ static _LIBCPP_HIDE_FROM_ABI _Iterator __compose(__segment_iterator __segment, __local_iterator __local) {
+ if (__local == __end(__segment)) {
+ ++__segment;
+ return _Iterator(__segment, *__segment);
}
- __r = _VSTD::move_backward(__lb, __le, __r);
- __n -= __bs;
- __l -= __bs - 1;
- }
- return __r;
-}
+ return _Iterator(__segment, __local);
+ }
+};
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
-{
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
- difference_type __n = __l - __f;
- while (__n > 0)
- {
- --__l;
- pointer __lb = *__l.__m_iter_;
- pointer __le = __l.__ptr_ + 1;
- difference_type __bs = __le - __lb;
- if (__bs > __n)
- {
- __bs = __n;
- __lb = __le - __bs;
- }
- __r = _VSTD::move_backward(__lb, __le, __r);
- __n -= __bs;
- __l -= __bs - 1;
- }
- return __r;
-}
+template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
+ class _DiffType, _DiffType _BlockSize>
+const _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer,
+ _DiffType, _BlockSize>::__block_size =
+ __deque_block_size<_ValueType, _DiffType>::value;
template <class _Tp, class _Allocator /*= allocator<_Tp>*/>
class _LIBCPP_TEMPLATE_VIS deque
@@ -2317,7 +1805,7 @@ deque<_Tp, _Allocator>::__add_front_capacity()
else
{
__split_buffer<pointer, __pointer_allocator&>
- __buf(max<size_type>(2 * __map_.capacity(), 1),
+ __buf(std::max<size_type>(2 * __map_.capacity(), 1),
0, __map_.__alloc());
typedef __allocator_destructor<_Allocator> _Dp;
@@ -2390,8 +1878,8 @@ deque<_Tp, _Allocator>::__add_front_capacity(size_type __n)
{
size_type __ds = (__nb + __back_capacity) * __block_size - __map_.empty();
__split_buffer<pointer, __pointer_allocator&>
- __buf(max<size_type>(2* __map_.capacity(),
- __nb + __map_.size()),
+ __buf(std::max<size_type>(2* __map_.capacity(),
+ __nb + __map_.size()),
0, __map_.__alloc());
#ifndef _LIBCPP_NO_EXCEPTIONS
try
@@ -2459,7 +1947,7 @@ deque<_Tp, _Allocator>::__add_back_capacity()
else
{
__split_buffer<pointer, __pointer_allocator&>
- __buf(max<size_type>(2* __map_.capacity(), 1),
+ __buf(std::max<size_type>(2* __map_.capacity(), 1),
__map_.size(),
__map_.__alloc());
@@ -2531,8 +2019,8 @@ deque<_Tp, _Allocator>::__add_back_capacity(size_type __n)
{
size_type __ds = __front_capacity * __block_size;
__split_buffer<pointer, __pointer_allocator&>
- __buf(max<size_type>(2* __map_.capacity(),
- __nb + __map_.size()),
+ __buf(std::max<size_type>(2* __map_.capacity(),
+ __nb + __map_.size()),
__map_.size() - __front_capacity,
__map_.__alloc());
#ifndef _LIBCPP_NO_EXCEPTIONS
diff --git a/contrib/libs/cxxsupp/libcxx/include/exception b/contrib/libs/cxxsupp/libcxx/include/exception
index 2d37d7ab09..d63bb8f858 100644
--- a/contrib/libs/cxxsupp/libcxx/include/exception
+++ b/contrib/libs/cxxsupp/libcxx/include/exception
@@ -80,9 +80,15 @@ template <class E> void rethrow_if_nested(const E& e);
#include <__availability>
#include <__config>
#include <__memory/addressof.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_base_of.h>
+#include <__type_traits/is_class.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_copy_constructible.h>
+#include <__type_traits/is_final.h>
+#include <__type_traits/is_polymorphic.h>
#include <cstddef>
#include <cstdlib>
-#include <type_traits>
#include <version>
// <vcruntime_exception.h> defines its own std::exception and std::bad_exception types,
@@ -350,4 +356,8 @@ rethrow_if_nested(const _Ep&,
} // namespace std
+#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+# include <type_traits>
+#endif
+
#endif // _LIBCPP_EXCEPTION
diff --git a/contrib/libs/cxxsupp/libcxx/include/format b/contrib/libs/cxxsupp/libcxx/include/format
index 8817dceb1e..2c583c1065 100644
--- a/contrib/libs/cxxsupp/libcxx/include/format
+++ b/contrib/libs/cxxsupp/libcxx/include/format
@@ -112,6 +112,40 @@ namespace std {
using format_parse_context = basic_format_parse_context<char>;
using wformat_parse_context = basic_format_parse_context<wchar_t>;
+ // [format.range], formatting of ranges
+ // [format.range.fmtkind], variable template format_kind
+ enum class range_format { // since C++23
+ disabled,
+ map,
+ set,
+ sequence,
+ string,
+ debug_string
+ };
+
+ template<class R>
+ constexpr unspecified format_kind = unspecified; // since C++23
+
+ template<ranges::input_range R>
+ requires same_as<R, remove_cvref_t<R>>
+ constexpr range_format format_kind<R> = see below; // since C++23
+
+ // [format.range.formatter], class template range_formatter
+ template<class T, class charT = char>
+ requires same_as<remove_cvref_t<T>, T> && formattable<T, charT>
+ class range_formatter; // since C++23
+
+ // [format.range.fmtdef], class template range-default-formatter
+ template<range_format K, ranges::input_range R, class charT>
+ struct range-default-formatter; // exposition only, since C++23
+
+ // [format.range.fmtmap], [format.range.fmtset], [format.range.fmtstr],
+ // specializations for maps, sets, and strings
+ template<ranges::input_range R, class charT>
+ requires (format_kind<R> != range_format::disabled) &&
+ formattable<ranges::range_reference_t<R>, charT>
+ struct formatter<R, charT> : range-default-formatter<format_kind<R>, R, charT> { }; // since C++23
+
// [format.arguments], arguments
// [format.arg], class template basic_format_arg
template<class Context> class basic_format_arg;
@@ -144,6 +178,7 @@ namespace std {
#include <__config>
#include <__format/buffer.h>
#include <__format/concepts.h>
+#include <__format/container_adaptor.h>
#include <__format/enable_insertable.h>
#include <__format/format_arg.h>
#include <__format/format_arg_store.h>
@@ -162,7 +197,10 @@ namespace std {
#include <__format/formatter_integer.h>
#include <__format/formatter_pointer.h>
#include <__format/formatter_string.h>
+#include <__format/formatter_tuple.h>
#include <__format/parser_std_format_spec.h>
+#include <__format/range_default_formatter.h>
+#include <__format/range_formatter.h>
#include <__format/unicode.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
diff --git a/contrib/libs/cxxsupp/libcxx/include/fstream b/contrib/libs/cxxsupp/libcxx/include/fstream
index 62c6f53e9f..41e95bf3dc 100644
--- a/contrib/libs/cxxsupp/libcxx/include/fstream
+++ b/contrib/libs/cxxsupp/libcxx/include/fstream
@@ -313,9 +313,9 @@ basic_filebuf<_CharT, _Traits>::basic_filebuf()
__owns_ib_(false),
__always_noconv_(false)
{
- if (has_facet<codecvt<char_type, char, state_type> >(this->getloc()))
+ if (std::has_facet<codecvt<char_type, char, state_type> >(this->getloc()))
{
- __cv_ = &use_facet<codecvt<char_type, char, state_type> >(this->getloc());
+ __cv_ = &std::use_facet<codecvt<char_type, char, state_type> >(this->getloc());
__always_noconv_ = __cv_->always_noconv();
}
setbuf(nullptr, 4096);
@@ -734,7 +734,7 @@ basic_filebuf<_CharT, _Traits>::underflow()
char_type __1buf;
if (this->gptr() == nullptr)
this->setg(&__1buf, &__1buf+1, &__1buf+1);
- const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
+ const size_t __unget_sz = __initial ? 0 : std::min<size_t>((this->egptr() - this->eback()) / 2, 4);
int_type __c = traits_type::eof();
if (this->gptr() == this->egptr())
{
@@ -742,7 +742,7 @@ basic_filebuf<_CharT, _Traits>::underflow()
if (__always_noconv_)
{
size_t __nmemb = static_cast<size_t>(this->egptr() - this->eback() - __unget_sz);
- __nmemb = fread(this->eback() + __unget_sz, 1, __nmemb, __file_);
+ __nmemb = ::fread(this->eback() + __unget_sz, 1, __nmemb, __file_);
if (__nmemb != 0)
{
this->setg(this->eback(),
@@ -840,7 +840,7 @@ basic_filebuf<_CharT, _Traits>::overflow(int_type __c)
if (__always_noconv_)
{
size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
- if (fwrite(this->pbase(), sizeof(char_type), __nmemb, __file_) != __nmemb)
+ if (std::fwrite(this->pbase(), sizeof(char_type), __nmemb, __file_) != __nmemb)
return traits_type::eof();
}
else
@@ -860,7 +860,7 @@ basic_filebuf<_CharT, _Traits>::overflow(int_type __c)
if (__r == codecvt_base::noconv)
{
size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
- if (fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb)
+ if (std::fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb)
return traits_type::eof();
}
else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
@@ -968,7 +968,7 @@ basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way,
return pos_type(off_type(-1));
pos_type __r = ftell(__file_);
#else
- if (fseeko(__file_, __width > 0 ? __width * __off : 0, __whence))
+ if (::fseeko(__file_, __width > 0 ? __width * __off : 0, __whence))
return pos_type(off_type(-1));
pos_type __r = ftello(__file_);
#endif
@@ -986,7 +986,7 @@ basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode)
if (fseek(__file_, __sp, SEEK_SET))
return pos_type(off_type(-1));
#else
- if (fseeko(__file_, __sp, SEEK_SET))
+ if (::fseeko(__file_, __sp, SEEK_SET))
return pos_type(off_type(-1));
#endif
__st_ = __sp.state();
@@ -1050,7 +1050,7 @@ basic_filebuf<_CharT, _Traits>::sync()
if (fseek(__file_, -__c, SEEK_CUR))
return -1;
#else
- if (fseeko(__file_, -__c, SEEK_CUR))
+ if (::fseeko(__file_, -__c, SEEK_CUR))
return -1;
#endif
if (__update_st)
@@ -1067,7 +1067,7 @@ void
basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc)
{
sync();
- __cv_ = &use_facet<codecvt<char_type, char, state_type> >(__loc);
+ __cv_ = &std::use_facet<codecvt<char_type, char, state_type> >(__loc);
bool __old_anc = __always_noconv_;
__always_noconv_ = __cv_->always_noconv();
if (__old_anc != __always_noconv_)
@@ -1757,6 +1757,7 @@ _LIBCPP_POP_MACROS
# include <limits>
# include <new>
# include <stdexcept>
+# include <type_traits>
#endif
#endif // _LIBCPP_FSTREAM
diff --git a/contrib/libs/cxxsupp/libcxx/include/future b/contrib/libs/cxxsupp/libcxx/include/future
index e317e8d636..2f14a471c4 100644
--- a/contrib/libs/cxxsupp/libcxx/include/future
+++ b/contrib/libs/cxxsupp/libcxx/include/future
@@ -369,6 +369,7 @@ template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
#include <__memory/allocator_arg_t.h>
#include <__memory/allocator_destructor.h>
#include <__memory/uses_allocator.h>
+#include <__type_traits/strip_signature.h>
#include <__utility/auto_cast.h>
#include <__utility/forward.h>
#include <__utility/move.h>
@@ -624,7 +625,9 @@ class _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_HIDDEN __assoc_state
: public __assoc_sub_state
{
typedef __assoc_sub_state base;
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
+_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
_Up __value_;
@@ -684,7 +687,7 @@ __assoc_state<_Rp>::move()
unique_lock<mutex> __lk(this->__mut_);
this->__sub_wait(__lk);
if (this->__exception_ != nullptr)
- rethrow_exception(this->__exception_);
+ std::rethrow_exception(this->__exception_);
return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
}
@@ -695,7 +698,7 @@ __assoc_state<_Rp>::copy()
unique_lock<mutex> __lk(this->__mut_);
this->__sub_wait(__lk);
if (this->__exception_ != nullptr)
- rethrow_exception(this->__exception_);
+ std::rethrow_exception(this->__exception_);
return *reinterpret_cast<_Rp*>(&__value_);
}
@@ -755,7 +758,7 @@ __assoc_state<_Rp&>::copy()
unique_lock<mutex> __lk(this->__mut_);
this->__sub_wait(__lk);
if (this->__exception_ != nullptr)
- rethrow_exception(this->__exception_);
+ std::rethrow_exception(this->__exception_);
return *__value_;
}
@@ -1625,7 +1628,7 @@ class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_base<_Rp(_ArgTypes...)>
public:
_LIBCPP_INLINE_VISIBILITY
__packaged_task_base() {}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL
virtual ~__packaged_task_base() {}
virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
virtual void destroy() = 0;
@@ -1701,7 +1704,9 @@ class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_NO_CFI
__base* __get_buf() { return (__base*)&__buf_; }
+ _LIBCPP_SUPPRESS_DEPRECATED_PUSH
typename aligned_storage<3*sizeof(void*)>::type __buf_;
+ _LIBCPP_SUPPRESS_DEPRECATED_POP
__base* __f_;
public:
@@ -1834,7 +1839,9 @@ __packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f)
{
if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
{
+ _LIBCPP_SUPPRESS_DEPRECATED_PUSH
typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
+ _LIBCPP_SUPPRESS_DEPRECATED_POP
__base* __t = (__base*)&__tempbuf;
__f_->__move_to(__t);
__f_->destroy();
@@ -2050,6 +2057,16 @@ public:
void reset();
};
+#if _LIBCPP_STD_VER >= 17
+
+template <class _Rp, class... _Args>
+packaged_task(_Rp(*)(_Args...)) -> packaged_task<_Rp(_Args...)>;
+
+template <class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type>
+packaged_task(_Fp) -> packaged_task<_Stripped>;
+
+#endif
+
template<class ..._ArgTypes>
void
packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
diff --git a/contrib/libs/cxxsupp/libcxx/include/iomanip b/contrib/libs/cxxsupp/libcxx/include/iomanip
index 76229fcaa2..38c5c9b9c6 100644
--- a/contrib/libs/cxxsupp/libcxx/include/iomanip
+++ b/contrib/libs/cxxsupp/libcxx/include/iomanip
@@ -311,7 +311,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x)
typedef istreambuf_iterator<_CharT, _Traits> _Ip;
typedef money_get<_CharT, _Ip> _Fp;
ios_base::iostate __err = ios_base::goodbit;
- const _Fp& __mf = use_facet<_Fp>(__is.getloc());
+ const _Fp& __mf = std::use_facet<_Fp>(__is.getloc());
__mf.get(_Ip(__is), _Ip(), __x.__intl_, __is, __err, __x.__mon_);
__is.setstate(__err);
}
@@ -370,7 +370,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x)
{
typedef ostreambuf_iterator<_CharT, _Traits> _Op;
typedef money_put<_CharT, _Op> _Fp;
- const _Fp& __mf = use_facet<_Fp>(__os.getloc());
+ const _Fp& __mf = std::use_facet<_Fp>(__os.getloc());
if (__mf.put(_Op(__os), __x.__intl_, __os, __os.fill(), __x.__mon_).failed())
__os.setstate(ios_base::badbit);
}
@@ -430,7 +430,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t9<_CharT>& __x)
typedef istreambuf_iterator<_CharT, _Traits> _Ip;
typedef time_get<_CharT, _Ip> _Fp;
ios_base::iostate __err = ios_base::goodbit;
- const _Fp& __tf = use_facet<_Fp>(__is.getloc());
+ const _Fp& __tf = std::use_facet<_Fp>(__is.getloc());
__tf.get(_Ip(__is), _Ip(), __is, __err, __x.__tm_,
__x.__fmt_, __x.__fmt_ + _Traits::length(__x.__fmt_));
__is.setstate(__err);
@@ -490,7 +490,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x)
{
typedef ostreambuf_iterator<_CharT, _Traits> _Op;
typedef time_put<_CharT, _Op> _Fp;
- const _Fp& __tf = use_facet<_Fp>(__os.getloc());
+ const _Fp& __tf = std::use_facet<_Fp>(__os.getloc());
if (__tf.put(_Op(__os), __os, __os.fill(), __x.__tm_,
__x.__fmt_, __x.__fmt_ + _Traits::length(__x.__fmt_)).failed())
__os.setstate(ios_base::badbit);
diff --git a/contrib/libs/cxxsupp/libcxx/include/ios b/contrib/libs/cxxsupp/libcxx/include/ios
index e67b7d2b77..9eecf4d8dd 100644
--- a/contrib/libs/cxxsupp/libcxx/include/ios
+++ b/contrib/libs/cxxsupp/libcxx/include/ios
@@ -766,7 +766,7 @@ inline _LIBCPP_INLINE_VISIBILITY
char
basic_ios<_CharT, _Traits>::narrow(char_type __c, char __dfault) const
{
- return use_facet<ctype<char_type> >(getloc()).narrow(__c, __dfault);
+ return std::use_facet<ctype<char_type> >(getloc()).narrow(__c, __dfault);
}
template <class _CharT, class _Traits>
@@ -774,7 +774,7 @@ inline _LIBCPP_INLINE_VISIBILITY
_CharT
basic_ios<_CharT, _Traits>::widen(char __c) const
{
- return use_facet<ctype<char_type> >(getloc()).widen(__c);
+ return std::use_facet<ctype<char_type> >(getloc()).widen(__c);
}
template <class _CharT, class _Traits>
diff --git a/contrib/libs/cxxsupp/libcxx/include/istream b/contrib/libs/cxxsupp/libcxx/include/istream
index 1c9adcc0c6..6e67d61de2 100644
--- a/contrib/libs/cxxsupp/libcxx/include/istream
+++ b/contrib/libs/cxxsupp/libcxx/include/istream
@@ -316,7 +316,7 @@ basic_istream<_CharT, _Traits>::sentry::sentry(basic_istream<_CharT, _Traits>& _
if (!__noskipws && (__is.flags() & ios_base::skipws))
{
typedef istreambuf_iterator<_CharT, _Traits> _Ip;
- const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());
+ const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> >(__is.getloc());
_Ip __i(__is);
_Ip __eof;
for (; __i != __eof; ++__i)
@@ -366,7 +366,7 @@ __input_arithmetic(basic_istream<_CharT, _Traits>& __is, _Tp& __n) {
#endif // _LIBCPP_NO_EXCEPTIONS
typedef istreambuf_iterator<_CharT, _Traits> _Ip;
typedef num_get<_CharT, _Ip> _Fp;
- use_facet<_Fp>(__is.getloc()).get(_Ip(__is), _Ip(), __is, __state, __n);
+ std::use_facet<_Fp>(__is.getloc()).get(_Ip(__is), _Ip(), __is, __state, __n);
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
@@ -476,7 +476,7 @@ __input_arithmetic_with_numeric_limits(basic_istream<_CharT, _Traits>& __is, _Tp
typedef istreambuf_iterator<_CharT, _Traits> _Ip;
typedef num_get<_CharT, _Ip> _Fp;
long __temp;
- use_facet<_Fp>(__is.getloc()).get(_Ip(__is), _Ip(), __is, __state, __temp);
+ std::use_facet<_Fp>(__is.getloc()).get(_Ip(__is), _Ip(), __is, __state, __temp);
if (__temp < numeric_limits<_Tp>::min())
{
__state |= ios_base::failbit;
@@ -536,7 +536,7 @@ __input_c_string(basic_istream<_CharT, _Traits>& __is, _CharT* __p, size_t __n)
{
#endif
_CharT* __s = __p;
- const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());
+ const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> >(__is.getloc());
while (__s != __p + (__n-1))
{
typename _Traits::int_type __i = __is.rdbuf()->sgetc();
@@ -1340,7 +1340,7 @@ ws(basic_istream<_CharT, _Traits>& __is)
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
- const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());
+ const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> >(__is.getloc());
while (true)
{
typename _Traits::int_type __i = __is.rdbuf()->sgetc();
@@ -1375,7 +1375,7 @@ struct __is_istreamable : false_type { };
template <class _Stream, class _Tp>
struct __is_istreamable<_Stream, _Tp, decltype(
- declval<_Stream>() >> declval<_Tp>(), void()
+ std::declval<_Stream>() >> std::declval<_Tp>(), void()
)> : true_type { };
template <class _Stream, class _Tp, class = typename enable_if<
@@ -1461,7 +1461,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is,
if (__n <= 0)
__n = numeric_limits<streamsize>::max();
streamsize __c = 0;
- const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());
+ const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> >(__is.getloc());
while (__c < __n)
{
typename _Traits::int_type __i = __is.rdbuf()->sgetc();
@@ -1556,7 +1556,7 @@ basic_istream<_CharT, _Traits>&
getline(basic_istream<_CharT, _Traits>& __is,
basic_string<_CharT, _Traits, _Allocator>& __str)
{
- return getline(__is, __str, __is.widen('\n'));
+ return std::getline(__is, __str, __is.widen('\n'));
}
template<class _CharT, class _Traits, class _Allocator>
@@ -1565,7 +1565,7 @@ basic_istream<_CharT, _Traits>&
getline(basic_istream<_CharT, _Traits>&& __is,
basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm)
{
- return getline(__is, __str, __dlm);
+ return std::getline(__is, __str, __dlm);
}
template<class _CharT, class _Traits, class _Allocator>
@@ -1574,7 +1574,7 @@ basic_istream<_CharT, _Traits>&
getline(basic_istream<_CharT, _Traits>&& __is,
basic_string<_CharT, _Traits, _Allocator>& __str)
{
- return getline(__is, __str, __is.widen('\n'));
+ return std::getline(__is, __str, __is.widen('\n'));
}
template <class _CharT, class _Traits, size_t _Size>
@@ -1590,7 +1590,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x)
{
#endif
basic_string<_CharT, _Traits> __str;
- const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());
+ const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> >(__is.getloc());
size_t __c = 0;
_CharT __zero = __ct.widen('0');
_CharT __one = __ct.widen('1');
@@ -1639,6 +1639,7 @@ _LIBCPP_END_NAMESPACE_STD
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <concepts>
+# include <type_traits>
#endif
_LIBCPP_POP_MACROS
diff --git a/contrib/libs/cxxsupp/libcxx/include/iterator b/contrib/libs/cxxsupp/libcxx/include/iterator
index 679b3da317..35eca67b4a 100644
--- a/contrib/libs/cxxsupp/libcxx/include/iterator
+++ b/contrib/libs/cxxsupp/libcxx/include/iterator
@@ -719,7 +719,6 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
#include <__memory/pointer_traits.h>
#include <cstddef>
#include <initializer_list>
-#include <type_traits>
#include <version>
// standard-mandated includes
@@ -735,6 +734,7 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <exception>
# include <new>
+# include <type_traits>
# include <typeinfo>
# include <utility>
#endif
diff --git a/contrib/libs/cxxsupp/libcxx/include/limits b/contrib/libs/cxxsupp/libcxx/include/limits
index ee8249fa3e..9f5949e63c 100644
--- a/contrib/libs/cxxsupp/libcxx/include/limits
+++ b/contrib/libs/cxxsupp/libcxx/include/limits
@@ -104,7 +104,9 @@ template<> class numeric_limits<cv long double>;
#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
-#include <type_traits>
+#include <__type_traits/is_arithmetic.h>
+#include <__type_traits/is_signed.h>
+#include <__type_traits/remove_cv.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -821,4 +823,8 @@ _LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
+#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+# include <type_traits>
+#endif
+
#endif // _LIBCPP_LIMITS
diff --git a/contrib/libs/cxxsupp/libcxx/include/locale b/contrib/libs/cxxsupp/libcxx/include/locale
index 2c0df7f726..3d76ec862d 100644
--- a/contrib/libs/cxxsupp/libcxx/include/locale
+++ b/contrib/libs/cxxsupp/libcxx/include/locale
@@ -211,6 +211,9 @@ template <class charT> class messages_byname;
#include <streambuf>
#include <version>
+// TODO: Fix __bsd_locale_defaults.h
+// NOLINTBEGIN(libcpp-robust-against-adl)
+
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
// Most unix variants have catopen. These are the specific ones that don't.
# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION) && !defined(__EMSCRIPTEN__)
@@ -446,8 +449,8 @@ string
__num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep)
{
locale __loc = __iob.getloc();
- use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 26, __atoms);
- const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+ std::use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 26, __atoms);
+ const numpunct<_CharT>& __np = std::use_facet<numpunct<_CharT> >(__loc);
__thousands_sep = __np.thousands_sep();
return __np.grouping();
}
@@ -459,8 +462,8 @@ __num_get<_CharT>::__stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT&
_CharT& __thousands_sep)
{
locale __loc = __iob.getloc();
- use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 32, __atoms);
- const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+ std::use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 32, __atoms);
+ const numpunct<_CharT>& __np = std::use_facet<numpunct<_CharT> >(__loc);
__decimal_point = __np.decimal_point();
__thousands_sep = __np.thousands_sep();
return __np.grouping();
@@ -494,7 +497,7 @@ __num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*&
}
return 0;
}
- ptrdiff_t __f = find(__atoms, __atoms + 26, __ct) - __atoms;
+ ptrdiff_t __f = std::find(__atoms, __atoms + 26, __ct) - __atoms;
if (__f >= 24)
return -1;
switch (__base)
@@ -547,7 +550,7 @@ __num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __ex
}
return 0;
}
- ptrdiff_t __f = find(__atoms, __atoms + 32, __ct) - __atoms;
+ ptrdiff_t __f = std::find(__atoms, __atoms + 32, __ct) - __atoms;
if (__f >= 32)
return -1;
char __x = __src[__f];
@@ -677,7 +680,7 @@ public:
static locale::id id;
protected:
- _LIBCPP_HIDE_FROM_ABI ~num_get() override {}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~num_get() override {}
template <class _Fp>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
@@ -849,7 +852,7 @@ __num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err)
__libcpp_remove_reference_t<decltype(errno)> __save_errno = errno;
errno = 0;
char *__p2;
- _Tp __ld = __do_strtod<_Tp>(__a, &__p2);
+ _Tp __ld = std::__do_strtod<_Tp>(__a, &__p2);
__libcpp_remove_reference_t<decltype(errno)> __current_errno = errno;
if (__current_errno == 0)
errno = __save_errno;
@@ -892,8 +895,8 @@ num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
}
return __b;
}
- const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__iob.getloc());
- const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__iob.getloc());
+ const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> >(__iob.getloc());
+ const numpunct<_CharT>& __np = std::use_facet<numpunct<_CharT> >(__iob.getloc());
typedef typename numpunct<_CharT>::string_type string_type;
const string_type __names[2] = {__np.truename(), __np.falsename()};
const string_type* __i = _VSTD::__scan_keyword(__b, __e, __names, __names+2,
@@ -950,7 +953,7 @@ num_get<_CharT, _InputIterator>::__do_get_signed(iter_type __b, iter_type __e,
if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
*__g_end++ = __dc;
// Stage 3
- __v = __num_get_signed_integral<_Signed>(__a, __a_end, __err, __base);
+ __v = std::__num_get_signed_integral<_Signed>(__a, __a_end, __err, __base);
// Digit grouping checked
__check_grouping(__grouping, __g, __g_end, __err);
// EOF checked
@@ -1007,7 +1010,7 @@ num_get<_CharT, _InputIterator>::__do_get_unsigned(iter_type __b, iter_type __e,
if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
*__g_end++ = __dc;
// Stage 3
- __v = __num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base);
+ __v = std::__num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base);
// Digit grouping checked
__check_grouping(__grouping, __g, __g_end, __err);
// EOF checked
@@ -1062,7 +1065,7 @@ num_get<_CharT, _InputIterator>::__do_get_floating_point(iter_type __b, iter_typ
if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
*__g_end++ = __dc;
// Stage 3
- __v = __num_get_float<_Fp>(__a, __a_end, __err);
+ __v = std::__num_get_float<_Fp>(__a, __a_end, __err);
// Digit grouping checked
__check_grouping(__grouping, __g, __g_end, __err);
// EOF checked
@@ -1084,8 +1087,8 @@ num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
char_type __atoms[26];
char_type __thousands_sep = 0;
string __grouping;
- use_facet<ctype<_CharT> >(__iob.getloc()).widen(__num_get_base::__src,
- __num_get_base::__src + 26, __atoms);
+ std::use_facet<ctype<_CharT> >(__iob.getloc()).widen(__num_get_base::__src,
+ __num_get_base::__src + 26, __atoms);
string __buf;
__buf.resize(__buf.capacity());
char* __a = &__buf[0];
@@ -1152,8 +1155,8 @@ __num_put<_CharT>::__widen_and_group_int(char* __nb, char* __np, char* __ne,
_CharT* __ob, _CharT*& __op, _CharT*& __oe,
const locale& __loc)
{
- const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc);
- const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
+ const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> > (__loc);
+ const numpunct<_CharT>& __npt = std::use_facet<numpunct<_CharT> >(__loc);
string __grouping = __npt.grouping();
if (__grouping.empty())
{
@@ -1172,7 +1175,7 @@ __num_put<_CharT>::__widen_and_group_int(char* __nb, char* __np, char* __ne,
*__oe++ = __ct.widen(*__nf++);
*__oe++ = __ct.widen(*__nf++);
}
- reverse(__nf, __ne);
+ std::reverse(__nf, __ne);
_CharT __thousands_sep = __npt.thousands_sep();
unsigned __dc = 0;
unsigned __dg = 0;
@@ -1189,7 +1192,7 @@ __num_put<_CharT>::__widen_and_group_int(char* __nb, char* __np, char* __ne,
*__oe++ = __ct.widen(*__p);
++__dc;
}
- reverse(__ob + (__nf - __nb), __oe);
+ std::reverse(__ob + (__nf - __nb), __oe);
}
if (__np == __ne)
__op = __oe;
@@ -1203,8 +1206,8 @@ __num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne,
_CharT* __ob, _CharT*& __op, _CharT*& __oe,
const locale& __loc)
{
- const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc);
- const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
+ const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> > (__loc);
+ const numpunct<_CharT>& __npt = std::use_facet<numpunct<_CharT> >(__loc);
string __grouping = __npt.grouping();
__oe = __ob;
char* __nf = __nb;
@@ -1233,7 +1236,7 @@ __num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne,
}
else
{
- reverse(__nf, __ns);
+ std::reverse(__nf, __ns);
_CharT __thousands_sep = __npt.thousands_sep();
unsigned __dc = 0;
unsigned __dg = 0;
@@ -1249,7 +1252,7 @@ __num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne,
*__oe++ = __ct.widen(*__p);
++__dc;
}
- reverse(__ob + (__nf - __nb), __oe);
+ std::reverse(__ob + (__nf - __nb), __oe);
}
for (__nf = __ns; __nf < __ne; ++__nf)
{
@@ -1347,7 +1350,7 @@ public:
static locale::id id;
protected:
- _LIBCPP_HIDE_FROM_ABI ~num_put() override {}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~num_put() override {}
virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
bool __v) const;
@@ -1459,7 +1462,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
{
if ((__iob.flags() & ios_base::boolalpha) == 0)
return do_put(__s, __iob, __fl, (unsigned long)__v);
- const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__iob.getloc());
+ const numpunct<char_type>& __np = std::use_facet<numpunct<char_type> >(__iob.getloc());
typedef typename numpunct<char_type>::string_type string_type;
#ifdef _LIBCPP_ENABLE_DEBUG_MODE
string_type __tmp(__v ? __np.truename() : __np.falsename());
@@ -1505,7 +1508,7 @@ num_put<_CharT, _OutputIterator>::__do_put_integral(iter_type __s, ios_base& __i
this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
// [__o, __oe) contains thousands_sep'd wide number
// Stage 3 & 4
- return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
+ return std::__pad_and_output(__s, __o, __op, __oe, __iob, __fl);
}
template <class _CharT, class _OutputIterator>
@@ -1593,7 +1596,7 @@ num_put<_CharT, _OutputIterator>::__do_put_floating_point(iter_type __s, ios_bas
this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
// [__o, __oe) contains thousands_sep'd wide number
// Stage 3 & 4
- __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
+ __s = std::__pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
return __s;
}
@@ -1628,7 +1631,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
char_type __o[2*(__nbuf-1) - 1];
char_type* __op; // pad here
char_type* __oe; // end of output
- const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
+ const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc());
__ct.widen(__nar, __ne, __o);
__oe = __o + (__ne - __nar);
if (__np == __ne)
@@ -1637,7 +1640,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
__op = __o + (__np - __nar);
// [__o, __oe) contains wide number
// Stage 3 & 4
- return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
+ return std::__pad_and_output(__s, __o, __op, __oe, __iob, __fl);
}
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<char>;
@@ -1792,7 +1795,7 @@ public:
static locale::id id;
protected:
- _LIBCPP_HIDE_FROM_ABI ~time_get() override {}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_get() override {}
virtual dateorder do_date_order() const;
virtual iter_type do_get_time(iter_type __b, iter_type __e, ios_base& __iob,
@@ -1923,7 +1926,7 @@ time_get<_CharT, _InputIterator>::__get_month(int& __m,
ios_base::iostate& __err,
const ctype<char_type>& __ct) const
{
- int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1;
+ int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1;
if (!(__err & ios_base::failbit) && 0 <= __t && __t <= 11)
__m = __t;
else
@@ -1937,7 +1940,7 @@ time_get<_CharT, _InputIterator>::__get_year(int& __y,
ios_base::iostate& __err,
const ctype<char_type>& __ct) const
{
- int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
+ int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 4);
if (!(__err & ios_base::failbit))
{
if (__t < 69)
@@ -1955,7 +1958,7 @@ time_get<_CharT, _InputIterator>::__get_year4(int& __y,
ios_base::iostate& __err,
const ctype<char_type>& __ct) const
{
- int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
+ int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 4);
if (!(__err & ios_base::failbit))
__y = __t - 1900;
}
@@ -1967,7 +1970,7 @@ time_get<_CharT, _InputIterator>::__get_hour(int& __h,
ios_base::iostate& __err,
const ctype<char_type>& __ct) const
{
- int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
+ int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2);
if (!(__err & ios_base::failbit) && __t <= 23)
__h = __t;
else
@@ -1981,7 +1984,7 @@ time_get<_CharT, _InputIterator>::__get_12_hour(int& __h,
ios_base::iostate& __err,
const ctype<char_type>& __ct) const
{
- int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
+ int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2);
if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12)
__h = __t;
else
@@ -1995,7 +1998,7 @@ time_get<_CharT, _InputIterator>::__get_minute(int& __m,
ios_base::iostate& __err,
const ctype<char_type>& __ct) const
{
- int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
+ int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2);
if (!(__err & ios_base::failbit) && __t <= 59)
__m = __t;
else
@@ -2009,7 +2012,7 @@ time_get<_CharT, _InputIterator>::__get_second(int& __s,
ios_base::iostate& __err,
const ctype<char_type>& __ct) const
{
- int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
+ int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2);
if (!(__err & ios_base::failbit) && __t <= 60)
__s = __t;
else
@@ -2023,7 +2026,7 @@ time_get<_CharT, _InputIterator>::__get_weekday(int& __w,
ios_base::iostate& __err,
const ctype<char_type>& __ct) const
{
- int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 1);
+ int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 1);
if (!(__err & ios_base::failbit) && __t <= 6)
__w = __t;
else
@@ -2037,7 +2040,7 @@ time_get<_CharT, _InputIterator>::__get_day_year_num(int& __d,
ios_base::iostate& __err,
const ctype<char_type>& __ct) const
{
- int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 3);
+ int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 3);
if (!(__err & ios_base::failbit) && __t <= 365)
__d = __t;
else
@@ -2102,7 +2105,7 @@ time_get<_CharT, _InputIterator>::get(iter_type __b, iter_type __e,
ios_base::iostate& __err, tm* __tm,
const char_type* __fmtb, const char_type* __fmte) const
{
- const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
+ const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc());
__err = ios_base::goodbit;
while (__fmtb != __fmte && __err == ios_base::goodbit)
{
@@ -2189,7 +2192,7 @@ time_get<_CharT, _InputIterator>::do_get_weekday(iter_type __b, iter_type __e,
ios_base::iostate& __err,
tm* __tm) const
{
- const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
+ const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc());
__get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
return __b;
}
@@ -2201,7 +2204,7 @@ time_get<_CharT, _InputIterator>::do_get_monthname(iter_type __b, iter_type __e,
ios_base::iostate& __err,
tm* __tm) const
{
- const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
+ const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc());
__get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
return __b;
}
@@ -2213,7 +2216,7 @@ time_get<_CharT, _InputIterator>::do_get_year(iter_type __b, iter_type __e,
ios_base::iostate& __err,
tm* __tm) const
{
- const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
+ const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc());
__get_year(__tm->tm_year, __b, __e, __err, __ct);
return __b;
}
@@ -2226,7 +2229,7 @@ time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
char __fmt, char) const
{
__err = ios_base::goodbit;
- const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
+ const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc());
switch (__fmt)
{
case 'a':
@@ -2411,25 +2414,17 @@ public:
__time_get_storage<_CharT>(__nm) {}
protected:
- _LIBCPP_HIDE_FROM_ABI ~time_get_byname() override {}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_get_byname() override {}
- _LIBCPP_INLINE_VISIBILITY
- dateorder do_date_order() const override {return this->__do_date_order();}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL dateorder do_date_order() const override {return this->__do_date_order();}
private:
- _LIBCPP_INLINE_VISIBILITY
- const string_type* __weeks() const override {return this->__weeks_;}
- _LIBCPP_INLINE_VISIBILITY
- const string_type* __months() const override {return this->__months_;}
- _LIBCPP_INLINE_VISIBILITY
- const string_type* __am_pm() const override {return this->__am_pm_;}
- _LIBCPP_INLINE_VISIBILITY
- const string_type& __c() const override {return this->__c_;}
- _LIBCPP_INLINE_VISIBILITY
- const string_type& __r() const override {return this->__r_;}
- _LIBCPP_INLINE_VISIBILITY
- const string_type& __x() const override {return this->__x_;}
- _LIBCPP_INLINE_VISIBILITY
- const string_type& __X() const override {return this->__X_;}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type* __weeks() const override {return this->__weeks_;}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type* __months() const override {return this->__months_;}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type* __am_pm() const override {return this->__am_pm_;}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __c() const override {return this->__c_;}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __r() const override {return this->__r_;}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __x() const override {return this->__x_;}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __X() const override {return this->__X_;}
};
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<char>;
@@ -2479,7 +2474,7 @@ public:
static locale::id id;
protected:
- _LIBCPP_HIDE_FROM_ABI ~time_put() override {}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_put() override {}
virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm,
char __fmt, char __mod) const;
@@ -2504,7 +2499,7 @@ time_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob,
const char_type* __pb,
const char_type* __pe) const
{
- const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
+ const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc());
for (; __pb != __pe; ++__pb)
{
if (__ct.narrow(*__pb, 0) == '%')
@@ -2570,7 +2565,7 @@ protected:
#if defined(_MSC_VER) && defined(__clang__)
~time_put_byname() {}
#else
- _LIBCPP_HIDE_FROM_ABI ~time_put_byname() override {}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_put_byname() override {}
#endif
};
@@ -2619,7 +2614,7 @@ public:
static const bool intl = _International;
protected:
- _LIBCPP_HIDE_FROM_ABI ~moneypunct() override {}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~moneypunct() override {}
virtual char_type do_decimal_point() const {return numeric_limits<char_type>::max();}
virtual char_type do_thousands_sep() const {return numeric_limits<char_type>::max();}
@@ -2669,7 +2664,7 @@ public:
: moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());}
protected:
- _LIBCPP_HIDE_FROM_ABI ~moneypunct_byname() override {}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~moneypunct_byname() override {}
char_type do_decimal_point() const override {return __decimal_point_;}
char_type do_thousands_sep() const override {return __thousands_sep_;}
@@ -2736,7 +2731,7 @@ __money_get<_CharT>::__gather_info(bool __intl, const locale& __loc,
if (__intl)
{
const moneypunct<char_type, true>& __mp =
- use_facet<moneypunct<char_type, true> >(__loc);
+ std::use_facet<moneypunct<char_type, true> >(__loc);
__pat = __mp.neg_format();
__nsn = __mp.negative_sign();
__psn = __mp.positive_sign();
@@ -2749,7 +2744,7 @@ __money_get<_CharT>::__gather_info(bool __intl, const locale& __loc,
else
{
const moneypunct<char_type, false>& __mp =
- use_facet<moneypunct<char_type, false> >(__loc);
+ std::use_facet<moneypunct<char_type, false> >(__loc);
__pat = __mp.neg_format();
__nsn = __mp.negative_sign();
__psn = __mp.positive_sign();
@@ -2797,7 +2792,7 @@ public:
static locale::id id;
protected:
- _LIBCPP_HIDE_FROM_ABI ~money_get() override {}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~money_get() override {}
virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
ios_base& __iob, ios_base::iostate& __err,
@@ -2833,7 +2828,7 @@ __double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e)
if (__new_cap == 0)
__new_cap = sizeof(_Tp);
size_t __n_off = static_cast<size_t>(__n - __b.get());
- _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap);
+ _Tp* __t = (_Tp*)std::realloc(__owns ? __b.get() : 0, __new_cap);
if (__t == 0)
__throw_bad_alloc();
if (__owns)
@@ -2948,7 +2943,7 @@ money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e,
++__sym_space_end;
const size_t __num_spaces = __sym_space_end - __sym.begin();
if (__num_spaces > __spaces.size() ||
- !equal(__spaces.end() - __num_spaces, __spaces.end(),
+ !std::equal(__spaces.end() - __num_spaces, __spaces.end(),
__sym.begin())) {
// No match. Put __sym_space_end back at the
// beginning of __sym, which will prevent a
@@ -2979,14 +2974,14 @@ money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e,
if (__ct.is(ctype_base::digit, __c))
{
if (__wn == __we)
- __double_or_nothing(__wb, __wn, __we);
+ std::__double_or_nothing(__wb, __wn, __we);
*__wn++ = __c;
++__ng;
}
else if (__grp.size() > 0 && __ng > 0 && __c == __ts)
{
if (__gn == __ge)
- __double_or_nothing(__gb, __gn, __ge);
+ std::__double_or_nothing(__gb, __gn, __ge);
*__gn++ = __ng;
__ng = 0;
}
@@ -2996,7 +2991,7 @@ money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e,
if (__gb.get() != __gn && __ng > 0)
{
if (__gn == __ge)
- __double_or_nothing(__gb, __gn, __ge);
+ std::__double_or_nothing(__gb, __gn, __ge);
*__gn++ = __ng;
}
if (__fd > 0)
@@ -3014,7 +3009,7 @@ money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e,
return false;
}
if (__wn == __we)
- __double_or_nothing(__wb, __wn, __we);
+ std::__double_or_nothing(__wb, __wn, __we);
*__wn++ = *__b;
}
}
@@ -3064,7 +3059,7 @@ money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
char_type* __wn;
char_type* __we = __wbuf + __bz;
locale __loc = __iob.getloc();
- const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
+ const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__loc);
bool __neg = false;
if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
__wb, __wn, __we))
@@ -3085,7 +3080,7 @@ money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
if (__neg)
*__nc++ = '-';
for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc)
- *__nc = __src[find(__atoms, _VSTD::end(__atoms), *__w) - __atoms];
+ *__nc = __src[std::find(__atoms, _VSTD::end(__atoms), *__w) - __atoms];
*__nc = char();
if (sscanf(__nbuf, "%Lf", &__v) != 1)
__throw_runtime_error("money_get error");
@@ -3108,7 +3103,7 @@ money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
char_type* __wn;
char_type* __we = __wbuf + __bz;
locale __loc = __iob.getloc();
- const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
+ const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__loc);
bool __neg = false;
if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
__wb, __wn, __we))
@@ -3170,7 +3165,7 @@ __money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc,
if (__intl)
{
const moneypunct<char_type, true>& __mp =
- use_facet<moneypunct<char_type, true> >(__loc);
+ std::use_facet<moneypunct<char_type, true> >(__loc);
if (__neg)
{
__pat = __mp.neg_format();
@@ -3190,7 +3185,7 @@ __money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc,
else
{
const moneypunct<char_type, false>& __mp =
- use_facet<moneypunct<char_type, false> >(__loc);
+ std::use_facet<moneypunct<char_type, false> >(__loc);
if (__neg)
{
__pat = __mp.neg_format();
@@ -3290,7 +3285,7 @@ __money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __m
}
}
// reverse it
- reverse(__t, __me);
+ std::reverse(__t, __me);
}
break;
}
@@ -3341,7 +3336,7 @@ public:
static locale::id id;
protected:
- _LIBCPP_HIDE_FROM_ABI ~money_put() override {}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~money_put() override {}
virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
char_type __fl, long double __units) const;
@@ -3382,7 +3377,7 @@ money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
}
// gather info
locale __loc = __iob.getloc();
- const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
+ const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__loc);
__ct.widen(__bb, __bb + __n, __db);
bool __neg = __n > 0 && __bb[0] == '-';
money_base::pattern __pat;
@@ -3414,7 +3409,7 @@ money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
this->__format(__mb, __mi, __me, __iob.flags(),
__db, __db + __n, __ct,
__neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
- return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
+ return std::__pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
}
template <class _CharT, class _OutputIterator>
@@ -3425,7 +3420,7 @@ money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
{
// gather info
locale __loc = __iob.getloc();
- const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
+ const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__loc);
bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-');
money_base::pattern __pat;
char_type __dp;
@@ -3456,7 +3451,7 @@ money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
this->__format(__mb, __mi, __me, __iob.flags(),
__digits.data(), __digits.data() + __digits.size(), __ct,
__neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
- return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
+ return std::__pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
}
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<char>;
@@ -3509,7 +3504,7 @@ public:
static locale::id id;
protected:
- _LIBCPP_HIDE_FROM_ABI ~messages() override {}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~messages() override {}
virtual catalog do_open(const basic_string<char>&, const locale&) const;
virtual string_type do_get(catalog, int __set, int __msgid,
@@ -3543,7 +3538,7 @@ messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
{
#ifdef _LIBCPP_HAS_CATOPEN
string __ndflt;
- __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__ndflt),
+ __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(std::back_inserter(__ndflt),
__dflt.c_str(),
__dflt.c_str() + __dflt.size());
if (__c != -1)
@@ -3551,7 +3546,7 @@ messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
nl_catd __cat = (nl_catd)__c;
char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str());
string_type __w;
- __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w),
+ __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(std::back_inserter(__w),
__n, __n + _VSTD::strlen(__n));
return __w;
#else // !_LIBCPP_HAS_CATOPEN
@@ -3598,7 +3593,7 @@ public:
: messages<_CharT>(__refs) {}
protected:
- _LIBCPP_HIDE_FROM_ABI ~messages_byname() override {}
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~messages_byname() override {}
};
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<char>;
@@ -3998,7 +3993,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
char_type __1buf;
if (this->gptr() == 0)
this->setg(&__1buf, &__1buf+1, &__1buf+1);
- const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
+ const size_t __unget_sz = __initial ? 0 : std::min<size_t>((this->egptr() - this->eback()) / 2, 4);
int_type __c = traits_type::eof();
if (this->gptr() == this->egptr())
{
@@ -4269,7 +4264,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
{
if (this->gptr() != this->egptr())
{
- reverse(this->gptr(), this->egptr());
+ std::reverse(this->gptr(), this->egptr());
codecvt_base::result __r;
const char_type* __e = this->gptr();
char* __extbe;
@@ -4362,12 +4357,15 @@ _LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
+// NOLINTEND(libcpp-robust-against-adl)
+
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <atomic>
# include <concepts>
# include <cstdarg>
# include <iterator>
# include <stdexcept>
+# include <type_traits>
# include <typeinfo>
#endif
diff --git a/contrib/libs/cxxsupp/libcxx/include/math.h b/contrib/libs/cxxsupp/libcxx/include/math.h
index f2d4eaedf8..7f9330eb1a 100644
--- a/contrib/libs/cxxsupp/libcxx/include/math.h
+++ b/contrib/libs/cxxsupp/libcxx/include/math.h
@@ -307,10 +307,13 @@ long double truncl(long double x);
// back to C++ linkage before including these C++ headers.
extern "C++" {
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_floating_point.h>
+#include <__type_traits/is_integral.h>
+#include <__type_traits/is_same.h>
#include <__type_traits/promote.h>
#include <limits>
#include <stdlib.h>
-#include <type_traits>
# ifdef fpclassify
@@ -364,29 +367,29 @@ extern "C++" {
// signbit
template <class _A1, std::__enable_if_t<std::is_floating_point<_A1>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT {
return __builtin_signbit(__x);
}
template <class _A1, std::__enable_if_t<std::is_integral<_A1>::value && std::is_signed<_A1>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT {
return __x < 0;
}
template <class _A1, std::__enable_if_t<std::is_integral<_A1>::value && !std::is_signed<_A1>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1) _NOEXCEPT {
return false;
}
// fpclassify
template <class _A1, std::__enable_if_t<std::is_floating_point<_A1>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI int fpclassify(_A1 __x) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI int fpclassify(_A1 __x) _NOEXCEPT {
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
}
template <class _A1, std::__enable_if_t<std::is_integral<_A1>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI int fpclassify(_A1 __x) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI int fpclassify(_A1 __x) _NOEXCEPT {
return __x == 0 ? FP_ZERO : FP_NORMAL;
}
@@ -397,13 +400,13 @@ inline _LIBCPP_HIDE_FROM_ABI int fpclassify(_A1 __x) _NOEXCEPT {
template <class _A1,
std::__enable_if_t<std::is_arithmetic<_A1>::value && std::numeric_limits<_A1>::has_infinity, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1 __x) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1 __x) _NOEXCEPT {
return __builtin_isfinite((typename std::__promote<_A1>::type)__x);
}
template <class _A1,
std::__enable_if_t<std::is_arithmetic<_A1>::value && !std::numeric_limits<_A1>::has_infinity, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1) _NOEXCEPT {
return true;
}
@@ -411,54 +414,66 @@ inline _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1) _NOEXCEPT {
template <class _A1,
std::__enable_if_t<std::is_arithmetic<_A1>::value && std::numeric_limits<_A1>::has_infinity, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI bool isinf(_A1 __x) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(_A1 __x) _NOEXCEPT {
return __builtin_isinf((typename std::__promote<_A1>::type)__x);
}
template <class _A1>
-inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI
typename std::enable_if< std::is_arithmetic<_A1>::value && !std::numeric_limits<_A1>::has_infinity, bool>::type
isinf(_A1) _NOEXCEPT {
return false;
}
#if defined(_LIBCPP_PREFERRED_OVERLOAD) && !defined(__CUDACC__)
-inline _LIBCPP_HIDE_FROM_ABI bool isinf(float __x) _NOEXCEPT { return __builtin_isinf(__x); }
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(float __x) _NOEXCEPT {
+ return __builtin_isinf(__x);
+}
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool isinf(double __x) _NOEXCEPT { return __builtin_isinf(__x); }
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool isinf(double __x) _NOEXCEPT {
+ return __builtin_isinf(__x);
+}
-inline _LIBCPP_HIDE_FROM_ABI bool isinf(long double __x) _NOEXCEPT { return __builtin_isinf(__x); }
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(long double __x) _NOEXCEPT {
+ return __builtin_isinf(__x);
+}
# endif
// isnan
template <class _A1, std::__enable_if_t<std::is_floating_point<_A1>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI bool isnan(_A1 __x) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1 __x) _NOEXCEPT {
return __builtin_isnan(__x);
}
template <class _A1, std::__enable_if_t<std::is_integral<_A1>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI bool isnan(_A1) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1) _NOEXCEPT {
return false;
}
#if defined(_LIBCPP_PREFERRED_OVERLOAD) && !defined(__CUDACC__)
-inline _LIBCPP_HIDE_FROM_ABI bool isnan(float __x) _NOEXCEPT { return __builtin_isnan(__x); }
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(float __x) _NOEXCEPT {
+ return __builtin_isnan(__x);
+}
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool isnan(double __x) _NOEXCEPT { return __builtin_isnan(__x); }
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool isnan(double __x) _NOEXCEPT {
+ return __builtin_isnan(__x);
+}
-inline _LIBCPP_HIDE_FROM_ABI bool isnan(long double __x) _NOEXCEPT { return __builtin_isnan(__x); }
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(long double __x) _NOEXCEPT {
+ return __builtin_isnan(__x);
+}
# endif
// isnormal
template <class _A1, std::__enable_if_t<std::is_floating_point<_A1>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT {
return __builtin_isnormal(__x);
}
template <class _A1, std::__enable_if_t<std::is_integral<_A1>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT {
return __x != 0;
}
@@ -467,7 +482,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT {
template <class _A1,
class _A2,
std::__enable_if_t<std::is_arithmetic<_A1>::value && std::is_arithmetic<_A2>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI bool isgreater(_A1 __x, _A2 __y) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isgreater(_A1 __x, _A2 __y) _NOEXCEPT {
typedef typename std::__promote<_A1, _A2>::type type;
return __builtin_isgreater((type)__x, (type)__y);
}
@@ -477,7 +492,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool isgreater(_A1 __x, _A2 __y) _NOEXCEPT {
template <class _A1,
class _A2,
std::__enable_if_t<std::is_arithmetic<_A1>::value && std::is_arithmetic<_A2>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_A1 __x, _A2 __y) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_A1 __x, _A2 __y) _NOEXCEPT {
typedef typename std::__promote<_A1, _A2>::type type;
return __builtin_isgreaterequal((type)__x, (type)__y);
}
@@ -487,7 +502,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_A1 __x, _A2 __y) _NOEXCEPT {
template <class _A1,
class _A2,
std::__enable_if_t<std::is_arithmetic<_A1>::value && std::is_arithmetic<_A2>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI bool isless(_A1 __x, _A2 __y) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isless(_A1 __x, _A2 __y) _NOEXCEPT {
typedef typename std::__promote<_A1, _A2>::type type;
return __builtin_isless((type)__x, (type)__y);
}
@@ -497,7 +512,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool isless(_A1 __x, _A2 __y) _NOEXCEPT {
template <class _A1,
class _A2,
std::__enable_if_t<std::is_arithmetic<_A1>::value && std::is_arithmetic<_A2>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI bool islessequal(_A1 __x, _A2 __y) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool islessequal(_A1 __x, _A2 __y) _NOEXCEPT {
typedef typename std::__promote<_A1, _A2>::type type;
return __builtin_islessequal((type)__x, (type)__y);
}
@@ -507,7 +522,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool islessequal(_A1 __x, _A2 __y) _NOEXCEPT {
template <class _A1,
class _A2,
std::__enable_if_t<std::is_arithmetic<_A1>::value && std::is_arithmetic<_A2>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI bool islessgreater(_A1 __x, _A2 __y) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool islessgreater(_A1 __x, _A2 __y) _NOEXCEPT {
typedef typename std::__promote<_A1, _A2>::type type;
return __builtin_islessgreater((type)__x, (type)__y);
}
@@ -517,7 +532,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool islessgreater(_A1 __x, _A2 __y) _NOEXCEPT {
template <class _A1,
class _A2,
std::__enable_if_t<std::is_arithmetic<_A1>::value && std::is_arithmetic<_A2>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2 __y) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2 __y) _NOEXCEPT {
typedef typename std::__promote<_A1, _A2>::type type;
return __builtin_isunordered((type)__x, (type)__y);
}
@@ -532,10 +547,21 @@ inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2 __y) _NOEXCEPT {
//
// handled in stdlib.h
+// We have to provide double overloads for <math.h> to work on platforms that don't provide the full set of math
+// functions. To make the overload set work with multiple functions that take the same arguments, we make our overloads
+// templates. Functions are preferred over function templates during overload resolution, which means that our overload
+// will only be selected when the C library doesn't provide one.
+
// acos
# if !defined(__sun__)
inline _LIBCPP_HIDE_FROM_ABI float acos(float __x) _NOEXCEPT {return __builtin_acosf(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double acos(double __x) _NOEXCEPT {
+ return __builtin_acos(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double acos(long double __x) _NOEXCEPT {return __builtin_acosl(__x);}
# endif
@@ -548,6 +574,12 @@ acos(_A1 __x) _NOEXCEPT {return __builtin_acos((double)__x);}
# if !defined(__sun__)
inline _LIBCPP_HIDE_FROM_ABI float asin(float __x) _NOEXCEPT {return __builtin_asinf(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double asin(double __x) _NOEXCEPT {
+ return __builtin_asin(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double asin(long double __x) _NOEXCEPT {return __builtin_asinl(__x);}
# endif
@@ -560,6 +592,12 @@ asin(_A1 __x) _NOEXCEPT {return __builtin_asin((double)__x);}
# if !defined(__sun__)
inline _LIBCPP_HIDE_FROM_ABI float atan(float __x) _NOEXCEPT {return __builtin_atanf(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double atan(double __x) _NOEXCEPT {
+ return __builtin_atan(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double atan(long double __x) _NOEXCEPT {return __builtin_atanl(__x);}
# endif
@@ -572,6 +610,12 @@ atan(_A1 __x) _NOEXCEPT {return __builtin_atan((double)__x);}
# if !defined(__sun__)
inline _LIBCPP_HIDE_FROM_ABI float atan2(float __y, float __x) _NOEXCEPT {return __builtin_atan2f(__y, __x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double atan2(double __x, double __y) _NOEXCEPT {
+ return __builtin_atan2(__x, __y);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double atan2(long double __y, long double __x) _NOEXCEPT {return __builtin_atan2l(__y, __x);}
# endif
@@ -594,12 +638,18 @@ atan2(_A1 __y, _A2 __x) _NOEXCEPT
// ceil
# if !defined(__sun__)
-inline _LIBCPP_HIDE_FROM_ABI float ceil(float __x) _NOEXCEPT {return __builtin_ceilf(__x);}
-inline _LIBCPP_HIDE_FROM_ABI long double ceil(long double __x) _NOEXCEPT {return __builtin_ceill(__x);}
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float ceil(float __x) _NOEXCEPT {return __builtin_ceilf(__x);}
+
+template <class = int>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double ceil(double __x) _NOEXCEPT {
+ return __builtin_ceil(__x);
+}
+
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double ceil(long double __x) _NOEXCEPT {return __builtin_ceill(__x);}
# endif
template <class _A1>
-inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
typename std::enable_if<std::is_integral<_A1>::value, double>::type
ceil(_A1 __x) _NOEXCEPT {return __builtin_ceil((double)__x);}
@@ -607,6 +657,12 @@ ceil(_A1 __x) _NOEXCEPT {return __builtin_ceil((double)__x);}
# if !defined(__sun__)
inline _LIBCPP_HIDE_FROM_ABI float cos(float __x) _NOEXCEPT {return __builtin_cosf(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double cos(double __x) _NOEXCEPT {
+ return __builtin_cos(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double cos(long double __x) _NOEXCEPT {return __builtin_cosl(__x);}
# endif
@@ -619,6 +675,12 @@ cos(_A1 __x) _NOEXCEPT {return __builtin_cos((double)__x);}
# if !defined(__sun__)
inline _LIBCPP_HIDE_FROM_ABI float cosh(float __x) _NOEXCEPT {return __builtin_coshf(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double cosh(double __x) _NOEXCEPT {
+ return __builtin_cosh(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double cosh(long double __x) _NOEXCEPT {return __builtin_coshl(__x);}
# endif
@@ -631,6 +693,12 @@ cosh(_A1 __x) _NOEXCEPT {return __builtin_cosh((double)__x);}
# if !defined(__sun__)
inline _LIBCPP_HIDE_FROM_ABI float exp(float __x) _NOEXCEPT {return __builtin_expf(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double exp(double __x) _NOEXCEPT {
+ return __builtin_exp(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double exp(long double __x) _NOEXCEPT {return __builtin_expl(__x);}
# endif
@@ -642,24 +710,36 @@ exp(_A1 __x) _NOEXCEPT {return __builtin_exp((double)__x);}
// fabs
# if !defined(__sun__)
-inline _LIBCPP_HIDE_FROM_ABI float fabs(float __x) _NOEXCEPT {return __builtin_fabsf(__x);}
-inline _LIBCPP_HIDE_FROM_ABI long double fabs(long double __x) _NOEXCEPT {return __builtin_fabsl(__x);}
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float fabs(float __x) _NOEXCEPT {return __builtin_fabsf(__x);}
+
+template <class = int>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double fabs(double __x) _NOEXCEPT {
+ return __builtin_fabs(__x);
+}
+
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double fabs(long double __x) _NOEXCEPT {return __builtin_fabsl(__x);}
# endif
template <class _A1>
-inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
typename std::enable_if<std::is_integral<_A1>::value, double>::type
fabs(_A1 __x) _NOEXCEPT {return __builtin_fabs((double)__x);}
// floor
# if !defined(__sun__)
-inline _LIBCPP_HIDE_FROM_ABI float floor(float __x) _NOEXCEPT {return __builtin_floorf(__x);}
-inline _LIBCPP_HIDE_FROM_ABI long double floor(long double __x) _NOEXCEPT {return __builtin_floorl(__x);}
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float floor(float __x) _NOEXCEPT {return __builtin_floorf(__x);}
+
+template <class = int>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double floor(double __x) _NOEXCEPT {
+ return __builtin_floor(__x);
+}
+
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double floor(long double __x) _NOEXCEPT {return __builtin_floorl(__x);}
# endif
template <class _A1>
-inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
typename std::enable_if<std::is_integral<_A1>::value, double>::type
floor(_A1 __x) _NOEXCEPT {return __builtin_floor((double)__x);}
@@ -667,6 +747,12 @@ floor(_A1 __x) _NOEXCEPT {return __builtin_floor((double)__x);}
# if !defined(__sun__)
inline _LIBCPP_HIDE_FROM_ABI float fmod(float __x, float __y) _NOEXCEPT {return __builtin_fmodf(__x, __y);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double fmod(double __x, double __y) _NOEXCEPT {
+ return __builtin_fmod(__x, __y);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double fmod(long double __x, long double __y) _NOEXCEPT {return __builtin_fmodl(__x, __y);}
# endif
@@ -690,6 +776,12 @@ fmod(_A1 __x, _A2 __y) _NOEXCEPT
# if !defined(__sun__)
inline _LIBCPP_HIDE_FROM_ABI float frexp(float __x, int* __e) _NOEXCEPT {return __builtin_frexpf(__x, __e);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double frexp(double __x, int* __e) _NOEXCEPT {
+ return __builtin_frexp(__x, __e);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double frexp(long double __x, int* __e) _NOEXCEPT {return __builtin_frexpl(__x, __e);}
# endif
@@ -702,6 +794,12 @@ frexp(_A1 __x, int* __e) _NOEXCEPT {return __builtin_frexp((double)__x, __e);}
# if !defined(__sun__)
inline _LIBCPP_HIDE_FROM_ABI float ldexp(float __x, int __e) _NOEXCEPT {return __builtin_ldexpf(__x, __e);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double ldexp(double __x, int __e) _NOEXCEPT {
+ return __builtin_ldexp(__x, __e);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double ldexp(long double __x, int __e) _NOEXCEPT {return __builtin_ldexpl(__x, __e);}
# endif
@@ -714,6 +812,12 @@ ldexp(_A1 __x, int __e) _NOEXCEPT {return __builtin_ldexp((double)__x, __e);}
# if !defined(__sun__)
inline _LIBCPP_HIDE_FROM_ABI float log(float __x) _NOEXCEPT {return __builtin_logf(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double log(double __x) _NOEXCEPT {
+ return __builtin_log(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double log(long double __x) _NOEXCEPT {return __builtin_logl(__x);}
# endif
@@ -726,6 +830,13 @@ log(_A1 __x) _NOEXCEPT {return __builtin_log((double)__x);}
# if !defined(__sun__)
inline _LIBCPP_HIDE_FROM_ABI float log10(float __x) _NOEXCEPT {return __builtin_log10f(__x);}
+
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double log10(double __x) _NOEXCEPT {
+ return __builtin_log10(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double log10(long double __x) _NOEXCEPT {return __builtin_log10l(__x);}
# endif
@@ -738,6 +849,12 @@ log10(_A1 __x) _NOEXCEPT {return __builtin_log10((double)__x);}
# if !defined(__sun__)
inline _LIBCPP_HIDE_FROM_ABI float modf(float __x, float* __y) _NOEXCEPT {return __builtin_modff(__x, __y);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double modf(double __x, double* __y) _NOEXCEPT {
+ return __builtin_modf(__x, __y);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double modf(long double __x, long double* __y) _NOEXCEPT {return __builtin_modfl(__x, __y);}
# endif
@@ -745,6 +862,12 @@ inline _LIBCPP_HIDE_FROM_ABI long double modf(long double __x, long double* __y)
# if !defined(__sun__)
inline _LIBCPP_HIDE_FROM_ABI float pow(float __x, float __y) _NOEXCEPT {return __builtin_powf(__x, __y);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double pow(double __x, double __y) _NOEXCEPT {
+ return __builtin_pow(__x, __y);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double pow(long double __x, long double __y) _NOEXCEPT {return __builtin_powl(__x, __y);}
# endif
@@ -768,6 +891,12 @@ pow(_A1 __x, _A2 __y) _NOEXCEPT
# if !defined(__sun__)
inline _LIBCPP_HIDE_FROM_ABI float sin(float __x) _NOEXCEPT {return __builtin_sinf(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double sin(double __x) _NOEXCEPT {
+ return __builtin_sin(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double sin(long double __x) _NOEXCEPT {return __builtin_sinl(__x);}
#endif
@@ -780,6 +909,12 @@ sin(_A1 __x) _NOEXCEPT {return __builtin_sin((double)__x);}
# if !defined(__sun__)
inline _LIBCPP_HIDE_FROM_ABI float sinh(float __x) _NOEXCEPT {return __builtin_sinhf(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double sinh(double __x) _NOEXCEPT {
+ return __builtin_sinh(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double sinh(long double __x) _NOEXCEPT {return __builtin_sinhl(__x);}
# endif
@@ -792,6 +927,12 @@ sinh(_A1 __x) _NOEXCEPT {return __builtin_sinh((double)__x);}
# if !defined(__sun__)
inline _LIBCPP_HIDE_FROM_ABI float sqrt(float __x) _NOEXCEPT {return __builtin_sqrtf(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double sqrt(double __x) _NOEXCEPT {
+ return __builtin_sqrt(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double sqrt(long double __x) _NOEXCEPT {return __builtin_sqrtl(__x);}
# endif
@@ -804,6 +945,12 @@ sqrt(_A1 __x) _NOEXCEPT {return __builtin_sqrt((double)__x);}
# if !defined(__sun__)
inline _LIBCPP_HIDE_FROM_ABI float tan(float __x) _NOEXCEPT {return __builtin_tanf(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double tan(double __x) _NOEXCEPT {
+ return __builtin_tan(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double tan(long double __x) _NOEXCEPT {return __builtin_tanl(__x);}
# endif
@@ -816,6 +963,12 @@ tan(_A1 __x) _NOEXCEPT {return __builtin_tan((double)__x);}
# if !defined(__sun__)
inline _LIBCPP_HIDE_FROM_ABI float tanh(float __x) _NOEXCEPT {return __builtin_tanhf(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double tanh(double __x) _NOEXCEPT {
+ return __builtin_tanh(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double tanh(long double __x) _NOEXCEPT {return __builtin_tanhl(__x);}
# endif
@@ -827,6 +980,12 @@ tanh(_A1 __x) _NOEXCEPT {return __builtin_tanh((double)__x);}
// acosh
inline _LIBCPP_HIDE_FROM_ABI float acosh(float __x) _NOEXCEPT {return __builtin_acoshf(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double acosh(double __x) _NOEXCEPT {
+ return __builtin_acosh(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double acosh(long double __x) _NOEXCEPT {return __builtin_acoshl(__x);}
template <class _A1>
@@ -837,6 +996,12 @@ acosh(_A1 __x) _NOEXCEPT {return __builtin_acosh((double)__x);}
// asinh
inline _LIBCPP_HIDE_FROM_ABI float asinh(float __x) _NOEXCEPT {return __builtin_asinhf(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double asinh(double __x) _NOEXCEPT {
+ return __builtin_asinh(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double asinh(long double __x) _NOEXCEPT {return __builtin_asinhl(__x);}
template <class _A1>
@@ -847,6 +1012,12 @@ asinh(_A1 __x) _NOEXCEPT {return __builtin_asinh((double)__x);}
// atanh
inline _LIBCPP_HIDE_FROM_ABI float atanh(float __x) _NOEXCEPT {return __builtin_atanhf(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double atanh(double __x) _NOEXCEPT {
+ return __builtin_atanh(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double atanh(long double __x) _NOEXCEPT {return __builtin_atanhl(__x);}
template <class _A1>
@@ -856,57 +1027,32 @@ atanh(_A1 __x) _NOEXCEPT {return __builtin_atanh((double)__x);}
// cbrt
-inline _LIBCPP_HIDE_FROM_ABI float cbrt(float __x) _NOEXCEPT {return __builtin_cbrtf(__x);}
-inline _LIBCPP_HIDE_FROM_ABI long double cbrt(long double __x) _NOEXCEPT {return __builtin_cbrtl(__x);}
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float cbrt(float __x) _NOEXCEPT {return __builtin_cbrtf(__x);}
+
+template <class = int>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double cbrt(double __x) _NOEXCEPT {
+ return __builtin_cbrt(__x);
+}
+
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double cbrt(long double __x) _NOEXCEPT {return __builtin_cbrtl(__x);}
template <class _A1>
-inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
typename std::enable_if<std::is_integral<_A1>::value, double>::type
cbrt(_A1 __x) _NOEXCEPT {return __builtin_cbrt((double)__x);}
// copysign
-_LIBCPP_CONSTEXPR
-inline _LIBCPP_HIDE_FROM_ABI float __libcpp_copysign(float __x, float __y) _NOEXCEPT {
- return __builtin_copysignf(__x, __y);
-}
-
-_LIBCPP_CONSTEXPR
-inline _LIBCPP_HIDE_FROM_ABI double __libcpp_copysign(double __x, double __y) _NOEXCEPT {
- return __builtin_copysign(__x, __y);
-}
-
-_LIBCPP_CONSTEXPR
-inline _LIBCPP_HIDE_FROM_ABI long double __libcpp_copysign(long double __x, long double __y) _NOEXCEPT {
- return __builtin_copysignl(__x, __y);
-}
-
-template <class _A1, class _A2>
-_LIBCPP_CONSTEXPR
-inline _LIBCPP_HIDE_FROM_ABI
-typename std::__enable_if_t
-<
- std::is_arithmetic<_A1>::value &&
- std::is_arithmetic<_A2>::value,
- std::__promote<_A1, _A2>
->::type
-__libcpp_copysign(_A1 __x, _A2 __y) _NOEXCEPT {
- typedef typename std::__promote<_A1, _A2>::type __result_type;
- static_assert((!(std::_IsSame<_A1, __result_type>::value &&
- std::_IsSame<_A2, __result_type>::value)), "");
- return __builtin_copysign((__result_type)__x, (__result_type)__y);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI float copysign(float __x, float __y) _NOEXCEPT {
- return ::__libcpp_copysign(__x, __y);
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float copysign(float __x, float __y) _NOEXCEPT {
+ return ::__builtin_copysignf(__x, __y);
}
-inline _LIBCPP_HIDE_FROM_ABI long double copysign(long double __x, long double __y) _NOEXCEPT {
- return ::__libcpp_copysign(__x, __y);
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double copysign(long double __x, long double __y) _NOEXCEPT {
+ return ::__builtin_copysignl(__x, __y);
}
template <class _A1, class _A2>
-inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
typename std::__enable_if_t
<
std::is_arithmetic<_A1>::value &&
@@ -914,12 +1060,18 @@ typename std::__enable_if_t
std::__promote<_A1, _A2>
>::type
copysign(_A1 __x, _A2 __y) _NOEXCEPT {
- return ::__libcpp_copysign(__x, __y);
+ return ::__builtin_copysign(__x, __y);
}
// erf
inline _LIBCPP_HIDE_FROM_ABI float erf(float __x) _NOEXCEPT {return __builtin_erff(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double erf(double __x) _NOEXCEPT {
+ return __builtin_erf(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double erf(long double __x) _NOEXCEPT {return __builtin_erfl(__x);}
template <class _A1>
@@ -930,6 +1082,12 @@ erf(_A1 __x) _NOEXCEPT {return __builtin_erf((double)__x);}
// erfc
inline _LIBCPP_HIDE_FROM_ABI float erfc(float __x) _NOEXCEPT {return __builtin_erfcf(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double erfc(double __x) _NOEXCEPT {
+ return __builtin_erfc(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double erfc(long double __x) _NOEXCEPT {return __builtin_erfcl(__x);}
template <class _A1>
@@ -940,6 +1098,12 @@ erfc(_A1 __x) _NOEXCEPT {return __builtin_erfc((double)__x);}
// exp2
inline _LIBCPP_HIDE_FROM_ABI float exp2(float __x) _NOEXCEPT {return __builtin_exp2f(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double exp2(double __x) _NOEXCEPT {
+ return __builtin_exp2(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double exp2(long double __x) _NOEXCEPT {return __builtin_exp2l(__x);}
template <class _A1>
@@ -950,6 +1114,12 @@ exp2(_A1 __x) _NOEXCEPT {return __builtin_exp2((double)__x);}
// expm1
inline _LIBCPP_HIDE_FROM_ABI float expm1(float __x) _NOEXCEPT {return __builtin_expm1f(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double expm1(double __x) _NOEXCEPT {
+ return __builtin_expm1(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double expm1(long double __x) _NOEXCEPT {return __builtin_expm1l(__x);}
template <class _A1>
@@ -960,6 +1130,12 @@ expm1(_A1 __x) _NOEXCEPT {return __builtin_expm1((double)__x);}
// fdim
inline _LIBCPP_HIDE_FROM_ABI float fdim(float __x, float __y) _NOEXCEPT {return __builtin_fdimf(__x, __y);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double fdim(double __x, double __y) _NOEXCEPT {
+ return __builtin_fdim(__x, __y);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double fdim(long double __x, long double __y) _NOEXCEPT {return __builtin_fdiml(__x, __y);}
template <class _A1, class _A2>
@@ -984,6 +1160,13 @@ inline _LIBCPP_HIDE_FROM_ABI float fma(float __x, float __y, float __z) _N
{
return __builtin_fmaf(__x, __y, __z);
}
+
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double fma(double __x, double __y, double __z) _NOEXCEPT {
+ return __builtin_fma(__x, __y, __z);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double fma(long double __x, long double __y, long double __z) _NOEXCEPT
{
return __builtin_fmal(__x, __y, __z);
@@ -1009,11 +1192,17 @@ fma(_A1 __x, _A2 __y, _A3 __z) _NOEXCEPT
// fmax
-inline _LIBCPP_HIDE_FROM_ABI float fmax(float __x, float __y) _NOEXCEPT {return __builtin_fmaxf(__x, __y);}
-inline _LIBCPP_HIDE_FROM_ABI long double fmax(long double __x, long double __y) _NOEXCEPT {return __builtin_fmaxl(__x, __y);}
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float fmax(float __x, float __y) _NOEXCEPT {return __builtin_fmaxf(__x, __y);}
+
+template <class = int>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double fmax(double __x, double __y) _NOEXCEPT {
+ return __builtin_fmax(__x, __y);
+}
+
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double fmax(long double __x, long double __y) _NOEXCEPT {return __builtin_fmaxl(__x, __y);}
template <class _A1, class _A2>
-inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
typename std::__enable_if_t
<
std::is_arithmetic<_A1>::value &&
@@ -1030,11 +1219,17 @@ fmax(_A1 __x, _A2 __y) _NOEXCEPT
// fmin
-inline _LIBCPP_HIDE_FROM_ABI float fmin(float __x, float __y) _NOEXCEPT {return __builtin_fminf(__x, __y);}
-inline _LIBCPP_HIDE_FROM_ABI long double fmin(long double __x, long double __y) _NOEXCEPT {return __builtin_fminl(__x, __y);}
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float fmin(float __x, float __y) _NOEXCEPT {return __builtin_fminf(__x, __y);}
+
+template <class = int>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double fmin(double __x, double __y) _NOEXCEPT {
+ return __builtin_fmin(__x, __y);
+}
+
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double fmin(long double __x, long double __y) _NOEXCEPT {return __builtin_fminl(__x, __y);}
template <class _A1, class _A2>
-inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
typename std::__enable_if_t
<
std::is_arithmetic<_A1>::value &&
@@ -1052,6 +1247,12 @@ fmin(_A1 __x, _A2 __y) _NOEXCEPT
// hypot
inline _LIBCPP_HIDE_FROM_ABI float hypot(float __x, float __y) _NOEXCEPT {return __builtin_hypotf(__x, __y);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double hypot(double __x, double __y) _NOEXCEPT {
+ return __builtin_hypot(__x, __y);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double hypot(long double __x, long double __y) _NOEXCEPT {return __builtin_hypotl(__x, __y);}
template <class _A1, class _A2>
@@ -1073,6 +1274,12 @@ hypot(_A1 __x, _A2 __y) _NOEXCEPT
// ilogb
inline _LIBCPP_HIDE_FROM_ABI int ilogb(float __x) _NOEXCEPT {return __builtin_ilogbf(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double ilogb(double __x) _NOEXCEPT {
+ return __builtin_ilogb(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI int ilogb(long double __x) _NOEXCEPT {return __builtin_ilogbl(__x);}
template <class _A1>
@@ -1083,6 +1290,12 @@ ilogb(_A1 __x) _NOEXCEPT {return __builtin_ilogb((double)__x);}
// lgamma
inline _LIBCPP_HIDE_FROM_ABI float lgamma(float __x) _NOEXCEPT {return __builtin_lgammaf(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double lgamma(double __x) _NOEXCEPT {
+ return __builtin_lgamma(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double lgamma(long double __x) _NOEXCEPT {return __builtin_lgammal(__x);}
template <class _A1>
@@ -1096,6 +1309,12 @@ inline _LIBCPP_HIDE_FROM_ABI long long llrint(float __x) _NOEXCEPT
{
return __builtin_llrintf(__x);
}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI long long llrint(double __x) _NOEXCEPT {
+ return __builtin_llrint(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long long llrint(long double __x) _NOEXCEPT
{
return __builtin_llrintl(__x);
@@ -1115,6 +1334,12 @@ inline _LIBCPP_HIDE_FROM_ABI long long llround(float __x) _NOEXCEPT
{
return __builtin_llroundf(__x);
}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI long long llround(double __x) _NOEXCEPT {
+ return __builtin_llround(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long long llround(long double __x) _NOEXCEPT
{
return __builtin_llroundl(__x);
@@ -1131,6 +1356,12 @@ llround(_A1 __x) _NOEXCEPT
// log1p
inline _LIBCPP_HIDE_FROM_ABI float log1p(float __x) _NOEXCEPT {return __builtin_log1pf(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double log1p(double __x) _NOEXCEPT {
+ return __builtin_log1p(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double log1p(long double __x) _NOEXCEPT {return __builtin_log1pl(__x);}
template <class _A1>
@@ -1141,6 +1372,12 @@ log1p(_A1 __x) _NOEXCEPT {return __builtin_log1p((double)__x);}
// log2
inline _LIBCPP_HIDE_FROM_ABI float log2(float __x) _NOEXCEPT {return __builtin_log2f(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double log2(double __x) _NOEXCEPT {
+ return __builtin_log2(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double log2(long double __x) _NOEXCEPT {return __builtin_log2l(__x);}
template <class _A1>
@@ -1151,6 +1388,12 @@ log2(_A1 __x) _NOEXCEPT {return __builtin_log2((double)__x);}
// logb
inline _LIBCPP_HIDE_FROM_ABI float logb(float __x) _NOEXCEPT {return __builtin_logbf(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double logb(double __x) _NOEXCEPT {
+ return __builtin_logb(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double logb(long double __x) _NOEXCEPT {return __builtin_logbl(__x);}
template <class _A1>
@@ -1164,6 +1407,12 @@ inline _LIBCPP_HIDE_FROM_ABI long lrint(float __x) _NOEXCEPT
{
return __builtin_lrintf(__x);
}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI long lrint(double __x) _NOEXCEPT {
+ return __builtin_lrint(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long lrint(long double __x) _NOEXCEPT
{
return __builtin_lrintl(__x);
@@ -1183,6 +1432,12 @@ inline _LIBCPP_HIDE_FROM_ABI long lround(float __x) _NOEXCEPT
{
return __builtin_lroundf(__x);
}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI long lround(double __x) _NOEXCEPT {
+ return __builtin_lround(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long lround(long double __x) _NOEXCEPT
{
return __builtin_lroundl(__x);
@@ -1200,17 +1455,29 @@ lround(_A1 __x) _NOEXCEPT
// nearbyint
-inline _LIBCPP_HIDE_FROM_ABI float nearbyint(float __x) _NOEXCEPT {return __builtin_nearbyintf(__x);}
-inline _LIBCPP_HIDE_FROM_ABI long double nearbyint(long double __x) _NOEXCEPT {return __builtin_nearbyintl(__x);}
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float nearbyint(float __x) _NOEXCEPT {return __builtin_nearbyintf(__x);}
+
+template <class = int>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double nearbyint(double __x) _NOEXCEPT {
+ return __builtin_nearbyint(__x);
+}
+
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double nearbyint(long double __x) _NOEXCEPT {return __builtin_nearbyintl(__x);}
template <class _A1>
-inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
typename std::enable_if<std::is_integral<_A1>::value, double>::type
nearbyint(_A1 __x) _NOEXCEPT {return __builtin_nearbyint((double)__x);}
// nextafter
inline _LIBCPP_HIDE_FROM_ABI float nextafter(float __x, float __y) _NOEXCEPT {return __builtin_nextafterf(__x, __y);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double nextafter(double __x, double __y) _NOEXCEPT {
+ return __builtin_nextafter(__x, __y);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double nextafter(long double __x, long double __y) _NOEXCEPT {return __builtin_nextafterl(__x, __y);}
template <class _A1, class _A2>
@@ -1232,6 +1499,12 @@ nextafter(_A1 __x, _A2 __y) _NOEXCEPT
// nexttoward
inline _LIBCPP_HIDE_FROM_ABI float nexttoward(float __x, long double __y) _NOEXCEPT {return __builtin_nexttowardf(__x, __y);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double nexttoward(double __x, long double __y) _NOEXCEPT {
+ return __builtin_nexttoward(__x, __y);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double nexttoward(long double __x, long double __y) _NOEXCEPT {return __builtin_nexttowardl(__x, __y);}
template <class _A1>
@@ -1242,6 +1515,12 @@ nexttoward(_A1 __x, long double __y) _NOEXCEPT {return __builtin_nexttoward((dou
// remainder
inline _LIBCPP_HIDE_FROM_ABI float remainder(float __x, float __y) _NOEXCEPT {return __builtin_remainderf(__x, __y);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double remainder(double __x, double __y) _NOEXCEPT {
+ return __builtin_remainder(__x, __y);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double remainder(long double __x, long double __y) _NOEXCEPT {return __builtin_remainderl(__x, __y);}
template <class _A1, class _A2>
@@ -1263,6 +1542,12 @@ remainder(_A1 __x, _A2 __y) _NOEXCEPT
// remquo
inline _LIBCPP_HIDE_FROM_ABI float remquo(float __x, float __y, int* __z) _NOEXCEPT {return __builtin_remquof(__x, __y, __z);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double remquo(double __x, double __y, int* __z) _NOEXCEPT {
+ return __builtin_remquo(__x, __y, __z);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double remquo(long double __x, long double __y, int* __z) _NOEXCEPT {return __builtin_remquol(__x, __y, __z);}
template <class _A1, class _A2>
@@ -1283,17 +1568,23 @@ remquo(_A1 __x, _A2 __y, int* __z) _NOEXCEPT
// rint
-inline _LIBCPP_HIDE_FROM_ABI float rint(float __x) _NOEXCEPT
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float rint(float __x) _NOEXCEPT
{
return __builtin_rintf(__x);
}
-inline _LIBCPP_HIDE_FROM_ABI long double rint(long double __x) _NOEXCEPT
+
+template <class = int>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double rint(double __x) _NOEXCEPT {
+ return __builtin_rint(__x);
+}
+
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double rint(long double __x) _NOEXCEPT
{
return __builtin_rintl(__x);
}
template <class _A1>
-inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
typename std::enable_if<std::is_integral<_A1>::value, double>::type
rint(_A1 __x) _NOEXCEPT
{
@@ -1302,17 +1593,23 @@ rint(_A1 __x) _NOEXCEPT
// round
-inline _LIBCPP_HIDE_FROM_ABI float round(float __x) _NOEXCEPT
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float round(float __x) _NOEXCEPT
{
return __builtin_roundf(__x);
}
-inline _LIBCPP_HIDE_FROM_ABI long double round(long double __x) _NOEXCEPT
+
+template <class = int>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double round(double __x) _NOEXCEPT {
+ return __builtin_round(__x);
+}
+
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double round(long double __x) _NOEXCEPT
{
return __builtin_roundl(__x);
}
template <class _A1>
-inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
typename std::enable_if<std::is_integral<_A1>::value, double>::type
round(_A1 __x) _NOEXCEPT
{
@@ -1322,6 +1619,12 @@ round(_A1 __x) _NOEXCEPT
// scalbln
inline _LIBCPP_HIDE_FROM_ABI float scalbln(float __x, long __y) _NOEXCEPT {return __builtin_scalblnf(__x, __y);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double scalbln(double __x, long __y) _NOEXCEPT {
+ return __builtin_scalbln(__x, __y);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double scalbln(long double __x, long __y) _NOEXCEPT {return __builtin_scalblnl(__x, __y);}
template <class _A1>
@@ -1332,6 +1635,12 @@ scalbln(_A1 __x, long __y) _NOEXCEPT {return __builtin_scalbln((double)__x, __y)
// scalbn
inline _LIBCPP_HIDE_FROM_ABI float scalbn(float __x, int __y) _NOEXCEPT {return __builtin_scalbnf(__x, __y);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double scalbn(double __x, int __y) _NOEXCEPT {
+ return __builtin_scalbn(__x, __y);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double scalbn(long double __x, int __y) _NOEXCEPT {return __builtin_scalbnl(__x, __y);}
template <class _A1>
@@ -1342,6 +1651,12 @@ scalbn(_A1 __x, int __y) _NOEXCEPT {return __builtin_scalbn((double)__x, __y);}
// tgamma
inline _LIBCPP_HIDE_FROM_ABI float tgamma(float __x) _NOEXCEPT {return __builtin_tgammaf(__x);}
+
+template <class = int>
+_LIBCPP_HIDE_FROM_ABI double tgamma(double __x) _NOEXCEPT {
+ return __builtin_tgamma(__x);
+}
+
inline _LIBCPP_HIDE_FROM_ABI long double tgamma(long double __x) _NOEXCEPT {return __builtin_tgammal(__x);}
template <class _A1>
@@ -1351,17 +1666,23 @@ tgamma(_A1 __x) _NOEXCEPT {return __builtin_tgamma((double)__x);}
// trunc
-inline _LIBCPP_HIDE_FROM_ABI float trunc(float __x) _NOEXCEPT
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float trunc(float __x) _NOEXCEPT
{
return __builtin_truncf(__x);
}
-inline _LIBCPP_HIDE_FROM_ABI long double trunc(long double __x) _NOEXCEPT
+
+template <class = int>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double trunc(double __x) _NOEXCEPT {
+ return __builtin_trunc(__x);
+}
+
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double trunc(long double __x) _NOEXCEPT
{
return __builtin_truncl(__x);
}
template <class _A1>
-inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
typename std::enable_if<std::is_integral<_A1>::value, double>::type
trunc(_A1 __x) _NOEXCEPT
{
diff --git a/contrib/libs/cxxsupp/libcxx/include/memory b/contrib/libs/cxxsupp/libcxx/include/memory
index 11a8823fce..8d63fb94b7 100644
--- a/contrib/libs/cxxsupp/libcxx/include/memory
+++ b/contrib/libs/cxxsupp/libcxx/include/memory
@@ -569,6 +569,13 @@ template<class T>
constexpr unique_ptr<T> make_unique(size_t n); // C++14, constexpr since C++23
template<class T, class... Args> unspecified make_unique(Args&&...) = delete; // C++14, T == U[N]
+template<class T>
+ constexpr unique_ptr<T> make_unique_for_overwrite(); // T is not array, C++20, constexpr since C++23
+template<class T>
+ constexpr unique_ptr<T> make_unique_for_overwrite(size_t n); // T is U[], C++20, constexpr since C++23
+template<class T, class... Args>
+ unspecified make_unique_for_overwrite(Args&&...) = delete; // T is U[N], C++20
+
template<class E, class T, class Y, class D>
basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, unique_ptr<Y, D> const& p);
@@ -718,6 +725,16 @@ template<class T, class A>
shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& u); // T is U[N] (since C++20)
template<class T>
+ shared_ptr<T> make_shared_for_overwrite(); // T is not U[], C++20
+template<class T, class A>
+ shared_ptr<T> allocate_shared_for_overwrite(const A& a); // T is not U[], C++20
+
+template<class T>
+ shared_ptr<T> make_shared_for_overwrite(size_t N); // T is U[], C++20
+template<class T, class A>
+ shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N); // T is U[], C++20
+
+template<class T>
class weak_ptr
{
public:
diff --git a/contrib/libs/cxxsupp/libcxx/include/mutex b/contrib/libs/cxxsupp/libcxx/include/mutex
index 92695ee8a0..dc51d572c0 100644
--- a/contrib/libs/cxxsupp/libcxx/include/mutex
+++ b/contrib/libs/cxxsupp/libcxx/include/mutex
@@ -356,7 +356,7 @@ try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3)
unique_lock<_L0> __u0(__l0, try_to_lock);
if (__u0.owns_lock())
{
- __r = try_lock(__l1, __l2, __l3...);
+ __r = std::try_lock(__l1, __l2, __l3...);
if (__r == -1)
__u0.release();
else
@@ -407,7 +407,7 @@ __lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3)
case 0:
{
unique_lock<_L0> __u0(__l0);
- __i = try_lock(__l1, __l2, __l3...);
+ __i = std::try_lock(__l1, __l2, __l3...);
if (__i == -1)
{
__u0.release();
@@ -420,7 +420,7 @@ __lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3)
case 1:
{
unique_lock<_L1> __u1(__l1);
- __i = try_lock(__l2, __l3..., __l0);
+ __i = std::try_lock(__l2, __l3..., __l0);
if (__i == -1)
{
__u1.release();
@@ -434,7 +434,7 @@ __lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3)
__libcpp_thread_yield();
break;
default:
- __lock_first(__i - 2, __l2, __l3..., __l0, __l1);
+ std::__lock_first(__i - 2, __l2, __l3..., __l0, __l1);
return;
}
}
@@ -445,7 +445,7 @@ inline _LIBCPP_INLINE_VISIBILITY
void
lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3)
{
- __lock_first(0, __l0, __l1, __l2, __l3...);
+ std::__lock_first(0, __l0, __l1, __l2, __l3...);
}
template <class _L0>
@@ -684,7 +684,7 @@ call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args)
typedef tuple<_Callable&&, _Args&&...> _Gp;
_Gp __f(_VSTD::forward<_Callable>(__func), _VSTD::forward<_Args>(__args)...);
__call_once_param<_Gp> __p(__f);
- __call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>);
+ std::__call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>);
}
}
@@ -702,7 +702,7 @@ call_once(once_flag& __flag, _Callable& __func)
#endif
{
__call_once_param<_Callable> __p(__func);
- __call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>);
+ std::__call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>);
}
}
@@ -718,7 +718,7 @@ call_once(once_flag& __flag, const _Callable& __func)
#endif
{
__call_once_param<const _Callable> __p(__func);
- __call_once(__flag.__state_, &__p, &__call_once_proxy<const _Callable>);
+ std::__call_once(__flag.__state_, &__p, &__call_once_proxy<const _Callable>);
}
}
@@ -731,6 +731,7 @@ _LIBCPP_POP_MACROS
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <concepts>
# include <functional>
+# include <type_traits>
#endif
#endif // _LIBCPP_MUTEX
diff --git a/contrib/libs/cxxsupp/libcxx/include/new b/contrib/libs/cxxsupp/libcxx/include/new
index 825034c44c..aa62f81b02 100644
--- a/contrib/libs/cxxsupp/libcxx/include/new
+++ b/contrib/libs/cxxsupp/libcxx/include/new
@@ -89,10 +89,12 @@ void operator delete[](void* ptr, void*) noexcept;
#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
#include <__config>
+#include <__type_traits/is_function.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/remove_cv.h>
#include <cstddef>
#include <cstdlib>
#include <exception>
-#include <type_traits>
#include <version>
#if defined(_LIBCPP_ABI_VCRUNTIME)
@@ -295,9 +297,9 @@ _LIBCPP_INLINE_VISIBILITY
void __do_deallocate_handle_size(void *__ptr, size_t __size, _Args ...__args) {
#ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
(void)__size;
- return __libcpp_operator_delete(__ptr, __args...);
+ return std::__libcpp_operator_delete(__ptr, __args...);
#else
- return __libcpp_operator_delete(__ptr, __size, __args...);
+ return std::__libcpp_operator_delete(__ptr, __size, __args...);
#endif
}
@@ -337,16 +339,27 @@ inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, s
// chances are that you want to use `__libcpp_allocate` instead.
//
// Returns the allocated memory, or `nullptr` on failure.
-inline _LIBCPP_INLINE_VISIBILITY
-void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
-#if defined(_LIBCPP_MSVCRT_LIKE)
- return ::_aligned_malloc(__size, __alignment);
-#else
- void* __result = nullptr;
- (void)::posix_memalign(&__result, __alignment, __size);
- // If posix_memalign fails, __result is unmodified so we still return `nullptr`.
- return __result;
-#endif
+inline _LIBCPP_INLINE_VISIBILITY void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
+# if defined(_LIBCPP_MSVCRT_LIKE)
+ return ::_aligned_malloc(__size, __alignment);
+ // Use posix_memalign instead of ::aligned_alloc to fix the musl and some of the tests
+# elif _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_C11_ALIGNED_ALLOC) && false
+ // aligned_alloc() requires that __size is a multiple of __alignment,
+ // but for C++ [new.delete.general], only states "if the value of an
+ // alignment argument passed to any of these functions is not a valid
+ // alignment value, the behavior is undefined".
+ // To handle calls such as ::operator new(1, std::align_val_t(128)), we
+ // round __size up to the next multiple of __alignment.
+ size_t __rounded_size = (__size + __alignment - 1) & ~(__alignment - 1);
+ // Rounding up could have wrapped around to zero, so we have to add another
+ // max() ternary to the actual call site to avoid succeeded in that case.
+ return ::aligned_alloc(__alignment, __size > __rounded_size ? __size : __rounded_size);
+# else
+ void* __result = nullptr;
+ (void)::posix_memalign(&__result, __alignment, __size);
+ // If posix_memalign fails, __result is unmodified so we still return `nullptr`.
+ return __result;
+# endif
}
inline _LIBCPP_INLINE_VISIBILITY
@@ -391,4 +404,8 @@ inline constexpr size_t hardware_constructive_interference_size = __GCC_CONSTRUC
_LIBCPP_END_NAMESPACE_STD
+#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+# include <type_traits>
+#endif
+
#endif // _LIBCPP_NEW
diff --git a/contrib/libs/cxxsupp/libcxx/include/numeric b/contrib/libs/cxxsupp/libcxx/include/numeric
index e427695f1c..f025913cb5 100644
--- a/contrib/libs/cxxsupp/libcxx/include/numeric
+++ b/contrib/libs/cxxsupp/libcxx/include/numeric
@@ -175,6 +175,7 @@ template<class T>
# include <concepts>
# include <functional>
# include <iterator>
+# include <type_traits>
#endif
#endif // _LIBCPP_NUMERIC
diff --git a/contrib/libs/cxxsupp/libcxx/include/optional b/contrib/libs/cxxsupp/libcxx/include/optional
index 41c003cdb6..c8fca8885c 100644
--- a/contrib/libs/cxxsupp/libcxx/include/optional
+++ b/contrib/libs/cxxsupp/libcxx/include/optional
@@ -166,7 +166,7 @@ template<class T>
#include <__functional/invoke.h>
#include <__functional/unary_function.h>
#include <__memory/construct_at.h>
-#include <__tuple/sfinae_helpers.h>
+#include <__tuple_dir/sfinae_helpers.h>
#include <__utility/forward.h>
#include <__utility/in_place.h>
#include <__utility/move.h>
@@ -1185,8 +1185,8 @@ template<class _Tp>
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
- is_convertible_v<decltype(declval<const _Tp&>() ==
- declval<const _Up&>()), bool>,
+ is_convertible_v<decltype(std::declval<const _Tp&>() ==
+ std::declval<const _Up&>()), bool>,
bool
>
operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
@@ -1201,8 +1201,8 @@ operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
- is_convertible_v<decltype(declval<const _Tp&>() !=
- declval<const _Up&>()), bool>,
+ is_convertible_v<decltype(std::declval<const _Tp&>() !=
+ std::declval<const _Up&>()), bool>,
bool
>
operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
@@ -1217,8 +1217,8 @@ operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
- is_convertible_v<decltype(declval<const _Tp&>() <
- declval<const _Up&>()), bool>,
+ is_convertible_v<decltype(std::declval<const _Tp&>() <
+ std::declval<const _Up&>()), bool>,
bool
>
operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
@@ -1233,8 +1233,8 @@ operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
- is_convertible_v<decltype(declval<const _Tp&>() >
- declval<const _Up&>()), bool>,
+ is_convertible_v<decltype(std::declval<const _Tp&>() >
+ std::declval<const _Up&>()), bool>,
bool
>
operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
@@ -1249,8 +1249,8 @@ operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
- is_convertible_v<decltype(declval<const _Tp&>() <=
- declval<const _Up&>()), bool>,
+ is_convertible_v<decltype(std::declval<const _Tp&>() <=
+ std::declval<const _Up&>()), bool>,
bool
>
operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
@@ -1265,8 +1265,8 @@ operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
- is_convertible_v<decltype(declval<const _Tp&>() >=
- declval<const _Up&>()), bool>,
+ is_convertible_v<decltype(std::declval<const _Tp&>() >=
+ std::declval<const _Up&>()), bool>,
bool
>
operator>=(const optional<_Tp>& __x, const optional<_Up>& __y)
@@ -1379,8 +1379,8 @@ operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
- is_convertible_v<decltype(declval<const _Tp&>() ==
- declval<const _Up&>()), bool>,
+ is_convertible_v<decltype(std::declval<const _Tp&>() ==
+ std::declval<const _Up&>()), bool>,
bool
>
operator==(const optional<_Tp>& __x, const _Up& __v)
@@ -1391,8 +1391,8 @@ operator==(const optional<_Tp>& __x, const _Up& __v)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
- is_convertible_v<decltype(declval<const _Tp&>() ==
- declval<const _Up&>()), bool>,
+ is_convertible_v<decltype(std::declval<const _Tp&>() ==
+ std::declval<const _Up&>()), bool>,
bool
>
operator==(const _Tp& __v, const optional<_Up>& __x)
@@ -1403,8 +1403,8 @@ operator==(const _Tp& __v, const optional<_Up>& __x)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
- is_convertible_v<decltype(declval<const _Tp&>() !=
- declval<const _Up&>()), bool>,
+ is_convertible_v<decltype(std::declval<const _Tp&>() !=
+ std::declval<const _Up&>()), bool>,
bool
>
operator!=(const optional<_Tp>& __x, const _Up& __v)
@@ -1415,8 +1415,8 @@ operator!=(const optional<_Tp>& __x, const _Up& __v)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
- is_convertible_v<decltype(declval<const _Tp&>() !=
- declval<const _Up&>()), bool>,
+ is_convertible_v<decltype(std::declval<const _Tp&>() !=
+ std::declval<const _Up&>()), bool>,
bool
>
operator!=(const _Tp& __v, const optional<_Up>& __x)
@@ -1427,8 +1427,8 @@ operator!=(const _Tp& __v, const optional<_Up>& __x)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
- is_convertible_v<decltype(declval<const _Tp&>() <
- declval<const _Up&>()), bool>,
+ is_convertible_v<decltype(std::declval<const _Tp&>() <
+ std::declval<const _Up&>()), bool>,
bool
>
operator<(const optional<_Tp>& __x, const _Up& __v)
@@ -1439,8 +1439,8 @@ operator<(const optional<_Tp>& __x, const _Up& __v)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
- is_convertible_v<decltype(declval<const _Tp&>() <
- declval<const _Up&>()), bool>,
+ is_convertible_v<decltype(std::declval<const _Tp&>() <
+ std::declval<const _Up&>()), bool>,
bool
>
operator<(const _Tp& __v, const optional<_Up>& __x)
@@ -1451,8 +1451,8 @@ operator<(const _Tp& __v, const optional<_Up>& __x)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
- is_convertible_v<decltype(declval<const _Tp&>() <=
- declval<const _Up&>()), bool>,
+ is_convertible_v<decltype(std::declval<const _Tp&>() <=
+ std::declval<const _Up&>()), bool>,
bool
>
operator<=(const optional<_Tp>& __x, const _Up& __v)
@@ -1463,8 +1463,8 @@ operator<=(const optional<_Tp>& __x, const _Up& __v)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
- is_convertible_v<decltype(declval<const _Tp&>() <=
- declval<const _Up&>()), bool>,
+ is_convertible_v<decltype(std::declval<const _Tp&>() <=
+ std::declval<const _Up&>()), bool>,
bool
>
operator<=(const _Tp& __v, const optional<_Up>& __x)
@@ -1475,8 +1475,8 @@ operator<=(const _Tp& __v, const optional<_Up>& __x)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
- is_convertible_v<decltype(declval<const _Tp&>() >
- declval<const _Up&>()), bool>,
+ is_convertible_v<decltype(std::declval<const _Tp&>() >
+ std::declval<const _Up&>()), bool>,
bool
>
operator>(const optional<_Tp>& __x, const _Up& __v)
@@ -1487,8 +1487,8 @@ operator>(const optional<_Tp>& __x, const _Up& __v)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
- is_convertible_v<decltype(declval<const _Tp&>() >
- declval<const _Up&>()), bool>,
+ is_convertible_v<decltype(std::declval<const _Tp&>() >
+ std::declval<const _Up&>()), bool>,
bool
>
operator>(const _Tp& __v, const optional<_Up>& __x)
@@ -1499,8 +1499,8 @@ operator>(const _Tp& __v, const optional<_Up>& __x)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
- is_convertible_v<decltype(declval<const _Tp&>() >=
- declval<const _Up&>()), bool>,
+ is_convertible_v<decltype(std::declval<const _Tp&>() >=
+ std::declval<const _Up&>()), bool>,
bool
>
operator>=(const optional<_Tp>& __x, const _Up& __v)
@@ -1511,8 +1511,8 @@ operator>=(const optional<_Tp>& __x, const _Up& __v)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
- is_convertible_v<decltype(declval<const _Tp&>() >=
- declval<const _Up&>()), bool>,
+ is_convertible_v<decltype(std::declval<const _Tp&>() >=
+ std::declval<const _Up&>()), bool>,
bool
>
operator>=(const _Tp& __v, const optional<_Up>& __x)
@@ -1574,10 +1574,6 @@ _LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 14
-#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17
-# include <chrono>
-#endif
-
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <atomic>
# include <climits>
diff --git a/contrib/libs/cxxsupp/libcxx/include/ostream b/contrib/libs/cxxsupp/libcxx/include/ostream
index 6e0d3d5a23..743d40539c 100644
--- a/contrib/libs/cxxsupp/libcxx/include/ostream
+++ b/contrib/libs/cxxsupp/libcxx/include/ostream
@@ -412,7 +412,7 @@ basic_ostream<_CharT, _Traits>::operator<<(bool __n)
if (__s)
{
typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
- const _Fp& __f = use_facet<_Fp>(this->getloc());
+ const _Fp& __f = std::use_facet<_Fp>(this->getloc());
if (__f.put(*this, *this, this->fill(), __n).failed())
this->setstate(ios_base::badbit | ios_base::failbit);
}
@@ -439,7 +439,7 @@ basic_ostream<_CharT, _Traits>::operator<<(short __n)
{
ios_base::fmtflags __flags = ios_base::flags() & ios_base::basefield;
typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
- const _Fp& __f = use_facet<_Fp>(this->getloc());
+ const _Fp& __f = std::use_facet<_Fp>(this->getloc());
if (__f.put(*this, *this, this->fill(),
__flags == ios_base::oct || __flags == ios_base::hex ?
static_cast<long>(static_cast<unsigned short>(__n)) :
@@ -468,7 +468,7 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned short __n)
if (__s)
{
typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
- const _Fp& __f = use_facet<_Fp>(this->getloc());
+ const _Fp& __f = std::use_facet<_Fp>(this->getloc());
if (__f.put(*this, *this, this->fill(), static_cast<unsigned long>(__n)).failed())
this->setstate(ios_base::badbit | ios_base::failbit);
}
@@ -495,7 +495,7 @@ basic_ostream<_CharT, _Traits>::operator<<(int __n)
{
ios_base::fmtflags __flags = ios_base::flags() & ios_base::basefield;
typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
- const _Fp& __f = use_facet<_Fp>(this->getloc());
+ const _Fp& __f = std::use_facet<_Fp>(this->getloc());
if (__f.put(*this, *this, this->fill(),
__flags == ios_base::oct || __flags == ios_base::hex ?
static_cast<long>(static_cast<unsigned int>(__n)) :
@@ -524,7 +524,7 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned int __n)
if (__s)
{
typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
- const _Fp& __f = use_facet<_Fp>(this->getloc());
+ const _Fp& __f = std::use_facet<_Fp>(this->getloc());
if (__f.put(*this, *this, this->fill(), static_cast<unsigned long>(__n)).failed())
this->setstate(ios_base::badbit | ios_base::failbit);
}
@@ -550,7 +550,7 @@ basic_ostream<_CharT, _Traits>::operator<<(long __n)
if (__s)
{
typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
- const _Fp& __f = use_facet<_Fp>(this->getloc());
+ const _Fp& __f = std::use_facet<_Fp>(this->getloc());
if (__f.put(*this, *this, this->fill(), __n).failed())
this->setstate(ios_base::badbit | ios_base::failbit);
}
@@ -576,7 +576,7 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned long __n)
if (__s)
{
typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
- const _Fp& __f = use_facet<_Fp>(this->getloc());
+ const _Fp& __f = std::use_facet<_Fp>(this->getloc());
if (__f.put(*this, *this, this->fill(), __n).failed())
this->setstate(ios_base::badbit | ios_base::failbit);
}
@@ -602,7 +602,7 @@ basic_ostream<_CharT, _Traits>::operator<<(long long __n)
if (__s)
{
typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
- const _Fp& __f = use_facet<_Fp>(this->getloc());
+ const _Fp& __f = std::use_facet<_Fp>(this->getloc());
if (__f.put(*this, *this, this->fill(), __n).failed())
this->setstate(ios_base::badbit | ios_base::failbit);
}
@@ -628,7 +628,7 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n)
if (__s)
{
typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
- const _Fp& __f = use_facet<_Fp>(this->getloc());
+ const _Fp& __f = std::use_facet<_Fp>(this->getloc());
if (__f.put(*this, *this, this->fill(), __n).failed())
this->setstate(ios_base::badbit | ios_base::failbit);
}
@@ -654,7 +654,7 @@ basic_ostream<_CharT, _Traits>::operator<<(float __n)
if (__s)
{
typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
- const _Fp& __f = use_facet<_Fp>(this->getloc());
+ const _Fp& __f = std::use_facet<_Fp>(this->getloc());
if (__f.put(*this, *this, this->fill(), static_cast<double>(__n)).failed())
this->setstate(ios_base::badbit | ios_base::failbit);
}
@@ -680,7 +680,7 @@ basic_ostream<_CharT, _Traits>::operator<<(double __n)
if (__s)
{
typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
- const _Fp& __f = use_facet<_Fp>(this->getloc());
+ const _Fp& __f = std::use_facet<_Fp>(this->getloc());
if (__f.put(*this, *this, this->fill(), __n).failed())
this->setstate(ios_base::badbit | ios_base::failbit);
}
@@ -706,7 +706,7 @@ basic_ostream<_CharT, _Traits>::operator<<(long double __n)
if (__s)
{
typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
- const _Fp& __f = use_facet<_Fp>(this->getloc());
+ const _Fp& __f = std::use_facet<_Fp>(this->getloc());
if (__f.put(*this, *this, this->fill(), __n).failed())
this->setstate(ios_base::badbit | ios_base::failbit);
}
@@ -732,7 +732,7 @@ basic_ostream<_CharT, _Traits>::operator<<(const void* __n)
if (__s)
{
typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
- const _Fp& __f = use_facet<_Fp>(this->getloc());
+ const _Fp& __f = std::use_facet<_Fp>(this->getloc());
if (__f.put(*this, *this, this->fill(), __n).failed())
this->setstate(ios_base::badbit | ios_base::failbit);
}
@@ -759,14 +759,14 @@ __put_character_sequence(basic_ostream<_CharT, _Traits>& __os,
if (__s)
{
typedef ostreambuf_iterator<_CharT, _Traits> _Ip;
- if (__pad_and_output(_Ip(__os),
- __str,
- (__os.flags() & ios_base::adjustfield) == ios_base::left ?
- __str + __len :
- __str,
- __str + __len,
- __os,
- __os.fill()).failed())
+ if (std::__pad_and_output(_Ip(__os),
+ __str,
+ (__os.flags() & ios_base::adjustfield) == ios_base::left ?
+ __str + __len :
+ __str,
+ __str + __len,
+ __os,
+ __os.fill()).failed())
__os.setstate(ios_base::badbit | ios_base::failbit);
}
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -800,14 +800,14 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, char __cn)
{
_CharT __c = __os.widen(__cn);
typedef ostreambuf_iterator<_CharT, _Traits> _Ip;
- if (__pad_and_output(_Ip(__os),
- &__c,
- (__os.flags() & ios_base::adjustfield) == ios_base::left ?
- &__c + 1 :
- &__c,
- &__c + 1,
- __os,
- __os.fill()).failed())
+ if (std::__pad_and_output(_Ip(__os),
+ &__c,
+ (__os.flags() & ios_base::adjustfield) == ios_base::left ?
+ &__c + 1 :
+ &__c,
+ &__c + 1,
+ __os,
+ __os.fill()).failed())
__os.setstate(ios_base::badbit | ios_base::failbit);
}
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -874,14 +874,14 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const char* __strn)
}
for (_CharT* __p = __wb; *__strn != '\0'; ++__strn, ++__p)
*__p = __os.widen(*__strn);
- if (__pad_and_output(_Ip(__os),
- __wb,
- (__os.flags() & ios_base::adjustfield) == ios_base::left ?
- __wb + __len :
- __wb,
- __wb + __len,
- __os,
- __os.fill()).failed())
+ if (std::__pad_and_output(_Ip(__os),
+ __wb,
+ (__os.flags() & ios_base::adjustfield) == ios_base::left ?
+ __wb + __len :
+ __wb,
+ __wb + __len,
+ __os,
+ __os.fill()).failed())
__os.setstate(ios_base::badbit | ios_base::failbit);
}
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -1063,7 +1063,7 @@ struct __is_ostreamable : false_type { };
template <class _Stream, class _Tp>
struct __is_ostreamable<_Stream, _Tp, decltype(
- declval<_Stream>() << declval<_Tp>(), void()
+ std::declval<_Stream>() << std::declval<_Tp>(), void()
)> : true_type { };
template <class _Stream, class _Tp, class = typename enable_if<
@@ -1113,7 +1113,7 @@ template<class _CharT, class _Traits, class _Yp, class _Dp>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
<
- is_same<void, __void_t<decltype((declval<basic_ostream<_CharT, _Traits>&>() << declval<typename unique_ptr<_Yp, _Dp>::pointer>()))> >::value,
+ is_same<void, __void_t<decltype((std::declval<basic_ostream<_CharT, _Traits>&>() << std::declval<typename unique_ptr<_Yp, _Dp>::pointer>()))> >::value,
basic_ostream<_CharT, _Traits>&
>::type
operator<<(basic_ostream<_CharT, _Traits>& __os, unique_ptr<_Yp, _Dp> const& __p)
@@ -1126,8 +1126,8 @@ _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x)
{
return __os << __x.template to_string<_CharT, _Traits>
- (use_facet<ctype<_CharT> >(__os.getloc()).widen('0'),
- use_facet<ctype<_CharT> >(__os.getloc()).widen('1'));
+ (std::use_facet<ctype<_CharT> >(__os.getloc()).widen('0'),
+ std::use_facet<ctype<_CharT> >(__os.getloc()).widen('1'));
}
#if 0
@@ -1191,6 +1191,7 @@ _LIBCPP_END_NAMESPACE_STD
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <concepts>
# include <iterator>
+# include <type_traits>
#endif
#endif // _LIBCPP_OSTREAM
diff --git a/contrib/libs/cxxsupp/libcxx/include/queue b/contrib/libs/cxxsupp/libcxx/include/queue
index c58da5ec6e..6c1b892efa 100644
--- a/contrib/libs/cxxsupp/libcxx/include/queue
+++ b/contrib/libs/cxxsupp/libcxx/include/queue
@@ -382,6 +382,8 @@ public:
swap(c, __q.c);
}
+ _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI const _Container& __get_container() const { return c; }
+
template <class _T1, class _C1>
friend
_LIBCPP_INLINE_VISIBILITY
@@ -633,6 +635,8 @@ public:
void swap(priority_queue& __q)
_NOEXCEPT_(__is_nothrow_swappable<container_type>::value &&
__is_nothrow_swappable<value_compare>::value);
+
+ _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI const _Container& __get_container() const { return c; }
};
#if _LIBCPP_STD_VER >= 17
diff --git a/contrib/libs/cxxsupp/libcxx/include/ranges b/contrib/libs/cxxsupp/libcxx/include/ranges
index 643853e1d3..f999fa00c3 100644
--- a/contrib/libs/cxxsupp/libcxx/include/ranges
+++ b/contrib/libs/cxxsupp/libcxx/include/ranges
@@ -115,6 +115,27 @@ namespace std::ranges {
template<range R>
using borrowed_subrange_t = see below;
+ // [range.elements], elements view
+ template<input_range V, size_t N>
+ requires see below
+ class elements_view;
+
+ template<class T, size_t N>
+ inline constexpr bool enable_borrowed_range<elements_view<T, N>> =
+ enable_borrowed_range<T>;
+
+ template<class R>
+ using keys_view = elements_view<R, 0>;
+ template<class R>
+ using values_view = elements_view<R, 1>;
+
+ namespace views {
+ template<size_t N>
+ inline constexpr unspecified elements = unspecified;
+ inline constexpr auto keys = elements<0>;
+ inline constexpr auto values = elements<1>;
+ }
+
// [range.empty], empty view
template<class T>
requires is_object_v<T>
@@ -244,8 +265,15 @@ namespace std::ranges {
(forward_range<V> || tiny-range<Pattern>)
class lazy_split_view;
+ // [range.split], split view
+ template<forward_range V, forward_range Pattern>
+ requires view<V> && view<Pattern> &&
+ indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>
+ class split_view;
+
namespace views {
inline constexpr unspecified lazy_split = unspecified;
+ inline constexpr unspecified split = unspecified;
}
// [range.istream], istream view
@@ -271,6 +299,13 @@ namespace std::ranges {
(enable_borrowed_range<Views> && ...);
namespace views { inline constexpr unspecified zip = unspecified; } // C++2b
+
+ // [range.as.rvalue]
+ template <view V>
+ requires input_range<V>
+ class as_rvalue_view; // since C++23
+
+ namespace views { inline constexpr unspecified as_rvalue ) unspecified; } // since C++23
}
namespace std {
@@ -309,6 +344,7 @@ namespace std {
#include <__config>
#include <__ranges/access.h>
#include <__ranges/all.h>
+#include <__ranges/as_rvalue_view.h>
#include <__ranges/common_view.h>
#include <__ranges/concepts.h>
#include <__ranges/counted.h>
@@ -316,6 +352,7 @@ namespace std {
#include <__ranges/data.h>
#include <__ranges/drop_view.h>
#include <__ranges/drop_while_view.h>
+#include <__ranges/elements_view.h>
#include <__ranges/empty.h>
#include <__ranges/empty_view.h>
#include <__ranges/enable_borrowed_range.h>
@@ -330,6 +367,7 @@ namespace std {
#include <__ranges/reverse_view.h>
#include <__ranges/single_view.h>
#include <__ranges/size.h>
+#include <__ranges/split_view.h>
#include <__ranges/subrange.h>
#include <__ranges/take_view.h>
#include <__ranges/take_while_view.h>
@@ -352,8 +390,8 @@ namespace std {
#include <iterator>
// [tuple.helper]
-#include <__tuple/tuple_element.h>
-#include <__tuple/tuple_size.h>
+#include <__tuple_dir/tuple_element.h>
+#include <__tuple_dir/tuple_size.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/contrib/libs/cxxsupp/libcxx/include/ratio b/contrib/libs/cxxsupp/libcxx/include/ratio
index 5d7af88a2a..3969a392f3 100644
--- a/contrib/libs/cxxsupp/libcxx/include/ratio
+++ b/contrib/libs/cxxsupp/libcxx/include/ratio
@@ -79,9 +79,9 @@ typedef ratio<1000000000000000000000000, 1> yotta; // not supported
#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
+#include <__type_traits/integral_constant.h>
#include <climits>
#include <cstdint>
-#include <type_traits>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -525,4 +525,8 @@ _LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
+#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+# include <type_traits>
+#endif
+
#endif // _LIBCPP_RATIO
diff --git a/contrib/libs/cxxsupp/libcxx/include/regex b/contrib/libs/cxxsupp/libcxx/include/regex
index f35197339b..06c017fcce 100644
--- a/contrib/libs/cxxsupp/libcxx/include/regex
+++ b/contrib/libs/cxxsupp/libcxx/include/regex
@@ -1157,8 +1157,8 @@ template <class _CharT>
void
regex_traits<_CharT>::__init()
{
- __ct_ = &use_facet<ctype<char_type> >(__loc_);
- __col_ = &use_facet<collate<char_type> >(__loc_);
+ __ct_ = &std::use_facet<ctype<char_type> >(__loc_);
+ __col_ = &std::use_facet<collate<char_type> >(__loc_);
}
template <class _CharT>
@@ -1233,7 +1233,7 @@ regex_traits<_CharT>::__lookup_collatename(_ForwardIterator __f,
string_type __r;
if (!__s.empty())
{
- __r = __get_collation_name(__s.c_str());
+ __r = std::__get_collation_name(__s.c_str());
if (__r.empty() && __s.size() <= 2)
{
__r = __col_->transform(__s.data(), __s.data() + __s.size());
@@ -1296,7 +1296,7 @@ regex_traits<_CharT>::__lookup_classname(_ForwardIterator __f,
{
string_type __s(__f, __l);
__ct_->tolower(&__s[0], &__s[0] + __s.size());
- return __get_classname(__s.c_str(), __icase);
+ return std::__get_classname(__s.c_str(), __icase);
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
@@ -1446,12 +1446,12 @@ public:
_LIBCPP_INLINE_VISIBILITY
__node() {}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL
virtual ~__node() {}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL
virtual void __exec(__state&) const {}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL
virtual void __exec_split(bool, __state&) const {}
};
@@ -2094,7 +2094,7 @@ __l_anchor_multiline<_CharT>::__exec(__state& __s) const
}
else if (__multiline_ &&
!__s.__at_first_ &&
- __is_eol(*_VSTD::prev(__s.__current_)))
+ std::__is_eol(*_VSTD::prev(__s.__current_)))
{
__s.__do_ = __state::__accept_but_not_consume;
__s.__node_ = this->first();
@@ -2136,7 +2136,7 @@ __r_anchor_multiline<_CharT>::__exec(__state& __s) const
__s.__do_ = __state::__accept_but_not_consume;
__s.__node_ = this->first();
}
- else if (__multiline_ && __is_eol(*__s.__current_))
+ else if (__multiline_ && std::__is_eol(*__s.__current_))
{
__s.__do_ = __state::__accept_but_not_consume;
__s.__node_ = this->first();
@@ -2405,7 +2405,7 @@ public:
for (size_t __i = 0; __i < __e.size(); ++__i)
__e[__i] = __traits_.translate(__e[__i]);
}
- __ranges_.push_back(make_pair(
+ __ranges_.push_back(std::make_pair(
__traits_.transform(__b.begin(), __b.end()),
__traits_.transform(__e.begin(), __e.end())));
}
@@ -2418,20 +2418,20 @@ public:
__b[0] = __traits_.translate_nocase(__b[0]);
__e[0] = __traits_.translate_nocase(__e[0]);
}
- __ranges_.push_back(make_pair(_VSTD::move(__b), _VSTD::move(__e)));
+ __ranges_.push_back(std::make_pair(_VSTD::move(__b), _VSTD::move(__e)));
}
}
_LIBCPP_INLINE_VISIBILITY
void __add_digraph(_CharT __c1, _CharT __c2)
{
if (__icase_)
- __digraphs_.push_back(make_pair(__traits_.translate_nocase(__c1),
- __traits_.translate_nocase(__c2)));
+ __digraphs_.push_back(std::make_pair(__traits_.translate_nocase(__c1),
+ __traits_.translate_nocase(__c2)));
else if (__collate_)
- __digraphs_.push_back(make_pair(__traits_.translate(__c1),
- __traits_.translate(__c2)));
+ __digraphs_.push_back(std::make_pair(__traits_.translate(__c1),
+ __traits_.translate(__c2)));
else
- __digraphs_.push_back(make_pair(__c1, __c2));
+ __digraphs_.push_back(std::make_pair(__c1, __c2));
}
_LIBCPP_INLINE_VISIBILITY
void __add_equivalence(const string_type& __s)
@@ -5523,7 +5523,7 @@ public:
regex_constants::match_flag_type __flags = regex_constants::format_default) const
{
basic_string<char_type, _ST, _SA> __r;
- format(back_inserter(__r), __fmt.data(), __fmt.data() + __fmt.size(),
+ format(std::back_inserter(__r), __fmt.data(), __fmt.data() + __fmt.size(),
__flags);
return __r;
}
@@ -5533,7 +5533,7 @@ public:
regex_constants::match_flag_type __flags = regex_constants::format_default) const
{
string_type __r;
- format(back_inserter(__r), __fmt,
+ format(std::back_inserter(__r), __fmt,
__fmt + char_traits<char_type>::length(__fmt), __flags);
return __r;
}
@@ -6794,7 +6794,7 @@ regex_replace(const basic_string<_CharT, _ST, _SA>& __s,
regex_constants::match_flag_type __flags = regex_constants::match_default)
{
basic_string<_CharT, _ST, _SA> __r;
- _VSTD::regex_replace(back_inserter(__r), __s.begin(), __s.end(), __e,
+ _VSTD::regex_replace(std::back_inserter(__r), __s.begin(), __s.end(), __e,
__fmt.c_str(), __flags);
return __r;
}
@@ -6807,7 +6807,7 @@ regex_replace(const basic_string<_CharT, _ST, _SA>& __s,
regex_constants::match_flag_type __flags = regex_constants::match_default)
{
basic_string<_CharT, _ST, _SA> __r;
- _VSTD::regex_replace(back_inserter(__r), __s.begin(), __s.end(), __e,
+ _VSTD::regex_replace(std::back_inserter(__r), __s.begin(), __s.end(), __e,
__fmt, __flags);
return __r;
}
@@ -6821,7 +6821,7 @@ regex_replace(const _CharT* __s,
regex_constants::match_flag_type __flags = regex_constants::match_default)
{
basic_string<_CharT> __r;
- _VSTD::regex_replace(back_inserter(__r), __s,
+ _VSTD::regex_replace(std::back_inserter(__r), __s,
__s + char_traits<_CharT>::length(__s), __e,
__fmt.c_str(), __flags);
return __r;
@@ -6836,7 +6836,7 @@ regex_replace(const _CharT* __s,
regex_constants::match_flag_type __flags = regex_constants::match_default)
{
basic_string<_CharT> __r;
- _VSTD::regex_replace(back_inserter(__r), __s,
+ _VSTD::regex_replace(std::back_inserter(__r), __s,
__s + char_traits<_CharT>::length(__s), __e,
__fmt, __flags);
return __r;
diff --git a/contrib/libs/cxxsupp/libcxx/include/semaphore b/contrib/libs/cxxsupp/libcxx/include/semaphore
index 3e4f51cae5..ddccb28dab 100644
--- a/contrib/libs/cxxsupp/libcxx/include/semaphore
+++ b/contrib/libs/cxxsupp/libcxx/include/semaphore
@@ -113,7 +113,7 @@ public:
if (__rel_time == chrono::duration<Rep, Period>::zero())
return try_acquire();
auto const __test_fn = [this]() { return try_acquire(); };
- return __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy(), __rel_time);
+ return std::__libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy(), __rel_time);
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
bool try_acquire()
diff --git a/contrib/libs/cxxsupp/libcxx/include/source_location b/contrib/libs/cxxsupp/libcxx/include/source_location
new file mode 100644
index 0000000000..e9e852a6e4
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/include/source_location
@@ -0,0 +1,87 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SOURCE_LOCATION
+#define _LIBCPP_SOURCE_LOCATION
+
+/* source_location synopsis
+
+namespace std {
+ struct source_location {
+ static consteval source_location current() noexcept;
+ constexpr source_location() noexcept;
+
+ constexpr uint_least32_t line() const noexcept;
+ constexpr uint_least32_t column() const noexcept;
+ constexpr const char* file_name() const noexcept;
+ constexpr const char* function_name() const noexcept;
+ };
+}
+*/
+
+#include <__config>
+#include <cstdint>
+#include <version>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20 && __has_builtin(__builtin_source_location) && \
+ !(defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER <= 1403)
+
+class source_location {
+ // The names source_location::__impl, _M_file_name, _M_function_name, _M_line, and _M_column
+ // are hard-coded in the compiler and must not be changed here.
+ struct __impl {
+ const char* _M_file_name;
+ const char* _M_function_name;
+ unsigned _M_line;
+ unsigned _M_column;
+ };
+ const __impl* __ptr_ = nullptr;
+ // GCC returns the type 'const void*' from the builtin, while clang returns
+ // `const __impl*`. Per C++ [expr.const], casts from void* are not permitted
+ // in constant evaluation, so we don't want to use `void*` as the argument
+ // type unless the builtin returned that, anyhow, and the invalid cast is
+ // unavoidable.
+ using __bsl_ty = decltype(__builtin_source_location());
+
+public:
+ // The defaulted __ptr argument is necessary so that the builtin is evaluated
+ // in the context of the caller. An explicit value should never be provided.
+ static consteval source_location current(__bsl_ty __ptr = __builtin_source_location()) noexcept {
+ source_location __sl;
+ __sl.__ptr_ = static_cast<const __impl*>(__ptr);
+ return __sl;
+ }
+ _LIBCPP_HIDE_FROM_ABI constexpr source_location() noexcept = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr uint_least32_t line() const noexcept {
+ return __ptr_ != nullptr ? __ptr_->_M_line : 0;
+ }
+ _LIBCPP_HIDE_FROM_ABI constexpr uint_least32_t column() const noexcept {
+ return __ptr_ != nullptr ? __ptr_->_M_column : 0;
+ }
+ _LIBCPP_HIDE_FROM_ABI constexpr const char* file_name() const noexcept {
+ return __ptr_ != nullptr ? __ptr_->_M_file_name : "";
+ }
+ _LIBCPP_HIDE_FROM_ABI constexpr const char* function_name() const noexcept {
+ return __ptr_ != nullptr ? __ptr_->_M_function_name : "";
+ }
+};
+
+#endif // _LIBCPP_STD_VER >= 20 && __has_builtin(__builtin_source_location) && !(defined(_LIBCPP_APPLE_CLANG_VER) &&
+ // _LIBCPP_APPLE_CLANG_VER <= 1403)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_SOURCE_LOCATION
diff --git a/contrib/libs/cxxsupp/libcxx/include/sstream b/contrib/libs/cxxsupp/libcxx/include/sstream
index 91d1a07353..78cc28a502 100644
--- a/contrib/libs/cxxsupp/libcxx/include/sstream
+++ b/contrib/libs/cxxsupp/libcxx/include/sstream
@@ -260,7 +260,7 @@ protected:
int_type overflow (int_type __c = traits_type::eof()) override;
pos_type seekoff(off_type __off, ios_base::seekdir __way,
ios_base::openmode __wch = ios_base::in | ios_base::out) override;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL
pos_type seekpos(pos_type __sp,
ios_base::openmode __wch = ios_base::in | ios_base::out) override {
return seekoff(__sp, ios_base::beg, __wch);
@@ -876,4 +876,8 @@ _LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
+#if _LIBCPP_STD_VER <= 20 && !defined(_LIPCPP_REMOVE_TRANSITIVE_INCLUDES)
+# include <type_traits>
+#endif
+
#endif // _LIBCPP_SSTREAM
diff --git a/contrib/libs/cxxsupp/libcxx/include/stack b/contrib/libs/cxxsupp/libcxx/include/stack
index 2abbcd025c..d653d1bc7e 100644
--- a/contrib/libs/cxxsupp/libcxx/include/stack
+++ b/contrib/libs/cxxsupp/libcxx/include/stack
@@ -255,6 +255,8 @@ public:
swap(c, __s.c);
}
+ _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI const _Container& __get_container() const { return c; }
+
template <class T1, class _C1>
friend
bool
diff --git a/contrib/libs/cxxsupp/libcxx/include/stdlib.h b/contrib/libs/cxxsupp/libcxx/include/stdlib.h
index 64581b67f2..4dd3a9c14a 100644
--- a/contrib/libs/cxxsupp/libcxx/include/stdlib.h
+++ b/contrib/libs/cxxsupp/libcxx/include/stdlib.h
@@ -110,24 +110,24 @@ extern "C++" {
// MSVCRT already has the correct prototype in <stdlib.h> if __cplusplus is defined
#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__)
-inline _LIBCPP_INLINE_VISIBILITY long abs(long __x) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY long abs(long __x) _NOEXCEPT {
return __builtin_labs(__x);
}
-inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT {
return __builtin_llabs(__x);
}
#endif // !defined(_LIBCPP_MSVCRT) && !defined(__sun__)
#if !defined(__sun__)
-inline _LIBCPP_INLINE_VISIBILITY float abs(float __lcpp_x) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY float abs(float __lcpp_x) _NOEXCEPT {
return __builtin_fabsf(__lcpp_x); // Use builtins to prevent needing math.h
}
-inline _LIBCPP_INLINE_VISIBILITY double abs(double __lcpp_x) _NOEXCEPT {
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY double abs(double __lcpp_x) _NOEXCEPT {
return __builtin_fabs(__lcpp_x);
}
-inline _LIBCPP_INLINE_VISIBILITY long double
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY long double
abs(long double __lcpp_x) _NOEXCEPT {
return __builtin_fabsl(__lcpp_x);
}
diff --git a/contrib/libs/cxxsupp/libcxx/include/string b/contrib/libs/cxxsupp/libcxx/include/string
index bbb1c1a859..7ad144a79e 100644
--- a/contrib/libs/cxxsupp/libcxx/include/string
+++ b/contrib/libs/cxxsupp/libcxx/include/string
@@ -3518,7 +3518,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
size_type __n) const _NOEXCEPT
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): received nullptr");
- return __str_find<value_type, size_type, traits_type, npos>
+ return std::__str_find<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, __n);
}
@@ -3528,7 +3528,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str,
size_type __pos) const _NOEXCEPT
{
- return __str_find<value_type, size_type, traits_type, npos>
+ return std::__str_find<value_type, size_type, traits_type, npos>
(data(), size(), __str.data(), __pos, __str.size());
}
@@ -3544,7 +3544,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t,
size_type __pos) const _NOEXCEPT
{
__self_view __sv = __t;
- return __str_find<value_type, size_type, traits_type, npos>
+ return std::__str_find<value_type, size_type, traits_type, npos>
(data(), size(), __sv.data(), __pos, __sv.size());
}
@@ -3555,7 +3555,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
size_type __pos) const _NOEXCEPT
{
_LIBCPP_ASSERT(__s != nullptr, "string::find(): received nullptr");
- return __str_find<value_type, size_type, traits_type, npos>
+ return std::__str_find<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, traits_type::length(__s));
}
@@ -3565,7 +3565,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find(value_type __c,
size_type __pos) const _NOEXCEPT
{
- return __str_find<value_type, size_type, traits_type, npos>
+ return std::__str_find<value_type, size_type, traits_type, npos>
(data(), size(), __c, __pos);
}
@@ -3579,7 +3579,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
size_type __n) const _NOEXCEPT
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");
- return __str_rfind<value_type, size_type, traits_type, npos>
+ return std::__str_rfind<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, __n);
}
@@ -3589,7 +3589,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str,
size_type __pos) const _NOEXCEPT
{
- return __str_rfind<value_type, size_type, traits_type, npos>
+ return std::__str_rfind<value_type, size_type, traits_type, npos>
(data(), size(), __str.data(), __pos, __str.size());
}
@@ -3605,7 +3605,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t,
size_type __pos) const _NOEXCEPT
{
__self_view __sv = __t;
- return __str_rfind<value_type, size_type, traits_type, npos>
+ return std::__str_rfind<value_type, size_type, traits_type, npos>
(data(), size(), __sv.data(), __pos, __sv.size());
}
@@ -3616,7 +3616,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
size_type __pos) const _NOEXCEPT
{
_LIBCPP_ASSERT(__s != nullptr, "string::rfind(): received nullptr");
- return __str_rfind<value_type, size_type, traits_type, npos>
+ return std::__str_rfind<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, traits_type::length(__s));
}
@@ -3626,7 +3626,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c,
size_type __pos) const _NOEXCEPT
{
- return __str_rfind<value_type, size_type, traits_type, npos>
+ return std::__str_rfind<value_type, size_type, traits_type, npos>
(data(), size(), __c, __pos);
}
@@ -3640,7 +3640,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
size_type __n) const _NOEXCEPT
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");
- return __str_find_first_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_first_of<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, __n);
}
@@ -3650,7 +3650,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str,
size_type __pos) const _NOEXCEPT
{
- return __str_find_first_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_first_of<value_type, size_type, traits_type, npos>
(data(), size(), __str.data(), __pos, __str.size());
}
@@ -3666,7 +3666,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t,
size_type __pos) const _NOEXCEPT
{
__self_view __sv = __t;
- return __str_find_first_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_first_of<value_type, size_type, traits_type, npos>
(data(), size(), __sv.data(), __pos, __sv.size());
}
@@ -3677,7 +3677,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
size_type __pos) const _NOEXCEPT
{
_LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): received nullptr");
- return __str_find_first_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_first_of<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, traits_type::length(__s));
}
@@ -3700,7 +3700,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
size_type __n) const _NOEXCEPT
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");
- return __str_find_last_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_last_of<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, __n);
}
@@ -3710,7 +3710,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str,
size_type __pos) const _NOEXCEPT
{
- return __str_find_last_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_last_of<value_type, size_type, traits_type, npos>
(data(), size(), __str.data(), __pos, __str.size());
}
@@ -3726,7 +3726,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t,
size_type __pos) const _NOEXCEPT
{
__self_view __sv = __t;
- return __str_find_last_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_last_of<value_type, size_type, traits_type, npos>
(data(), size(), __sv.data(), __pos, __sv.size());
}
@@ -3737,7 +3737,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
size_type __pos) const _NOEXCEPT
{
_LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): received nullptr");
- return __str_find_last_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_last_of<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, traits_type::length(__s));
}
@@ -3760,7 +3760,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* _
size_type __n) const _NOEXCEPT
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");
- return __str_find_first_not_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, __n);
}
@@ -3770,7 +3770,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str,
size_type __pos) const _NOEXCEPT
{
- return __str_find_first_not_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
(data(), size(), __str.data(), __pos, __str.size());
}
@@ -3786,7 +3786,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t,
size_type __pos) const _NOEXCEPT
{
__self_view __sv = __t;
- return __str_find_first_not_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
(data(), size(), __sv.data(), __pos, __sv.size());
}
@@ -3797,7 +3797,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* _
size_type __pos) const _NOEXCEPT
{
_LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): received nullptr");
- return __str_find_first_not_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, traits_type::length(__s));
}
@@ -3807,7 +3807,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c,
size_type __pos) const _NOEXCEPT
{
- return __str_find_first_not_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
(data(), size(), __c, __pos);
}
@@ -3821,7 +3821,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __
size_type __n) const _NOEXCEPT
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");
- return __str_find_last_not_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, __n);
}
@@ -3831,7 +3831,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str,
size_type __pos) const _NOEXCEPT
{
- return __str_find_last_not_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
(data(), size(), __str.data(), __pos, __str.size());
}
@@ -3847,7 +3847,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t,
size_type __pos) const _NOEXCEPT
{
__self_view __sv = __t;
- return __str_find_last_not_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
(data(), size(), __sv.data(), __pos, __sv.size());
}
@@ -3858,7 +3858,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __
size_type __pos) const _NOEXCEPT
{
_LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): received nullptr");
- return __str_find_last_not_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, traits_type::length(__s));
}
@@ -3868,7 +3868,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c,
size_type __pos) const _NOEXCEPT
{
- return __str_find_last_not_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
(data(), size(), __c, __pos);
}
@@ -4487,7 +4487,7 @@ struct __string_hash : public __unary_function<basic_string<_CharT, char_traits<
{
size_t
operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT
- { return __do_string_hash(__val.data(), __val.data() + __val.size()); }
+ { return std::__do_string_hash(__val.data(), __val.data() + __val.size()); }
};
template <class _Allocator>
diff --git a/contrib/libs/cxxsupp/libcxx/include/string_view b/contrib/libs/cxxsupp/libcxx/include/string_view
index 7ebef2a104..4ba6b0e12d 100644
--- a/contrib/libs/cxxsupp/libcxx/include/string_view
+++ b/contrib/libs/cxxsupp/libcxx/include/string_view
@@ -496,14 +496,14 @@ public:
size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
{
_LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
- return __str_find<value_type, size_type, traits_type, npos>
+ return std::__str_find<value_type, size_type, traits_type, npos>
(data(), size(), __s.data(), __pos, __s.size());
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT
{
- return __str_find<value_type, size_type, traits_type, npos>
+ return std::__str_find<value_type, size_type, traits_type, npos>
(data(), size(), __c, __pos);
}
@@ -511,7 +511,7 @@ public:
size_type find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
- return __str_find<value_type, size_type, traits_type, npos>
+ return std::__str_find<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, __n);
}
@@ -519,7 +519,7 @@ public:
size_type find(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT
{
_LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr");
- return __str_find<value_type, size_type, traits_type, npos>
+ return std::__str_find<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, traits_type::length(__s));
}
@@ -528,14 +528,14 @@ public:
size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT
{
_LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
- return __str_rfind<value_type, size_type, traits_type, npos>
+ return std::__str_rfind<value_type, size_type, traits_type, npos>
(data(), size(), __s.data(), __pos, __s.size());
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
size_type rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT
{
- return __str_rfind<value_type, size_type, traits_type, npos>
+ return std::__str_rfind<value_type, size_type, traits_type, npos>
(data(), size(), __c, __pos);
}
@@ -543,7 +543,7 @@ public:
size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
- return __str_rfind<value_type, size_type, traits_type, npos>
+ return std::__str_rfind<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, __n);
}
@@ -551,7 +551,7 @@ public:
size_type rfind(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT
{
_LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr");
- return __str_rfind<value_type, size_type, traits_type, npos>
+ return std::__str_rfind<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, traits_type::length(__s));
}
@@ -560,7 +560,7 @@ public:
size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
{
_LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr");
- return __str_find_first_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_first_of<value_type, size_type, traits_type, npos>
(data(), size(), __s.data(), __pos, __s.size());
}
@@ -572,7 +572,7 @@ public:
size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
- return __str_find_first_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_first_of<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, __n);
}
@@ -580,7 +580,7 @@ public:
size_type find_first_of(const _CharT* __s, size_type __pos=0) const _NOEXCEPT
{
_LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr");
- return __str_find_first_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_first_of<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, traits_type::length(__s));
}
@@ -589,7 +589,7 @@ public:
size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
{
_LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr");
- return __str_find_last_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_last_of<value_type, size_type, traits_type, npos>
(data(), size(), __s.data(), __pos, __s.size());
}
@@ -601,7 +601,7 @@ public:
size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");
- return __str_find_last_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_last_of<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, __n);
}
@@ -609,7 +609,7 @@ public:
size_type find_last_of(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT
{
_LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr");
- return __str_find_last_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_last_of<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, traits_type::length(__s));
}
@@ -618,14 +618,14 @@ public:
size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT
{
_LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr");
- return __str_find_first_not_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
(data(), size(), __s.data(), __pos, __s.size());
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
size_type find_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT
{
- return __str_find_first_not_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
(data(), size(), __c, __pos);
}
@@ -633,7 +633,7 @@ public:
size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");
- return __str_find_first_not_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, __n);
}
@@ -641,7 +641,7 @@ public:
size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const _NOEXCEPT
{
_LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr");
- return __str_find_first_not_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, traits_type::length(__s));
}
@@ -650,14 +650,14 @@ public:
size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
{
_LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr");
- return __str_find_last_not_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
(data(), size(), __s.data(), __pos, __s.size());
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
size_type find_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT
{
- return __str_find_last_not_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
(data(), size(), __c, __pos);
}
@@ -665,7 +665,7 @@ public:
size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");
- return __str_find_last_not_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, __n);
}
@@ -673,7 +673,7 @@ public:
size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT
{
_LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr");
- return __str_find_last_not_of<value_type, size_type, traits_type, npos>
+ return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>
(data(), size(), __s, __pos, traits_type::length(__s));
}
@@ -957,7 +957,7 @@ struct __string_view_hash : public __unary_function<basic_string_view<_CharT, ch
{
_LIBCPP_INLINE_VISIBILITY
size_t operator()(const basic_string_view<_CharT, char_traits<_CharT> > __val) const _NOEXCEPT {
- return __do_string_hash(__val.data(), __val.data() + __val.size());
+ return std::__do_string_hash(__val.data(), __val.data() + __val.size());
}
};
diff --git a/contrib/libs/cxxsupp/libcxx/include/thread b/contrib/libs/cxxsupp/libcxx/include/thread
index 7c6d4f8828..7a1117f555 100644
--- a/contrib/libs/cxxsupp/libcxx/include/thread
+++ b/contrib/libs/cxxsupp/libcxx/include/thread
@@ -199,7 +199,7 @@ __thread_specific_ptr<_Tp>::set_pointer(pointer __p)
{
_LIBCPP_ASSERT(get() == nullptr,
"Attempting to overwrite thread local data");
- __libcpp_tls_set(__key_, __p);
+ std::__libcpp_tls_set(__key_, __p);
}
template<>
diff --git a/contrib/libs/cxxsupp/libcxx/include/tuple b/contrib/libs/cxxsupp/libcxx/include/tuple
index a307461658..221b50375d 100644
--- a/contrib/libs/cxxsupp/libcxx/include/tuple
+++ b/contrib/libs/cxxsupp/libcxx/include/tuple
@@ -205,11 +205,45 @@ template <class... Types>
#include <__compare/common_comparison_category.h>
#include <__compare/synth_three_way.h>
#include <__config>
+#include <__functional/invoke.h>
#include <__functional/unwrap_ref.h>
#include <__fwd/array.h>
#include <__memory/allocator_arg_t.h>
#include <__memory/uses_allocator.h>
+#include <__type_traits/apply_cv.h>
+#include <__type_traits/common_reference.h>
+#include <__type_traits/common_type.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/conjunction.h>
+#include <__type_traits/copy_cvref.h>
+#include <__type_traits/disjunction.h>
+#include <__type_traits/is_arithmetic.h>
+#include <__type_traits/is_assignable.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_copy_assignable.h>
+#include <__type_traits/is_copy_constructible.h>
+#include <__type_traits/is_default_constructible.h>
+#include <__type_traits/is_empty.h>
+#include <__type_traits/is_final.h>
+#include <__type_traits/is_implicitly_default_constructible.h>
+#include <__type_traits/is_move_assignable.h>
+#include <__type_traits/is_move_constructible.h>
+#include <__type_traits/is_nothrow_assignable.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_nothrow_copy_assignable.h>
+#include <__type_traits/is_nothrow_copy_constructible.h>
+#include <__type_traits/is_nothrow_default_constructible.h>
+#include <__type_traits/is_nothrow_move_assignable.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_swappable.h>
+#include <__type_traits/lazy.h>
#include <__type_traits/maybe_const.h>
+#include <__type_traits/nat.h>
+#include <__type_traits/negation.h>
+#include <__type_traits/remove_cvref.h>
+#include <__type_traits/remove_reference.h>
#include <__utility/forward.h>
#include <__utility/integer_sequence.h>
#include <__utility/move.h>
@@ -217,7 +251,6 @@ template <class... Types>
#include <__utility/piecewise_construct.h>
#include <__utility/swap.h>
#include <cstddef>
-#include <type_traits>
#include <version>
// standard-mandated includes
@@ -1397,7 +1430,7 @@ template <size_t _Nx>
inline _LIBCPP_INLINE_VISIBILITY
constexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) {
return __i == _Nx ? __not_found :
- __find_idx_return(__i, __find_idx(__i + 1, __matches), __matches[__i]);
+ __find_detail::__find_idx_return(__i, __find_detail::__find_idx(__i + 1, __matches), __matches[__i]);
}
template <class _T1, class ..._Args>
@@ -1644,7 +1677,7 @@ struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...
tuple<_Types...>,
typename __make_tuple_types<__remove_cvref_t<_Tuple0> >::type
>::type,
- __tuple_like<__libcpp_remove_reference_t<_Tuple1> >::value,
+ __tuple_like_ext<__libcpp_remove_reference_t<_Tuple1> >::value,
_Tuple1, _Tuples...>
{
};
@@ -1654,7 +1687,7 @@ template <class ..._Tuples> struct __tuple_cat_return;
template <class _Tuple0, class ..._Tuples>
struct __tuple_cat_return<_Tuple0, _Tuples...>
: public __tuple_cat_return_1<tuple<>,
- __tuple_like<__libcpp_remove_reference_t<_Tuple0> >::value, _Tuple0,
+ __tuple_like_ext<__libcpp_remove_reference_t<_Tuple0> >::value, _Tuple0,
_Tuples...>
{
};
@@ -1822,6 +1855,7 @@ _LIBCPP_END_NAMESPACE_STD
# include <exception>
# include <iosfwd>
# include <new>
+# include <type_traits>
# include <typeinfo>
# include <utility>
#endif
diff --git a/contrib/libs/cxxsupp/libcxx/include/type_traits b/contrib/libs/cxxsupp/libcxx/include/type_traits
index e70039e35a..7646f58059 100644
--- a/contrib/libs/cxxsupp/libcxx/include/type_traits
+++ b/contrib/libs/cxxsupp/libcxx/include/type_traits
@@ -158,8 +158,8 @@ namespace std
// Alignment properties and transformations:
template <class T> struct alignment_of;
template <size_t Len, size_t Align = most_stringent_alignment_requirement>
- struct aligned_storage;
- template <size_t Len, class... Types> struct aligned_union;
+ struct aligned_storage; // deprecated in C++23
+ template <size_t Len, class... Types> struct aligned_union; // deprecated in C++23
template <class T> struct remove_cvref; // C++20
template <class T> struct decay;
@@ -497,6 +497,7 @@ namespace std
#include <__type_traits/is_scalar.h>
#include <__type_traits/is_scoped_enum.h>
#include <__type_traits/is_signed.h>
+#include <__type_traits/is_specialization.h>
#include <__type_traits/is_standard_layout.h>
#include <__type_traits/is_swappable.h>
#include <__type_traits/is_trivial.h>
@@ -541,14 +542,4 @@ namespace std
# pragma GCC system_header
#endif
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-// CUDA headers use libc++ internals.
-#ifdef __CUDACC__
-template <bool _Cond, class _Ret = void>
-using __lazy_enable_if _LIBCPP_NODEBUG = __enable_if_t<_Cond, _Ret>;
-#endif
-
-_LIBCPP_END_NAMESPACE_STD
-
#endif // _LIBCPP_TYPE_TRAITS
diff --git a/contrib/libs/cxxsupp/libcxx/include/unordered_map b/contrib/libs/cxxsupp/libcxx/include/unordered_map
index cd0aea1205..14f93bab36 100644
--- a/contrib/libs/cxxsupp/libcxx/include/unordered_map
+++ b/contrib/libs/cxxsupp/libcxx/include/unordered_map
@@ -1149,7 +1149,7 @@ public:
#endif
_LIBCPP_INLINE_VISIBILITY
~unordered_map() {
- static_assert(sizeof(__diagnose_unordered_container_requirements<_Key, _Hash, _Pred>(0)), "");
+ static_assert(sizeof(std::__diagnose_unordered_container_requirements<_Key, _Hash, _Pred>(0)), "");
}
_LIBCPP_INLINE_VISIBILITY
@@ -2041,7 +2041,7 @@ private:
#endif
_LIBCPP_INLINE_VISIBILITY
~unordered_multimap() {
- static_assert(sizeof(__diagnose_unordered_container_requirements<_Key, _Hash, _Pred>(0)), "");
+ static_assert(sizeof(std::__diagnose_unordered_container_requirements<_Key, _Hash, _Pred>(0)), "");
}
_LIBCPP_INLINE_VISIBILITY
diff --git a/contrib/libs/cxxsupp/libcxx/include/unordered_set b/contrib/libs/cxxsupp/libcxx/include/unordered_set
index 9a25510139..b4203c08a9 100644
--- a/contrib/libs/cxxsupp/libcxx/include/unordered_set
+++ b/contrib/libs/cxxsupp/libcxx/include/unordered_set
@@ -613,7 +613,7 @@ public:
#endif // _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
~unordered_set() {
- static_assert(sizeof(__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), "");
+ static_assert(sizeof(std::__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), "");
}
_LIBCPP_INLINE_VISIBILITY
@@ -1267,7 +1267,7 @@ public:
#endif // _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
~unordered_multiset() {
- static_assert(sizeof(__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), "");
+ static_assert(sizeof(std::__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), "");
}
_LIBCPP_INLINE_VISIBILITY
diff --git a/contrib/libs/cxxsupp/libcxx/include/utility b/contrib/libs/cxxsupp/libcxx/include/utility
index ac6c18b06a..a4d8cf853d 100644
--- a/contrib/libs/cxxsupp/libcxx/include/utility
+++ b/contrib/libs/cxxsupp/libcxx/include/utility
@@ -243,6 +243,7 @@ template <class T>
#include <__utility/auto_cast.h>
#include <__utility/cmp.h>
#include <__utility/declval.h>
+#include <__utility/exception_guard.h>
#include <__utility/exchange.h>
#include <__utility/forward.h>
#include <__utility/forward_like.h>
@@ -255,9 +256,7 @@ template <class T>
#include <__utility/rel_ops.h>
#include <__utility/swap.h>
#include <__utility/to_underlying.h>
-#include <__utility/transaction.h>
#include <__utility/unreachable.h>
-#include <type_traits>
#include <version>
// standard-mandated includes
@@ -267,15 +266,17 @@ template <class T>
#include <initializer_list>
// [tuple.helper]
-#include <__tuple/tuple_element.h>
-#include <__tuple/tuple_size.h>
+#include <__tuple_dir/tuple_element.h>
+#include <__tuple_dir/tuple_size.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+# include <cstdlib>
# include <iosfwd>
+# include <type_traits>
#endif
#endif // _LIBCPP_UTILITY
diff --git a/contrib/libs/cxxsupp/libcxx/include/valarray b/contrib/libs/cxxsupp/libcxx/include/valarray
index 6c33d0531c..92521ed381 100644
--- a/contrib/libs/cxxsupp/libcxx/include/valarray
+++ b/contrib/libs/cxxsupp/libcxx/include/valarray
@@ -353,6 +353,7 @@ template <class T> unspecified2 end(const valarray<T>& v);
#include <__functional/operations.h>
#include <__memory/allocator.h>
#include <__memory/uninitialized_algorithms.h>
+#include <__type_traits/remove_reference.h>
#include <__utility/move.h>
#include <__utility/swap.h>
#include <cmath>
@@ -545,7 +546,7 @@ struct __abs_expr
typedef _Tp __result_type;
_LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x) const
- {return abs(__x);}
+ {return std::abs(__x);}
};
template <class _Tp>
@@ -554,7 +555,7 @@ struct __acos_expr
typedef _Tp __result_type;
_LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x) const
- {return acos(__x);}
+ {return std::acos(__x);}
};
template <class _Tp>
@@ -563,7 +564,7 @@ struct __asin_expr
typedef _Tp __result_type;
_LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x) const
- {return asin(__x);}
+ {return std::asin(__x);}
};
template <class _Tp>
@@ -572,7 +573,7 @@ struct __atan_expr
typedef _Tp __result_type;
_LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x) const
- {return atan(__x);}
+ {return std::atan(__x);}
};
template <class _Tp>
@@ -581,7 +582,7 @@ struct __atan2_expr
typedef _Tp __result_type;
_LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x, const _Tp& __y) const
- {return atan2(__x, __y);}
+ {return std::atan2(__x, __y);}
};
template <class _Tp>
@@ -590,7 +591,7 @@ struct __cos_expr
typedef _Tp __result_type;
_LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x) const
- {return cos(__x);}
+ {return std::cos(__x);}
};
template <class _Tp>
@@ -599,7 +600,7 @@ struct __cosh_expr
typedef _Tp __result_type;
_LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x) const
- {return cosh(__x);}
+ {return std::cosh(__x);}
};
template <class _Tp>
@@ -608,7 +609,7 @@ struct __exp_expr
typedef _Tp __result_type;
_LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x) const
- {return exp(__x);}
+ {return std::exp(__x);}
};
template <class _Tp>
@@ -617,7 +618,7 @@ struct __log_expr
typedef _Tp __result_type;
_LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x) const
- {return log(__x);}
+ {return std::log(__x);}
};
template <class _Tp>
@@ -626,7 +627,7 @@ struct __log10_expr
typedef _Tp __result_type;
_LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x) const
- {return log10(__x);}
+ {return std::log10(__x);}
};
template <class _Tp>
@@ -635,7 +636,7 @@ struct __pow_expr
typedef _Tp __result_type;
_LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x, const _Tp& __y) const
- {return pow(__x, __y);}
+ {return std::pow(__x, __y);}
};
template <class _Tp>
@@ -644,7 +645,7 @@ struct __sin_expr
typedef _Tp __result_type;
_LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x) const
- {return sin(__x);}
+ {return std::sin(__x);}
};
template <class _Tp>
@@ -653,7 +654,7 @@ struct __sinh_expr
typedef _Tp __result_type;
_LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x) const
- {return sinh(__x);}
+ {return std::sinh(__x);}
};
template <class _Tp>
@@ -662,7 +663,7 @@ struct __sqrt_expr
typedef _Tp __result_type;
_LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x) const
- {return sqrt(__x);}
+ {return std::sqrt(__x);}
};
template <class _Tp>
@@ -671,7 +672,7 @@ struct __tan_expr
typedef _Tp __result_type;
_LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x) const
- {return tan(__x);}
+ {return std::tan(__x);}
};
template <class _Tp>
@@ -680,7 +681,7 @@ struct __tanh_expr
typedef _Tp __result_type;
_LIBCPP_INLINE_VISIBILITY
_Tp operator()(const _Tp& __x) const
- {return tanh(__x);}
+ {return std::tanh(__x);}
};
template <class _ValExpr>
@@ -4932,6 +4933,7 @@ _LIBCPP_POP_MACROS
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <algorithm>
# include <concepts>
+# include <cstring>
# include <functional>
#endif
diff --git a/contrib/libs/cxxsupp/libcxx/include/variant b/contrib/libs/cxxsupp/libcxx/include/variant
index 26835f327d..13c89822ca 100644
--- a/contrib/libs/cxxsupp/libcxx/include/variant
+++ b/contrib/libs/cxxsupp/libcxx/include/variant
@@ -211,9 +211,26 @@ namespace std {
#include <__compare/three_way_comparable.h>
#include <__config>
#include <__functional/hash.h>
+#include <__functional/invoke.h>
#include <__functional/operations.h>
#include <__functional/unary_function.h>
+#include <__type_traits/add_const.h>
+#include <__type_traits/add_cv.h>
+#include <__type_traits/add_pointer.h>
+#include <__type_traits/add_volatile.h>
#include <__type_traits/dependent_type.h>
+#include <__type_traits/is_array.h>
+#include <__type_traits/is_destructible.h>
+#include <__type_traits/is_nothrow_move_constructible.h>
+#include <__type_traits/is_trivially_copy_assignable.h>
+#include <__type_traits/is_trivially_copy_constructible.h>
+#include <__type_traits/is_trivially_destructible.h>
+#include <__type_traits/is_trivially_move_assignable.h>
+#include <__type_traits/is_trivially_move_constructible.h>
+#include <__type_traits/is_void.h>
+#include <__type_traits/remove_const.h>
+#include <__type_traits/type_identity.h>
+#include <__type_traits/void_t.h>
#include <__utility/forward.h>
#include <__utility/in_place.h>
#include <__utility/move.h>
@@ -224,7 +241,6 @@ namespace std {
#include <limits>
#include <new>
#include <tuple>
-#include <type_traits>
#include <version>
// standard-mandated includes
@@ -436,24 +452,24 @@ constexpr _Trait __common_trait(initializer_list<_Trait> __traits) {
template <typename... _Types>
struct __traits {
static constexpr _Trait __copy_constructible_trait =
- __common_trait({__trait<_Types,
+ __variant_detail::__common_trait({__trait<_Types,
is_trivially_copy_constructible,
is_copy_constructible>...});
static constexpr _Trait __move_constructible_trait =
- __common_trait({__trait<_Types,
+ __variant_detail::__common_trait({__trait<_Types,
is_trivially_move_constructible,
is_move_constructible>...});
- static constexpr _Trait __copy_assignable_trait = __common_trait(
+ static constexpr _Trait __copy_assignable_trait = __variant_detail::__common_trait(
{__copy_constructible_trait,
__trait<_Types, is_trivially_copy_assignable, is_copy_assignable>...});
- static constexpr _Trait __move_assignable_trait = __common_trait(
+ static constexpr _Trait __move_assignable_trait = __variant_detail::__common_trait(
{__move_constructible_trait,
__trait<_Types, is_trivially_move_assignable, is_move_assignable>...});
- static constexpr _Trait __destructible_trait = __common_trait(
+ static constexpr _Trait __destructible_trait = __variant_detail::__common_trait(
{__trait<_Types, is_trivially_destructible, is_destructible>...});
};
@@ -1213,7 +1229,7 @@ struct __narrowing_check {
template <class _Dest>
static auto __test_impl(_Dest (&&)[1]) -> __type_identity<_Dest>;
template <class _Dest, class _Source>
- using _Apply _LIBCPP_NODEBUG = decltype(__test_impl<_Dest>({declval<_Source>()}));
+ using _Apply _LIBCPP_NODEBUG = decltype(__test_impl<_Dest>({std::declval<_Source>()}));
};
template <class _Dest, class _Source>
@@ -1484,7 +1500,7 @@ constexpr bool __holds_alternative(const variant<_Types...>& __v) noexcept {
template <class _Tp, class... _Types>
_LIBCPP_HIDE_FROM_ABI
constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept {
- return __holds_alternative<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
+ return std::__holds_alternative<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
}
template <size_t _Ip, class _Vp>
@@ -1492,7 +1508,7 @@ _LIBCPP_HIDE_FROM_ABI
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
constexpr auto&& __generic_get(_Vp&& __v) {
using __variant_detail::__access::__variant;
- if (!__holds_alternative<_Ip>(__v)) {
+ if (!std::__holds_alternative<_Ip>(__v)) {
__throw_bad_variant_access();
}
return __variant::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v)).__value;
@@ -1505,7 +1521,7 @@ constexpr variant_alternative_t<_Ip, variant<_Types...>>& get(
variant<_Types...>& __v) {
static_assert(_Ip < sizeof...(_Types));
static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
- return __generic_get<_Ip>(__v);
+ return std::__generic_get<_Ip>(__v);
}
template <size_t _Ip, class... _Types>
@@ -1515,7 +1531,7 @@ constexpr variant_alternative_t<_Ip, variant<_Types...>>&& get(
variant<_Types...>&& __v) {
static_assert(_Ip < sizeof...(_Types));
static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
- return __generic_get<_Ip>(_VSTD::move(__v));
+ return std::__generic_get<_Ip>(_VSTD::move(__v));
}
template <size_t _Ip, class... _Types>
@@ -1525,7 +1541,7 @@ constexpr const variant_alternative_t<_Ip, variant<_Types...>>& get(
const variant<_Types...>& __v) {
static_assert(_Ip < sizeof...(_Types));
static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
- return __generic_get<_Ip>(__v);
+ return std::__generic_get<_Ip>(__v);
}
template <size_t _Ip, class... _Types>
@@ -1535,7 +1551,7 @@ constexpr const variant_alternative_t<_Ip, variant<_Types...>>&& get(
const variant<_Types...>&& __v) {
static_assert(_Ip < sizeof...(_Types));
static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
- return __generic_get<_Ip>(_VSTD::move(__v));
+ return std::__generic_get<_Ip>(_VSTD::move(__v));
}
template <class _Tp, class... _Types>
@@ -1576,7 +1592,7 @@ template <size_t _Ip, class _Vp>
_LIBCPP_HIDE_FROM_ABI
constexpr auto* __generic_get_if(_Vp* __v) noexcept {
using __variant_detail::__access::__variant;
- return __v && __holds_alternative<_Ip>(*__v)
+ return __v && std::__holds_alternative<_Ip>(*__v)
? _VSTD::addressof(__variant::__get_alt<_Ip>(*__v).__value)
: nullptr;
}
@@ -1587,7 +1603,7 @@ constexpr add_pointer_t<variant_alternative_t<_Ip, variant<_Types...>>>
get_if(variant<_Types...>* __v) noexcept {
static_assert(_Ip < sizeof...(_Types));
static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
- return __generic_get_if<_Ip>(__v);
+ return std::__generic_get_if<_Ip>(__v);
}
template <size_t _Ip, class... _Types>
@@ -1596,7 +1612,7 @@ constexpr add_pointer_t<const variant_alternative_t<_Ip, variant<_Types...>>>
get_if(const variant<_Types...>* __v) noexcept {
static_assert(_Ip < sizeof...(_Types));
static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
- return __generic_get_if<_Ip>(__v);
+ return std::__generic_get_if<_Ip>(__v);
}
template <class _Tp, class... _Types>
@@ -1731,7 +1747,7 @@ constexpr void __throw_if_valueless(_Vs&&... __vs) {
template <
class _Visitor, class... _Vs,
- typename = void_t<decltype(_VSTD::__as_variant(declval<_Vs>()))...> >
+ typename = void_t<decltype(_VSTD::__as_variant(std::declval<_Vs>()))...> >
_LIBCPP_HIDE_FROM_ABI
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
constexpr decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) {
@@ -1744,7 +1760,7 @@ constexpr decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) {
#if _LIBCPP_STD_VER > 17
template <
class _Rp, class _Visitor, class... _Vs,
- typename = void_t<decltype(_VSTD::__as_variant(declval<_Vs>()))...> >
+ typename = void_t<decltype(_VSTD::__as_variant(std::declval<_Vs>()))...> >
_LIBCPP_HIDE_FROM_ABI
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
constexpr _Rp visit(_Visitor&& __visitor, _Vs&&... __vs) {
@@ -1782,7 +1798,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<
return hash<__value_type>{}(__alt.__value);
},
__v);
- return __hash_combine(__res, hash<size_t>{}(__v.index()));
+ return std::__hash_combine(__res, hash<size_t>{}(__v.index()));
}
};
@@ -1799,13 +1815,13 @@ constexpr auto&& __unchecked_get(_Vp&& __v) noexcept {
template <class _Tp, class... _Types>
_LIBCPP_HIDE_FROM_ABI
constexpr auto&& __unchecked_get(const variant<_Types...>& __v) noexcept {
- return __unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
+ return std::__unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
}
template <class _Tp, class... _Types>
_LIBCPP_HIDE_FROM_ABI
constexpr auto&& __unchecked_get(variant<_Types...>& __v) noexcept {
- return __unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
+ return std::__unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
}
#endif // _LIBCPP_STD_VER > 14
@@ -1815,6 +1831,7 @@ _LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+# include <type_traits>
# include <typeinfo>
# include <utility>
#endif
diff --git a/contrib/libs/cxxsupp/libcxx/include/vector b/contrib/libs/cxxsupp/libcxx/include/vector
index 53bb94c828..32ee8cd450 100644
--- a/contrib/libs/cxxsupp/libcxx/include/vector
+++ b/contrib/libs/cxxsupp/libcxx/include/vector
@@ -267,6 +267,13 @@ template <class T, class Allocator, class Predicate>
typename vector<T, Allocator>::size_type
erase_if(vector<T, Allocator>& c, Predicate pred); // C++20
+
+template<class T>
+ inline constexpr bool is-vector-bool-reference = see below; // exposition only, since C++23
+
+template<class T, class charT> requires is-vector-bool-reference<T> // Since C++23
+ struct formatter<T, charT>;
+
} // std
*/
@@ -281,9 +288,11 @@ erase_if(vector<T, Allocator>& c, Predicate pred); // C++20
#include <__algorithm/unwrap_iter.h>
#include <__assert> // all public C++ headers provide the assertion handler
#include <__bit_reference>
+#include <__concepts/same_as.h>
#include <__config>
#include <__debug>
#include <__format/enable_insertable.h>
+#include <__format/formatter.h>
#include <__functional/hash.h>
#include <__functional/unary_function.h>
#include <__iterator/advance.h>
@@ -299,6 +308,7 @@ erase_if(vector<T, Allocator>& c, Predicate pred); // C++20
#include <__split_buffer>
#include <__type_traits/is_allocator.h>
#include <__type_traits/noexcept_move_assign_container.h>
+#include <__utility/exception_guard.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#include <__utility/swap.h>
@@ -428,18 +438,27 @@ public:
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a);
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
- ~vector()
- {
- __annotate_delete();
- std::__debug_db_erase_c(this);
+private:
+ class __destroy_vector {
+ public:
+ _LIBCPP_CONSTEXPR __destroy_vector(vector& __vec) : __vec_(__vec) {}
- if (this->__begin_ != nullptr)
- {
- __clear();
- __alloc_traits::deallocate(__alloc(), this->__begin_, capacity());
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void operator()() {
+ __vec_.__annotate_delete();
+ std::__debug_db_erase_c(std::addressof(__vec_));
+
+ if (__vec_.__begin_ != nullptr) {
+ __vec_.__clear();
+ __alloc_traits::deallocate(__vec_.__alloc(), __vec_.__begin_, __vec_.capacity());
+ }
}
- }
+
+ private:
+ vector& __vec_;
+ };
+
+public:
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~vector() { __destroy_vector(*this)(); }
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(const vector& __x);
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(const vector& __x, const __type_identity_t<allocator_type>& __a);
@@ -1080,12 +1099,14 @@ template <class _Tp, class _Allocator>
_LIBCPP_CONSTEXPR_SINCE_CXX20
vector<_Tp, _Allocator>::vector(size_type __n)
{
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
if (__n > 0)
{
__vallocate(__n);
__construct_at_end(__n);
}
+ __guard.__complete();
}
#if _LIBCPP_STD_VER > 11
@@ -1094,12 +1115,14 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
vector<_Tp, _Allocator>::vector(size_type __n, const allocator_type& __a)
: __end_cap_(nullptr, __a)
{
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
if (__n > 0)
{
__vallocate(__n);
__construct_at_end(__n);
}
+ __guard.__complete();
}
#endif
@@ -1107,12 +1130,14 @@ template <class _Tp, class _Allocator>
_LIBCPP_CONSTEXPR_SINCE_CXX20
vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x)
{
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
if (__n > 0)
{
__vallocate(__n);
__construct_at_end(__n, __x);
}
+ __guard.__complete();
}
template <class _Tp, class _Allocator>
@@ -1122,9 +1147,11 @@ template <class _InputIterator, __enable_if_t<__is_exactly_cpp17_input_iterator<
_LIBCPP_CONSTEXPR_SINCE_CXX20
vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last)
{
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
for (; __first != __last; ++__first)
emplace_back(*__first);
+ __guard.__complete();
}
template <class _Tp, class _Allocator>
@@ -1135,9 +1162,11 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a)
: __end_cap_(nullptr, __a)
{
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
for (; __first != __last; ++__first)
emplace_back(*__first);
+ __guard.__complete();
}
template <class _Tp, class _Allocator>
@@ -1147,6 +1176,7 @@ template <class _ForwardIterator, __enable_if_t<__is_cpp17_forward_iterator<_For
_LIBCPP_CONSTEXPR_SINCE_CXX20
vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last)
{
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
size_type __n = static_cast<size_type>(std::distance(__first, __last));
if (__n > 0)
@@ -1154,6 +1184,7 @@ vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __las
__vallocate(__n);
__construct_at_end(__first, __last, __n);
}
+ __guard.__complete();
}
template <class _Tp, class _Allocator>
@@ -1164,6 +1195,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a)
: __end_cap_(nullptr, __a)
{
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
size_type __n = static_cast<size_type>(std::distance(__first, __last));
if (__n > 0)
@@ -1171,6 +1203,7 @@ vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __las
__vallocate(__n);
__construct_at_end(__first, __last, __n);
}
+ __guard.__complete();
}
template <class _Tp, class _Allocator>
@@ -1178,6 +1211,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
vector<_Tp, _Allocator>::vector(const vector& __x)
: __end_cap_(nullptr, __alloc_traits::select_on_container_copy_construction(__x.__alloc()))
{
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
size_type __n = __x.size();
if (__n > 0)
@@ -1185,6 +1219,7 @@ vector<_Tp, _Allocator>::vector(const vector& __x)
__vallocate(__n);
__construct_at_end(__x.__begin_, __x.__end_, __n);
}
+ __guard.__complete();
}
template <class _Tp, class _Allocator>
@@ -1192,6 +1227,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
vector<_Tp, _Allocator>::vector(const vector& __x, const __type_identity_t<allocator_type>& __a)
: __end_cap_(nullptr, __a)
{
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
size_type __n = __x.size();
if (__n > 0)
@@ -1199,6 +1235,7 @@ vector<_Tp, _Allocator>::vector(const vector& __x, const __type_identity_t<alloc
__vallocate(__n);
__construct_at_end(__x.__begin_, __x.__end_, __n);
}
+ __guard.__complete();
}
template <class _Tp, class _Allocator>
@@ -1238,7 +1275,9 @@ vector<_Tp, _Allocator>::vector(vector&& __x, const __type_identity_t<allocator_
else
{
typedef move_iterator<iterator> _Ip;
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
assign(_Ip(__x.begin()), _Ip(__x.end()));
+ __guard.__complete();
}
}
@@ -1249,12 +1288,14 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
inline _LIBCPP_HIDE_FROM_ABI
vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il)
{
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
if (__il.size() > 0)
{
__vallocate(__il.size());
__construct_at_end(__il.begin(), __il.end(), __il.size());
}
+ __guard.__complete();
}
template <class _Tp, class _Allocator>
@@ -1263,12 +1304,14 @@ inline _LIBCPP_HIDE_FROM_ABI
vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il, const allocator_type& __a)
: __end_cap_(nullptr, __a)
{
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
if (__il.size() > 0)
{
__vallocate(__il.size());
__construct_at_end(__il.begin(), __il.end(), __il.size());
}
+ __guard.__complete();
}
#endif // _LIBCPP_CXX03_LANG
@@ -1923,18 +1966,6 @@ vector<_Tp, _Allocator>::resize(size_type __sz)
this->__destruct_at_end(this->__begin_ + __sz);
}
-template <class _Tp, class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
-void
-vector<_Tp, _Allocator>::resize(size_type __sz, const_reference __x)
-{
- size_type __cs = size();
- if (__cs < __sz)
- this->__append(__sz - __cs, __x);
- else if (__cs > __sz)
- this->__destruct_at_end(this->__begin_ + __sz);
-}
-
#if _YNDX_LIBCXX_ENABLE_VECTOR_POD_RESIZE_UNINITIALIZED
template <class _Tp, class _Allocator>
@@ -1955,6 +1986,18 @@ vector<_Tp, _Allocator>::resize_uninitialized(size_type __sz)
template <class _Tp, class _Allocator>
_LIBCPP_CONSTEXPR_SINCE_CXX20
void
+vector<_Tp, _Allocator>::resize(size_type __sz, const_reference __x)
+{
+ size_type __cs = size();
+ if (__cs < __sz)
+ this->__append(__sz - __cs, __x);
+ else if (__cs > __sz)
+ this->__destruct_at_end(this->__begin_ + __sz);
+}
+
+template <class _Tp, class _Allocator>
+_LIBCPP_CONSTEXPR_SINCE_CXX20
+void
vector<_Tp, _Allocator>::swap(vector& __x)
#if _LIBCPP_STD_VER >= 14
_NOEXCEPT
@@ -2132,7 +2175,25 @@ public:
#else
_NOEXCEPT;
#endif
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~vector();
+
+private:
+ class __destroy_vector {
+ public:
+ _LIBCPP_CONSTEXPR __destroy_vector(vector& __vec) : __vec_(__vec) {}
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void operator()() {
+ if (__vec_.__begin_ != nullptr)
+ __storage_traits::deallocate(__vec_.__alloc(), __vec_.__begin_, __vec_.__cap());
+ std::__debug_db_invalidate_all(this);
+ }
+
+ private:
+ vector& __vec_;
+ };
+
+public:
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~vector() { __destroy_vector(*this)(); }
+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector(size_type __n);
#if _LIBCPP_STD_VER > 11
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector(size_type __n, const allocator_type& __a);
@@ -2668,12 +2729,14 @@ vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __la
__size_(0),
__cap_alloc_(0, __default_init_tag())
{
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
size_type __n = static_cast<size_type>(std::distance(__first, __last));
if (__n > 0)
{
__vallocate(__n);
__construct_at_end(__first, __last);
}
+ __guard.__complete();
}
template <class _Allocator>
@@ -2685,12 +2748,14 @@ vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __la
__size_(0),
__cap_alloc_(0, static_cast<__storage_allocator>(__a))
{
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
size_type __n = static_cast<size_type>(std::distance(__first, __last));
if (__n > 0)
{
__vallocate(__n);
__construct_at_end(__first, __last);
}
+ __guard.__complete();
}
#ifndef _LIBCPP_CXX03_LANG
@@ -2729,15 +2794,6 @@ vector<bool, _Allocator>::vector(initializer_list<value_type> __il, const alloca
template <class _Allocator>
_LIBCPP_CONSTEXPR_SINCE_CXX20
-vector<bool, _Allocator>::~vector()
-{
- if (__begin_ != nullptr)
- __storage_traits::deallocate(__alloc(), __begin_, __cap());
- std::__debug_db_invalidate_all(this);
-}
-
-template <class _Allocator>
-_LIBCPP_CONSTEXPR_SINCE_CXX20
vector<bool, _Allocator>::vector(const vector& __v)
: __begin_(nullptr),
__size_(0),
@@ -3355,14 +3411,35 @@ erase_if(vector<_Tp, _Allocator>& __c, _Predicate __pred) {
}
template <>
-inline constexpr bool __format::__enable_insertable<std::vector<char>> = true;
+inline constexpr bool __format::__enable_insertable<vector<char>> = true;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <>
-inline constexpr bool __format::__enable_insertable<std::vector<wchar_t>> = true;
+inline constexpr bool __format::__enable_insertable<vector<wchar_t>> = true;
#endif
#endif // _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER > 20
+template <class _Tp, class CharT>
+// Since is-vector-bool-reference is only used once it's inlined here.
+ requires same_as<typename _Tp::__container, vector<bool, typename _Tp::__container::allocator_type>>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_Tp, CharT> {
+private:
+ formatter<bool, CharT> __underlying_;
+
+public:
+ template <class _ParseContext>
+ _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+ return __underlying_.parse(__ctx);
+ }
+
+ template <class _FormatContext>
+ _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(const _Tp& __ref, _FormatContext& __ctx) const {
+ return __underlying_.format(__ref, __ctx);
+ }
+};
+#endif // _LIBCPP_STD_VER > 20
+
_LIBCPP_END_NAMESPACE_STD
#if _LIBCPP_STD_VER > 14
diff --git a/contrib/libs/cxxsupp/libcxx/include/version b/contrib/libs/cxxsupp/libcxx/include/version
index f69d4ba252..a998eb56ca 100644
--- a/contrib/libs/cxxsupp/libcxx/include/version
+++ b/contrib/libs/cxxsupp/libcxx/include/version
@@ -55,7 +55,7 @@ __cpp_lib_chrono_udls 201304L <chrono>
__cpp_lib_clamp 201603L <algorithm>
__cpp_lib_complex_udls 201309L <complex>
__cpp_lib_concepts 202002L <concepts>
-__cpp_lib_constexpr_algorithms 201806L <algorithm>
+__cpp_lib_constexpr_algorithms 201806L <algorithm> <utility>
__cpp_lib_constexpr_bitset 202207L <bitset>
__cpp_lib_constexpr_charconv 202207L <charconv>
__cpp_lib_constexpr_cmath 202202L <cmath> <cstdlib>
@@ -82,6 +82,7 @@ __cpp_lib_erase_if 202002L <deque> <forward
__cpp_lib_exchange_function 201304L <utility>
__cpp_lib_execution 201902L <execution>
201603L // C++17
+__cpp_lib_expected 202202L <expected>
__cpp_lib_filesystem 201703L <filesystem>
__cpp_lib_format 202106L <format>
__cpp_lib_forward_like 202207L <utility>
@@ -136,8 +137,9 @@ __cpp_lib_out_ptr 202106L <memory>
__cpp_lib_parallel_algorithm 201603L <algorithm> <numeric>
__cpp_lib_polymorphic_allocator 201902L <memory_resource>
__cpp_lib_quoted_string_io 201304L <iomanip>
-__cpp_lib_ranges 201811L <algorithm> <functional> <iterator>
+__cpp_lib_ranges 202106L <algorithm> <functional> <iterator>
<memory> <ranges>
+__cpp_lib_ranges_as_rvalue 202207L <ranges>
__cpp_lib_ranges_chunk 202202L <ranges>
__cpp_lib_ranges_chunk_by 202202L <ranges>
__cpp_lib_ranges_iota 202202L <numeric>
@@ -324,7 +326,7 @@ __cpp_lib_void_t 201411L <type_traits>
# endif
# define __cpp_lib_concepts 202002L
# define __cpp_lib_constexpr_algorithms 201806L
-// # define __cpp_lib_constexpr_complex 201711L
+# define __cpp_lib_constexpr_complex 201711L
# define __cpp_lib_constexpr_dynamic_alloc 201907L
# define __cpp_lib_constexpr_functional 201907L
# define __cpp_lib_constexpr_iterator 201811L
@@ -362,8 +364,8 @@ __cpp_lib_void_t 201411L <type_traits>
# endif
# define __cpp_lib_list_remove_return_type 201806L
# define __cpp_lib_math_constants 201907L
-// # define __cpp_lib_polymorphic_allocator 201902L
-# define __cpp_lib_ranges 201811L
+# define __cpp_lib_polymorphic_allocator 201902L
+# define __cpp_lib_ranges 202106L
# define __cpp_lib_remove_cvref 201711L
# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore)
# define __cpp_lib_semaphore 201907L
@@ -372,7 +374,9 @@ __cpp_lib_void_t 201411L <type_traits>
# define __cpp_lib_shared_ptr_arrays 201707L
# define __cpp_lib_shift 201806L
// # define __cpp_lib_smart_ptr_for_overwrite 202002L
-// # define __cpp_lib_source_location 201907L
+# if __has_builtin(__builtin_source_location) && !(defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER <= 1403)
+# define __cpp_lib_source_location 201907L
+# endif
# define __cpp_lib_span 202002L
# define __cpp_lib_ssize 201902L
# define __cpp_lib_starts_ends_with 201711L
@@ -398,6 +402,7 @@ __cpp_lib_void_t 201411L <type_traits>
# undef __cpp_lib_constexpr_memory
# define __cpp_lib_constexpr_memory 202202L
// # define __cpp_lib_constexpr_typeinfo 202106L
+# define __cpp_lib_expected 202202L
# define __cpp_lib_forward_like 202207L
// # define __cpp_lib_invoke_r 202106L
# define __cpp_lib_is_scoped_enum 202011L
@@ -405,6 +410,7 @@ __cpp_lib_void_t 201411L <type_traits>
# undef __cpp_lib_optional
# define __cpp_lib_optional 202110L
// # define __cpp_lib_out_ptr 202106L
+# define __cpp_lib_ranges_as_rvalue 202207L
// # define __cpp_lib_ranges_chunk 202202L
// # define __cpp_lib_ranges_chunk_by 202202L
// # define __cpp_lib_ranges_iota 202202L
diff --git a/contrib/libs/cxxsupp/libcxx/src/atomic.cpp b/contrib/libs/cxxsupp/libcxx/src/atomic.cpp
index ec7bb7d9b2..7777e888c0 100644
--- a/contrib/libs/cxxsupp/libcxx/src/atomic.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/atomic.cpp
@@ -26,6 +26,11 @@
# define SYS_futex SYS_futex_time64
#endif
+#elif defined(__FreeBSD__)
+
+#include <sys/types.h>
+#include <sys/umtx.h>
+
#else // <- Add other operating systems here
// Baseline needs no new headers
@@ -72,6 +77,22 @@ static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const vo
const_cast<__cxx_atomic_contention_t*>(__ptr), 0);
}
+#elif defined(__FreeBSD__)
+
+static void __libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr,
+ __cxx_contention_t __val)
+{
+ _umtx_op(const_cast<__cxx_atomic_contention_t*>(__ptr),
+ UMTX_OP_WAIT_UINT_PRIVATE, __val, NULL, NULL);
+}
+
+static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile* __ptr,
+ bool __notify_one)
+{
+ _umtx_op(const_cast<__cxx_atomic_contention_t*>(__ptr),
+ UMTX_OP_WAKE_PRIVATE, __notify_one ? 1 : INT_MAX, NULL, NULL);
+}
+
#else // <- Add other operating systems here
// Baseline is just a timed backoff
diff --git a/contrib/libs/cxxsupp/libcxx/src/memory_resource.cpp b/contrib/libs/cxxsupp/libcxx/src/memory_resource.cpp
index d4a735b423..e00611dd1c 100644
--- a/contrib/libs/cxxsupp/libcxx/src/memory_resource.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/memory_resource.cpp
@@ -410,23 +410,39 @@ bool synchronized_pool_resource::do_is_equal(const memory_resource& other) const
// 23.12.6, mem.res.monotonic.buffer
+static void* align_down(size_t align, size_t size, void*& ptr, size_t& space) {
+ if (size > space)
+ return nullptr;
+
+ char* p1 = static_cast<char*>(ptr);
+ char* new_ptr = reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(p1 - size) & ~(align - 1));
+
+ if (new_ptr < (p1 - space))
+ return nullptr;
+
+ ptr = new_ptr;
+ space -= p1 - new_ptr;
+
+ return ptr;
+}
+
void* monotonic_buffer_resource::__initial_descriptor::__try_allocate_from_chunk(size_t bytes, size_t align) {
if (!__cur_)
return nullptr;
void* new_ptr = static_cast<void*>(__cur_);
- size_t new_capacity = (__end_ - __cur_);
- void* aligned_ptr = std::align(align, bytes, new_ptr, new_capacity);
+ size_t new_capacity = (__cur_ - __start_);
+ void* aligned_ptr = align_down(align, bytes, new_ptr, new_capacity);
if (aligned_ptr != nullptr)
- __cur_ = static_cast<char*>(new_ptr) + bytes;
+ __cur_ = static_cast<char*>(new_ptr);
return aligned_ptr;
}
void* monotonic_buffer_resource::__chunk_footer::__try_allocate_from_chunk(size_t bytes, size_t align) {
void* new_ptr = static_cast<void*>(__cur_);
- size_t new_capacity = (reinterpret_cast<char*>(this) - __cur_);
- void* aligned_ptr = std::align(align, bytes, new_ptr, new_capacity);
+ size_t new_capacity = (__cur_ - __start_);
+ void* aligned_ptr = align_down(align, bytes, new_ptr, new_capacity);
if (aligned_ptr != nullptr)
- __cur_ = static_cast<char*>(new_ptr) + bytes;
+ __cur_ = static_cast<char*>(new_ptr);
return aligned_ptr;
}
@@ -464,10 +480,11 @@ void* monotonic_buffer_resource::do_allocate(size_t bytes, size_t align) {
}
char* start = (char*)__res_->allocate(aligned_capacity, align);
- __chunk_footer* footer = (__chunk_footer*)(start + aligned_capacity - footer_size);
+ auto end = start + aligned_capacity - footer_size;
+ __chunk_footer* footer = (__chunk_footer*)(end);
footer->__next_ = __chunks_;
footer->__start_ = start;
- footer->__cur_ = start;
+ footer->__cur_ = end;
footer->__align_ = align;
__chunks_ = footer;
diff --git a/contrib/libs/cxxsupp/libcxx/src/thread.cpp b/contrib/libs/cxxsupp/libcxx/src/thread.cpp
index ce2822dbac..ec4f65f982 100644
--- a/contrib/libs/cxxsupp/libcxx/src/thread.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/thread.cpp
@@ -164,8 +164,8 @@ __thread_struct_imp::~__thread_struct_imp()
for (_Notify::iterator i = notify_.begin(), e = notify_.end();
i != e; ++i)
{
- i->second->unlock();
i->first->notify_all();
+ i->second->unlock();
}
for (_AsyncStates::iterator i = async_states_.begin(), e = async_states_.end();
i != e; ++i)
diff --git a/contrib/libs/cxxsupp/libcxx/ya.make b/contrib/libs/cxxsupp/libcxx/ya.make
index 56dc15f5c1..a1e7dad497 100644
--- a/contrib/libs/cxxsupp/libcxx/ya.make
+++ b/contrib/libs/cxxsupp/libcxx/ya.make
@@ -14,9 +14,9 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(2022-12-06)
+VERSION(2023-06-02)
-ORIGINAL_SOURCE(https://github.com/llvm/llvm-project/archive/96d63993dd3698bbf2d6a83c035cd05faed7317b.tar.gz)
+ORIGINAL_SOURCE(https://github.com/llvm/llvm-project/archive/185b81e034ba60081023b6e59504dfffb560f3e3.tar.gz)
ADDINCL(
GLOBAL contrib/libs/cxxsupp/libcxx/include
diff --git a/contrib/libs/opentelemetry-proto/CHANGELOG.md b/contrib/libs/opentelemetry-proto/CHANGELOG.md
index bca0bb7ae3..ab793a015e 100644
--- a/contrib/libs/opentelemetry-proto/CHANGELOG.md
+++ b/contrib/libs/opentelemetry-proto/CHANGELOG.md
@@ -2,7 +2,35 @@
## Unreleased
-Full list of differences found in [this compare](https://github.com/open-telemetry/opentelemetry-proto/compare/v0.20.0...main).
+Full list of differences found in [this compare](https://github.com/open-telemetry/opentelemetry-proto/compare/v1.1.0...main).
+
+## 1.1.0 - 2024-01-10
+
+Full list of differences found in [this compare](https://github.com/open-telemetry/opentelemetry-proto/compare/v1.0.0...v1.1.0).
+
+### Added
+
+* Add `flags` field to `Span` and `Span/Link` for W3C-specified Trace Context flags .
+ [#503](https://github.com/open-telemetry/opentelemetry-proto/pull/503)
+
+### Changed
+
+* Update and fix OTLP JSON examples. [#516](https://github.com/open-telemetry/opentelemetry-proto/pull/516),
+ [#510](https://github.com/open-telemetry/opentelemetry-proto/pull/510),
+ [#499](https://github.com/open-telemetry/opentelemetry-proto/pull/499)
+* Remove irrelevant comments from metric name field. [#512](https://github.com/open-telemetry/opentelemetry-proto/pull/512)
+* Add comment to explain schema_url fields. [#504](https://github.com/open-telemetry/opentelemetry-proto/pull/504)
+
+## 1.0.0 - 2023-07-03
+
+Full list of differences found in [this compare](https://github.com/open-telemetry/opentelemetry-proto/compare/v0.20.0...v1.0.0).
+
+### Maturity
+
+* Add note about the possibility to have unstable components after 1.0.0
+ [#489](https://github.com/open-telemetry/opentelemetry-proto/pull/489)
+* Add maturity JSON entry per package
+ [#490](https://github.com/open-telemetry/opentelemetry-proto/pull/490)
## 0.20.0 - 2023-06-06
@@ -47,7 +75,7 @@ Full list of differences found in [this compare](https://github.com/open-telemet
* Add `csharp_namespace` option to protos.
([#399](https://github.com/open-telemetry/opentelemetry-proto/pull/399))
* Fix some out-of-date urls which link to [specification](https://github.com/open-telemetry/opentelemetry-specification). ([#402](https://github.com/open-telemetry/opentelemetry-proto/pull/402))
-* :stop_sign: [BREAKING] Delete deprecated InstrumentationLibrary,
+* :stop_sign: [BREAKING] Delete deprecated InstrumentationLibrary,
InstrumentationLibraryLogs, InstrumentationLibrarySpans and
InstrumentationLibraryMetrics messages. Delete deprecated
instrumentation_library_logs, instrumentation_library_spans and
@@ -126,7 +154,7 @@ Full list of differences found in [this compare](https://github.com/open-telemet
* Remove unused deprecated message StringKeyValue (#358)
* Remove experimental metrics config service (#359)
-
+
## 0.12.0 - 2022-01-19
Full list of differences found in [this compare](https://github.com/open-telemetry/opentelemetry-proto/compare/v0.11.0...v0.12.0).
@@ -277,9 +305,9 @@ Full list of differences found in [this compare.](https://github.com/open-teleme
### Changed
* :stop_sign: [BREAKING] Metrics - protocol was refactored, and lots of breaking changes.
-** Removed MetricDescriptor and embedded into Metric and the new data types.
-** Add new data types Gauge/Sum/Histogram.
-** Make use of the "AggregationTemporality" into the data types that allow that support.
+ * Removed MetricDescriptor and embedded into Metric and the new data types.
+ * Add new data types Gauge/Sum/Histogram.
+ * Make use of the "AggregationTemporality" into the data types that allow that support.
* Rename enum values to follow the proto3 style guide.
### Added
diff --git a/contrib/libs/opentelemetry-proto/opentelemetry/proto/logs/v1/logs.proto b/contrib/libs/opentelemetry-proto/opentelemetry/proto/logs/v1/logs.proto
index 0b4b649729..f9b97dd745 100644
--- a/contrib/libs/opentelemetry-proto/opentelemetry/proto/logs/v1/logs.proto
+++ b/contrib/libs/opentelemetry-proto/opentelemetry/proto/logs/v1/logs.proto
@@ -55,6 +55,9 @@ message ResourceLogs {
// A list of ScopeLogs that originate from a resource.
repeated ScopeLogs scope_logs = 2;
+ // The Schema URL, if known. This is the identifier of the Schema that the resource data
+ // is recorded in. To learn more about Schema URL see
+ // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url
// This schema_url applies to the data in the "resource" field. It does not apply
// to the data in the "scope_logs" field which have their own schema_url field.
string schema_url = 3;
@@ -70,6 +73,9 @@ message ScopeLogs {
// A list of log records.
repeated LogRecord log_records = 2;
+ // The Schema URL, if known. This is the identifier of the Schema that the log data
+ // is recorded in. To learn more about Schema URL see
+ // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url
// This schema_url applies to all logs in the "logs" field.
string schema_url = 3;
}
@@ -104,9 +110,11 @@ enum SeverityNumber {
SEVERITY_NUMBER_FATAL4 = 24;
}
-// LogRecordFlags is defined as a protobuf 'uint32' type and is to be used as
-// bit-fields. Each non-zero value defined in this enum is a bit-mask.
-// To extract the bit-field, for example, use an expression like:
+// LogRecordFlags represents constants used to interpret the
+// LogRecord.flags field, which is protobuf 'fixed32' type and is to
+// be used as bit-fields. Each non-zero value defined in this enum is
+// a bit-mask. To extract the bit-field, for example, use an
+// expression like:
//
// (logRecord.flags & LOG_RECORD_FLAGS_TRACE_FLAGS_MASK)
//
diff --git a/contrib/libs/opentelemetry-proto/opentelemetry/proto/metrics/v1/metrics.proto b/contrib/libs/opentelemetry-proto/opentelemetry/proto/metrics/v1/metrics.proto
index da986dda18..3394aee933 100644
--- a/contrib/libs/opentelemetry-proto/opentelemetry/proto/metrics/v1/metrics.proto
+++ b/contrib/libs/opentelemetry-proto/opentelemetry/proto/metrics/v1/metrics.proto
@@ -55,6 +55,9 @@ message ResourceMetrics {
// A list of metrics that originate from a resource.
repeated ScopeMetrics scope_metrics = 2;
+ // The Schema URL, if known. This is the identifier of the Schema that the resource data
+ // is recorded in. To learn more about Schema URL see
+ // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url
// This schema_url applies to the data in the "resource" field. It does not apply
// to the data in the "scope_metrics" field which have their own schema_url field.
string schema_url = 3;
@@ -70,6 +73,9 @@ message ScopeMetrics {
// A list of metrics that originate from an instrumentation library.
repeated Metric metrics = 2;
+ // The Schema URL, if known. This is the identifier of the Schema that the metric data
+ // is recorded in. To learn more about Schema URL see
+ // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url
// This schema_url applies to all metrics in the "metrics" field.
string schema_url = 3;
}
@@ -162,7 +168,7 @@ message ScopeMetrics {
message Metric {
reserved 4, 6, 8;
- // name of the metric, including its DNS name prefix. It must be unique.
+ // name of the metric.
string name = 1;
// description of the metric, which can be used in documentation.
diff --git a/contrib/libs/opentelemetry-proto/opentelemetry/proto/trace/v1/trace.proto b/contrib/libs/opentelemetry-proto/opentelemetry/proto/trace/v1/trace.proto
index b2869edc42..a1fdfa3ac9 100644
--- a/contrib/libs/opentelemetry-proto/opentelemetry/proto/trace/v1/trace.proto
+++ b/contrib/libs/opentelemetry-proto/opentelemetry/proto/trace/v1/trace.proto
@@ -55,6 +55,9 @@ message ResourceSpans {
// A list of ScopeSpans that originate from a resource.
repeated ScopeSpans scope_spans = 2;
+ // The Schema URL, if known. This is the identifier of the Schema that the resource data
+ // is recorded in. To learn more about Schema URL see
+ // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url
// This schema_url applies to the data in the "resource" field. It does not apply
// to the data in the "scope_spans" field which have their own schema_url field.
string schema_url = 3;
@@ -70,6 +73,9 @@ message ScopeSpans {
// A list of Spans that originate from an instrumentation scope.
repeated Span spans = 2;
+ // The Schema URL, if known. This is the identifier of the Schema that the span data
+ // is recorded in. To learn more about Schema URL see
+ // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url
// This schema_url applies to all spans and span events in the "spans" field.
string schema_url = 3;
}
@@ -103,6 +109,22 @@ message Span {
// field must be empty. The ID is an 8-byte array.
bytes parent_span_id = 4;
+ // Flags, a bit field. 8 least significant bits are the trace
+ // flags as defined in W3C Trace Context specification. Readers
+ // MUST not assume that 24 most significant bits will be zero.
+ // To read the 8-bit W3C trace flag, use `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`.
+ //
+ // When creating span messages, if the message is logically forwarded from another source
+ // with an equivalent flags fields (i.e., usually another OTLP span message), the field SHOULD
+ // be copied as-is. If creating from a source that does not have an equivalent flags field
+ // (such as a runtime representation of an OpenTelemetry span), the high 24 bits MUST
+ // be set to zero.
+ //
+ // [Optional].
+ //
+ // See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions.
+ fixed32 flags = 16;
+
// A description of the span's operation.
//
// For example, the name can be a qualified method name or a file name
@@ -236,6 +258,16 @@ message Span {
// dropped_attributes_count is the number of dropped attributes. If the value is 0,
// then no attributes were dropped.
uint32 dropped_attributes_count = 5;
+
+ // Flags, a bit field. 8 least significant bits are the trace
+ // flags as defined in W3C Trace Context specification. Readers
+ // MUST not assume that 24 most significant bits will be zero.
+ // When creating new spans, the most-significant 24-bits MUST be
+ // zero. To read the 8-bit W3C trace flag (use flags &
+ // SPAN_FLAGS_TRACE_FLAGS_MASK). [Optional].
+ //
+ // See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions.
+ fixed32 flags = 6;
}
// links is a collection of Links, which are references from this span to a span
@@ -274,3 +306,28 @@ message Status {
// The status code.
StatusCode code = 3;
}
+
+// SpanFlags represents constants used to interpret the
+// Span.flags field, which is protobuf 'fixed32' type and is to
+// be used as bit-fields. Each non-zero value defined in this enum is
+// a bit-mask. To extract the bit-field, for example, use an
+// expression like:
+//
+// (span.flags & SPAN_FLAGS_TRACE_FLAGS_MASK)
+//
+// See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions.
+//
+// Note that Span flags were introduced in version 1.1 of the
+// OpenTelemetry protocol. Older Span producers do not set this
+// field, consequently consumers should not rely on the absence of a
+// particular flag bit to indicate the presence of a particular feature.
+enum SpanFlags {
+ // The zero value for the enum. Should not be used for comparisons.
+ // Instead use bitwise "and" with the appropriate mask as shown above.
+ SPAN_FLAGS_DO_NOT_USE = 0;
+
+ // Bits 0-7 are used for trace flags.
+ SPAN_FLAGS_TRACE_FLAGS_MASK = 0x000000FF;
+
+ // Bits 8-31 are reserved for future use.
+}
diff --git a/contrib/libs/opentelemetry-proto/ya.make b/contrib/libs/opentelemetry-proto/ya.make
index 84c5759554..14dfa177e8 100644
--- a/contrib/libs/opentelemetry-proto/ya.make
+++ b/contrib/libs/opentelemetry-proto/ya.make
@@ -6,9 +6,9 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(1.0.0)
+VERSION(1.1.0)
-ORIGINAL_SOURCE(https://github.com/open-telemetry/opentelemetry-proto/archive/v1.0.0.tar.gz)
+ORIGINAL_SOURCE(https://github.com/open-telemetry/opentelemetry-proto/archive/v1.1.0.tar.gz)
PY_NAMESPACE(.)
diff --git a/contrib/python/Jinja2/py3/.dist-info/METADATA b/contrib/python/Jinja2/py3/.dist-info/METADATA
index f54bb5ca1a..56e942902a 100644
--- a/contrib/python/Jinja2/py3/.dist-info/METADATA
+++ b/contrib/python/Jinja2/py3/.dist-info/METADATA
@@ -1,10 +1,8 @@
Metadata-Version: 2.1
Name: Jinja2
-Version: 3.1.2
+Version: 3.1.3
Summary: A very fast and expressive template engine.
Home-page: https://palletsprojects.com/p/jinja/
-Author: Armin Ronacher
-Author-email: armin.ronacher@active-4.com
Maintainer: Pallets
Maintainer-email: contact@palletsprojects.com
License: BSD-3-Clause
@@ -13,9 +11,7 @@ Project-URL: Documentation, https://jinja.palletsprojects.com/
Project-URL: Changes, https://jinja.palletsprojects.com/changes/
Project-URL: Source Code, https://github.com/pallets/jinja/
Project-URL: Issue Tracker, https://github.com/pallets/jinja/issues/
-Project-URL: Twitter, https://twitter.com/PalletsTeam
Project-URL: Chat, https://discord.gg/pallets
-Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
@@ -27,9 +23,9 @@ Classifier: Topic :: Text Processing :: Markup :: HTML
Requires-Python: >=3.7
Description-Content-Type: text/x-rst
License-File: LICENSE.rst
-Requires-Dist: MarkupSafe (>=2.0)
+Requires-Dist: MarkupSafe >=2.0
Provides-Extra: i18n
-Requires-Dist: Babel (>=2.7) ; extra == 'i18n'
+Requires-Dist: Babel >=2.7 ; extra == 'i18n'
Jinja
=====
@@ -106,8 +102,4 @@ Links
- PyPI Releases: https://pypi.org/project/Jinja2/
- Source Code: https://github.com/pallets/jinja/
- Issue Tracker: https://github.com/pallets/jinja/issues/
-- Website: https://palletsprojects.com/p/jinja/
-- Twitter: https://twitter.com/PalletsTeam
- Chat: https://discord.gg/pallets
-
-
diff --git a/contrib/python/Jinja2/py3/README.rst b/contrib/python/Jinja2/py3/README.rst
index a197aea647..94b22ecabe 100644
--- a/contrib/python/Jinja2/py3/README.rst
+++ b/contrib/python/Jinja2/py3/README.rst
@@ -73,6 +73,4 @@ Links
- PyPI Releases: https://pypi.org/project/Jinja2/
- Source Code: https://github.com/pallets/jinja/
- Issue Tracker: https://github.com/pallets/jinja/issues/
-- Website: https://palletsprojects.com/p/jinja/
-- Twitter: https://twitter.com/PalletsTeam
- Chat: https://discord.gg/pallets
diff --git a/contrib/python/Jinja2/py3/jinja2/__init__.py b/contrib/python/Jinja2/py3/jinja2/__init__.py
index a684093795..8076e72cd1 100644
--- a/contrib/python/Jinja2/py3/jinja2/__init__.py
+++ b/contrib/python/Jinja2/py3/jinja2/__init__.py
@@ -35,4 +35,4 @@ from .utils import pass_environment as pass_environment
from .utils import pass_eval_context as pass_eval_context
from .utils import select_autoescape as select_autoescape
-__version__ = "3.1.2"
+__version__ = "3.1.3"
diff --git a/contrib/python/Jinja2/py3/jinja2/async_utils.py b/contrib/python/Jinja2/py3/jinja2/async_utils.py
index 1a4f3892ce..715d70119b 100644
--- a/contrib/python/Jinja2/py3/jinja2/async_utils.py
+++ b/contrib/python/Jinja2/py3/jinja2/async_utils.py
@@ -74,7 +74,7 @@ async def auto_aiter(
async for item in t.cast("t.AsyncIterable[V]", iterable):
yield item
else:
- for item in t.cast("t.Iterable[V]", iterable):
+ for item in iterable:
yield item
diff --git a/contrib/python/Jinja2/py3/jinja2/compiler.py b/contrib/python/Jinja2/py3/jinja2/compiler.py
index 3458095f54..ff95c807b0 100644
--- a/contrib/python/Jinja2/py3/jinja2/compiler.py
+++ b/contrib/python/Jinja2/py3/jinja2/compiler.py
@@ -993,7 +993,6 @@ class CodeGenerator(NodeVisitor):
# far, we don't have to add a check if something extended
# the template before this one.
if self.extends_so_far > 0:
-
# if we have a known extends we just add a template runtime
# error into the generated code. We could catch that at compile
# time too, but i welcome it not to confuse users by throwing the
@@ -1407,7 +1406,7 @@ class CodeGenerator(NodeVisitor):
if pass_arg is None:
- def finalize(value: t.Any) -> t.Any:
+ def finalize(value: t.Any) -> t.Any: # noqa: F811
return default(env_finalize(value))
else:
@@ -1415,7 +1414,7 @@ class CodeGenerator(NodeVisitor):
if pass_arg == "environment":
- def finalize(value: t.Any) -> t.Any:
+ def finalize(value: t.Any) -> t.Any: # noqa: F811
return default(env_finalize(self.environment, value))
self._finalize = self._FinalizeInfo(finalize, src)
diff --git a/contrib/python/Jinja2/py3/jinja2/environment.py b/contrib/python/Jinja2/py3/jinja2/environment.py
index ea04e8b443..185d33246e 100644
--- a/contrib/python/Jinja2/py3/jinja2/environment.py
+++ b/contrib/python/Jinja2/py3/jinja2/environment.py
@@ -701,7 +701,7 @@ class Environment:
.. versionadded:: 2.5
"""
- return compile(source, filename, "exec") # type: ignore
+ return compile(source, filename, "exec")
@typing.overload
def compile( # type: ignore
@@ -920,7 +920,7 @@ class Environment:
)
def filter_func(x: str) -> bool:
- return "." in x and x.rsplit(".", 1)[1] in extensions # type: ignore
+ return "." in x and x.rsplit(".", 1)[1] in extensions
if filter_func is not None:
names = [name for name in names if filter_func(name)]
@@ -1253,7 +1253,7 @@ class Template:
t.blocks = namespace["blocks"]
# render function and module
- t.root_render_func = namespace["root"] # type: ignore
+ t.root_render_func = namespace["root"]
t._module = None
# debug and loader helpers
@@ -1349,7 +1349,7 @@ class Template:
ctx = self.new_context(dict(*args, **kwargs))
try:
- yield from self.root_render_func(ctx) # type: ignore
+ yield from self.root_render_func(ctx)
except Exception:
yield self.environment.handle_exception()
@@ -1532,7 +1532,7 @@ class TemplateModule:
" API you are using."
)
- body_stream = list(template.root_render_func(context)) # type: ignore
+ body_stream = list(template.root_render_func(context))
self._body_stream = body_stream
self.__dict__.update(context.get_exported())
@@ -1564,7 +1564,7 @@ class TemplateExpression:
def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Optional[t.Any]:
context = self._template.new_context(dict(*args, **kwargs))
- consume(self._template.root_render_func(context)) # type: ignore
+ consume(self._template.root_render_func(context))
rv = context.vars["result"]
if self._undefined_to_none and isinstance(rv, Undefined):
rv = None
diff --git a/contrib/python/Jinja2/py3/jinja2/ext.py b/contrib/python/Jinja2/py3/jinja2/ext.py
index d5550540cd..fade1fa3bc 100644
--- a/contrib/python/Jinja2/py3/jinja2/ext.py
+++ b/contrib/python/Jinja2/py3/jinja2/ext.py
@@ -291,14 +291,14 @@ class InternationalizationExtension(Extension):
if hasattr(translations, "pgettext"):
# Python < 3.8
- pgettext = translations.pgettext # type: ignore
+ pgettext = translations.pgettext
else:
def pgettext(c: str, s: str) -> str:
return s
if hasattr(translations, "npgettext"):
- npgettext = translations.npgettext # type: ignore
+ npgettext = translations.npgettext
else:
def npgettext(c: str, s: str, p: str, n: int) -> str:
@@ -495,16 +495,26 @@ class InternationalizationExtension(Extension):
parser.stream.expect("variable_end")
elif parser.stream.current.type == "block_begin":
next(parser.stream)
- if parser.stream.current.test("name:endtrans"):
+ block_name = (
+ parser.stream.current.value
+ if parser.stream.current.type == "name"
+ else None
+ )
+ if block_name == "endtrans":
break
- elif parser.stream.current.test("name:pluralize"):
+ elif block_name == "pluralize":
if allow_pluralize:
break
parser.fail(
"a translatable section can have only one pluralize section"
)
+ elif block_name == "trans":
+ parser.fail(
+ "trans blocks can't be nested; did you mean `endtrans`?"
+ )
parser.fail(
- "control structures in translatable sections are not allowed"
+ f"control structures in translatable sections are not allowed; "
+ f"saw `{block_name}`"
)
elif parser.stream.eos:
parser.fail("unclosed translation block")
diff --git a/contrib/python/Jinja2/py3/jinja2/filters.py b/contrib/python/Jinja2/py3/jinja2/filters.py
index ed07c4c0e2..c7ecc9bb68 100644
--- a/contrib/python/Jinja2/py3/jinja2/filters.py
+++ b/contrib/python/Jinja2/py3/jinja2/filters.py
@@ -248,13 +248,17 @@ def do_items(value: t.Union[t.Mapping[K, V], Undefined]) -> t.Iterator[t.Tuple[K
yield from value.items()
+_space_re = re.compile(r"\s", flags=re.ASCII)
+
+
@pass_eval_context
def do_xmlattr(
eval_ctx: "EvalContext", d: t.Mapping[str, t.Any], autospace: bool = True
) -> str:
"""Create an SGML/XML attribute string based on the items in a dict.
- All values that are neither `none` nor `undefined` are automatically
- escaped:
+
+ If any key contains a space, this fails with a ``ValueError``. Values that
+ are neither ``none`` nor ``undefined`` are automatically escaped.
.. sourcecode:: html+jinja
@@ -273,12 +277,22 @@ def do_xmlattr(
As you can see it automatically prepends a space in front of the item
if the filter returned something unless the second parameter is false.
+
+ .. versionchanged:: 3.1.3
+ Keys with spaces are not allowed.
"""
- rv = " ".join(
- f'{escape(key)}="{escape(value)}"'
- for key, value in d.items()
- if value is not None and not isinstance(value, Undefined)
- )
+ items = []
+
+ for key, value in d.items():
+ if value is None or isinstance(value, Undefined):
+ continue
+
+ if _space_re.search(key) is not None:
+ raise ValueError(f"Spaces are not allowed in attributes: '{key}'")
+
+ items.append(f'{escape(key)}="{escape(value)}"')
+
+ rv = " ".join(items)
if autospace and rv:
rv = " " + rv
diff --git a/contrib/python/Jinja2/py3/jinja2/loaders.py b/contrib/python/Jinja2/py3/jinja2/loaders.py
index 261802176a..dfa2ad7ec5 100644
--- a/contrib/python/Jinja2/py3/jinja2/loaders.py
+++ b/contrib/python/Jinja2/py3/jinja2/loaders.py
@@ -16,7 +16,6 @@ from types import ModuleType
from .exceptions import TemplateNotFound
from .utils import internalcode
-from .utils import open_if_exists
if t.TYPE_CHECKING:
from .environment import Environment
@@ -196,29 +195,30 @@ class FileSystemLoader(BaseLoader):
self, environment: "Environment", template: str
) -> t.Tuple[str, str, t.Callable[[], bool]]:
pieces = split_template_path(template)
+
for searchpath in self.searchpath:
# Use posixpath even on Windows to avoid "drive:" or UNC
# segments breaking out of the search directory.
filename = posixpath.join(searchpath, *pieces)
- f = open_if_exists(filename)
- if f is None:
- continue
- try:
- contents = f.read().decode(self.encoding)
- finally:
- f.close()
- mtime = os.path.getmtime(filename)
+ if os.path.isfile(filename):
+ break
+ else:
+ raise TemplateNotFound(template)
- def uptodate() -> bool:
- try:
- return os.path.getmtime(filename) == mtime
- except OSError:
- return False
+ with open(filename, encoding=self.encoding) as f:
+ contents = f.read()
- # Use normpath to convert Windows altsep to sep.
- return contents, os.path.normpath(filename), uptodate
- raise TemplateNotFound(template)
+ mtime = os.path.getmtime(filename)
+
+ def uptodate() -> bool:
+ try:
+ return os.path.getmtime(filename) == mtime
+ except OSError:
+ return False
+
+ # Use normpath to convert Windows altsep to sep.
+ return contents, os.path.normpath(filename), uptodate
def list_templates(self) -> t.List[str]:
found = set()
@@ -412,7 +412,7 @@ class PackageLoader(BaseLoader):
)
offset = len(prefix)
- for name in self._loader._files.keys(): # type: ignore
+ for name in self._loader._files.keys():
# Find names under the templates directory that aren't directories.
if name.startswith(prefix) and name[-1] != os.path.sep:
results.append(name[offset:].replace(os.path.sep, "/"))
diff --git a/contrib/python/Jinja2/py3/jinja2/nativetypes.py b/contrib/python/Jinja2/py3/jinja2/nativetypes.py
index ac08610348..71db8cc31f 100644
--- a/contrib/python/Jinja2/py3/jinja2/nativetypes.py
+++ b/contrib/python/Jinja2/py3/jinja2/nativetypes.py
@@ -106,7 +106,7 @@ class NativeTemplate(Template):
try:
return self.environment_class.concat( # type: ignore
- self.root_render_func(ctx) # type: ignore
+ self.root_render_func(ctx)
)
except Exception:
return self.environment.handle_exception()
diff --git a/contrib/python/Jinja2/py3/jinja2/parser.py b/contrib/python/Jinja2/py3/jinja2/parser.py
index cefce2dfa1..3354bc9339 100644
--- a/contrib/python/Jinja2/py3/jinja2/parser.py
+++ b/contrib/python/Jinja2/py3/jinja2/parser.py
@@ -311,12 +311,14 @@ class Parser:
# enforce that required blocks only contain whitespace or comments
# by asserting that the body, if not empty, is just TemplateData nodes
# with whitespace data
- if node.required and not all(
- isinstance(child, nodes.TemplateData) and child.data.isspace()
- for body in node.body
- for child in body.nodes # type: ignore
- ):
- self.fail("Required blocks can only contain comments or whitespace")
+ if node.required:
+ for body_node in node.body:
+ if not isinstance(body_node, nodes.Output) or any(
+ not isinstance(output_node, nodes.TemplateData)
+ or not output_node.data.isspace()
+ for output_node in body_node.nodes
+ ):
+ self.fail("Required blocks can only contain comments or whitespace")
self.stream.skip_if("name:" + node.name)
return node
@@ -857,7 +859,7 @@ class Parser:
else:
args.append(None)
- return nodes.Slice(lineno=lineno, *args)
+ return nodes.Slice(lineno=lineno, *args) # noqa: B026
def parse_call_args(self) -> t.Tuple:
token = self.stream.expect("lparen")
diff --git a/contrib/python/Jinja2/py3/jinja2/runtime.py b/contrib/python/Jinja2/py3/jinja2/runtime.py
index 985842b284..58a540ba3f 100644
--- a/contrib/python/Jinja2/py3/jinja2/runtime.py
+++ b/contrib/python/Jinja2/py3/jinja2/runtime.py
@@ -272,9 +272,9 @@ class Context:
# Allow callable classes to take a context
if (
hasattr(__obj, "__call__") # noqa: B004
- and _PassArg.from_obj(__obj.__call__) is not None # type: ignore
+ and _PassArg.from_obj(__obj.__call__) is not None
):
- __obj = __obj.__call__ # type: ignore
+ __obj = __obj.__call__
pass_arg = _PassArg.from_obj(__obj)
@@ -927,9 +927,7 @@ def make_logging_undefined(
logger.addHandler(logging.StreamHandler(sys.stderr))
def _log_message(undef: Undefined) -> None:
- logger.warning( # type: ignore
- "Template variable warning: %s", undef._undefined_message
- )
+ logger.warning("Template variable warning: %s", undef._undefined_message)
class LoggingUndefined(base): # type: ignore
__slots__ = ()
diff --git a/contrib/python/Jinja2/py3/jinja2/utils.py b/contrib/python/Jinja2/py3/jinja2/utils.py
index 9b5f5a50eb..18914a58fd 100644
--- a/contrib/python/Jinja2/py3/jinja2/utils.py
+++ b/contrib/python/Jinja2/py3/jinja2/utils.py
@@ -182,7 +182,7 @@ def object_type_repr(obj: t.Any) -> str:
def pformat(obj: t.Any) -> str:
"""Format an object using :func:`pprint.pformat`."""
- from pprint import pformat # type: ignore
+ from pprint import pformat
return pformat(obj)
@@ -259,7 +259,7 @@ def urlize(
if trim_url_limit is not None:
def trim_url(x: str) -> str:
- if len(x) > trim_url_limit: # type: ignore
+ if len(x) > trim_url_limit:
return f"{x[:trim_url_limit]}..."
return x
diff --git a/contrib/python/Jinja2/py3/tests/test_ext.py b/contrib/python/Jinja2/py3/tests/test_ext.py
index 2e842e0ab5..0b48ca2586 100644
--- a/contrib/python/Jinja2/py3/tests/test_ext.py
+++ b/contrib/python/Jinja2/py3/tests/test_ext.py
@@ -7,6 +7,7 @@ from jinja2 import DictLoader
from jinja2 import Environment
from jinja2 import nodes
from jinja2 import pass_context
+from jinja2 import TemplateSyntaxError
from jinja2.exceptions import TemplateAssertionError
from jinja2.ext import Extension
from jinja2.lexer import count_newlines
@@ -468,6 +469,18 @@ class TestInternationalization:
(3, "npgettext", ("babel", "%(users)s user", "%(users)s users", None), []),
]
+ def test_nested_trans_error(self):
+ s = "{% trans %}foo{% trans %}{% endtrans %}"
+ with pytest.raises(TemplateSyntaxError) as excinfo:
+ i18n_env.from_string(s)
+ assert "trans blocks can't be nested" in str(excinfo.value)
+
+ def test_trans_block_error(self):
+ s = "{% trans %}foo{% wibble bar %}{% endwibble %}{% endtrans %}"
+ with pytest.raises(TemplateSyntaxError) as excinfo:
+ i18n_env.from_string(s)
+ assert "saw `wibble`" in str(excinfo.value)
+
class TestScope:
def test_basic_scope_behavior(self):
diff --git a/contrib/python/Jinja2/py3/tests/test_filters.py b/contrib/python/Jinja2/py3/tests/test_filters.py
index 73f0f0be3c..f50ed13ab5 100644
--- a/contrib/python/Jinja2/py3/tests/test_filters.py
+++ b/contrib/python/Jinja2/py3/tests/test_filters.py
@@ -474,6 +474,12 @@ class TestFilter:
assert 'bar="23"' in out
assert 'blub:blub="&lt;?&gt;"' in out
+ def test_xmlattr_key_with_spaces(self, env):
+ with pytest.raises(ValueError, match="Spaces are not allowed"):
+ env.from_string(
+ "{{ {'src=1 onerror=alert(1)': 'my_class'}|xmlattr }}"
+ ).render()
+
def test_sort1(self, env):
tmpl = env.from_string("{{ [2, 3, 1]|sort }}|{{ [2, 3, 1]|sort(true) }}")
assert tmpl.render() == "[1, 2, 3]|[3, 2, 1]"
@@ -870,4 +876,6 @@ class TestFilter:
with pytest.raises(TemplateRuntimeError, match="No filter named 'f'"):
t1.render(x=42)
+
+ with pytest.raises(TemplateRuntimeError, match="No filter named 'f'"):
t2.render(x=42)
diff --git a/contrib/python/Jinja2/py3/tests/test_inheritance.py b/contrib/python/Jinja2/py3/tests/test_inheritance.py
index 0c20d4da7d..0a525e7ac9 100644
--- a/contrib/python/Jinja2/py3/tests/test_inheritance.py
+++ b/contrib/python/Jinja2/py3/tests/test_inheritance.py
@@ -287,26 +287,34 @@ class TestInheritance:
env = Environment(
loader=DictLoader(
{
- "default": "{% block x required %}data {# #}{% endblock %}",
- "default1": "{% block x required %}{% block y %}"
- "{% endblock %} {% endblock %}",
- "default2": "{% block x required %}{% if true %}"
- "{% endif %} {% endblock %}",
- "level1": "{% if default %}{% extends default %}"
- "{% else %}{% extends 'default' %}{% endif %}"
- "{%- block x %}CHILD{% endblock %}",
+ "empty": "{% block x required %}{% endblock %}",
+ "blank": "{% block x required %} {# c #}{% endblock %}",
+ "text": "{% block x required %}data {# c #}{% endblock %}",
+ "block": "{% block x required %}{% block y %}"
+ "{% endblock %}{% endblock %}",
+ "if": "{% block x required %}{% if true %}"
+ "{% endif %}{% endblock %}",
+ "top": "{% extends t %}{% block x %}CHILD{% endblock %}",
}
)
)
- t = env.get_template("level1")
+ t = env.get_template("top")
+ assert t.render(t="empty") == "CHILD"
+ assert t.render(t="blank") == "CHILD"
- with pytest.raises(
+ required_block_check = pytest.raises(
TemplateSyntaxError,
match="Required blocks can only contain comments or whitespace",
- ):
- assert t.render(default="default")
- assert t.render(default="default2")
- assert t.render(default="default3")
+ )
+
+ with required_block_check:
+ t.render(t="text")
+
+ with required_block_check:
+ t.render(t="block")
+
+ with required_block_check:
+ t.render(t="if")
def test_required_with_scope(self, env):
env = Environment(
@@ -347,8 +355,11 @@ class TestInheritance:
)
)
tmpl = env.get_template("child")
+
with pytest.raises(TemplateSyntaxError):
tmpl.render(default="default1", seq=list(range(3)))
+
+ with pytest.raises(TemplateSyntaxError):
tmpl.render(default="default2", seq=list(range(3)))
diff --git a/contrib/python/Jinja2/py3/tests/test_loader.py b/contrib/python/Jinja2/py3/tests/test_loader.py
index a396e18fec..d3b4ddf1ba 100644
--- a/contrib/python/Jinja2/py3/tests/test_loader.py
+++ b/contrib/python/Jinja2/py3/tests/test_loader.py
@@ -186,6 +186,7 @@ class TestFileSystemLoader:
class TestModuleLoader:
archive = None
+ mod_env = None
def compile_down(self, prefix_loader, zip="deflated"):
log = []
@@ -199,13 +200,14 @@ class TestModuleLoader:
self.mod_env = Environment(loader=loaders.ModuleLoader(self.archive))
return "".join(log)
- def teardown(self):
- if hasattr(self, "mod_env"):
+ def teardown_method(self):
+ if self.archive is not None:
if os.path.isfile(self.archive):
os.remove(self.archive)
else:
shutil.rmtree(self.archive)
self.archive = None
+ self.mod_env = None
def test_log(self, prefix_loader):
log = self.compile_down(prefix_loader)
diff --git a/contrib/python/Jinja2/py3/ya.make b/contrib/python/Jinja2/py3/ya.make
index 67ba20df0c..2c15cb57d4 100644
--- a/contrib/python/Jinja2/py3/ya.make
+++ b/contrib/python/Jinja2/py3/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(3.1.2)
+VERSION(3.1.3)
LICENSE(BSD-3-Clause)
diff --git a/contrib/python/fonttools/.dist-info/METADATA b/contrib/python/fonttools/.dist-info/METADATA
index f156c42697..f9e01c388f 100644
--- a/contrib/python/fonttools/.dist-info/METADATA
+++ b/contrib/python/fonttools/.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: fonttools
-Version: 4.47.0
+Version: 4.47.2
Summary: Tools to manipulate font files
Home-page: http://github.com/fonttools/fonttools
Author: Just van Rossum
@@ -375,6 +375,18 @@ Have fun!
Changelog
~~~~~~~~~
+4.47.2 (released 2024-01-11)
+----------------------------
+
+Minor release to fix uploading wheels to PyPI.
+
+4.47.1 (released 2024-01-11)
+----------------------------
+
+- [merge] Improve help message and add standard command line options (#3408)
+- [otlLib] Pass ``ttFont`` to ``name.addName`` in ``buildStatTable`` (#3406)
+- [featureVars] Re-use ``FeatureVariationRecord``'s when possible (#3413)
+
4.47.0 (released 2023-12-18)
----------------------------
diff --git a/contrib/python/fonttools/fontTools/__init__.py b/contrib/python/fonttools/fontTools/__init__.py
index 6c00e567a4..7410d3c7fe 100644
--- a/contrib/python/fonttools/fontTools/__init__.py
+++ b/contrib/python/fonttools/fontTools/__init__.py
@@ -3,6 +3,6 @@ from fontTools.misc.loggingTools import configLogger
log = logging.getLogger(__name__)
-version = __version__ = "4.47.0"
+version = __version__ = "4.47.2"
__all__ = ["version", "log", "configLogger"]
diff --git a/contrib/python/fonttools/fontTools/merge/__init__.py b/contrib/python/fonttools/fontTools/merge/__init__.py
index 8d8a5213e8..7653e4a079 100644
--- a/contrib/python/fonttools/fontTools/merge/__init__.py
+++ b/contrib/python/fonttools/fontTools/merge/__init__.py
@@ -139,6 +139,7 @@ class Merger(object):
*(vars(table).keys() for table in tables if table is not NotImplemented),
)
for key in allKeys:
+ log.info(" %s", key)
try:
mergeLogic = logic[key]
except KeyError:
@@ -181,17 +182,50 @@ def main(args=None):
args = sys.argv[1:]
options = Options()
- args = options.parse_opts(args, ignore_unknown=["output-file"])
- outfile = "merged.ttf"
+ args = options.parse_opts(args)
fontfiles = []
+ if options.input_file:
+ with open(options.input_file) as inputfile:
+ fontfiles = [
+ line.strip()
+ for line in inputfile.readlines()
+ if not line.lstrip().startswith("#")
+ ]
for g in args:
- if g.startswith("--output-file="):
- outfile = g[14:]
- continue
fontfiles.append(g)
- if len(args) < 1:
- print("usage: pyftmerge font...", file=sys.stderr)
+ if len(fontfiles) < 1:
+ print(
+ "usage: pyftmerge [font1 ... fontN] [--input-file=filelist.txt] [--output-file=merged.ttf] [--import-file=tables.ttx]",
+ file=sys.stderr,
+ )
+ print(
+ " [--drop-tables=tags] [--verbose] [--timing]",
+ file=sys.stderr,
+ )
+ print("", file=sys.stderr)
+ print(" font1 ... fontN Files to merge.", file=sys.stderr)
+ print(
+ " --input-file=<filename> Read files to merge from a text file, each path new line. # Comment lines allowed.",
+ file=sys.stderr,
+ )
+ print(
+ " --output-file=<filename> Specify output file name (default: merged.ttf).",
+ file=sys.stderr,
+ )
+ print(
+ " --import-file=<filename> TTX file to import after merging. This can be used to set metadata.",
+ file=sys.stderr,
+ )
+ print(
+ " --drop-tables=<table tags> Comma separated list of table tags to skip, case sensitive.",
+ file=sys.stderr,
+ )
+ print(
+ " --verbose Output progress information.",
+ file=sys.stderr,
+ )
+ print(" --timing Output progress timing.", file=sys.stderr)
return 1
configLogger(level=logging.INFO if options.verbose else logging.WARNING)
@@ -202,8 +236,12 @@ def main(args=None):
merger = Merger(options=options)
font = merger.merge(fontfiles)
+
+ if options.import_file:
+ font.importXML(options.import_file)
+
with timer("compile and save font"):
- font.save(outfile)
+ font.save(options.output_file)
if __name__ == "__main__":
diff --git a/contrib/python/fonttools/fontTools/merge/options.py b/contrib/python/fonttools/fontTools/merge/options.py
index f134009368..8bc8947138 100644
--- a/contrib/python/fonttools/fontTools/merge/options.py
+++ b/contrib/python/fonttools/fontTools/merge/options.py
@@ -11,6 +11,9 @@ class Options(object):
self.verbose = False
self.timing = False
self.drop_tables = []
+ self.input_file = None
+ self.output_file = "merged.ttf"
+ self.import_file = None
self.set(**kwargs)
diff --git a/contrib/python/fonttools/fontTools/otlLib/builder.py b/contrib/python/fonttools/fontTools/otlLib/builder.py
index 3508a7e28d..4b457f4d9f 100644
--- a/contrib/python/fonttools/fontTools/otlLib/builder.py
+++ b/contrib/python/fonttools/fontTools/otlLib/builder.py
@@ -2781,14 +2781,13 @@ def buildStatTable(
"""
ttFont["STAT"] = ttLib.newTable("STAT")
statTable = ttFont["STAT"].table = ot.STAT()
- nameTable = ttFont["name"]
statTable.ElidedFallbackNameID = _addName(
- nameTable, elidedFallbackName, windows=windowsNames, mac=macNames
+ ttFont, elidedFallbackName, windows=windowsNames, mac=macNames
)
# 'locations' contains data for AxisValue Format 4
axisRecords, axisValues = _buildAxisRecords(
- axes, nameTable, windowsNames=windowsNames, macNames=macNames
+ axes, ttFont, windowsNames=windowsNames, macNames=macNames
)
if not locations:
statTable.Version = 0x00010001
@@ -2797,10 +2796,10 @@ def buildStatTable(
# requires a higher table version
statTable.Version = 0x00010002
multiAxisValues = _buildAxisValuesFormat4(
- locations, axes, nameTable, windowsNames=windowsNames, macNames=macNames
+ locations, axes, ttFont, windowsNames=windowsNames, macNames=macNames
)
axisValues = multiAxisValues + axisValues
- nameTable.names.sort()
+ ttFont["name"].names.sort()
# Store AxisRecords
axisRecordArray = ot.AxisRecordArray()
@@ -2820,14 +2819,14 @@ def buildStatTable(
statTable.AxisValueCount = len(axisValues)
-def _buildAxisRecords(axes, nameTable, windowsNames=True, macNames=True):
+def _buildAxisRecords(axes, ttFont, windowsNames=True, macNames=True):
axisRecords = []
axisValues = []
for axisRecordIndex, axisDict in enumerate(axes):
axis = ot.AxisRecord()
axis.AxisTag = axisDict["tag"]
axis.AxisNameID = _addName(
- nameTable, axisDict["name"], 256, windows=windowsNames, mac=macNames
+ ttFont, axisDict["name"], 256, windows=windowsNames, mac=macNames
)
axis.AxisOrdering = axisDict.get("ordering", axisRecordIndex)
axisRecords.append(axis)
@@ -2837,7 +2836,7 @@ def _buildAxisRecords(axes, nameTable, windowsNames=True, macNames=True):
axisValRec.AxisIndex = axisRecordIndex
axisValRec.Flags = axisVal.get("flags", 0)
axisValRec.ValueNameID = _addName(
- nameTable, axisVal["name"], windows=windowsNames, mac=macNames
+ ttFont, axisVal["name"], windows=windowsNames, mac=macNames
)
if "value" in axisVal:
@@ -2863,9 +2862,7 @@ def _buildAxisRecords(axes, nameTable, windowsNames=True, macNames=True):
return axisRecords, axisValues
-def _buildAxisValuesFormat4(
- locations, axes, nameTable, windowsNames=True, macNames=True
-):
+def _buildAxisValuesFormat4(locations, axes, ttFont, windowsNames=True, macNames=True):
axisTagToIndex = {}
for axisRecordIndex, axisDict in enumerate(axes):
axisTagToIndex[axisDict["tag"]] = axisRecordIndex
@@ -2875,7 +2872,7 @@ def _buildAxisValuesFormat4(
axisValRec = ot.AxisValue()
axisValRec.Format = 4
axisValRec.ValueNameID = _addName(
- nameTable, axisLocationDict["name"], windows=windowsNames, mac=macNames
+ ttFont, axisLocationDict["name"], windows=windowsNames, mac=macNames
)
axisValRec.Flags = axisLocationDict.get("flags", 0)
axisValueRecords = []
@@ -2891,7 +2888,8 @@ def _buildAxisValuesFormat4(
return axisValues
-def _addName(nameTable, value, minNameID=0, windows=True, mac=True):
+def _addName(ttFont, value, minNameID=0, windows=True, mac=True):
+ nameTable = ttFont["name"]
if isinstance(value, int):
# Already a nameID
return value
@@ -2916,5 +2914,5 @@ def _addName(nameTable, value, minNameID=0, windows=True, mac=True):
else:
raise TypeError("value must be int, str, dict or list")
return nameTable.addMultilingualName(
- names, windows=windows, mac=mac, minNameID=minNameID
+ names, ttFont=ttFont, windows=windows, mac=mac, minNameID=minNameID
)
diff --git a/contrib/python/fonttools/fontTools/varLib/featureVars.py b/contrib/python/fonttools/fontTools/varLib/featureVars.py
index a6beb5c7d2..828b843594 100644
--- a/contrib/python/fonttools/fontTools/varLib/featureVars.py
+++ b/contrib/python/fonttools/fontTools/varLib/featureVars.py
@@ -414,6 +414,10 @@ def addFeatureVariationsRaw(font, table, conditionalSubstitutions, featureTag="r
axis.axisTag: axisIndex for axisIndex, axis in enumerate(font["fvar"].axes)
}
+ hasFeatureVariations = (
+ hasattr(table, "FeatureVariations") and table.FeatureVariations is not None
+ )
+
featureVariationRecords = []
for conditionSet, lookupIndices in conditionalSubstitutions:
conditionTable = []
@@ -440,11 +444,19 @@ def addFeatureVariationsRaw(font, table, conditionalSubstitutions, featureTag="r
varFeatureIndex, combinedLookupIndices
)
)
- featureVariationRecords.append(
- buildFeatureVariationRecord(conditionTable, records)
- )
+ if hasFeatureVariations and (
+ fvr := findFeatureVariationRecord(table.FeatureVariations, conditionTable)
+ ):
+ fvr.FeatureTableSubstitution.SubstitutionRecord.extend(records)
+ fvr.FeatureTableSubstitution.SubstitutionCount = len(
+ fvr.FeatureTableSubstitution.SubstitutionRecord
+ )
+ else:
+ featureVariationRecords.append(
+ buildFeatureVariationRecord(conditionTable, records)
+ )
- if hasattr(table, "FeatureVariations") and table.FeatureVariations is not None:
+ if hasFeatureVariations:
if table.FeatureVariations.Version != 0x00010000:
raise VarLibError(
"Unsupported FeatureVariations table version: "
@@ -614,6 +626,21 @@ def buildConditionTable(axisIndex, filterRangeMinValue, filterRangeMaxValue):
return ct
+def findFeatureVariationRecord(featureVariations, conditionTable):
+ """Find a FeatureVariationRecord that has the same conditionTable."""
+ if featureVariations.Version != 0x00010000:
+ raise VarLibError(
+ "Unsupported FeatureVariations table version: "
+ f"0x{featureVariations.Version:08x} (expected 0x00010000)."
+ )
+
+ for fvr in featureVariations.FeatureVariationRecord:
+ if conditionTable == fvr.ConditionSet.ConditionTable:
+ return fvr
+
+ return None
+
+
def sortFeatureList(table):
"""Sort the feature list by feature tag, and remap the feature indices
elsewhere. This is needed after the feature list has been modified.
diff --git a/contrib/python/fonttools/fontTools/varLib/interpolatable.py b/contrib/python/fonttools/fontTools/varLib/interpolatable.py
index 0a9bbebc41..5fc12e04c9 100644
--- a/contrib/python/fonttools/fontTools/varLib/interpolatable.py
+++ b/contrib/python/fonttools/fontTools/varLib/interpolatable.py
@@ -376,9 +376,6 @@ def test_gen(
size1 = m1Vec[0] * m1Vec[0]
midSize = midVector[0] * midVector[0]
- power = 1
- t = tolerance**power
-
for overweight, problem_type in enumerate(
(
InterpolatableProblem.UNDERWEIGHT,
@@ -386,8 +383,7 @@ def test_gen(
)
):
if overweight:
- expectedSize = sqrt(size0 * size1)
- expectedSize = (size0 + size1) - expectedSize
+ expectedSize = max(size0, size1)
continue
else:
expectedSize = sqrt(size0 * size1)
@@ -406,13 +402,9 @@ def test_gen(
) or (overweight and 1e-5 + expectedSize / tolerance < midSize):
try:
if overweight:
- this_tolerance = (expectedSize / midSize) ** (
- 1 / power
- )
+ this_tolerance = expectedSize / midSize
else:
- this_tolerance = (midSize / expectedSize) ** (
- 1 / power
- )
+ this_tolerance = midSize / expectedSize
except ZeroDivisionError:
this_tolerance = 0
log.debug("tolerance %g", this_tolerance)
diff --git a/contrib/python/fonttools/ya.make b/contrib/python/fonttools/ya.make
index 6e76c94da1..4d380b556c 100644
--- a/contrib/python/fonttools/ya.make
+++ b/contrib/python/fonttools/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(4.47.0)
+VERSION(4.47.2)
LICENSE(MIT)
diff --git a/contrib/python/google-auth/py3/.dist-info/METADATA b/contrib/python/google-auth/py3/.dist-info/METADATA
index 21345a0555..2820e8856d 100644
--- a/contrib/python/google-auth/py3/.dist-info/METADATA
+++ b/contrib/python/google-auth/py3/.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: google-auth
-Version: 2.26.1
+Version: 2.26.2
Summary: Google Authentication Library
Home-page: https://github.com/googleapis/google-auth-library-python
Author: Google Cloud Platform
diff --git a/contrib/python/google-auth/py3/google/auth/external_account_authorized_user.py b/contrib/python/google-auth/py3/google/auth/external_account_authorized_user.py
index 55230103f4..526588f7e8 100644
--- a/contrib/python/google-auth/py3/google/auth/external_account_authorized_user.py
+++ b/contrib/python/google-auth/py3/google/auth/external_account_authorized_user.py
@@ -342,6 +342,7 @@ class Credentials(
revoke_url=info.get("revoke_url"),
quota_project_id=info.get("quota_project_id"),
scopes=info.get("scopes"),
+ universe_domain=info.get("universe_domain", _DEFAULT_UNIVERSE_DOMAIN),
**kwargs
)
diff --git a/contrib/python/google-auth/py3/google/auth/version.py b/contrib/python/google-auth/py3/google/auth/version.py
index 1c94c2f5f6..6d53c4c411 100644
--- a/contrib/python/google-auth/py3/google/auth/version.py
+++ b/contrib/python/google-auth/py3/google/auth/version.py
@@ -12,4 +12,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-__version__ = "2.26.1"
+__version__ = "2.26.2"
diff --git a/contrib/python/google-auth/py3/tests/data/external_account_authorized_user_non_gdu.json b/contrib/python/google-auth/py3/tests/data/external_account_authorized_user_non_gdu.json
new file mode 100644
index 0000000000..b82854c743
--- /dev/null
+++ b/contrib/python/google-auth/py3/tests/data/external_account_authorized_user_non_gdu.json
@@ -0,0 +1,10 @@
+{
+ "type": "external_account_authorized_user",
+ "audience": "//iam.fake_universe_domain/locations/global/workforcePools/$WORKFORCE_POOL_ID/providers/$PROVIDER_ID",
+ "refresh_token": "refreshToken",
+ "token_url": "https://sts.fake_universe_domain/v1/oauth/token",
+ "token_info_url": "https://sts.fake_universe_domain/v1/instrospect",
+ "client_id": "clientId",
+ "client_secret": "clientSecret",
+ "universe_domain": "fake_universe_domain"
+}
diff --git a/contrib/python/google-auth/py3/tests/test__default.py b/contrib/python/google-auth/py3/tests/test__default.py
index d619614790..aaf892f6d0 100644
--- a/contrib/python/google-auth/py3/tests/test__default.py
+++ b/contrib/python/google-auth/py3/tests/test__default.py
@@ -158,6 +158,10 @@ EXTERNAL_ACCOUNT_AUTHORIZED_USER_FILE = os.path.join(
DATA_DIR, "external_account_authorized_user.json"
)
+EXTERNAL_ACCOUNT_AUTHORIZED_USER_NON_GDU_FILE = os.path.join(
+ DATA_DIR, "external_account_authorized_user_non_gdu.json"
+)
+
MOCK_CREDENTIALS = mock.Mock(spec=credentials.CredentialsWithQuotaProject)
MOCK_CREDENTIALS.with_quota_project.return_value = MOCK_CREDENTIALS
@@ -577,6 +581,15 @@ def test_load_credentials_from_file_external_account_authorized_user():
assert project_id is None
+def test_load_credentials_from_file_external_account_authorized_user_non_gdu():
+ credentials, _ = _default.load_credentials_from_file(
+ EXTERNAL_ACCOUNT_AUTHORIZED_USER_NON_GDU_FILE, request=mock.sentinel.request
+ )
+
+ assert isinstance(credentials, external_account_authorized_user.Credentials)
+ assert credentials.universe_domain == "fake_universe_domain"
+
+
def test_load_credentials_from_file_external_account_authorized_user_bad_format(tmpdir):
filename = tmpdir.join("external_account_authorized_user_bad.json")
filename.write(json.dumps({"type": "external_account_authorized_user"}))
diff --git a/contrib/python/google-auth/py3/ya.make b/contrib/python/google-auth/py3/ya.make
index 75848da971..976b926bff 100644
--- a/contrib/python/google-auth/py3/ya.make
+++ b/contrib/python/google-auth/py3/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(2.26.1)
+VERSION(2.26.2)
LICENSE(Apache-2.0)
diff --git a/contrib/python/hypothesis/py3/.dist-info/METADATA b/contrib/python/hypothesis/py3/.dist-info/METADATA
index 15385afbc9..b4f00cf430 100644
--- a/contrib/python/hypothesis/py3/.dist-info/METADATA
+++ b/contrib/python/hypothesis/py3/.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: hypothesis
-Version: 6.92.6
+Version: 6.92.8
Summary: A library for property-based testing
Home-page: https://hypothesis.works
Author: David R. MacIver and Zac Hatfield-Dodds
diff --git a/contrib/python/hypothesis/py3/hypothesis/control.py b/contrib/python/hypothesis/py3/hypothesis/control.py
index c49dba2954..3a973f666f 100644
--- a/contrib/python/hypothesis/py3/hypothesis/control.py
+++ b/contrib/python/hypothesis/py3/hypothesis/control.py
@@ -8,6 +8,7 @@
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at https://mozilla.org/MPL/2.0/.
+import inspect
import math
from collections import defaultdict
from typing import NoReturn, Union
@@ -25,6 +26,10 @@ from hypothesis.utils.dynamicvariables import DynamicVariable
from hypothesis.vendor.pretty import IDKey
+def _calling_function_name(frame):
+ return frame.f_back.f_code.co_name
+
+
def reject() -> NoReturn:
if _current_build_context.value is None:
note_deprecation(
@@ -32,7 +37,8 @@ def reject() -> NoReturn:
since="2023-09-25",
has_codemod=False,
)
- raise UnsatisfiedAssumption
+ f = _calling_function_name(inspect.currentframe())
+ raise UnsatisfiedAssumption(f"reject() in {f}")
def assume(condition: object) -> bool:
@@ -49,7 +55,8 @@ def assume(condition: object) -> bool:
has_codemod=False,
)
if not condition:
- raise UnsatisfiedAssumption
+ f = _calling_function_name(inspect.currentframe())
+ raise UnsatisfiedAssumption(f"failed to satisfy assume() in {f}")
return True
diff --git a/contrib/python/hypothesis/py3/hypothesis/core.py b/contrib/python/hypothesis/py3/hypothesis/core.py
index 7c149d1222..86b20ea6f9 100644
--- a/contrib/python/hypothesis/py3/hypothesis/core.py
+++ b/contrib/python/hypothesis/py3/hypothesis/core.py
@@ -1005,10 +1005,10 @@ class StateForActualGivenExecution:
f"{self.test.__name__} returned {result!r} instead.",
HealthCheck.return_value,
)
- except UnsatisfiedAssumption:
+ except UnsatisfiedAssumption as e:
# An "assume" check failed, so instead we inform the engine that
# this test run was invalid.
- data.mark_invalid()
+ data.mark_invalid(e.reason)
except StopTest:
# The engine knows how to handle this control exception, so it's
# OK to re-raise it.
diff --git a/contrib/python/hypothesis/py3/hypothesis/errors.py b/contrib/python/hypothesis/py3/hypothesis/errors.py
index 9ee81cfc36..8387a87586 100644
--- a/contrib/python/hypothesis/py3/hypothesis/errors.py
+++ b/contrib/python/hypothesis/py3/hypothesis/errors.py
@@ -23,6 +23,9 @@ class UnsatisfiedAssumption(HypothesisException):
If you're seeing this error something has gone wrong.
"""
+ def __init__(self, reason=None):
+ self.reason = reason
+
class NoSuchExample(HypothesisException):
"""The condition we have been asked to satisfy appears to be always false.
diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/filtering.py b/contrib/python/hypothesis/py3/hypothesis/internal/filtering.py
index 8af37e453b..4ba92b1da8 100644
--- a/contrib/python/hypothesis/py3/hypothesis/internal/filtering.py
+++ b/contrib/python/hypothesis/py3/hypothesis/internal/filtering.py
@@ -73,6 +73,14 @@ def convert(node: ast.AST, argname: str) -> object:
if node.id != argname:
raise ValueError("Non-local variable")
return ARG
+ if isinstance(node, ast.Call):
+ if (
+ isinstance(node.func, ast.Name)
+ and node.func.id == "len"
+ and len(node.args) == 1
+ ):
+ # error unless comparison is to the len *of the lambda arg*
+ return convert(node.args[0], argname)
return ast.literal_eval(node)
@@ -86,26 +94,28 @@ def comp_to_kwargs(x: ast.AST, op: ast.AST, y: ast.AST, *, argname: str) -> dict
# (and we can't even do `arg == arg`, because what if it's NaN?)
raise ValueError("Can't analyse this comparison")
+ of_len = {"len": True} if isinstance(x, ast.Call) or isinstance(y, ast.Call) else {}
+
if isinstance(op, ast.Lt):
if a is ARG:
- return {"max_value": b, "exclude_max": True}
- return {"min_value": a, "exclude_min": True}
+ return {"max_value": b, "exclude_max": True, **of_len}
+ return {"min_value": a, "exclude_min": True, **of_len}
elif isinstance(op, ast.LtE):
if a is ARG:
- return {"max_value": b}
- return {"min_value": a}
+ return {"max_value": b, **of_len}
+ return {"min_value": a, **of_len}
elif isinstance(op, ast.Eq):
if a is ARG:
- return {"min_value": b, "max_value": b}
- return {"min_value": a, "max_value": a}
+ return {"min_value": b, "max_value": b, **of_len}
+ return {"min_value": a, "max_value": a, **of_len}
elif isinstance(op, ast.GtE):
if a is ARG:
- return {"min_value": b}
- return {"max_value": a}
+ return {"min_value": b, **of_len}
+ return {"max_value": a, **of_len}
elif isinstance(op, ast.Gt):
if a is ARG:
- return {"min_value": b, "exclude_min": True}
- return {"max_value": a, "exclude_max": True}
+ return {"min_value": b, "exclude_min": True, **of_len}
+ return {"max_value": a, "exclude_max": True, **of_len}
raise ValueError("Unhandled comparison operator") # e.g. ast.Ne
@@ -120,6 +130,9 @@ def merge_preds(*con_predicates: ConstructivePredicate) -> ConstructivePredicate
}
predicate = None
for kw, p in con_predicates:
+ assert (
+ not p or not predicate or p is predicate
+ ), "Can't merge two partially-constructive preds"
predicate = p or predicate
if "min_value" in kw:
if kw["min_value"] > base["min_value"]:
@@ -134,6 +147,11 @@ def merge_preds(*con_predicates: ConstructivePredicate) -> ConstructivePredicate
elif kw["max_value"] == base["max_value"]:
base["exclude_max"] |= kw.get("exclude_max", False)
+ has_len = {"len" in kw for kw, _ in con_predicates}
+ assert len(has_len) == 1, "can't mix numeric with length constraints"
+ if has_len == {True}:
+ base["len"] = True
+
if not base["exclude_min"]:
del base["exclude_min"]
if base["min_value"] == -math.inf:
@@ -154,6 +172,8 @@ def numeric_bounds_from_ast(
{"min_value": 0}, None
>>> lambda x: x < 10
{"max_value": 10, "exclude_max": True}, None
+ >>> lambda x: len(x) >= 5
+ {"min_value": 5, "len": True}, None
>>> lambda x: x >= y
{}, lambda x: x >= y
@@ -169,7 +189,10 @@ def numeric_bounds_from_ast(
for comp in comparisons:
try:
kwargs = comp_to_kwargs(*comp, argname=argname)
- bounds.append(ConstructivePredicate(kwargs, None))
+ # Because `len` could be redefined in the enclosing scope, we *always*
+ # have to apply the condition as a filter, in addition to rewriting.
+ pred = fallback.predicate if "len" in kwargs else None
+ bounds.append(ConstructivePredicate(kwargs, pred))
except ValueError:
bounds.append(fallback)
return merge_preds(*bounds)
@@ -209,6 +232,9 @@ def get_numeric_predicate_bounds(predicate: Predicate) -> ConstructivePredicate:
operator.eq: {"min_value": arg, "max_value": arg}, # lambda x: arg == x
operator.ge: {"max_value": arg}, # lambda x: arg >= x
operator.gt: {"max_value": arg, "exclude_max": True}, # lambda x: arg > x
+ # Special-case our default predicates for length bounds
+ min_len: {"min_value": arg, "len": True},
+ max_len: {"max_value": arg, "len": True},
}
if predicate.func in options:
return ConstructivePredicate(options[predicate.func], None)
@@ -270,7 +296,8 @@ def get_integer_predicate_bounds(predicate: Predicate) -> ConstructivePredicate:
elif kwargs.get("exclude_max", False):
kwargs["max_value"] = int(kwargs["max_value"]) - 1
- kwargs = {k: v for k, v in kwargs.items() if k in {"min_value", "max_value"}}
+ kw_categories = {"min_value", "max_value", "len"}
+ kwargs = {k: v for k, v in kwargs.items() if k in kw_categories}
return ConstructivePredicate(kwargs, predicate)
diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/reflection.py b/contrib/python/hypothesis/py3/hypothesis/internal/reflection.py
index 2f0480c987..d5ea7161f3 100644
--- a/contrib/python/hypothesis/py3/hypothesis/internal/reflection.py
+++ b/contrib/python/hypothesis/py3/hypothesis/internal/reflection.py
@@ -19,7 +19,7 @@ import re
import sys
import textwrap
import types
-from functools import wraps
+from functools import partial, wraps
from io import StringIO
from keyword import iskeyword
from tokenize import COMMENT, detect_encoding, generate_tokens, untokenize
@@ -432,6 +432,8 @@ def extract_lambda_source(f):
def get_pretty_function_description(f):
+ if isinstance(f, partial):
+ return pretty(f)
if not hasattr(f, "__name__"):
return repr(f)
name = f.__name__
diff --git a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/collections.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/collections.py
index 2bee499ac2..1f86f37a42 100644
--- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/collections.py
+++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/collections.py
@@ -15,6 +15,7 @@ from hypothesis.errors import InvalidArgument
from hypothesis.internal.conjecture import utils as cu
from hypothesis.internal.conjecture.junkdrawer import LazySequenceCopy
from hypothesis.internal.conjecture.utils import combine_labels
+from hypothesis.internal.filtering import get_integer_predicate_bounds
from hypothesis.internal.reflection import is_identity_function
from hypothesis.strategies._internal.strategies import (
T3,
@@ -199,7 +200,22 @@ class ListStrategy(SearchStrategy):
new = copy.copy(self)
new.min_size = 1
return new
- return super().filter(condition)
+
+ kwargs, pred = get_integer_predicate_bounds(condition)
+ if kwargs.get("len") and ("min_value" in kwargs or "max_value" in kwargs):
+ new = copy.copy(self)
+ new.min_size = max(self.min_size, kwargs.get("min_value", self.min_size))
+ new.max_size = min(self.max_size, kwargs.get("max_value", self.max_size))
+ # Recompute average size; this is cheaper than making it into a property.
+ new.average_size = min(
+ max(new.min_size * 2, new.min_size + 5),
+ 0.5 * (new.min_size + new.max_size),
+ )
+ if pred is None:
+ return new
+ return SearchStrategy.filter(new, condition)
+
+ return SearchStrategy.filter(self, condition)
class UniqueListStrategy(ListStrategy):
diff --git a/contrib/python/hypothesis/py3/hypothesis/version.py b/contrib/python/hypothesis/py3/hypothesis/version.py
index 382bffeb8b..ef8fe6a63a 100644
--- a/contrib/python/hypothesis/py3/hypothesis/version.py
+++ b/contrib/python/hypothesis/py3/hypothesis/version.py
@@ -8,5 +8,5 @@
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at https://mozilla.org/MPL/2.0/.
-__version_info__ = (6, 92, 6)
+__version_info__ = (6, 92, 8)
__version__ = ".".join(map(str, __version_info__))
diff --git a/contrib/python/hypothesis/py3/ya.make b/contrib/python/hypothesis/py3/ya.make
index 2a6ae3478d..92b1d0c734 100644
--- a/contrib/python/hypothesis/py3/ya.make
+++ b/contrib/python/hypothesis/py3/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(6.92.6)
+VERSION(6.92.8)
LICENSE(MPL-2.0)
diff --git a/contrib/python/ydb/py3/.dist-info/METADATA b/contrib/python/ydb/py3/.dist-info/METADATA
index 058eb80b41..675a1d8825 100644
--- a/contrib/python/ydb/py3/.dist-info/METADATA
+++ b/contrib/python/ydb/py3/.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: ydb
-Version: 3.7.0
+Version: 3.8.0
Summary: YDB Python SDK
Home-page: http://github.com/ydb-platform/ydb-python-sdk
Author: Yandex LLC
diff --git a/contrib/python/ydb/py3/ya.make b/contrib/python/ydb/py3/ya.make
index f92572fa82..484d68aafd 100644
--- a/contrib/python/ydb/py3/ya.make
+++ b/contrib/python/ydb/py3/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(3.7.0)
+VERSION(3.8.0)
LICENSE(Apache-2.0)
@@ -66,6 +66,8 @@ PY_SRCS(
ydb/dbapi/cursor.py
ydb/dbapi/errors.py
ydb/default_pem.py
+ ydb/draft/__init__.py
+ ydb/draft/dynamic_config.py
ydb/driver.py
ydb/export.py
ydb/global_settings.py
diff --git a/contrib/python/ydb/py3/ydb/__init__.py b/contrib/python/ydb/py3/ydb/__init__.py
index 902b1e0850..8bfba3a902 100644
--- a/contrib/python/ydb/py3/ydb/__init__.py
+++ b/contrib/python/ydb/py3/ydb/__init__.py
@@ -18,6 +18,7 @@ from .scripting import * # noqa
from .import_client import * # noqa
from .tracing import * # noqa
from .topic import * # noqa
+from .draft import * # noqa
try:
import ydb.aio as aio # noqa
diff --git a/contrib/python/ydb/py3/ydb/_apis.py b/contrib/python/ydb/py3/ydb/_apis.py
index 924e14c1b6..9ad2a32f21 100644
--- a/contrib/python/ydb/py3/ydb/_apis.py
+++ b/contrib/python/ydb/py3/ydb/_apis.py
@@ -11,6 +11,10 @@ try:
ydb_topic_v1_pb2_grpc,
)
+ from ydb.public.api.grpc.draft import (
+ ydb_dynamic_config_v1_pb2_grpc,
+ )
+
from ydb.public.api.protos import (
ydb_status_codes_pb2,
ydb_discovery_pb2,
@@ -20,6 +24,10 @@ try:
ydb_operation_pb2,
ydb_common_pb2,
)
+
+ from ydb.public.api.protos.draft import (
+ ydb_dynamic_config_pb2,
+ )
except ImportError:
from contrib.ydb.public.api.grpc import (
ydb_cms_v1_pb2_grpc,
@@ -30,6 +38,10 @@ except ImportError:
ydb_topic_v1_pb2_grpc,
)
+ from contrib.ydb.public.api.grpc.draft import (
+ ydb_dynamic_config_v1_pb2_grpc,
+ )
+
from contrib.ydb.public.api.protos import (
ydb_status_codes_pb2,
ydb_discovery_pb2,
@@ -40,6 +52,10 @@ except ImportError:
ydb_common_pb2,
)
+ from contrib.ydb.public.api.protos.draft import (
+ ydb_dynamic_config_pb2,
+ )
+
StatusIds = ydb_status_codes_pb2.StatusIds
FeatureFlag = ydb_common_pb2.FeatureFlag
@@ -49,6 +65,7 @@ ydb_scheme = ydb_scheme_pb2
ydb_table = ydb_table_pb2
ydb_discovery = ydb_discovery_pb2
ydb_operation = ydb_operation_pb2
+ydb_dynamic_config = ydb_dynamic_config_pb2
class CmsService(object):
@@ -108,3 +125,12 @@ class TopicService(object):
DropTopic = "DropTopic"
StreamRead = "StreamRead"
StreamWrite = "StreamWrite"
+
+
+class DynamicConfigService(object):
+ Stub = ydb_dynamic_config_v1_pb2_grpc.DynamicConfigServiceStub
+
+ ReplaceConfig = "ReplaceConfig"
+ SetConfig = "SetConfig"
+ GetConfig = "GetConfig"
+ GetNodeLabels = "GetNodeLabels"
diff --git a/contrib/python/ydb/py3/ydb/draft/__init__.py b/contrib/python/ydb/py3/ydb/draft/__init__.py
new file mode 100644
index 0000000000..c34316f2c2
--- /dev/null
+++ b/contrib/python/ydb/py3/ydb/draft/__init__.py
@@ -0,0 +1 @@
+from .dynamic_config import * # noqa
diff --git a/contrib/python/ydb/py3/ydb/draft/dynamic_config.py b/contrib/python/ydb/py3/ydb/draft/dynamic_config.py
new file mode 100644
index 0000000000..afec19eca7
--- /dev/null
+++ b/contrib/python/ydb/py3/ydb/draft/dynamic_config.py
@@ -0,0 +1,173 @@
+import abc
+from abc import abstractmethod
+from .. import issues, operation, _apis
+
+
+class IDynamicConfigClient(abc.ABC):
+ @abstractmethod
+ def __init__(self, driver):
+ pass
+
+ @abstractmethod
+ def replace_config(self, config, dry_run, allow_unknown_fields, settings):
+ pass
+
+ @abstractmethod
+ def set_config(self, config, dry_run, allow_unknown_fields, settings):
+ pass
+
+ @abstractmethod
+ def get_config(self, settings):
+ pass
+
+ @abstractmethod
+ def get_node_labels(self, node_id, settings):
+ pass
+
+
+class DynamicConfig(object):
+ __slots__ = ("version", "cluster", "config")
+
+ def __init__(self, version, cluster, config, *args, **kwargs):
+ self.version = version
+ self.cluster = cluster
+ self.config = config
+
+
+class NodeLabels(object):
+ __slots__ = "labels"
+
+ def __init__(self, labels, *args, **kwargs):
+ self.labels = labels
+
+
+def _replace_config_request_factory(config, dry_run, allow_unknown_fields):
+ request = _apis.ydb_dynamic_config.ReplaceConfigRequest()
+ request.config = config
+ request.dry_run = dry_run
+ request.allow_unknown_fields = allow_unknown_fields
+ return request
+
+
+def _set_config_request_factory(config, dry_run, allow_unknown_fields):
+ request = _apis.ydb_dynamic_config.SetConfigRequest()
+ request.config = config
+ request.dry_run = dry_run
+ request.allow_unknown_fields = allow_unknown_fields
+ return request
+
+
+def _get_config_request_factory():
+ request = _apis.ydb_dynamic_config.GetConfigRequest()
+ return request
+
+
+def _get_node_labels_request_factory(node_id):
+ request = _apis.ydb_dynamic_config.GetNodeLabelsRequest()
+ request.node_id = node_id
+ return request
+
+
+def _wrap_dynamic_config(config_pb, dynamic_config_cls=None, *args, **kwargs):
+ dynamic_config_cls = DynamicConfig if dynamic_config_cls is None else dynamic_config_cls
+ return dynamic_config_cls(config_pb.identity.version, config_pb.identity.cluster, config_pb.config, *args, **kwargs)
+
+
+def _wrap_get_config_response(rpc_state, response):
+ issues._process_response(response.operation)
+ message = _apis.ydb_dynamic_config.GetConfigResult()
+ response.operation.result.Unpack(message)
+ return _wrap_dynamic_config(message)
+
+
+def _wrap_node_labels(labels_pb, node_labels_cls=None, *args, **kwargs):
+ node_labels_cls = NodeLabels if node_labels_cls is None else node_labels_cls
+ return node_labels_cls(dict([(entry.label, entry.value) for entry in labels_pb.labels]), *args, **kwargs)
+
+
+def _wrap_get_node_labels_response(rpc_state, response):
+ issues._process_response(response.operation)
+ message = _apis.ydb_dynamic_config.GetNodeLabelsResult()
+ response.operation.result.Unpack(message)
+ return _wrap_node_labels(message)
+
+
+class BaseDynamicConfigClient(IDynamicConfigClient):
+ __slots__ = ("_driver",)
+
+ def __init__(self, driver):
+ self._driver = driver
+
+ def replace_config(self, config, dry_run, allow_unknown_fields, settings=None):
+ return self._driver(
+ _replace_config_request_factory(config, dry_run, allow_unknown_fields),
+ _apis.DynamicConfigService.Stub,
+ _apis.DynamicConfigService.ReplaceConfig,
+ operation.Operation,
+ settings,
+ )
+
+ def set_config(self, config, dry_run, allow_unknown_fields, settings=None):
+ return self._driver(
+ _set_config_request_factory(config, dry_run, allow_unknown_fields),
+ _apis.DynamicConfigService.Stub,
+ _apis.DynamicConfigService.SetConfig,
+ operation.Operation,
+ settings,
+ )
+
+ def get_config(self, settings=None):
+ return self._driver(
+ _get_config_request_factory(),
+ _apis.DynamicConfigService.Stub,
+ _apis.DynamicConfigService.GetConfig,
+ _wrap_get_config_response,
+ settings,
+ )
+
+ def get_node_labels(self, node_id, settings=None):
+ return self._driver(
+ _get_node_labels_request_factory(node_id),
+ _apis.DynamicConfigService.Stub,
+ _apis.DynamicConfigService.GetNodeLabels,
+ _wrap_get_node_labels_response,
+ settings,
+ )
+
+
+class DynamicConfigClient(BaseDynamicConfigClient):
+ def async_replace_config(self, config, dry_run, allow_unknown_fields, settings=None):
+ return self._driver.future(
+ _replace_config_request_factory(config, dry_run, allow_unknown_fields),
+ _apis.DynamicConfigService.Stub,
+ _apis.DynamicConfigService.ReplaceConfig,
+ operation.Operation,
+ settings,
+ )
+
+ def async_set_config(self, config, dry_run, allow_unknown_fields, settings=None):
+ return self._driver.future(
+ _set_config_request_factory(config, dry_run, allow_unknown_fields),
+ _apis.DynamicConfigService.Stub,
+ _apis.DynamicConfigService.SetConfig,
+ operation.Operation,
+ settings,
+ )
+
+ def async_get_config(self, settings=None):
+ return self._driver.future(
+ _get_config_request_factory(),
+ _apis.DynamicConfigService.Stub,
+ _apis.DynamicConfigService.GetConfig,
+ _wrap_get_config_response,
+ settings,
+ )
+
+ def async_get_node_labels(self, node_id, settings=None):
+ return self._driver.future(
+ _get_node_labels_request_factory(node_id),
+ _apis.DynamicConfigService.Stub,
+ _apis.DynamicConfigService.GetNodeLabels,
+ _wrap_get_node_labels_response,
+ settings,
+ )
diff --git a/contrib/python/ydb/py3/ydb/ydb_version.py b/contrib/python/ydb/py3/ydb/ydb_version.py
index 709cb0a9e5..8173e1e609 100644
--- a/contrib/python/ydb/py3/ydb/ydb_version.py
+++ b/contrib/python/ydb/py3/ydb/ydb_version.py
@@ -1 +1 @@
-VERSION = "3.7.0"
+VERSION = "3.8.0"
diff --git a/contrib/restricted/abseil-cpp/absl/algorithm/algorithm.h b/contrib/restricted/abseil-cpp/absl/algorithm/algorithm.h
index e9b4733872..59aeed7d26 100644
--- a/contrib/restricted/abseil-cpp/absl/algorithm/algorithm.h
+++ b/contrib/restricted/abseil-cpp/absl/algorithm/algorithm.h
@@ -31,92 +31,17 @@
namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace algorithm_internal {
-
-// Performs comparisons with operator==, similar to C++14's `std::equal_to<>`.
-struct EqualTo {
- template <typename T, typename U>
- bool operator()(const T& a, const U& b) const {
- return a == b;
- }
-};
-
-template <typename InputIter1, typename InputIter2, typename Pred>
-bool EqualImpl(InputIter1 first1, InputIter1 last1, InputIter2 first2,
- InputIter2 last2, Pred pred, std::input_iterator_tag,
- std::input_iterator_tag) {
- while (true) {
- if (first1 == last1) return first2 == last2;
- if (first2 == last2) return false;
- if (!pred(*first1, *first2)) return false;
- ++first1;
- ++first2;
- }
-}
-
-template <typename InputIter1, typename InputIter2, typename Pred>
-bool EqualImpl(InputIter1 first1, InputIter1 last1, InputIter2 first2,
- InputIter2 last2, Pred&& pred, std::random_access_iterator_tag,
- std::random_access_iterator_tag) {
- return (last1 - first1 == last2 - first2) &&
- std::equal(first1, last1, first2, std::forward<Pred>(pred));
-}
-
-// When we are using our own internal predicate that just applies operator==, we
-// forward to the non-predicate form of std::equal. This enables an optimization
-// in libstdc++ that can result in std::memcmp being used for integer types.
-template <typename InputIter1, typename InputIter2>
-bool EqualImpl(InputIter1 first1, InputIter1 last1, InputIter2 first2,
- InputIter2 last2, algorithm_internal::EqualTo /* unused */,
- std::random_access_iterator_tag,
- std::random_access_iterator_tag) {
- return (last1 - first1 == last2 - first2) &&
- std::equal(first1, last1, first2);
-}
-
-template <typename It>
-It RotateImpl(It first, It middle, It last, std::true_type) {
- return std::rotate(first, middle, last);
-}
-
-template <typename It>
-It RotateImpl(It first, It middle, It last, std::false_type) {
- std::rotate(first, middle, last);
- return std::next(first, std::distance(middle, last));
-}
-
-} // namespace algorithm_internal
-
// equal()
+// rotate()
//
-// Compares the equality of two ranges specified by pairs of iterators, using
-// the given predicate, returning true iff for each corresponding iterator i1
-// and i2 in the first and second range respectively, pred(*i1, *i2) == true
-//
-// This comparison takes at most min(`last1` - `first1`, `last2` - `first2`)
-// invocations of the predicate. Additionally, if InputIter1 and InputIter2 are
-// both random-access iterators, and `last1` - `first1` != `last2` - `first2`,
-// then the predicate is never invoked and the function returns false.
+// Historical note: Abseil once provided implementations of these algorithms
+// prior to their adoption in C++14. New code should prefer to use the std
+// variants.
//
-// This is a C++11-compatible implementation of C++14 `std::equal`. See
-// https://en.cppreference.com/w/cpp/algorithm/equal for more information.
-template <typename InputIter1, typename InputIter2, typename Pred>
-bool equal(InputIter1 first1, InputIter1 last1, InputIter2 first2,
- InputIter2 last2, Pred&& pred) {
- return algorithm_internal::EqualImpl(
- first1, last1, first2, last2, std::forward<Pred>(pred),
- typename std::iterator_traits<InputIter1>::iterator_category{},
- typename std::iterator_traits<InputIter2>::iterator_category{});
-}
-
-// Overload of equal() that performs comparison of two ranges specified by pairs
-// of iterators using operator==.
-template <typename InputIter1, typename InputIter2>
-bool equal(InputIter1 first1, InputIter1 last1, InputIter2 first2,
- InputIter2 last2) {
- return absl::equal(first1, last1, first2, last2,
- algorithm_internal::EqualTo{});
-}
+// See the documentation for the STL <algorithm> header for more information:
+// https://en.cppreference.com/w/cpp/header/algorithm
+using std::equal;
+using std::rotate;
// linear_search()
//
@@ -133,26 +58,6 @@ bool linear_search(InputIterator first, InputIterator last,
return std::find(first, last, value) != last;
}
-// rotate()
-//
-// Performs a left rotation on a range of elements (`first`, `last`) such that
-// `middle` is now the first element. `rotate()` returns an iterator pointing to
-// the first element before rotation. This function is exactly the same as
-// `std::rotate`, but fixes a bug in gcc
-// <= 4.9 where `std::rotate` returns `void` instead of an iterator.
-//
-// The complexity of this algorithm is the same as that of `std::rotate`, but if
-// `ForwardIterator` is not a random-access iterator, then `absl::rotate`
-// performs an additional pass over the range to construct the return value.
-template <typename ForwardIterator>
-ForwardIterator rotate(ForwardIterator first, ForwardIterator middle,
- ForwardIterator last) {
- return algorithm_internal::RotateImpl(
- first, middle, last,
- std::is_same<decltype(std::rotate(first, middle, last)),
- ForwardIterator>());
-}
-
ABSL_NAMESPACE_END
} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/algorithm/container.h b/contrib/restricted/abseil-cpp/absl/algorithm/container.h
index 679e02676c..c7bafae147 100644
--- a/contrib/restricted/abseil-cpp/absl/algorithm/container.h
+++ b/contrib/restricted/abseil-cpp/absl/algorithm/container.h
@@ -52,6 +52,7 @@
#include "absl/algorithm/algorithm.h"
#include "absl/base/macros.h"
+#include "absl/base/nullability.h"
#include "absl/meta/type_traits.h"
namespace absl {
@@ -116,18 +117,6 @@ template <class Key, class Hash, class KeyEqual, class Allocator>
struct IsUnorderedContainer<std::unordered_set<Key, Hash, KeyEqual, Allocator>>
: std::true_type {};
-// container_algorithm_internal::c_size. It is meant for internal use only.
-
-template <class C>
-auto c_size(C& c) -> decltype(c.size()) {
- return c.size();
-}
-
-template <class T, std::size_t N>
-constexpr std::size_t c_size(T (&)[N]) {
- return N;
-}
-
} // namespace container_algorithm_internal
// PUBLIC API
@@ -348,20 +337,10 @@ container_algorithm_internal::ContainerDifferenceType<const C> c_count_if(
template <typename C1, typename C2>
container_algorithm_internal::ContainerIterPairType<C1, C2> c_mismatch(C1& c1,
C2& c2) {
- auto first1 = container_algorithm_internal::c_begin(c1);
- auto last1 = container_algorithm_internal::c_end(c1);
- auto first2 = container_algorithm_internal::c_begin(c2);
- auto last2 = container_algorithm_internal::c_end(c2);
-
- for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) {
- // Negates equality because Cpp17EqualityComparable doesn't require clients
- // to overload both `operator==` and `operator!=`.
- if (!(*first1 == *first2)) {
- break;
- }
- }
-
- return std::make_pair(first1, first2);
+ return std::mismatch(container_algorithm_internal::c_begin(c1),
+ container_algorithm_internal::c_end(c1),
+ container_algorithm_internal::c_begin(c2),
+ container_algorithm_internal::c_end(c2));
}
// Overload of c_mismatch() for using a predicate evaluation other than `==` as
@@ -370,56 +349,33 @@ container_algorithm_internal::ContainerIterPairType<C1, C2> c_mismatch(C1& c1,
template <typename C1, typename C2, typename BinaryPredicate>
container_algorithm_internal::ContainerIterPairType<C1, C2> c_mismatch(
C1& c1, C2& c2, BinaryPredicate pred) {
- auto first1 = container_algorithm_internal::c_begin(c1);
- auto last1 = container_algorithm_internal::c_end(c1);
- auto first2 = container_algorithm_internal::c_begin(c2);
- auto last2 = container_algorithm_internal::c_end(c2);
-
- for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) {
- if (!pred(*first1, *first2)) {
- break;
- }
- }
-
- return std::make_pair(first1, first2);
+ return std::mismatch(container_algorithm_internal::c_begin(c1),
+ container_algorithm_internal::c_end(c1),
+ container_algorithm_internal::c_begin(c2),
+ container_algorithm_internal::c_end(c2), pred);
}
// c_equal()
//
// Container-based version of the <algorithm> `std::equal()` function to
// test whether two containers are equal.
-//
-// NOTE: the semantics of c_equal() are slightly different than those of
-// equal(): while the latter iterates over the second container only up to the
-// size of the first container, c_equal() also checks whether the container
-// sizes are equal. This better matches expectations about c_equal() based on
-// its signature.
-//
-// Example:
-// vector v1 = <1, 2, 3>;
-// vector v2 = <1, 2, 3, 4>;
-// equal(std::begin(v1), std::end(v1), std::begin(v2)) returns true
-// c_equal(v1, v2) returns false
-
template <typename C1, typename C2>
bool c_equal(const C1& c1, const C2& c2) {
- return ((container_algorithm_internal::c_size(c1) ==
- container_algorithm_internal::c_size(c2)) &&
- std::equal(container_algorithm_internal::c_begin(c1),
- container_algorithm_internal::c_end(c1),
- container_algorithm_internal::c_begin(c2)));
+ return std::equal(container_algorithm_internal::c_begin(c1),
+ container_algorithm_internal::c_end(c1),
+ container_algorithm_internal::c_begin(c2),
+ container_algorithm_internal::c_end(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) {
- return ((container_algorithm_internal::c_size(c1) ==
- container_algorithm_internal::c_size(c2)) &&
- std::equal(container_algorithm_internal::c_begin(c1),
- container_algorithm_internal::c_end(c1),
- container_algorithm_internal::c_begin(c2),
- std::forward<BinaryPredicate>(pred)));
+ return std::equal(container_algorithm_internal::c_begin(c1),
+ container_algorithm_internal::c_end(c1),
+ container_algorithm_internal::c_begin(c2),
+ container_algorithm_internal::c_end(c2),
+ std::forward<BinaryPredicate>(pred));
}
// c_is_permutation()
@@ -428,20 +384,20 @@ bool c_equal(const C1& c1, const C2& c2, BinaryPredicate&& pred) {
// 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) {
- using std::begin;
- using std::end;
- return c1.size() == c2.size() &&
- std::is_permutation(begin(c1), end(c1), begin(c2));
+ return std::is_permutation(container_algorithm_internal::c_begin(c1),
+ container_algorithm_internal::c_end(c1),
+ container_algorithm_internal::c_begin(c2),
+ container_algorithm_internal::c_end(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) {
- using std::begin;
- using std::end;
- return c1.size() == c2.size() &&
- std::is_permutation(begin(c1), end(c1), begin(c2),
+ return std::is_permutation(container_algorithm_internal::c_begin(c1),
+ container_algorithm_internal::c_end(c1),
+ container_algorithm_internal::c_begin(c2),
+ container_algorithm_internal::c_end(c2),
std::forward<BinaryPredicate>(pred));
}
@@ -818,6 +774,36 @@ void c_shuffle(RandomAccessContainer& c, UniformRandomBitGenerator&& gen) {
std::forward<UniformRandomBitGenerator>(gen));
}
+// c_sample()
+//
+// Container-based version of the <algorithm> `std::sample()` function to
+// randomly sample elements from the container without replacement using a
+// `gen()` uniform random number generator and write them to an iterator range.
+template <typename C, typename OutputIterator, typename Distance,
+ typename UniformRandomBitGenerator>
+OutputIterator c_sample(const C& c, OutputIterator result, Distance n,
+ UniformRandomBitGenerator&& gen) {
+#if defined(__cpp_lib_sample) && __cpp_lib_sample >= 201603L
+ return std::sample(container_algorithm_internal::c_begin(c),
+ container_algorithm_internal::c_end(c), result, n,
+ std::forward<UniformRandomBitGenerator>(gen));
+#else
+ // Fall back to a stable selection-sampling implementation.
+ auto first = container_algorithm_internal::c_begin(c);
+ Distance unsampled_elements = c_distance(c);
+ n = (std::min)(n, unsampled_elements);
+ for (; n != 0; ++first) {
+ Distance r =
+ std::uniform_int_distribution<Distance>(0, --unsampled_elements)(gen);
+ if (r < n) {
+ *result++ = *first;
+ --n;
+ }
+ }
+ return result;
+#endif
+}
+
//------------------------------------------------------------------------------
// <algorithm> Partition functions
//------------------------------------------------------------------------------
@@ -1657,7 +1643,7 @@ bool c_prev_permutation(C& c, LessThan&& comp) {
//
// Container-based version of the <numeric> `std::iota()` function
// to compute successive values of `value`, as if incremented with `++value`
-// after each element is written. and write them to the container.
+// after each element is written, and write them to the container.
template <typename Sequence, typename T>
void c_iota(Sequence& sequence, const T& value) {
std::iota(container_algorithm_internal::c_begin(sequence),
diff --git a/contrib/restricted/abseil-cpp/absl/algorithm/ya.make b/contrib/restricted/abseil-cpp/absl/algorithm/ya.make
index 3b66e3e400..3f9af85fe6 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(20230802.1)
+VERSION(20240116.0)
-ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20230802.1.tar.gz)
+ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20240116.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 a7f279a025..d4f67a1295 100644
--- a/contrib/restricted/abseil-cpp/absl/base/attributes.h
+++ b/contrib/restricted/abseil-cpp/absl/base/attributes.h
@@ -687,7 +687,7 @@
// When deprecating Abseil code, it is sometimes necessary to turn off the
// warning within Abseil, until the deprecated code is actually removed. The
-// deprecated code can be surrounded with these directives to acheive that
+// deprecated code can be surrounded with these directives to achieve that
// result.
//
// class ABSL_DEPRECATED("Use Bar instead") Foo;
@@ -747,9 +747,52 @@
#define ABSL_CONST_INIT
#endif
-// These annotations are not available yet due to fear of breaking code.
-#define ABSL_ATTRIBUTE_PURE_FUNCTION
-#define ABSL_ATTRIBUTE_CONST_FUNCTION
+// ABSL_ATTRIBUTE_PURE_FUNCTION
+//
+// ABSL_ATTRIBUTE_PURE_FUNCTION is used to annotate declarations of "pure"
+// functions. A function is pure if its return value is only a function of its
+// arguments. The pure attribute prohibits a function from modifying the state
+// of the program that is observable by means other than inspecting the
+// function's return value. Declaring such functions with the pure attribute
+// allows the compiler to avoid emitting some calls in repeated invocations of
+// the function with the same argument values.
+//
+// Example:
+//
+// ABSL_ATTRIBUTE_PURE_FUNCTION std::string FormatTime(Time t);
+#if ABSL_HAVE_CPP_ATTRIBUTE(gnu::pure)
+#define ABSL_ATTRIBUTE_PURE_FUNCTION [[gnu::pure]]
+#elif ABSL_HAVE_ATTRIBUTE(pure)
+#define ABSL_ATTRIBUTE_PURE_FUNCTION __attribute__((pure))
+#else
+// If the attribute isn't defined, we'll fallback to ABSL_MUST_USE_RESULT since
+// pure functions are useless if its return is ignored.
+#define ABSL_ATTRIBUTE_PURE_FUNCTION ABSL_MUST_USE_RESULT
+#endif
+
+// ABSL_ATTRIBUTE_CONST_FUNCTION
+//
+// ABSL_ATTRIBUTE_CONST_FUNCTION is used to annotate declarations of "const"
+// functions. A const function is similar to a pure function, with one
+// exception: Pure functions may return value that depend on a non-volatile
+// object that isn't provided as a function argument, while the const function
+// is guaranteed to return the same result given the same arguments.
+//
+// Example:
+//
+// ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToInt64Milliseconds(Duration d);
+#if defined(_MSC_VER) && !defined(__clang__)
+// Put the MSVC case first since MSVC seems to parse const as a C++ keyword.
+#define ABSL_ATTRIBUTE_CONST_FUNCTION ABSL_ATTRIBUTE_PURE_FUNCTION
+#elif ABSL_HAVE_CPP_ATTRIBUTE(gnu::const)
+#define ABSL_ATTRIBUTE_CONST_FUNCTION [[gnu::const]]
+#elif ABSL_HAVE_ATTRIBUTE(const)
+#define ABSL_ATTRIBUTE_CONST_FUNCTION __attribute__((const))
+#else
+// Since const functions are more restrictive pure function, we'll fallback to a
+// pure function if the const attribute is not handled.
+#define ABSL_ATTRIBUTE_CONST_FUNCTION ABSL_ATTRIBUTE_PURE_FUNCTION
+#endif
// ABSL_ATTRIBUTE_LIFETIME_BOUND indicates that a resource owned by a function
// parameter or implicit object parameter is retained by the return value of the
@@ -800,15 +843,11 @@
// See also the upstream documentation:
// https://clang.llvm.org/docs/AttributeReference.html#trivial-abi
//
-#if ABSL_HAVE_CPP_ATTRIBUTE(clang::trivial_abi)
-#define ABSL_ATTRIBUTE_TRIVIAL_ABI [[clang::trivial_abi]]
-#define ABSL_HAVE_ATTRIBUTE_TRIVIAL_ABI 1
-#elif ABSL_HAVE_ATTRIBUTE(trivial_abi)
-#define ABSL_ATTRIBUTE_TRIVIAL_ABI __attribute__((trivial_abi))
-#define ABSL_HAVE_ATTRIBUTE_TRIVIAL_ABI 1
-#else
+// b/321691395 - This is currently disabled in open-source builds since
+// compiler support differs. If system libraries compiled with GCC are mixed
+// with libraries compiled with Clang, types will have different ideas about
+// their ABI, leading to hard to debug crashes.
#define ABSL_ATTRIBUTE_TRIVIAL_ABI
-#endif
// ABSL_ATTRIBUTE_NO_UNIQUE_ADDRESS
//
diff --git a/contrib/restricted/abseil-cpp/absl/base/call_once.h b/contrib/restricted/abseil-cpp/absl/base/call_once.h
index 08436bac8a..7b0e69ccd5 100644
--- a/contrib/restricted/abseil-cpp/absl/base/call_once.h
+++ b/contrib/restricted/abseil-cpp/absl/base/call_once.h
@@ -37,6 +37,7 @@
#include "absl/base/internal/scheduling_mode.h"
#include "absl/base/internal/spinlock_wait.h"
#include "absl/base/macros.h"
+#include "absl/base/nullability.h"
#include "absl/base/optimization.h"
#include "absl/base/port.h"
@@ -46,7 +47,8 @@ ABSL_NAMESPACE_BEGIN
class once_flag;
namespace base_internal {
-std::atomic<uint32_t>* ControlWord(absl::once_flag* flag);
+absl::Nonnull<std::atomic<uint32_t>*> ControlWord(
+ absl::Nonnull<absl::once_flag*> flag);
} // namespace base_internal
// call_once()
@@ -89,7 +91,8 @@ class once_flag {
once_flag& operator=(const once_flag&) = delete;
private:
- friend std::atomic<uint32_t>* base_internal::ControlWord(once_flag* flag);
+ friend absl::Nonnull<std::atomic<uint32_t>*> base_internal::ControlWord(
+ absl::Nonnull<once_flag*> flag);
std::atomic<uint32_t> control_;
};
@@ -103,7 +106,8 @@ namespace base_internal {
// Like call_once, but uses KERNEL_ONLY scheduling. Intended to be used to
// initialize entities used by the scheduler implementation.
template <typename Callable, typename... Args>
-void LowLevelCallOnce(absl::once_flag* flag, Callable&& fn, Args&&... args);
+void LowLevelCallOnce(absl::Nonnull<absl::once_flag*> flag, Callable&& fn,
+ Args&&... args);
// Disables scheduling while on stack when scheduling mode is non-cooperative.
// No effect for cooperative scheduling modes.
@@ -143,10 +147,10 @@ enum {
};
template <typename Callable, typename... Args>
-ABSL_ATTRIBUTE_NOINLINE
-void CallOnceImpl(std::atomic<uint32_t>* control,
- base_internal::SchedulingMode scheduling_mode, Callable&& fn,
- Args&&... args) {
+ABSL_ATTRIBUTE_NOINLINE 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);
@@ -185,12 +189,14 @@ void CallOnceImpl(std::atomic<uint32_t>* control,
} // else *control is already kOnceDone
}
-inline std::atomic<uint32_t>* ControlWord(once_flag* flag) {
+inline absl::Nonnull<std::atomic<uint32_t>*> ControlWord(
+ absl::Nonnull<once_flag*> flag) {
return &flag->control_;
}
template <typename Callable, typename... Args>
-void LowLevelCallOnce(absl::once_flag* flag, Callable&& fn, Args&&... args) {
+void LowLevelCallOnce(absl::Nonnull<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/casts.h b/contrib/restricted/abseil-cpp/absl/base/casts.h
index d19588852f..e0b11bbe49 100644
--- a/contrib/restricted/abseil-cpp/absl/base/casts.h
+++ b/contrib/restricted/abseil-cpp/absl/base/casts.h
@@ -90,7 +90,7 @@ ABSL_NAMESPACE_BEGIN
//
// Such implicit cast chaining may be useful within template logic.
template <typename To>
-constexpr To implicit_cast(typename absl::internal::identity_t<To> to) {
+constexpr To implicit_cast(typename absl::internal::type_identity_t<To> to) {
return to;
}
diff --git a/contrib/restricted/abseil-cpp/absl/base/config.h b/contrib/restricted/abseil-cpp/absl/base/config.h
index 334e2767ac..8bd9a6d586 100644
--- a/contrib/restricted/abseil-cpp/absl/base/config.h
+++ b/contrib/restricted/abseil-cpp/absl/base/config.h
@@ -75,6 +75,12 @@
#define ABSL_INTERNAL_CPLUSPLUS_LANG __cplusplus
#endif
+#if defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
+ ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+// Include library feature test macros.
+#include <version>
+#endif
+
#if defined(__APPLE__)
// Included for TARGET_OS_IPHONE, __IPHONE_OS_VERSION_MIN_REQUIRED,
// __IPHONE_8_0.
@@ -111,8 +117,8 @@
//
// LTS releases can be obtained from
// https://github.com/abseil/abseil-cpp/releases.
-#define ABSL_LTS_RELEASE_VERSION 20230802
-#define ABSL_LTS_RELEASE_PATCH_LEVEL 1
+#define ABSL_LTS_RELEASE_VERSION 20240116
+#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
@@ -332,8 +338,8 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
#ifdef ABSL_HAVE_INTRINSIC_INT128
#error ABSL_HAVE_INTRINSIC_INT128 cannot be directly set
#elif defined(__SIZEOF_INT128__)
-#if (defined(__clang__) && !defined(_WIN32)) || \
- (defined(__CUDACC__) && __CUDACC_VER_MAJOR__ >= 9) || \
+#if (defined(__clang__) && !defined(_WIN32)) || \
+ (defined(__CUDACC__) && __CUDACC_VER_MAJOR__ >= 9) || \
(defined(__GNUC__) && !defined(__clang__) && !defined(__CUDACC__))
#define ABSL_HAVE_INTRINSIC_INT128 1
#elif defined(__CUDACC__)
@@ -395,7 +401,7 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
// Windows _WIN32
// NaCL __native_client__
// AsmJS __asmjs__
-// WebAssembly __wasm__
+// WebAssembly (Emscripten) __EMSCRIPTEN__
// Fuchsia __Fuchsia__
//
// Note that since Android defines both __ANDROID__ and __linux__, one
@@ -407,11 +413,11 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
// POSIX.1-2001.
#ifdef ABSL_HAVE_MMAP
#error ABSL_HAVE_MMAP cannot be directly set
-#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
- defined(_AIX) || defined(__ros__) || defined(__native_client__) || \
- defined(__asmjs__) || defined(__wasm__) || defined(__Fuchsia__) || \
- defined(__sun) || defined(__ASYLO__) || defined(__myriad2__) || \
- defined(__HAIKU__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
+#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
+ defined(_AIX) || defined(__ros__) || defined(__native_client__) || \
+ defined(__asmjs__) || defined(__EMSCRIPTEN__) || defined(__Fuchsia__) || \
+ defined(__sun) || defined(__ASYLO__) || defined(__myriad2__) || \
+ defined(__HAIKU__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
defined(__QNX__) || defined(__VXWORKS__) || defined(__hexagon__)
#define ABSL_HAVE_MMAP 1
#endif
@@ -484,6 +490,8 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
// https://sourceforge.net/p/mingw-w64/mingw-w64/ci/master/tree/mingw-w64-crt/misc/alarm.c
#elif defined(__EMSCRIPTEN__)
// emscripten doesn't support signals
+#elif defined(__wasi__)
+// WASI doesn't support signals
#elif defined(__Fuchsia__)
// Signals don't exist on fuchsia.
#elif defined(__native_client__)
@@ -536,14 +544,14 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
// and
// https://github.com/llvm/llvm-project/commit/0bc451e7e137c4ccadcd3377250874f641ca514a
// The second has the actually correct versions, thus, is what we copy here.
-#if defined(__APPLE__) && \
- ((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
- __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101300) || \
- (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \
- __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 120000) || \
- (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && \
- __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 50000) || \
- (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && \
+#if defined(__APPLE__) && \
+ ((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
+ __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101300) || \
+ (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \
+ __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 120000) || \
+ (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && \
+ __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 50000) || \
+ (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && \
__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 120000))
#define ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE 1
#else
@@ -555,7 +563,7 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
// Checks whether C++17 std::any is available.
#ifdef ABSL_HAVE_STD_ANY
#error "ABSL_HAVE_STD_ANY cannot be directly set."
-#elif defined(__cpp_lib_any)
+#elif defined(__cpp_lib_any) && __cpp_lib_any >= 201606L
#define ABSL_HAVE_STD_ANY 1
#elif defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L && \
@@ -568,9 +576,9 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
// Checks whether C++17 std::optional is available.
#ifdef ABSL_HAVE_STD_OPTIONAL
#error "ABSL_HAVE_STD_OPTIONAL cannot be directly set."
-#elif defined(__cpp_lib_optional)
+#elif defined(__cpp_lib_optional) && __cpp_lib_optional >= 202106L
#define ABSL_HAVE_STD_OPTIONAL 1
-#elif defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
+#elif defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L && \
!ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE
#define ABSL_HAVE_STD_OPTIONAL 1
@@ -581,7 +589,7 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
// Checks whether C++17 std::variant is available.
#ifdef ABSL_HAVE_STD_VARIANT
#error "ABSL_HAVE_STD_VARIANT cannot be directly set."
-#elif defined(__cpp_lib_variant)
+#elif defined(__cpp_lib_variant) && __cpp_lib_variant >= 201606L
#define ABSL_HAVE_STD_VARIANT 1
#elif defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L && \
@@ -594,13 +602,29 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
// Checks whether C++17 std::string_view is available.
#ifdef ABSL_HAVE_STD_STRING_VIEW
#error "ABSL_HAVE_STD_STRING_VIEW cannot be directly set."
-#elif defined(__cpp_lib_string_view)
+#elif defined(__cpp_lib_string_view) && __cpp_lib_string_view >= 201606L
#define ABSL_HAVE_STD_STRING_VIEW 1
#elif defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
#define ABSL_HAVE_STD_STRING_VIEW 1
#endif
+// ABSL_HAVE_STD_ORDERING
+//
+// Checks whether C++20 std::{partial,weak,strong}_ordering are available.
+//
+// __cpp_lib_three_way_comparison is missing on libc++
+// (https://github.com/llvm/llvm-project/issues/73953) so treat it as defined
+// when building in C++20 mode.
+#ifdef ABSL_HAVE_STD_ORDERING
+#error "ABSL_HAVE_STD_ORDERING cannot be directly set."
+#elif (defined(__cpp_lib_three_way_comparison) && \
+ __cpp_lib_three_way_comparison >= 201907L) || \
+ (defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
+ ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L)
+#define ABSL_HAVE_STD_ORDERING 1
+#endif
+
// ABSL_USES_STD_ANY
//
// Indicates whether absl::any is an alias for std::any.
@@ -663,6 +687,22 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
#error options.h is misconfigured.
#endif
+// ABSL_USES_STD_ORDERING
+//
+// Indicates whether absl::{partial,weak,strong}_ordering are aliases for the
+// std:: ordering types.
+#if !defined(ABSL_OPTION_USE_STD_ORDERING)
+#error options.h is misconfigured.
+#elif ABSL_OPTION_USE_STD_ORDERING == 0 || \
+ (ABSL_OPTION_USE_STD_ORDERING == 2 && !defined(ABSL_HAVE_STD_ORDERING))
+#undef ABSL_USES_STD_ORDERING
+#elif ABSL_OPTION_USE_STD_ORDERING == 1 || \
+ (ABSL_OPTION_USE_STD_ORDERING == 2 && defined(ABSL_HAVE_STD_ORDERING))
+#define ABSL_USES_STD_ORDERING 1
+#else
+#error options.h is misconfigured.
+#endif
+
// In debug mode, MSVC 2017's std::variant throws a EXCEPTION_ACCESS_VIOLATION
// SEH exception from emplace for variant<SomeStruct> when constructing the
// struct can throw. This defeats some of variant_test and
@@ -845,11 +885,30 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
// RTTI support.
#ifdef ABSL_INTERNAL_HAS_RTTI
#error ABSL_INTERNAL_HAS_RTTI cannot be directly set
-#elif (defined(__GNUC__) && defined(__GXX_RTTI)) || \
- (defined(_MSC_VER) && defined(_CPPRTTI)) || \
- (!defined(__GNUC__) && !defined(_MSC_VER))
+#elif ABSL_HAVE_FEATURE(cxx_rtti)
+#define ABSL_INTERNAL_HAS_RTTI 1
+#elif defined(__GNUC__) && defined(__GXX_RTTI)
#define ABSL_INTERNAL_HAS_RTTI 1
-#endif // !defined(__GNUC__) || defined(__GXX_RTTI)
+#elif defined(_MSC_VER) && defined(_CPPRTTI)
+#define ABSL_INTERNAL_HAS_RTTI 1
+#elif !defined(__GNUC__) && !defined(_MSC_VER)
+// Unknown compiler, default to RTTI
+#define ABSL_INTERNAL_HAS_RTTI 1
+#endif
+
+// `ABSL_INTERNAL_HAS_CXA_DEMANGLE` determines whether `abi::__cxa_demangle` is
+// available.
+#ifdef ABSL_INTERNAL_HAS_CXA_DEMANGLE
+#error ABSL_INTERNAL_HAS_CXA_DEMANGLE cannot be directly set
+#elif defined(OS_ANDROID) && (defined(__i386__) || defined(__x86_64__))
+#define ABSL_INTERNAL_HAS_CXA_DEMANGLE 0
+#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && \
+ (__GNUC__ >= 4 || (__GNUC__ >= 3 && __GNUC_MINOR__ >= 4)) && \
+ !defined(__mips__)
+#define ABSL_INTERNAL_HAS_CXA_DEMANGLE 1
+#elif defined(__clang__) && !defined(_MSC_VER)
+#define ABSL_INTERNAL_HAS_CXA_DEMANGLE 1
+#endif
// ABSL_INTERNAL_HAVE_SSE is used for compile-time detection of SSE support.
// See https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html for an overview of
@@ -936,8 +995,8 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
#if __EMSCRIPTEN_tiny__ >= 1000
#error __EMSCRIPTEN_tiny__ is too big to fit in ABSL_INTERNAL_EMSCRIPTEN_VERSION
#endif
-#define ABSL_INTERNAL_EMSCRIPTEN_VERSION \
- ((__EMSCRIPTEN_major__)*1000000 + (__EMSCRIPTEN_minor__)*1000 + \
+#define ABSL_INTERNAL_EMSCRIPTEN_VERSION \
+ ((__EMSCRIPTEN_major__) * 1000000 + (__EMSCRIPTEN_minor__) * 1000 + \
(__EMSCRIPTEN_tiny__))
#endif
#endif
diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/endian.h b/contrib/restricted/abseil-cpp/absl/base/internal/endian.h
index 50747d75ec..943f3d97e7 100644
--- a/contrib/restricted/abseil-cpp/absl/base/internal/endian.h
+++ b/contrib/restricted/abseil-cpp/absl/base/internal/endian.h
@@ -22,6 +22,7 @@
#include "absl/base/casts.h"
#include "absl/base/config.h"
#include "absl/base/internal/unaligned_access.h"
+#include "absl/base/nullability.h"
#include "absl/base/port.h"
namespace absl {
@@ -160,27 +161,27 @@ inline int64_t ToHost(int64_t x) {
}
// Functions to do unaligned loads and stores in little-endian order.
-inline uint16_t Load16(const void *p) {
+inline uint16_t Load16(absl::Nonnull<const void *> p) {
return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p));
}
-inline void Store16(void *p, uint16_t v) {
+inline void Store16(absl::Nonnull<void *> p, uint16_t v) {
ABSL_INTERNAL_UNALIGNED_STORE16(p, FromHost16(v));
}
-inline uint32_t Load32(const void *p) {
+inline uint32_t Load32(absl::Nonnull<const void *> p) {
return ToHost32(ABSL_INTERNAL_UNALIGNED_LOAD32(p));
}
-inline void Store32(void *p, uint32_t v) {
+inline void Store32(absl::Nonnull<void *> p, uint32_t v) {
ABSL_INTERNAL_UNALIGNED_STORE32(p, FromHost32(v));
}
-inline uint64_t Load64(const void *p) {
+inline uint64_t Load64(absl::Nonnull<const void *> p) {
return ToHost64(ABSL_INTERNAL_UNALIGNED_LOAD64(p));
}
-inline void Store64(void *p, uint64_t v) {
+inline void Store64(absl::Nonnull<void *> p, uint64_t v) {
ABSL_INTERNAL_UNALIGNED_STORE64(p, FromHost64(v));
}
@@ -250,27 +251,27 @@ inline int64_t ToHost(int64_t x) {
}
// Functions to do unaligned loads and stores in big-endian order.
-inline uint16_t Load16(const void *p) {
+inline uint16_t Load16(absl::Nonnull<const void *> p) {
return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p));
}
-inline void Store16(void *p, uint16_t v) {
+inline void Store16(absl::Nonnull<void *> p, uint16_t v) {
ABSL_INTERNAL_UNALIGNED_STORE16(p, FromHost16(v));
}
-inline uint32_t Load32(const void *p) {
+inline uint32_t Load32(absl::Nonnull<const void *> p) {
return ToHost32(ABSL_INTERNAL_UNALIGNED_LOAD32(p));
}
-inline void Store32(void *p, uint32_t v) {
+inline void Store32(absl::Nonnull<void *>p, uint32_t v) {
ABSL_INTERNAL_UNALIGNED_STORE32(p, FromHost32(v));
}
-inline uint64_t Load64(const void *p) {
+inline uint64_t Load64(absl::Nonnull<const void *> p) {
return ToHost64(ABSL_INTERNAL_UNALIGNED_LOAD64(p));
}
-inline void Store64(void *p, uint64_t v) {
+inline void Store64(absl::Nonnull<void *> p, uint64_t v) {
ABSL_INTERNAL_UNALIGNED_STORE64(p, FromHost64(v));
}
diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/identity.h b/contrib/restricted/abseil-cpp/absl/base/internal/identity.h
index a3154ed7bc..365207b7e7 100644
--- a/contrib/restricted/abseil-cpp/absl/base/internal/identity.h
+++ b/contrib/restricted/abseil-cpp/absl/base/internal/identity.h
@@ -22,13 +22,15 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
namespace internal {
+// This is a back-fill of C++20's `std::type_identity`.
template <typename T>
-struct identity {
+struct type_identity {
typedef T type;
};
+// This is a back-fill of C++20's `std::type_identity_t`.
template <typename T>
-using identity_t = typename identity<T>::type;
+using type_identity_t = typename type_identity<T>::type;
} // namespace internal
ABSL_NAMESPACE_END
diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/inline_variable.h b/contrib/restricted/abseil-cpp/absl/base/internal/inline_variable.h
index df933faff5..09daf0f5b7 100644
--- a/contrib/restricted/abseil-cpp/absl/base/internal/inline_variable.h
+++ b/contrib/restricted/abseil-cpp/absl/base/internal/inline_variable.h
@@ -63,12 +63,12 @@
// Bug: https://bugs.llvm.org/show_bug.cgi?id=35862
//
// Note:
-// identity_t is used here so that the const and name are in the
+// type_identity_t is used here so that the const and name are in the
// appropriate place for pointer types, reference types, function pointer
// types, etc..
#if defined(__clang__)
#define ABSL_INTERNAL_EXTERN_DECL(type, name) \
- extern const ::absl::internal::identity_t<type> name;
+ extern const ::absl::internal::type_identity_t<type> name;
#else // Otherwise, just define the macro to do nothing.
#define ABSL_INTERNAL_EXTERN_DECL(type, name)
#endif // defined(__clang__)
@@ -76,30 +76,31 @@
// See above comment at top of file for details.
#define ABSL_INTERNAL_INLINE_CONSTEXPR(type, name, init) \
ABSL_INTERNAL_EXTERN_DECL(type, name) \
- inline constexpr ::absl::internal::identity_t<type> name = init
+ inline constexpr ::absl::internal::type_identity_t<type> name = init
#else
// See above comment at top of file for details.
//
// Note:
-// identity_t is used here so that the const and name are in the
+// type_identity_t is used here so that the const and name are in the
// appropriate place for pointer types, reference types, function pointer
// types, etc..
-#define ABSL_INTERNAL_INLINE_CONSTEXPR(var_type, name, init) \
- template <class /*AbslInternalDummy*/ = void> \
- struct AbslInternalInlineVariableHolder##name { \
- static constexpr ::absl::internal::identity_t<var_type> kInstance = init; \
- }; \
- \
- template <class AbslInternalDummy> \
- constexpr ::absl::internal::identity_t<var_type> \
- AbslInternalInlineVariableHolder##name<AbslInternalDummy>::kInstance; \
- \
- static constexpr const ::absl::internal::identity_t<var_type>& \
- name = /* NOLINT */ \
- AbslInternalInlineVariableHolder##name<>::kInstance; \
- static_assert(sizeof(void (*)(decltype(name))) != 0, \
+#define ABSL_INTERNAL_INLINE_CONSTEXPR(var_type, name, init) \
+ template <class /*AbslInternalDummy*/ = void> \
+ struct AbslInternalInlineVariableHolder##name { \
+ static constexpr ::absl::internal::type_identity_t<var_type> kInstance = \
+ init; \
+ }; \
+ \
+ template <class AbslInternalDummy> \
+ constexpr ::absl::internal::type_identity_t<var_type> \
+ AbslInternalInlineVariableHolder##name<AbslInternalDummy>::kInstance; \
+ \
+ static constexpr const ::absl::internal::type_identity_t<var_type>& \
+ name = /* NOLINT */ \
+ AbslInternalInlineVariableHolder##name<>::kInstance; \
+ static_assert(sizeof(void (*)(decltype(name))) != 0, \
"Silence unused variable warnings.")
#endif // __cpp_inline_variables
diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc.cc b/contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc.cc
index 6d2cfeac3c..a563f7b9f9 100644
--- a/contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc.cc
+++ b/contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc.cc
@@ -329,7 +329,7 @@ size_t GetPageSize() {
SYSTEM_INFO system_info;
GetSystemInfo(&system_info);
return std::max(system_info.dwPageSize, system_info.dwAllocationGranularity);
-#elif defined(__wasm__) || defined(__asmjs__)
+#elif defined(__wasm__) || defined(__asmjs__) || defined(__hexagon__)
return getpagesize();
#else
return static_cast<size_t>(sysconf(_SC_PAGESIZE));
diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/nullability_impl.h b/contrib/restricted/abseil-cpp/absl/base/internal/nullability_impl.h
new file mode 100644
index 0000000000..36e1b33d65
--- /dev/null
+++ b/contrib/restricted/abseil-cpp/absl/base/internal/nullability_impl.h
@@ -0,0 +1,106 @@
+// Copyright 2023 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_NULLABILITY_IMPL_H_
+#define ABSL_BASE_INTERNAL_NULLABILITY_IMPL_H_
+
+#include <memory>
+#include <type_traits>
+
+#include "absl/base/attributes.h"
+#include "absl/meta/type_traits.h"
+
+namespace absl {
+
+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
+ = T;
+
+template <typename T, typename = typename EnableNonnull<T>::type>
+using NonnullImpl
+#if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate)
+ [[clang::annotate("Nonnull")]]
+#endif
+ = T;
+
+template <typename T, typename = typename EnableNullabilityUnknown<T>::type>
+using NullabilityUnknownImpl
+#if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate)
+ [[clang::annotate("Nullability_Unspecified")]]
+#endif
+ = T;
+
+} // namespace nullability_internal
+} // namespace absl
+
+#endif // ABSL_BASE_INTERNAL_NULLABILITY_IMPL_H_
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 a1ca876d4e..6f68002a3c 100644
--- a/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging.cc
+++ b/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging.cc
@@ -42,8 +42,9 @@
// This preprocessor token is also defined in raw_io.cc. If you need to copy
// this, consider moving both to config.h instead.
#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
- defined(__Fuchsia__) || defined(__native_client__) || \
- defined(__OpenBSD__) || defined(__EMSCRIPTEN__) || defined(__ASYLO__)
+ defined(__hexagon__) || defined(__Fuchsia__) || \
+ defined(__native_client__) || defined(__OpenBSD__) || \
+ defined(__EMSCRIPTEN__) || defined(__ASYLO__)
#include <unistd.h>
@@ -56,8 +57,7 @@
// ABSL_HAVE_SYSCALL_WRITE is defined when the platform provides the syscall
// syscall(SYS_write, /*int*/ fd, /*char* */ buf, /*size_t*/ len);
// for low level operations that want to avoid libc.
-#if (defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__)) && \
- !defined(__ANDROID__)
+#if (defined(__linux__) || defined(__FreeBSD__)) && !defined(__ANDROID__)
#include <sys/syscall.h>
#define ABSL_HAVE_SYSCALL_WRITE 1
#define ABSL_LOW_LEVEL_WRITE_SUPPORTED 1
@@ -93,8 +93,7 @@ constexpr char kTruncated[] = " ... (message truncated)\n";
bool VADoRawLog(char** buf, int* size, const char* format, va_list ap)
ABSL_PRINTF_ATTRIBUTE(3, 0);
bool VADoRawLog(char** buf, int* size, const char* format, va_list ap) {
- if (*size < 0)
- return false;
+ if (*size < 0) return false;
int n = vsnprintf(*buf, static_cast<size_t>(*size), format, ap);
bool result = true;
if (n < 0 || n > *size) {
@@ -122,8 +121,7 @@ constexpr int kLogBufSize = 3000;
bool DoRawLog(char** buf, int* size, const char* format, ...)
ABSL_PRINTF_ATTRIBUTE(3, 4);
bool DoRawLog(char** buf, int* size, const char* format, ...) {
- if (*size < 0)
- return false;
+ if (*size < 0) return false;
va_list ap;
va_start(ap, format);
int n = vsnprintf(*buf, static_cast<size_t>(*size), format, ap);
@@ -242,8 +240,8 @@ void AsyncSignalSafeWriteError(const char* s, size_t len) {
_write(/* stderr */ 2, s, static_cast<unsigned>(len));
#else
// stderr logging unsupported on this platform
- (void) s;
- (void) len;
+ (void)s;
+ (void)len;
#endif
}
@@ -258,7 +256,7 @@ void RawLog(absl::LogSeverity severity, const char* file, int line,
bool RawLoggingFullySupported() {
#ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED
return true;
-#else // !ABSL_LOW_LEVEL_WRITE_SUPPORTED
+#else // !ABSL_LOW_LEVEL_WRITE_SUPPORTED
return false;
#endif // !ABSL_LOW_LEVEL_WRITE_SUPPORTED
}
diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging.h b/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging.h
index b79550b2b7..d7cfbc576b 100644
--- a/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging.h
+++ b/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging.h
@@ -108,6 +108,7 @@
#define ABSL_RAW_LOG_INTERNAL_WARNING ::absl::LogSeverity::kWarning
#define ABSL_RAW_LOG_INTERNAL_ERROR ::absl::LogSeverity::kError
#define ABSL_RAW_LOG_INTERNAL_FATAL ::absl::LogSeverity::kFatal
+#define ABSL_RAW_LOG_INTERNAL_DFATAL ::absl::kLogDebugFatal
#define ABSL_RAW_LOG_INTERNAL_LEVEL(severity) \
::absl::NormalizeLogSeverity(severity)
@@ -115,6 +116,7 @@
#define ABSL_RAW_LOG_INTERNAL_MAYBE_UNREACHABLE_WARNING
#define ABSL_RAW_LOG_INTERNAL_MAYBE_UNREACHABLE_ERROR
#define ABSL_RAW_LOG_INTERNAL_MAYBE_UNREACHABLE_FATAL ABSL_UNREACHABLE()
+#define ABSL_RAW_LOG_INTERNAL_MAYBE_UNREACHABLE_DFATAL
#define ABSL_RAW_LOG_INTERNAL_MAYBE_UNREACHABLE_LEVEL(severity)
namespace absl {
diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/spinlock.h b/contrib/restricted/abseil-cpp/absl/base/internal/spinlock.h
index 09ba5824b1..2929cd6f5c 100644
--- a/contrib/restricted/abseil-cpp/absl/base/internal/spinlock.h
+++ b/contrib/restricted/abseil-cpp/absl/base/internal/spinlock.h
@@ -19,10 +19,10 @@
// - for use by Abseil internal code that Mutex itself depends on
// - for async signal safety (see below)
-// SpinLock is async signal safe. If a spinlock is used within a signal
-// handler, all code that acquires the lock must ensure that the signal cannot
-// arrive while they are holding the lock. Typically, this is done by blocking
-// the signal.
+// SpinLock with a base_internal::SchedulingMode::SCHEDULE_KERNEL_ONLY is async
+// signal safe. If a spinlock is used within a signal handler, all code that
+// acquires the lock must ensure that the signal cannot arrive while they are
+// holding the lock. Typically, this is done by blocking the signal.
//
// Threads waiting on a SpinLock may be woken in an arbitrary order.
@@ -41,6 +41,14 @@
#include "absl/base/internal/tsan_mutex_interface.h"
#include "absl/base/thread_annotations.h"
+namespace tcmalloc {
+namespace tcmalloc_internal {
+
+class AllocationGuardSpinLockHolder;
+
+} // namespace tcmalloc_internal
+} // namespace tcmalloc
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {
@@ -137,6 +145,7 @@ class ABSL_LOCKABLE SpinLock {
// Provide access to protected method above. Use for testing only.
friend struct SpinLockTest;
+ friend class tcmalloc::tcmalloc_internal::AllocationGuardSpinLockHolder;
private:
// lockword_ is used to store the following:
@@ -171,6 +180,10 @@ class ABSL_LOCKABLE SpinLock {
return scheduling_mode == base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL;
}
+ bool IsCooperative() const {
+ return lockword_.load(std::memory_order_relaxed) & kSpinLockCooperative;
+ }
+
uint32_t TryLockInternal(uint32_t lock_value, uint32_t wait_cycles);
void SlowLock() ABSL_ATTRIBUTE_COLD;
void SlowUnlock(uint32_t lock_value) ABSL_ATTRIBUTE_COLD;
diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/thread_annotations.h b/contrib/restricted/abseil-cpp/absl/base/internal/thread_annotations.h
deleted file mode 100644
index 8c5c67e0df..0000000000
--- a/contrib/restricted/abseil-cpp/absl/base/internal/thread_annotations.h
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright 2019 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// -----------------------------------------------------------------------------
-// File: thread_annotations.h
-// -----------------------------------------------------------------------------
-//
-// WARNING: This is a backwards compatible header and it will be removed after
-// the migration to prefixed thread annotations is finished; please include
-// "absl/base/thread_annotations.h".
-//
-// This header file contains macro definitions for thread safety annotations
-// that allow developers to document the locking policies of multi-threaded
-// code. The annotations can also help program analysis tools to identify
-// potential thread safety issues.
-//
-// These annotations are implemented using compiler attributes. Using the macros
-// defined here instead of raw attributes allow for portability and future
-// compatibility.
-//
-// When referring to mutexes in the arguments of the attributes, you should
-// use variable names or more complex expressions (e.g. my_object->mutex_)
-// that evaluate to a concrete mutex object whenever possible. If the mutex
-// you want to refer to is not in scope, you may use a member pointer
-// (e.g. &MyClass::mutex_) to refer to a mutex in some (unknown) object.
-
-#ifndef ABSL_BASE_INTERNAL_THREAD_ANNOTATIONS_H_
-#define ABSL_BASE_INTERNAL_THREAD_ANNOTATIONS_H_
-
-// ABSL_LEGACY_THREAD_ANNOTATIONS is a *temporary* compatibility macro that can
-// be defined on the compile command-line to restore the legacy spellings of the
-// thread annotations macros/functions. The macros in this file are available
-// under ABSL_ prefixed spellings in absl/base/thread_annotations.h. This macro
-// and the legacy spellings will be removed in the future.
-#ifdef ABSL_LEGACY_THREAD_ANNOTATIONS
-
-#if defined(__clang__)
-#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
-#else
-#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op
-#endif
-
-// GUARDED_BY()
-//
-// Documents if a shared field or global variable needs to be protected by a
-// mutex. GUARDED_BY() allows the user to specify a particular mutex that
-// should be held when accessing the annotated variable.
-//
-// Although this annotation (and PT_GUARDED_BY, below) cannot be applied to
-// local variables, a local variable and its associated mutex can often be
-// combined into a small class or struct, thereby allowing the annotation.
-//
-// Example:
-//
-// class Foo {
-// Mutex mu_;
-// int p1_ GUARDED_BY(mu_);
-// ...
-// };
-#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
-
-// PT_GUARDED_BY()
-//
-// Documents if the memory location pointed to by a pointer should be guarded
-// by a mutex when dereferencing the pointer.
-//
-// Example:
-// class Foo {
-// Mutex mu_;
-// int *p1_ PT_GUARDED_BY(mu_);
-// ...
-// };
-//
-// Note that a pointer variable to a shared memory location could itself be a
-// shared variable.
-//
-// Example:
-//
-// // `q_`, guarded by `mu1_`, points to a shared memory location that is
-// // guarded by `mu2_`:
-// int *q_ GUARDED_BY(mu1_) PT_GUARDED_BY(mu2_);
-#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
-
-// ACQUIRED_AFTER() / ACQUIRED_BEFORE()
-//
-// Documents the acquisition order between locks that can be held
-// simultaneously by a thread. For any two locks that need to be annotated
-// to establish an acquisition order, only one of them needs the annotation.
-// (i.e. You don't have to annotate both locks with both ACQUIRED_AFTER
-// and ACQUIRED_BEFORE.)
-//
-// As with GUARDED_BY, this is only applicable to mutexes that are shared
-// fields or global variables.
-//
-// Example:
-//
-// Mutex m1_;
-// Mutex m2_ ACQUIRED_AFTER(m1_);
-#define ACQUIRED_AFTER(...) \
- THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
-
-#define ACQUIRED_BEFORE(...) \
- THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
-
-// EXCLUSIVE_LOCKS_REQUIRED() / SHARED_LOCKS_REQUIRED()
-//
-// Documents a function that expects a mutex to be held prior to entry.
-// The mutex is expected to be held both on entry to, and exit from, the
-// function.
-//
-// An exclusive lock allows read-write access to the guarded data member(s), and
-// only one thread can acquire a lock exclusively at any one time. A shared lock
-// allows read-only access, and any number of threads can acquire a shared lock
-// concurrently.
-//
-// Generally, non-const methods should be annotated with
-// EXCLUSIVE_LOCKS_REQUIRED, while const methods should be annotated with
-// SHARED_LOCKS_REQUIRED.
-//
-// Example:
-//
-// Mutex mu1, mu2;
-// int a GUARDED_BY(mu1);
-// int b GUARDED_BY(mu2);
-//
-// void foo() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2) { ... }
-// void bar() const SHARED_LOCKS_REQUIRED(mu1, mu2) { ... }
-#define EXCLUSIVE_LOCKS_REQUIRED(...) \
- THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__))
-
-#define SHARED_LOCKS_REQUIRED(...) \
- THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(__VA_ARGS__))
-
-// LOCKS_EXCLUDED()
-//
-// Documents the locks acquired in the body of the function. These locks
-// cannot be held when calling this function (as Abseil's `Mutex` locks are
-// non-reentrant).
-#define LOCKS_EXCLUDED(...) \
- THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
-
-// LOCK_RETURNED()
-//
-// Documents a function that returns a mutex without acquiring it. For example,
-// a public getter method that returns a pointer to a private mutex should
-// be annotated with LOCK_RETURNED.
-#define LOCK_RETURNED(x) \
- THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
-
-// LOCKABLE
-//
-// Documents if a class/type is a lockable type (such as the `Mutex` class).
-#define LOCKABLE \
- THREAD_ANNOTATION_ATTRIBUTE__(lockable)
-
-// SCOPED_LOCKABLE
-//
-// Documents if a class does RAII locking (such as the `MutexLock` class).
-// The constructor should use `LOCK_FUNCTION()` to specify the mutex that is
-// acquired, and the destructor should use `UNLOCK_FUNCTION()` with no
-// arguments; the analysis will assume that the destructor unlocks whatever the
-// constructor locked.
-#define SCOPED_LOCKABLE \
- THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
-
-// EXCLUSIVE_LOCK_FUNCTION()
-//
-// Documents functions that acquire a lock in the body of a function, and do
-// not release it.
-#define EXCLUSIVE_LOCK_FUNCTION(...) \
- THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__))
-
-// SHARED_LOCK_FUNCTION()
-//
-// Documents functions that acquire a shared (reader) lock in the body of a
-// function, and do not release it.
-#define SHARED_LOCK_FUNCTION(...) \
- THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__))
-
-// UNLOCK_FUNCTION()
-//
-// Documents functions that expect a lock to be held on entry to the function,
-// and release it in the body of the function.
-#define UNLOCK_FUNCTION(...) \
- THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))
-
-// EXCLUSIVE_TRYLOCK_FUNCTION() / SHARED_TRYLOCK_FUNCTION()
-//
-// Documents functions that try to acquire a lock, and return success or failure
-// (or a non-boolean value that can be interpreted as a boolean).
-// The first argument should be `true` for functions that return `true` on
-// success, or `false` for functions that return `false` on success. The second
-// argument specifies the mutex that is locked on success. If unspecified, this
-// mutex is assumed to be `this`.
-#define EXCLUSIVE_TRYLOCK_FUNCTION(...) \
- THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))
-
-#define SHARED_TRYLOCK_FUNCTION(...) \
- THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__))
-
-// ASSERT_EXCLUSIVE_LOCK() / ASSERT_SHARED_LOCK()
-//
-// Documents functions that dynamically check to see if a lock is held, and fail
-// if it is not held.
-#define ASSERT_EXCLUSIVE_LOCK(...) \
- THREAD_ANNOTATION_ATTRIBUTE__(assert_exclusive_lock(__VA_ARGS__))
-
-#define ASSERT_SHARED_LOCK(...) \
- THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_lock(__VA_ARGS__))
-
-// NO_THREAD_SAFETY_ANALYSIS
-//
-// Turns off thread safety checking within the body of a particular function.
-// This annotation is used to mark functions that are known to be correct, but
-// the locking behavior is more complicated than the analyzer can handle.
-#define NO_THREAD_SAFETY_ANALYSIS \
- THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
-
-//------------------------------------------------------------------------------
-// Tool-Supplied Annotations
-//------------------------------------------------------------------------------
-
-// TS_UNCHECKED should be placed around lock expressions that are not valid
-// C++ syntax, but which are present for documentation purposes. These
-// annotations will be ignored by the analysis.
-#define TS_UNCHECKED(x) ""
-
-// TS_FIXME is used to mark lock expressions that are not valid C++ syntax.
-// It is used by automated tools to mark and disable invalid expressions.
-// The annotation should either be fixed, or changed to TS_UNCHECKED.
-#define TS_FIXME(x) ""
-
-// Like NO_THREAD_SAFETY_ANALYSIS, this turns off checking within the body of
-// a particular function. However, this attribute is used to mark functions
-// that are incorrect and need to be fixed. It is used by automated tools to
-// avoid breaking the build when the analysis is updated.
-// Code owners are expected to eventually fix the routine.
-#define NO_THREAD_SAFETY_ANALYSIS_FIXME NO_THREAD_SAFETY_ANALYSIS
-
-// Similar to NO_THREAD_SAFETY_ANALYSIS_FIXME, this macro marks a GUARDED_BY
-// annotation that needs to be fixed, because it is producing thread safety
-// warning. It disables the GUARDED_BY.
-#define GUARDED_BY_FIXME(x)
-
-// Disables warnings for a single read operation. This can be used to avoid
-// warnings when it is known that the read is not actually involved in a race,
-// but the compiler cannot confirm that.
-#define TS_UNCHECKED_READ(x) thread_safety_analysis::ts_unchecked_read(x)
-
-
-namespace thread_safety_analysis {
-
-// Takes a reference to a guarded data member, and returns an unguarded
-// reference.
-template <typename T>
-inline const T& ts_unchecked_read(const T& v) NO_THREAD_SAFETY_ANALYSIS {
- return v;
-}
-
-template <typename T>
-inline T& ts_unchecked_read(T& v) NO_THREAD_SAFETY_ANALYSIS {
- return v;
-}
-
-} // namespace thread_safety_analysis
-
-#endif // defined(ABSL_LEGACY_THREAD_ANNOTATIONS)
-
-#endif // ABSL_BASE_INTERNAL_THREAD_ANNOTATIONS_H_
diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/thread_identity.cc b/contrib/restricted/abseil-cpp/absl/base/internal/thread_identity.cc
index 252443ebcd..0471a25dce 100644
--- a/contrib/restricted/abseil-cpp/absl/base/internal/thread_identity.cc
+++ b/contrib/restricted/abseil-cpp/absl/base/internal/thread_identity.cc
@@ -16,8 +16,12 @@
#if !defined(_WIN32) || defined(__MINGW32__)
#include <pthread.h>
+#ifndef __wasi__
+// WASI does not provide this header, either way we disable use
+// of signals with it below.
#include <signal.h>
#endif
+#endif
#include <atomic>
#include <cassert>
@@ -80,10 +84,12 @@ void SetCurrentThreadIdentity(ThreadIdentity* identity,
absl::call_once(init_thread_identity_key_once, AllocateThreadIdentityKey,
reclaimer);
-#if defined(__EMSCRIPTEN__) || defined(__MINGW32__) || defined(__hexagon__)
- // Emscripten and MinGW pthread implementations does not support signals.
- // See https://kripken.github.io/emscripten-site/docs/porting/pthreads.html
- // for more information.
+#if defined(__wasi__) || defined(__EMSCRIPTEN__) || defined(__MINGW32__) || \
+ defined(__hexagon__)
+ // Emscripten, WASI and MinGW pthread implementations does not support
+ // signals. See
+ // https://kripken.github.io/emscripten-site/docs/porting/pthreads.html for
+ // more information.
pthread_setspecific(thread_identity_pthread_key,
reinterpret_cast<void*>(identity));
#else
diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/unaligned_access.h b/contrib/restricted/abseil-cpp/absl/base/internal/unaligned_access.h
index 093dd9b499..4fea457491 100644
--- a/contrib/restricted/abseil-cpp/absl/base/internal/unaligned_access.h
+++ b/contrib/restricted/abseil-cpp/absl/base/internal/unaligned_access.h
@@ -23,6 +23,7 @@
#include "absl/base/attributes.h"
#include "absl/base/config.h"
+#include "absl/base/nullability.h"
// unaligned APIs
@@ -35,29 +36,35 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {
-inline uint16_t UnalignedLoad16(const void *p) {
+inline uint16_t UnalignedLoad16(absl::Nonnull<const void *> p) {
uint16_t t;
memcpy(&t, p, sizeof t);
return t;
}
-inline uint32_t UnalignedLoad32(const void *p) {
+inline uint32_t UnalignedLoad32(absl::Nonnull<const void *> p) {
uint32_t t;
memcpy(&t, p, sizeof t);
return t;
}
-inline uint64_t UnalignedLoad64(const void *p) {
+inline uint64_t UnalignedLoad64(absl::Nonnull<const void *> p) {
uint64_t t;
memcpy(&t, p, sizeof t);
return t;
}
-inline void UnalignedStore16(void *p, uint16_t v) { memcpy(p, &v, sizeof v); }
+inline void UnalignedStore16(absl::Nonnull<void *> p, uint16_t v) {
+ memcpy(p, &v, sizeof v);
+}
-inline void UnalignedStore32(void *p, uint32_t v) { memcpy(p, &v, sizeof v); }
+inline void UnalignedStore32(absl::Nonnull<void *> p, uint32_t v) {
+ memcpy(p, &v, sizeof v);
+}
-inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); }
+inline void UnalignedStore64(absl::Nonnull<void *> p, uint64_t v) {
+ memcpy(p, &v, sizeof v);
+}
} // namespace base_internal
ABSL_NAMESPACE_END
diff --git a/contrib/restricted/abseil-cpp/absl/base/log_severity.cc b/contrib/restricted/abseil-cpp/absl/base/log_severity.cc
index 60a8fc1f89..8e7bbbc9e0 100644
--- a/contrib/restricted/abseil-cpp/absl/base/log_severity.cc
+++ b/contrib/restricted/abseil-cpp/absl/base/log_severity.cc
@@ -17,6 +17,7 @@
#include <ostream>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/contrib/restricted/abseil-cpp/absl/base/log_severity.h b/contrib/restricted/abseil-cpp/absl/base/log_severity.h
index 8bdca38b5f..de9702ab68 100644
--- a/contrib/restricted/abseil-cpp/absl/base/log_severity.h
+++ b/contrib/restricted/abseil-cpp/absl/base/log_severity.h
@@ -64,6 +64,8 @@ ABSL_NAMESPACE_BEGIN
// --my_log_level=info
// --my_log_level=0
//
+// `DFATAL` and `kLogDebugFatal` are similarly accepted.
+//
// Unparsing a flag produces the same result as `absl::LogSeverityName()` for
// the standard levels and a base-ten integer otherwise.
enum class LogSeverity : int {
@@ -82,18 +84,28 @@ constexpr std::array<absl::LogSeverity, 4> LogSeverities() {
absl::LogSeverity::kError, absl::LogSeverity::kFatal}};
}
+// `absl::kLogDebugFatal` equals `absl::LogSeverity::kFatal` in debug builds
+// (i.e. when `NDEBUG` is not defined) and `absl::LogSeverity::kError`
+// otherwise. Avoid ODR-using this variable as it has internal linkage and thus
+// distinct storage in different TUs.
+#ifdef NDEBUG
+static constexpr absl::LogSeverity kLogDebugFatal = absl::LogSeverity::kError;
+#else
+static constexpr absl::LogSeverity kLogDebugFatal = absl::LogSeverity::kFatal;
+#endif
+
// LogSeverityName()
//
// Returns the all-caps string representation (e.g. "INFO") of the specified
// severity level if it is one of the standard levels and "UNKNOWN" otherwise.
constexpr const char* LogSeverityName(absl::LogSeverity s) {
- return s == absl::LogSeverity::kInfo
- ? "INFO"
- : s == absl::LogSeverity::kWarning
- ? "WARNING"
- : s == absl::LogSeverity::kError
- ? "ERROR"
- : s == absl::LogSeverity::kFatal ? "FATAL" : "UNKNOWN";
+ switch (s) {
+ case absl::LogSeverity::kInfo: return "INFO";
+ case absl::LogSeverity::kWarning: return "WARNING";
+ case absl::LogSeverity::kError: return "ERROR";
+ case absl::LogSeverity::kFatal: return "FATAL";
+ }
+ return "UNKNOWN";
}
// NormalizeLogSeverity()
@@ -101,9 +113,10 @@ constexpr const char* LogSeverityName(absl::LogSeverity s) {
// Values less than `kInfo` normalize to `kInfo`; values greater than `kFatal`
// normalize to `kError` (**NOT** `kFatal`).
constexpr absl::LogSeverity NormalizeLogSeverity(absl::LogSeverity s) {
- return s < absl::LogSeverity::kInfo
- ? absl::LogSeverity::kInfo
- : s > absl::LogSeverity::kFatal ? absl::LogSeverity::kError : s;
+ absl::LogSeverity n = s;
+ if (n < absl::LogSeverity::kInfo) n = absl::LogSeverity::kInfo;
+ if (n > absl::LogSeverity::kFatal) n = absl::LogSeverity::kError;
+ return n;
}
constexpr absl::LogSeverity NormalizeLogSeverity(int s) {
return absl::NormalizeLogSeverity(static_cast<absl::LogSeverity>(s));
diff --git a/contrib/restricted/abseil-cpp/absl/base/no_destructor.h b/contrib/restricted/abseil-cpp/absl/base/no_destructor.h
new file mode 100644
index 0000000000..d4b16a6e88
--- /dev/null
+++ b/contrib/restricted/abseil-cpp/absl/base/no_destructor.h
@@ -0,0 +1,217 @@
+// Copyright 2023 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: no_destructor.h
+// -----------------------------------------------------------------------------
+//
+// This header file defines the absl::NoDestructor<T> wrapper for defining a
+// static type that does not need to be destructed upon program exit. Instead,
+// such an object survives during program exit (and can be safely accessed at
+// any time).
+//
+// Objects of such type, if constructed safely and under the right conditions,
+// provide two main benefits over other alternatives:
+//
+// * Global objects not normally allowed due to concerns of destruction order
+// (i.e. no "complex globals") can be safely allowed, provided that such
+// objects can be constant initialized.
+// * Function scope static objects can be optimized to avoid heap allocation,
+// pointer chasing, and allow lazy construction.
+//
+// See below for complete details.
+
+
+#ifndef ABSL_BASE_NO_DESTRUCTOR_H_
+#define ABSL_BASE_NO_DESTRUCTOR_H_
+
+#include <new>
+#include <type_traits>
+#include <utility>
+
+#include "absl/base/config.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+
+// absl::NoDestructor<T>
+//
+// NoDestructor<T> is a wrapper around an object of type T that behaves as an
+// object of type T but never calls T's destructor. NoDestructor<T> makes it
+// safer and/or more efficient to use such objects in static storage contexts:
+// as global or function scope static variables.
+//
+// An instance of absl::NoDestructor<T> has similar type semantics to an
+// instance of T:
+//
+// * Constructs in the same manner as an object of type T through perfect
+// forwarding.
+// * Provides pointer/reference semantic access to the object of type T via
+// `->`, `*`, and `get()`.
+// (Note that `const NoDestructor<T>` works like a pointer to const `T`.)
+//
+// An object of type NoDestructor<T> should be defined in static storage:
+// as either a global static object, or as a function scope static variable.
+//
+// Additionally, NoDestructor<T> provides the following benefits:
+//
+// * Never calls T's destructor for the object
+// * If the object is a function-local static variable, the type can be
+// lazily constructed.
+//
+// An object of type NoDestructor<T> is "trivially destructible" in the notion
+// that its destructor is never run. Provided that an object of this type can be
+// safely initialized and does not need to be cleaned up on program shutdown,
+// NoDestructor<T> allows you to define global static variables, since Google's
+// C++ style guide ban on such objects doesn't apply to objects that are
+// trivially destructible.
+//
+// Usage as Global Static Variables
+//
+// NoDestructor<T> allows declaration of a global object with a non-trivial
+// constructor in static storage without needing to add a destructor.
+// However, such objects still need to worry about initialization order, so
+// such objects should be const initialized:
+//
+// // Global or namespace scope.
+// ABSL_CONST_INIT absl::NoDestructor<MyRegistry> reg{"foo", "bar", 8008};
+//
+// Note that if your object already has a trivial destructor, you don't need to
+// use NoDestructor<T>.
+//
+// Usage as Function Scope Static Variables
+//
+// Function static objects will be lazily initialized within static storage:
+//
+// // Function scope.
+// const std::string& MyString() {
+// static const absl::NoDestructor<std::string> x("foo");
+// return *x;
+// }
+//
+// For function static variables, NoDestructor avoids heap allocation and can be
+// inlined in static storage, resulting in exactly-once, thread-safe
+// construction of an object, and very fast access thereafter (the cost is a few
+// extra cycles).
+//
+// Using NoDestructor<T> in this manner is generally better than other patterns
+// which require pointer chasing:
+//
+// // Prefer using absl::NoDestructor<T> instead for the static variable.
+// const std::string& MyString() {
+// static const std::string* x = new std::string("foo");
+// return *x;
+// }
+//
+template <typename T>
+class NoDestructor {
+ public:
+ // Forwards arguments to the T's constructor: calls T(args...).
+ template <typename... Ts,
+ // Disable this overload when it might collide with copy/move.
+ typename std::enable_if<!std::is_same<void(std::decay_t<Ts>&...),
+ void(NoDestructor&)>::value,
+ int>::type = 0>
+ explicit constexpr NoDestructor(Ts&&... args)
+ : impl_(std::forward<Ts>(args)...) {}
+
+ // Forwards copy and move construction for T. Enables usage like this:
+ // static NoDestructor<std::array<string, 3>> x{{{"1", "2", "3"}}};
+ // static NoDestructor<std::vector<int>> x{{1, 2, 3}};
+ explicit constexpr NoDestructor(const T& x) : impl_(x) {}
+ explicit constexpr NoDestructor(T&& x)
+ : impl_(std::move(x)) {}
+
+ // No copying.
+ NoDestructor(const NoDestructor&) = delete;
+ NoDestructor& operator=(const NoDestructor&) = delete;
+
+ // Pretend to be a smart pointer to T with deep constness.
+ // Never returns a null pointer.
+ T& operator*() { return *get(); }
+ T* operator->() { return get(); }
+ T* get() { return impl_.get(); }
+ const T& operator*() const { return *get(); }
+ const T* operator->() const { return get(); }
+ const T* get() const { return impl_.get(); }
+
+ private:
+ class DirectImpl {
+ public:
+ template <typename... Args>
+ explicit constexpr DirectImpl(Args&&... args)
+ : value_(std::forward<Args>(args)...) {}
+ const T* get() const { return &value_; }
+ T* get() { return &value_; }
+
+ private:
+ T value_;
+ };
+
+ class PlacementImpl {
+ public:
+ template <typename... Args>
+ explicit PlacementImpl(Args&&... args) {
+ new (&space_) T(std::forward<Args>(args)...);
+ }
+ const T* get() const {
+ return Launder(reinterpret_cast<const T*>(&space_));
+ }
+ T* get() { return Launder(reinterpret_cast<T*>(&space_)); }
+
+ private:
+ template <typename P>
+ static P* Launder(P* p) {
+#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606L
+ return std::launder(p);
+#elif ABSL_HAVE_BUILTIN(__builtin_launder)
+ return __builtin_launder(p);
+#else
+ // When `std::launder` or equivalent are not available, we rely on
+ // undefined behavior, which works as intended on Abseil's officially
+ // supported platforms as of Q3 2023.
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif
+ return p;
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+#endif
+ }
+
+ alignas(T) unsigned char space_[sizeof(T)];
+ };
+
+ // If the object is trivially destructible we use a member directly to avoid
+ // potential once-init runtime initialization. It somewhat defeats the
+ // purpose of NoDestructor in this case, but this makes the class more
+ // friendly to generic code.
+ std::conditional_t<std::is_trivially_destructible<T>::value, DirectImpl,
+ PlacementImpl>
+ impl_;
+};
+
+#ifdef ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
+// Provide 'Class Template Argument Deduction': the type of NoDestructor's T
+// will be the same type as the argument passed to NoDestructor's constructor.
+template <typename T>
+NoDestructor(T) -> NoDestructor<T>;
+#endif // ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
+
+ABSL_NAMESPACE_END
+} // namespace absl
+
+#endif // ABSL_BASE_NO_DESTRUCTOR_H_
diff --git a/contrib/restricted/abseil-cpp/absl/base/nullability.h b/contrib/restricted/abseil-cpp/absl/base/nullability.h
new file mode 100644
index 0000000000..6f49b6f535
--- /dev/null
+++ b/contrib/restricted/abseil-cpp/absl/base/nullability.h
@@ -0,0 +1,224 @@
+// Copyright 2023 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: nullability.h
+// -----------------------------------------------------------------------------
+//
+// This header file defines a set of "templated annotations" for designating the
+// expected nullability of pointers. These annotations allow you to designate
+// pointers in one of three classification states:
+//
+// * "Non-null" (for pointers annotated `Nonnull<T>`), indicating that it is
+// invalid for the given pointer to ever be null.
+// * "Nullable" (for pointers annotated `Nullable<T>`), indicating that it is
+// valid for the given pointer to be null.
+// * "Unknown" (for pointers annotated `NullabilityUnknown<T>`), indicating
+// that the given pointer has not been yet classified as either nullable or
+// non-null. This is the default state of unannotated pointers.
+//
+// NOTE: unannotated pointers implicitly bear the annotation
+// `NullabilityUnknown<T>`; you should rarely, if ever, see this annotation used
+// in the codebase explicitly.
+//
+// -----------------------------------------------------------------------------
+// Nullability and Contracts
+// -----------------------------------------------------------------------------
+//
+// These nullability annotations allow you to more clearly specify contracts on
+// software components by narrowing the *preconditions*, *postconditions*, and
+// *invariants* of pointer state(s) in any given interface. It then depends on
+// context who is responsible for fulfilling the annotation's requirements.
+//
+// For example, a function may receive a pointer argument. Designating that
+// pointer argument as "non-null" tightens the precondition of the contract of
+// that function. It is then the responsibility of anyone calling such a
+// function to ensure that the passed pointer is not null.
+//
+// Similarly, a function may have a pointer as a return value. Designating that
+// return value as "non-null" tightens the postcondition of the contract of that
+// function. In this case, however, it is the responsibility of the function
+// itself to ensure that the returned pointer is not null.
+//
+// Clearly defining these contracts allows providers (and consumers) of such
+// pointers to have more confidence in their null state. If a function declares
+// a return value as "non-null", for example, the caller should not need to
+// check whether the returned value is `nullptr`; it can simply assume the
+// pointer is valid.
+//
+// Of course most interfaces already have expectations on the nullability state
+// of pointers, and these expectations are, in effect, a contract; often,
+// however, those contracts are either poorly or partially specified, assumed,
+// or misunderstood. These nullability annotations are designed to allow you to
+// formalize those contracts within the codebase.
+//
+// -----------------------------------------------------------------------------
+// Using Nullability Annotations
+// -----------------------------------------------------------------------------
+//
+// It is important to note that these annotations are not distinct strong
+// *types*. They are alias templates defined to be equal to the underlying
+// pointer type. A pointer annotated `Nonnull<T*>`, for example, is simply a
+// pointer of type `T*`. Each annotation acts as a form of documentation about
+// the contract for the given pointer. Each annotation requires providers or
+// consumers of these pointers across API boundaries to take appropriate steps
+// when setting or using these pointers:
+//
+// * "Non-null" pointers should never be null. It is the responsibility of the
+// provider of this pointer to ensure that the pointer may never be set to
+// null. Consumers of such pointers can treat such pointers as non-null.
+// * "Nullable" pointers may or may not be null. Consumers of such pointers
+// should precede any usage of that pointer (e.g. a dereference operation)
+// with a a `nullptr` check.
+// * "Unknown" pointers may be either "non-null" or "nullable" but have not been
+// definitively determined to be in either classification state. Providers of
+// such pointers across API boundaries should determine -- over time -- to
+// annotate the pointer in either of the above two states. Consumers of such
+// pointers across an API boundary should continue to treat such pointers as
+// they currently do.
+//
+// Example:
+//
+// // PaySalary() requires the passed pointer to an `Employee` to be non-null.
+// void PaySalary(absl::Nonnull<Employee *> e) {
+// pay(e->salary); // OK to dereference
+// }
+//
+// // CompleteTransaction() guarantees the returned pointer to an `Account` to
+// // be non-null.
+// absl::Nonnull<Account *> balance CompleteTransaction(double fee) {
+// ...
+// }
+//
+// // Note that specifying a nullability annotation does not prevent someone
+// // from violating the contract:
+//
+// Nullable<Employee *> find(Map& employees, std::string_view name);
+//
+// void g(Map& employees) {
+// Employee *e = find(employees, "Pat");
+// // `e` can now be null.
+// PaySalary(e); // Violates contract, but compiles!
+// }
+//
+// Nullability annotations, in other words, are useful for defining and
+// narrowing contracts; *enforcement* of those contracts depends on use and any
+// additional (static or dynamic analysis) tooling.
+//
+// NOTE: The "unknown" annotation state indicates that a pointer's contract has
+// not yet been positively identified. The unknown state therefore acts as a
+// form of documentation of your technical debt, and a codebase that adopts
+// nullability annotations should aspire to annotate every pointer as either
+// "non-null" or "nullable".
+//
+// -----------------------------------------------------------------------------
+// Applicability of Nullability Annotations
+// -----------------------------------------------------------------------------
+//
+// By default, nullability annotations are applicable to raw and smart
+// pointers. User-defined types can indicate compatibility with nullability
+// annotations by providing an `absl_nullability_compatible` nested type. 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;
+// ...
+// };
+//
+// DISCLAIMER:
+// ===========================================================================
+// These nullability annotations are primarily a human readable signal about the
+// intended contract of the pointer. They are not *types* and do not currently
+// provide any correctness guarantees. For example, a pointer annotated as
+// `Nonnull<T*>` is *not guaranteed* to be non-null, and the compiler won't
+// alert or prevent assignment of a `Nullable<T*>` to a `Nonnull<T*>`.
+// ===========================================================================
+#ifndef ABSL_BASE_NULLABILITY_H_
+#define ABSL_BASE_NULLABILITY_H_
+
+#include "absl/base/internal/nullability_impl.h"
+
+namespace absl {
+
+// absl::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 be
+// set to null. Consumers of this pointer across an API boundary may safely
+// dereference the pointer.
+//
+// Example:
+//
+// // `employee` is designated as not null.
+// void PaySalary(absl::Nonnull<Employee *> employee) {
+// pay(*employee); // OK to dereference
+// }
+template <typename T>
+using Nonnull = nullability_internal::NonnullImpl<T>;
+
+// absl::Nullable
+//
+// The indicated pointer may, by design, be either null or non-null. Consumers
+// of this pointer across an API boundary should perform a `nullptr` check
+// before performing any operation using the pointer.
+//
+// Example:
+//
+// // `employee` may be null.
+// void PaySalary(absl::Nullable<Employee *> employee) {
+// if (employee != nullptr) {
+// Pay(*employee); // OK to dereference
+// }
+// }
+template <typename T>
+using Nullable = nullability_internal::NullableImpl<T>;
+
+// absl::NullabilityUnknown (default)
+//
+// The indicated pointer has not yet been determined to be definitively
+// "non-null" or "nullable." Providers of such pointers across API boundaries
+// should, over time, annotate such pointers as either "non-null" or "nullable."
+// Consumers of these pointers across an API boundary should treat such pointers
+// with the same caution they treat currently unannotated pointers. Most
+// existing code will have "unknown" pointers, which should eventually be
+// migrated into one of the above two nullability states: `Nonnull<T>` or
+// `Nullable<T>`.
+//
+// NOTE: Because this annotation is the global default state, pointers without
+// any annotation are assumed to have "unknown" semantics. This assumption is
+// designed to minimize churn and reduce clutter within the codebase.
+//
+// Example:
+//
+// // `employee`s nullability state is unknown.
+// void PaySalary(absl::NullabilityUnknown<Employee *> employee) {
+// Pay(*employee); // Potentially dangerous. API provider should investigate.
+// }
+//
+// Note that a pointer without an annotation, by default, is assumed to have the
+// annotation `NullabilityUnknown`.
+//
+// // `employee`s nullability state is unknown.
+// void PaySalary(Employee* employee) {
+// Pay(*employee); // Potentially dangerous. API provider should investigate.
+// }
+template <typename T>
+using NullabilityUnknown = nullability_internal::NullabilityUnknownImpl<T>;
+
+} // namespace absl
+
+#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 ad0121ad3b..f985995899 100644
--- a/contrib/restricted/abseil-cpp/absl/base/optimization.h
+++ b/contrib/restricted/abseil-cpp/absl/base/optimization.h
@@ -25,6 +25,7 @@
#include <assert.h>
#include "absl/base/config.h"
+#include "absl/base/options.h"
// ABSL_BLOCK_TAIL_CALL_OPTIMIZATION
//
diff --git a/contrib/restricted/abseil-cpp/absl/base/options.h b/contrib/restricted/abseil-cpp/absl/base/options.h
index f308e1bf8b..d7bf8cffe6 100644
--- a/contrib/restricted/abseil-cpp/absl/base/options.h
+++ b/contrib/restricted/abseil-cpp/absl/base/options.h
@@ -176,6 +176,32 @@
#define ABSL_OPTION_USE_STD_VARIANT 2
+// ABSL_OPTION_USE_STD_ORDERING
+//
+// This option controls whether absl::{partial,weak,strong}_ordering are
+// implemented as aliases to the std:: ordering types, or as an independent
+// implementation.
+//
+// A value of 0 means to use Abseil's implementation. This requires only C++11
+// support, and is expected to work on every toolchain we support.
+//
+// A value of 1 means to use aliases. This requires that all code using Abseil
+// is built in C++20 mode or later.
+//
+// A value of 2 means to detect the C++ version being used to compile Abseil,
+// and use an alias only if working std:: ordering types are available. This
+// option is useful when you are building your program from source. It should
+// not be used otherwise -- for example, if you are distributing Abseil in a
+// binary package manager -- since in mode 2, they will name different types,
+// with different mangled names and binary layout, depending on the compiler
+// flags passed by the end user. For more info, see
+// https://abseil.io/about/design/dropin-types.
+//
+// User code should not inspect this macro. To check in the preprocessor if
+// the ordering types are aliases of std:: ordering types, use the feature macro
+// ABSL_USES_STD_ORDERING.
+
+#define ABSL_OPTION_USE_STD_ORDERING 2
// ABSL_OPTION_USE_INLINE_NAMESPACE
// ABSL_OPTION_INLINE_NAMESPACE_NAME
@@ -200,7 +226,7 @@
// allowed.
#define ABSL_OPTION_USE_INLINE_NAMESPACE 1
-#define ABSL_OPTION_INLINE_NAMESPACE_NAME lts_20230802
+#define ABSL_OPTION_INLINE_NAMESPACE_NAME lts_20240116
// ABSL_OPTION_HARDENED
//
diff --git a/contrib/restricted/abseil-cpp/absl/base/prefetch.h b/contrib/restricted/abseil-cpp/absl/base/prefetch.h
index de7a180d60..eb40a4453c 100644
--- a/contrib/restricted/abseil-cpp/absl/base/prefetch.h
+++ b/contrib/restricted/abseil-cpp/absl/base/prefetch.h
@@ -24,17 +24,19 @@
#ifndef ABSL_BASE_PREFETCH_H_
#define ABSL_BASE_PREFETCH_H_
+#include "absl/base/attributes.h"
#include "absl/base/config.h"
#if defined(ABSL_INTERNAL_HAVE_SSE)
#include <xmmintrin.h>
#endif
-#if defined(_MSC_VER) && _MSC_VER >= 1900 && \
- (defined(_M_X64) || defined(_M_IX86))
+#if defined(_MSC_VER)
#include <intrin.h>
+#if defined(ABSL_INTERNAL_HAVE_SSE)
#pragma intrinsic(_mm_prefetch)
#endif
+#endif
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -140,21 +142,24 @@ void PrefetchToLocalCacheForWrite(const void* addr);
// See __builtin_prefetch:
// https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html.
//
-inline void PrefetchToLocalCache(const void* addr) {
+ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCache(
+ const void* addr) {
__builtin_prefetch(addr, 0, 3);
}
-inline void PrefetchToLocalCacheNta(const void* addr) {
+ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCacheNta(
+ const void* addr) {
__builtin_prefetch(addr, 0, 0);
}
-inline void PrefetchToLocalCacheForWrite(const void* addr) {
+ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCacheForWrite(
+ const void* addr) {
// [x86] gcc/clang don't generate PREFETCHW for __builtin_prefetch(.., 1)
// unless -march=broadwell or newer; this is not generally the default, so we
// manually emit prefetchw. PREFETCHW is recognized as a no-op on older Intel
// processors and has been present on AMD processors since the K6-2.
-#if defined(__x86_64__)
- asm("prefetchw (%0)" : : "r"(addr));
+#if defined(__x86_64__) && !defined(__PRFCHW__)
+ asm("prefetchw %0" : : "m"(*reinterpret_cast<const char*>(addr)));
#else
__builtin_prefetch(addr, 1, 3);
#endif
@@ -164,15 +169,18 @@ inline void PrefetchToLocalCacheForWrite(const void* addr) {
#define ABSL_HAVE_PREFETCH 1
-inline void PrefetchToLocalCache(const void* addr) {
+ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCache(
+ const void* addr) {
_mm_prefetch(reinterpret_cast<const char*>(addr), _MM_HINT_T0);
}
-inline void PrefetchToLocalCacheNta(const void* addr) {
+ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCacheNta(
+ const void* addr) {
_mm_prefetch(reinterpret_cast<const char*>(addr), _MM_HINT_NTA);
}
-inline void PrefetchToLocalCacheForWrite(const void* addr) {
+ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCacheForWrite(
+ const void* addr) {
#if defined(_MM_HINT_ET0)
_mm_prefetch(reinterpret_cast<const char*>(addr), _MM_HINT_ET0);
#elif !defined(_MSC_VER) && defined(__x86_64__)
@@ -180,15 +188,18 @@ inline void PrefetchToLocalCacheForWrite(const void* addr) {
// up, PREFETCHW is recognized as a no-op on older Intel processors
// and has been present on AMD processors since the K6-2. We have this
// disabled for MSVC compilers as this miscompiles on older MSVC compilers.
- asm("prefetchw (%0)" : : "r"(addr));
+ asm("prefetchw %0" : : "m"(*reinterpret_cast<const char*>(addr)));
#endif
}
#else
-inline void PrefetchToLocalCache(const void* addr) {}
-inline void PrefetchToLocalCacheNta(const void* addr) {}
-inline void PrefetchToLocalCacheForWrite(const void* addr) {}
+ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCache(
+ const void* addr) {}
+ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCacheNta(
+ const void* addr) {}
+ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCacheForWrite(
+ const void* addr) {}
#endif
diff --git a/contrib/restricted/abseil-cpp/absl/base/thread_annotations.h b/contrib/restricted/abseil-cpp/absl/base/thread_annotations.h
index bc8a620347..4a3f3e33e9 100644
--- a/contrib/restricted/abseil-cpp/absl/base/thread_annotations.h
+++ b/contrib/restricted/abseil-cpp/absl/base/thread_annotations.h
@@ -36,8 +36,6 @@
#include "absl/base/attributes.h"
#include "absl/base/config.h"
-// TODO(mbonadei): Remove after the backward compatibility period.
-#include "absl/base/internal/thread_annotations.h" // IWYU pragma: export
// ABSL_GUARDED_BY()
//
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 8f4d993911..acd013b026 100644
--- a/contrib/restricted/abseil-cpp/absl/container/flat_hash_map.h
+++ b/contrib/restricted/abseil-cpp/absl/container/flat_hash_map.h
@@ -64,7 +64,7 @@ struct FlatHashMapPolicy;
// `insert()`, provided that the map is provided a compatible heterogeneous
// hashing function and equality operator.
// * Invalidates any references and pointers to elements within the table after
-// `rehash()`.
+// `rehash()` and when the table is moved.
// * Contains a `capacity()` member function indicating the number of element
// slots (open, deleted, and empty) within the hash map.
// * Returns `void` from the `erase(iterator)` overload.
@@ -579,9 +579,9 @@ struct FlatHashMapPolicy {
}
template <class Allocator>
- static void transfer(Allocator* alloc, slot_type* new_slot,
+ static auto transfer(Allocator* alloc, slot_type* new_slot,
slot_type* old_slot) {
- slot_policy::transfer(alloc, new_slot, old_slot);
+ return slot_policy::transfer(alloc, new_slot, old_slot);
}
template <class F, class... Args>
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 c789c7ef54..a94a82a0bf 100644
--- a/contrib/restricted/abseil-cpp/absl/container/flat_hash_set.h
+++ b/contrib/restricted/abseil-cpp/absl/container/flat_hash_set.h
@@ -60,7 +60,7 @@ struct FlatHashSetPolicy;
// that the set is provided a compatible heterogeneous hashing function and
// equality operator.
// * Invalidates any references and pointers to elements within the table after
-// `rehash()`.
+// `rehash()` and when the table is moved.
// * Contains a `capacity()` member function indicating the number of element
// slots (open, deleted, and empty) within the hash set.
// * Returns `void` from the `erase(iterator)` overload.
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 3558a5439b..57eac678fa 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
@@ -93,11 +93,13 @@ struct common_policy_traits {
struct Rank0 : Rank1 {};
// Use auto -> decltype as an enabler.
+ // P::transfer returns std::true_type if transfer uses memcpy (e.g. in
+ // node_slot_policy).
template <class Alloc, class P = Policy>
static auto transfer_impl(Alloc* alloc, slot_type* new_slot,
slot_type* old_slot, Rank0)
- -> decltype((void)P::transfer(alloc, new_slot, old_slot)) {
- P::transfer(alloc, new_slot, old_slot);
+ -> decltype(P::transfer(alloc, new_slot, old_slot)) {
+ return P::transfer(alloc, new_slot, old_slot);
}
#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606
// This overload returns true_type for the trait below.
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 f59ca4ee22..3262d4eb8d 100644
--- a/contrib/restricted/abseil-cpp/absl/container/internal/container_memory.h
+++ b/contrib/restricted/abseil-cpp/absl/container/internal/container_memory.h
@@ -122,10 +122,10 @@ auto TupleRefImpl(T&& t, absl::index_sequence<Is...>)
// Returns a tuple of references to the elements of the input tuple. T must be a
// tuple.
template <class T>
-auto TupleRef(T&& t) -> decltype(
- TupleRefImpl(std::forward<T>(t),
- absl::make_index_sequence<
- std::tuple_size<typename std::decay<T>::type>::value>())) {
+auto TupleRef(T&& t) -> decltype(TupleRefImpl(
+ std::forward<T>(t),
+ absl::make_index_sequence<
+ std::tuple_size<typename std::decay<T>::type>::value>())) {
return TupleRefImpl(
std::forward<T>(t),
absl::make_index_sequence<
@@ -156,8 +156,8 @@ void ConstructFromTuple(Alloc* alloc, T* ptr, Tuple&& t) {
// Constructs T using the args specified in the tuple and calls F with the
// constructed value.
template <class T, class Tuple, class F>
-decltype(std::declval<F>()(std::declval<T>())) WithConstructed(
- Tuple&& t, F&& f) {
+decltype(std::declval<F>()(std::declval<T>())) WithConstructed(Tuple&& t,
+ F&& f) {
return memory_internal::WithConstructedImpl<T>(
std::forward<Tuple>(t),
absl::make_index_sequence<
@@ -423,16 +423,19 @@ struct map_slot_policy {
}
template <class Allocator>
- static void transfer(Allocator* alloc, slot_type* new_slot,
+ static auto transfer(Allocator* alloc, slot_type* new_slot,
slot_type* old_slot) {
+ auto is_relocatable =
+ typename absl::is_trivially_relocatable<value_type>::type();
+
emplace(new_slot);
#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606
- if (absl::is_trivially_relocatable<value_type>()) {
+ if (is_relocatable) {
// TODO(b/247130232,b/251814870): remove casts after fixing warnings.
std::memcpy(static_cast<void*>(std::launder(&new_slot->value)),
static_cast<const void*>(&old_slot->value),
sizeof(value_type));
- return;
+ return is_relocatable;
}
#endif
@@ -444,6 +447,7 @@ struct map_slot_policy {
std::move(old_slot->value));
}
destroy(alloc, old_slot);
+ return is_relocatable;
}
};
diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler.h b/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler.h
index d8fd8f34f9..e41ee2d747 100644
--- a/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler.h
+++ b/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler.h
@@ -137,18 +137,7 @@ class HashtablezInfoHandle {
UnsampleSlow(info_);
}
- HashtablezInfoHandle(const HashtablezInfoHandle&) = delete;
- HashtablezInfoHandle& operator=(const HashtablezInfoHandle&) = delete;
-
- HashtablezInfoHandle(HashtablezInfoHandle&& o) noexcept
- : info_(absl::exchange(o.info_, nullptr)) {}
- HashtablezInfoHandle& operator=(HashtablezInfoHandle&& o) noexcept {
- if (ABSL_PREDICT_FALSE(info_ != nullptr)) {
- UnsampleSlow(info_);
- }
- info_ = absl::exchange(o.info_, nullptr);
- return *this;
- }
+ inline bool IsSampled() const { return ABSL_PREDICT_FALSE(info_ != nullptr); }
inline void RecordStorageChanged(size_t size, size_t capacity) {
if (ABSL_PREDICT_TRUE(info_ == nullptr)) return;
@@ -198,6 +187,7 @@ class HashtablezInfoHandle {
explicit HashtablezInfoHandle(std::nullptr_t) {}
inline void Unregister() {}
+ inline bool IsSampled() const { return false; }
inline void RecordStorageChanged(size_t /*size*/, size_t /*capacity*/) {}
inline void RecordRehash(size_t /*total_probe_length*/) {}
inline void RecordReservation(size_t /*target_capacity*/) {}
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 b2a602db7e..0eb9c34ddd 100644
--- a/contrib/restricted/abseil-cpp/absl/container/internal/inlined_vector.h
+++ b/contrib/restricted/abseil-cpp/absl/container/internal/inlined_vector.h
@@ -26,6 +26,7 @@
#include <utility>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/container/internal/compressed_tuple.h"
#include "absl/memory/memory.h"
@@ -384,7 +385,17 @@ class Storage {
bool GetIsAllocated() const { return GetSizeAndIsAllocated() & 1; }
- Pointer<A> GetAllocatedData() { return data_.allocated.allocated_data; }
+ Pointer<A> GetAllocatedData() {
+ // GCC 12 has a false-positive -Wmaybe-uninitialized warning here.
+#if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(12, 0)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ return data_.allocated.allocated_data;
+#if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(12, 0)
+#pragma GCC diagnostic pop
+#endif
+ }
ConstPointer<A> GetAllocatedData() const {
return data_.allocated.allocated_data;
diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/layout.h b/contrib/restricted/abseil-cpp/absl/container/internal/layout.h
deleted file mode 100644
index a59a243059..0000000000
--- a/contrib/restricted/abseil-cpp/absl/container/internal/layout.h
+++ /dev/null
@@ -1,743 +0,0 @@
-// Copyright 2018 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// MOTIVATION AND TUTORIAL
-//
-// If you want to put in a single heap allocation N doubles followed by M ints,
-// it's easy if N and M are known at compile time.
-//
-// struct S {
-// double a[N];
-// int b[M];
-// };
-//
-// S* p = new S;
-//
-// But what if N and M are known only in run time? Class template Layout to the
-// rescue! It's a portable generalization of the technique known as struct hack.
-//
-// // This object will tell us everything we need to know about the memory
-// // layout of double[N] followed by int[M]. It's structurally identical to
-// // size_t[2] that stores N and M. It's very cheap to create.
-// const Layout<double, int> layout(N, M);
-//
-// // Allocate enough memory for both arrays. `AllocSize()` tells us how much
-// // memory is needed. We are free to use any allocation function we want as
-// // long as it returns aligned memory.
-// std::unique_ptr<unsigned char[]> p(new unsigned char[layout.AllocSize()]);
-//
-// // Obtain the pointer to the array of doubles.
-// // Equivalent to `reinterpret_cast<double*>(p.get())`.
-// //
-// // We could have written layout.Pointer<0>(p) instead. If all the types are
-// // unique you can use either form, but if some types are repeated you must
-// // use the index form.
-// double* a = layout.Pointer<double>(p.get());
-//
-// // Obtain the pointer to the array of ints.
-// // Equivalent to `reinterpret_cast<int*>(p.get() + N * 8)`.
-// int* b = layout.Pointer<int>(p);
-//
-// If we are unable to specify sizes of all fields, we can pass as many sizes as
-// we can to `Partial()`. In return, it'll allow us to access the fields whose
-// locations and sizes can be computed from the provided information.
-// `Partial()` comes in handy when the array sizes are embedded into the
-// allocation.
-//
-// // size_t[1] containing N, size_t[1] containing M, double[N], int[M].
-// using L = Layout<size_t, size_t, double, int>;
-//
-// unsigned char* Allocate(size_t n, size_t m) {
-// const L layout(1, 1, n, m);
-// unsigned char* p = new unsigned char[layout.AllocSize()];
-// *layout.Pointer<0>(p) = n;
-// *layout.Pointer<1>(p) = m;
-// return p;
-// }
-//
-// void Use(unsigned char* p) {
-// // First, extract N and M.
-// // Specify that the first array has only one element. Using `prefix` we
-// // can access the first two arrays but not more.
-// constexpr auto prefix = L::Partial(1);
-// size_t n = *prefix.Pointer<0>(p);
-// size_t m = *prefix.Pointer<1>(p);
-//
-// // Now we can get pointers to the payload.
-// const L layout(1, 1, n, m);
-// double* a = layout.Pointer<double>(p);
-// int* b = layout.Pointer<int>(p);
-// }
-//
-// The layout we used above combines fixed-size with dynamically-sized fields.
-// This is quite common. Layout is optimized for this use case and generates
-// optimal code. All computations that can be performed at compile time are
-// indeed performed at compile time.
-//
-// Efficiency tip: The order of fields matters. In `Layout<T1, ..., TN>` try to
-// ensure that `alignof(T1) >= ... >= alignof(TN)`. This way you'll have no
-// padding in between arrays.
-//
-// You can manually override the alignment of an array by wrapping the type in
-// `Aligned<T, N>`. `Layout<..., Aligned<T, N>, ...>` has exactly the same API
-// and behavior as `Layout<..., T, ...>` except that the first element of the
-// array of `T` is aligned to `N` (the rest of the elements follow without
-// padding). `N` cannot be less than `alignof(T)`.
-//
-// `AllocSize()` and `Pointer()` are the most basic methods for dealing with
-// memory layouts. Check out the reference or code below to discover more.
-//
-// EXAMPLE
-//
-// // Immutable move-only string with sizeof equal to sizeof(void*). The
-// // string size and the characters are kept in the same heap allocation.
-// class CompactString {
-// public:
-// CompactString(const char* s = "") {
-// const size_t size = strlen(s);
-// // size_t[1] followed by char[size + 1].
-// const L layout(1, size + 1);
-// p_.reset(new unsigned char[layout.AllocSize()]);
-// // If running under ASAN, mark the padding bytes, if any, to catch
-// // memory errors.
-// layout.PoisonPadding(p_.get());
-// // Store the size in the allocation.
-// *layout.Pointer<size_t>(p_.get()) = size;
-// // Store the characters in the allocation.
-// memcpy(layout.Pointer<char>(p_.get()), s, size + 1);
-// }
-//
-// size_t size() const {
-// // Equivalent to reinterpret_cast<size_t&>(*p).
-// return *L::Partial().Pointer<size_t>(p_.get());
-// }
-//
-// const char* c_str() const {
-// // Equivalent to reinterpret_cast<char*>(p.get() + sizeof(size_t)).
-// // The argument in Partial(1) specifies that we have size_t[1] in front
-// // of the characters.
-// return L::Partial(1).Pointer<char>(p_.get());
-// }
-//
-// private:
-// // Our heap allocation contains a size_t followed by an array of chars.
-// using L = Layout<size_t, char>;
-// std::unique_ptr<unsigned char[]> p_;
-// };
-//
-// int main() {
-// CompactString s = "hello";
-// assert(s.size() == 5);
-// assert(strcmp(s.c_str(), "hello") == 0);
-// }
-//
-// DOCUMENTATION
-//
-// The interface exported by this file consists of:
-// - class `Layout<>` and its public members.
-// - The public members of class `internal_layout::LayoutImpl<>`. That class
-// isn't intended to be used directly, and its name and template parameter
-// list are internal implementation details, but the class itself provides
-// most of the functionality in this file. See comments on its members for
-// detailed documentation.
-//
-// `Layout<T1,... Tn>::Partial(count1,..., countm)` (where `m` <= `n`) returns a
-// `LayoutImpl<>` object. `Layout<T1,..., Tn> layout(count1,..., countn)`
-// creates a `Layout` object, which exposes the same functionality by inheriting
-// from `LayoutImpl<>`.
-
-#ifndef ABSL_CONTAINER_INTERNAL_LAYOUT_H_
-#define ABSL_CONTAINER_INTERNAL_LAYOUT_H_
-
-#include <assert.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include <ostream>
-#include <string>
-#include <tuple>
-#include <type_traits>
-#include <typeinfo>
-#include <utility>
-
-#include "absl/base/config.h"
-#include "absl/meta/type_traits.h"
-#include "absl/strings/str_cat.h"
-#include "absl/types/span.h"
-#include "absl/utility/utility.h"
-
-#ifdef ABSL_HAVE_ADDRESS_SANITIZER
-#include <sanitizer/asan_interface.h>
-#endif
-
-#if defined(__GXX_RTTI)
-#define ABSL_INTERNAL_HAS_CXA_DEMANGLE
-#endif
-
-#ifdef ABSL_INTERNAL_HAS_CXA_DEMANGLE
-#include <cxxabi.h>
-#endif
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-namespace container_internal {
-
-// A type wrapper that instructs `Layout` to use the specific alignment for the
-// array. `Layout<..., Aligned<T, N>, ...>` has exactly the same API
-// and behavior as `Layout<..., T, ...>` except that the first element of the
-// array of `T` is aligned to `N` (the rest of the elements follow without
-// padding).
-//
-// Requires: `N >= alignof(T)` and `N` is a power of 2.
-template <class T, size_t N>
-struct Aligned;
-
-namespace internal_layout {
-
-template <class T>
-struct NotAligned {};
-
-template <class T, size_t N>
-struct NotAligned<const Aligned<T, N>> {
- static_assert(sizeof(T) == 0, "Aligned<T, N> cannot be const-qualified");
-};
-
-template <size_t>
-using IntToSize = size_t;
-
-template <class>
-using TypeToSize = size_t;
-
-template <class T>
-struct Type : NotAligned<T> {
- using type = T;
-};
-
-template <class T, size_t N>
-struct Type<Aligned<T, N>> {
- using type = T;
-};
-
-template <class T>
-struct SizeOf : NotAligned<T>, std::integral_constant<size_t, sizeof(T)> {};
-
-template <class T, size_t N>
-struct SizeOf<Aligned<T, N>> : std::integral_constant<size_t, sizeof(T)> {};
-
-// Note: workaround for https://gcc.gnu.org/PR88115
-template <class T>
-struct AlignOf : NotAligned<T> {
- static constexpr size_t value = alignof(T);
-};
-
-template <class T, size_t N>
-struct AlignOf<Aligned<T, N>> {
- static_assert(N % alignof(T) == 0,
- "Custom alignment can't be lower than the type's alignment");
- static constexpr size_t value = N;
-};
-
-// Does `Ts...` contain `T`?
-template <class T, class... Ts>
-using Contains = absl::disjunction<std::is_same<T, Ts>...>;
-
-template <class From, class To>
-using CopyConst =
- typename std::conditional<std::is_const<From>::value, const To, To>::type;
-
-// Note: We're not qualifying this with absl:: because it doesn't compile under
-// MSVC.
-template <class T>
-using SliceType = Span<T>;
-
-// This namespace contains no types. It prevents functions defined in it from
-// being found by ADL.
-namespace adl_barrier {
-
-template <class Needle, class... Ts>
-constexpr size_t Find(Needle, Needle, Ts...) {
- static_assert(!Contains<Needle, Ts...>(), "Duplicate element type");
- return 0;
-}
-
-template <class Needle, class T, class... Ts>
-constexpr size_t Find(Needle, T, Ts...) {
- return adl_barrier::Find(Needle(), Ts()...) + 1;
-}
-
-constexpr bool IsPow2(size_t n) { return !(n & (n - 1)); }
-
-// Returns `q * m` for the smallest `q` such that `q * m >= n`.
-// Requires: `m` is a power of two. It's enforced by IsLegalElementType below.
-constexpr size_t Align(size_t n, size_t m) { return (n + m - 1) & ~(m - 1); }
-
-constexpr size_t Min(size_t a, size_t b) { return b < a ? b : a; }
-
-constexpr size_t Max(size_t a) { return a; }
-
-template <class... Ts>
-constexpr size_t Max(size_t a, size_t b, Ts... rest) {
- return adl_barrier::Max(b < a ? a : b, rest...);
-}
-
-template <class T>
-std::string TypeName() {
- std::string out;
- int status = 0;
- char* demangled = nullptr;
-#ifdef ABSL_INTERNAL_HAS_CXA_DEMANGLE
- demangled = abi::__cxa_demangle(typeid(T).name(), nullptr, nullptr, &status);
-#endif
- if (status == 0 && demangled != nullptr) { // Demangling succeeded.
- absl::StrAppend(&out, "<", demangled, ">");
- free(demangled);
- } else {
-#if defined(__GXX_RTTI) || defined(_CPPRTTI)
- absl::StrAppend(&out, "<", typeid(T).name(), ">");
-#endif
- }
- return out;
-}
-
-} // namespace adl_barrier
-
-template <bool C>
-using EnableIf = typename std::enable_if<C, int>::type;
-
-// Can `T` be a template argument of `Layout`?
-template <class T>
-using IsLegalElementType = std::integral_constant<
- bool, !std::is_reference<T>::value && !std::is_volatile<T>::value &&
- !std::is_reference<typename Type<T>::type>::value &&
- !std::is_volatile<typename Type<T>::type>::value &&
- adl_barrier::IsPow2(AlignOf<T>::value)>;
-
-template <class Elements, class SizeSeq, class OffsetSeq>
-class LayoutImpl;
-
-// Public base class of `Layout` and the result type of `Layout::Partial()`.
-//
-// `Elements...` contains all template arguments of `Layout` that created this
-// instance.
-//
-// `SizeSeq...` is `[0, NumSizes)` where `NumSizes` is the number of arguments
-// passed to `Layout::Partial()` or `Layout::Layout()`.
-//
-// `OffsetSeq...` is `[0, NumOffsets)` where `NumOffsets` is
-// `Min(sizeof...(Elements), NumSizes + 1)` (the number of arrays for which we
-// can compute offsets).
-template <class... Elements, size_t... SizeSeq, size_t... OffsetSeq>
-class LayoutImpl<std::tuple<Elements...>, absl::index_sequence<SizeSeq...>,
- absl::index_sequence<OffsetSeq...>> {
- private:
- static_assert(sizeof...(Elements) > 0, "At least one field is required");
- static_assert(absl::conjunction<IsLegalElementType<Elements>...>::value,
- "Invalid element type (see IsLegalElementType)");
-
- enum {
- NumTypes = sizeof...(Elements),
- NumSizes = sizeof...(SizeSeq),
- NumOffsets = sizeof...(OffsetSeq),
- };
-
- // These are guaranteed by `Layout`.
- static_assert(NumOffsets == adl_barrier::Min(NumTypes, NumSizes + 1),
- "Internal error");
- static_assert(NumTypes > 0, "Internal error");
-
- // Returns the index of `T` in `Elements...`. Results in a compilation error
- // if `Elements...` doesn't contain exactly one instance of `T`.
- template <class T>
- static constexpr size_t ElementIndex() {
- static_assert(Contains<Type<T>, Type<typename Type<Elements>::type>...>(),
- "Type not found");
- return adl_barrier::Find(Type<T>(),
- Type<typename Type<Elements>::type>()...);
- }
-
- template <size_t N>
- using ElementAlignment =
- AlignOf<typename std::tuple_element<N, std::tuple<Elements...>>::type>;
-
- public:
- // Element types of all arrays packed in a tuple.
- using ElementTypes = std::tuple<typename Type<Elements>::type...>;
-
- // Element type of the Nth array.
- template <size_t N>
- using ElementType = typename std::tuple_element<N, ElementTypes>::type;
-
- constexpr explicit LayoutImpl(IntToSize<SizeSeq>... sizes)
- : size_{sizes...} {}
-
- // Alignment of the layout, equal to the strictest alignment of all elements.
- // All pointers passed to the methods of layout must be aligned to this value.
- static constexpr size_t Alignment() {
- return adl_barrier::Max(AlignOf<Elements>::value...);
- }
-
- // Offset in bytes of the Nth array.
- //
- // // int[3], 4 bytes of padding, double[4].
- // Layout<int, double> x(3, 4);
- // assert(x.Offset<0>() == 0); // The ints starts from 0.
- // assert(x.Offset<1>() == 16); // The doubles starts from 16.
- //
- // Requires: `N <= NumSizes && N < sizeof...(Ts)`.
- template <size_t N, EnableIf<N == 0> = 0>
- constexpr size_t Offset() const {
- return 0;
- }
-
- template <size_t N, EnableIf<N != 0> = 0>
- constexpr size_t Offset() const {
- static_assert(N < NumOffsets, "Index out of bounds");
- return adl_barrier::Align(
- Offset<N - 1>() + SizeOf<ElementType<N - 1>>::value * size_[N - 1],
- ElementAlignment<N>::value);
- }
-
- // Offset in bytes of the array with the specified element type. There must
- // be exactly one such array and its zero-based index must be at most
- // `NumSizes`.
- //
- // // int[3], 4 bytes of padding, double[4].
- // Layout<int, double> x(3, 4);
- // assert(x.Offset<int>() == 0); // The ints starts from 0.
- // assert(x.Offset<double>() == 16); // The doubles starts from 16.
- template <class T>
- constexpr size_t Offset() const {
- return Offset<ElementIndex<T>()>();
- }
-
- // Offsets in bytes of all arrays for which the offsets are known.
- constexpr std::array<size_t, NumOffsets> Offsets() const {
- return {{Offset<OffsetSeq>()...}};
- }
-
- // The number of elements in the Nth array. This is the Nth argument of
- // `Layout::Partial()` or `Layout::Layout()` (zero-based).
- //
- // // int[3], 4 bytes of padding, double[4].
- // Layout<int, double> x(3, 4);
- // assert(x.Size<0>() == 3);
- // assert(x.Size<1>() == 4);
- //
- // Requires: `N < NumSizes`.
- template <size_t N>
- constexpr size_t Size() const {
- static_assert(N < NumSizes, "Index out of bounds");
- return size_[N];
- }
-
- // The number of elements in the array with the specified element type.
- // There must be exactly one such array and its zero-based index must be
- // at most `NumSizes`.
- //
- // // int[3], 4 bytes of padding, double[4].
- // Layout<int, double> x(3, 4);
- // assert(x.Size<int>() == 3);
- // assert(x.Size<double>() == 4);
- template <class T>
- constexpr size_t Size() const {
- return Size<ElementIndex<T>()>();
- }
-
- // The number of elements of all arrays for which they are known.
- constexpr std::array<size_t, NumSizes> Sizes() const {
- return {{Size<SizeSeq>()...}};
- }
-
- // Pointer to the beginning of the Nth array.
- //
- // `Char` must be `[const] [signed|unsigned] char`.
- //
- // // int[3], 4 bytes of padding, double[4].
- // Layout<int, double> x(3, 4);
- // unsigned char* p = new unsigned char[x.AllocSize()];
- // int* ints = x.Pointer<0>(p);
- // double* doubles = x.Pointer<1>(p);
- //
- // Requires: `N <= NumSizes && N < sizeof...(Ts)`.
- // Requires: `p` is aligned to `Alignment()`.
- template <size_t N, class Char>
- CopyConst<Char, ElementType<N>>* Pointer(Char* p) const {
- using C = typename std::remove_const<Char>::type;
- static_assert(
- std::is_same<C, char>() || std::is_same<C, unsigned char>() ||
- std::is_same<C, signed char>(),
- "The argument must be a pointer to [const] [signed|unsigned] char");
- constexpr size_t alignment = Alignment();
- (void)alignment;
- assert(reinterpret_cast<uintptr_t>(p) % alignment == 0);
- return reinterpret_cast<CopyConst<Char, ElementType<N>>*>(p + Offset<N>());
- }
-
- // Pointer to the beginning of the array with the specified element type.
- // There must be exactly one such array and its zero-based index must be at
- // most `NumSizes`.
- //
- // `Char` must be `[const] [signed|unsigned] char`.
- //
- // // int[3], 4 bytes of padding, double[4].
- // Layout<int, double> x(3, 4);
- // unsigned char* p = new unsigned char[x.AllocSize()];
- // int* ints = x.Pointer<int>(p);
- // double* doubles = x.Pointer<double>(p);
- //
- // Requires: `p` is aligned to `Alignment()`.
- template <class T, class Char>
- CopyConst<Char, T>* Pointer(Char* p) const {
- return Pointer<ElementIndex<T>()>(p);
- }
-
- // Pointers to all arrays for which pointers are known.
- //
- // `Char` must be `[const] [signed|unsigned] char`.
- //
- // // int[3], 4 bytes of padding, double[4].
- // Layout<int, double> x(3, 4);
- // unsigned char* p = new unsigned char[x.AllocSize()];
- //
- // int* ints;
- // double* doubles;
- // std::tie(ints, doubles) = x.Pointers(p);
- //
- // Requires: `p` is aligned to `Alignment()`.
- //
- // Note: We're not using ElementType alias here because it does not compile
- // under MSVC.
- template <class Char>
- std::tuple<CopyConst<
- Char, typename std::tuple_element<OffsetSeq, ElementTypes>::type>*...>
- Pointers(Char* p) const {
- return std::tuple<CopyConst<Char, ElementType<OffsetSeq>>*...>(
- Pointer<OffsetSeq>(p)...);
- }
-
- // The Nth array.
- //
- // `Char` must be `[const] [signed|unsigned] char`.
- //
- // // int[3], 4 bytes of padding, double[4].
- // Layout<int, double> x(3, 4);
- // unsigned char* p = new unsigned char[x.AllocSize()];
- // Span<int> ints = x.Slice<0>(p);
- // Span<double> doubles = x.Slice<1>(p);
- //
- // Requires: `N < NumSizes`.
- // Requires: `p` is aligned to `Alignment()`.
- template <size_t N, class Char>
- SliceType<CopyConst<Char, ElementType<N>>> Slice(Char* p) const {
- return SliceType<CopyConst<Char, ElementType<N>>>(Pointer<N>(p), Size<N>());
- }
-
- // The array with the specified element type. There must be exactly one
- // such array and its zero-based index must be less than `NumSizes`.
- //
- // `Char` must be `[const] [signed|unsigned] char`.
- //
- // // int[3], 4 bytes of padding, double[4].
- // Layout<int, double> x(3, 4);
- // unsigned char* p = new unsigned char[x.AllocSize()];
- // Span<int> ints = x.Slice<int>(p);
- // Span<double> doubles = x.Slice<double>(p);
- //
- // Requires: `p` is aligned to `Alignment()`.
- template <class T, class Char>
- SliceType<CopyConst<Char, T>> Slice(Char* p) const {
- return Slice<ElementIndex<T>()>(p);
- }
-
- // All arrays with known sizes.
- //
- // `Char` must be `[const] [signed|unsigned] char`.
- //
- // // int[3], 4 bytes of padding, double[4].
- // Layout<int, double> x(3, 4);
- // unsigned char* p = new unsigned char[x.AllocSize()];
- //
- // Span<int> ints;
- // Span<double> doubles;
- // std::tie(ints, doubles) = x.Slices(p);
- //
- // Requires: `p` is aligned to `Alignment()`.
- //
- // Note: We're not using ElementType alias here because it does not compile
- // under MSVC.
- template <class Char>
- std::tuple<SliceType<CopyConst<
- Char, typename std::tuple_element<SizeSeq, ElementTypes>::type>>...>
- Slices(Char* p) const {
- // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63875 (fixed
- // in 6.1).
- (void)p;
- return std::tuple<SliceType<CopyConst<Char, ElementType<SizeSeq>>>...>(
- Slice<SizeSeq>(p)...);
- }
-
- // The size of the allocation that fits all arrays.
- //
- // // int[3], 4 bytes of padding, double[4].
- // Layout<int, double> x(3, 4);
- // unsigned char* p = new unsigned char[x.AllocSize()]; // 48 bytes
- //
- // Requires: `NumSizes == sizeof...(Ts)`.
- constexpr size_t AllocSize() const {
- static_assert(NumTypes == NumSizes, "You must specify sizes of all fields");
- return Offset<NumTypes - 1>() +
- SizeOf<ElementType<NumTypes - 1>>::value * size_[NumTypes - 1];
- }
-
- // If built with --config=asan, poisons padding bytes (if any) in the
- // allocation. The pointer must point to a memory block at least
- // `AllocSize()` bytes in length.
- //
- // `Char` must be `[const] [signed|unsigned] char`.
- //
- // Requires: `p` is aligned to `Alignment()`.
- template <class Char, size_t N = NumOffsets - 1, EnableIf<N == 0> = 0>
- void PoisonPadding(const Char* p) const {
- Pointer<0>(p); // verify the requirements on `Char` and `p`
- }
-
- template <class Char, size_t N = NumOffsets - 1, EnableIf<N != 0> = 0>
- void PoisonPadding(const Char* p) const {
- static_assert(N < NumOffsets, "Index out of bounds");
- (void)p;
-#ifdef ABSL_HAVE_ADDRESS_SANITIZER
- PoisonPadding<Char, N - 1>(p);
- // The `if` is an optimization. It doesn't affect the observable behaviour.
- if (ElementAlignment<N - 1>::value % ElementAlignment<N>::value) {
- size_t start =
- Offset<N - 1>() + SizeOf<ElementType<N - 1>>::value * size_[N - 1];
- ASAN_POISON_MEMORY_REGION(p + start, Offset<N>() - start);
- }
-#endif
- }
-
- // Human-readable description of the memory layout. Useful for debugging.
- // Slow.
- //
- // // char[5], 3 bytes of padding, int[3], 4 bytes of padding, followed
- // // by an unknown number of doubles.
- // auto x = Layout<char, int, double>::Partial(5, 3);
- // assert(x.DebugString() ==
- // "@0<char>(1)[5]; @8<int>(4)[3]; @24<double>(8)");
- //
- // Each field is in the following format: @offset<type>(sizeof)[size] (<type>
- // may be missing depending on the target platform). For example,
- // @8<int>(4)[3] means that at offset 8 we have an array of ints, where each
- // int is 4 bytes, and we have 3 of those ints. The size of the last field may
- // be missing (as in the example above). Only fields with known offsets are
- // described. Type names may differ across platforms: one compiler might
- // produce "unsigned*" where another produces "unsigned int *".
- std::string DebugString() const {
- const auto offsets = Offsets();
- const size_t sizes[] = {SizeOf<ElementType<OffsetSeq>>::value...};
- const std::string types[] = {
- adl_barrier::TypeName<ElementType<OffsetSeq>>()...};
- std::string res = absl::StrCat("@0", types[0], "(", sizes[0], ")");
- for (size_t i = 0; i != NumOffsets - 1; ++i) {
- absl::StrAppend(&res, "[", size_[i], "]; @", offsets[i + 1], types[i + 1],
- "(", sizes[i + 1], ")");
- }
- // NumSizes is a constant that may be zero. Some compilers cannot see that
- // inside the if statement "size_[NumSizes - 1]" must be valid.
- int last = static_cast<int>(NumSizes) - 1;
- if (NumTypes == NumSizes && last >= 0) {
- absl::StrAppend(&res, "[", size_[last], "]");
- }
- return res;
- }
-
- private:
- // Arguments of `Layout::Partial()` or `Layout::Layout()`.
- size_t size_[NumSizes > 0 ? NumSizes : 1];
-};
-
-template <size_t NumSizes, class... Ts>
-using LayoutType = LayoutImpl<
- std::tuple<Ts...>, absl::make_index_sequence<NumSizes>,
- absl::make_index_sequence<adl_barrier::Min(sizeof...(Ts), NumSizes + 1)>>;
-
-} // namespace internal_layout
-
-// Descriptor of arrays of various types and sizes laid out in memory one after
-// another. See the top of the file for documentation.
-//
-// Check out the public API of internal_layout::LayoutImpl above. The type is
-// internal to the library but its methods are public, and they are inherited
-// by `Layout`.
-template <class... Ts>
-class Layout : public internal_layout::LayoutType<sizeof...(Ts), Ts...> {
- public:
- static_assert(sizeof...(Ts) > 0, "At least one field is required");
- static_assert(
- absl::conjunction<internal_layout::IsLegalElementType<Ts>...>::value,
- "Invalid element type (see IsLegalElementType)");
-
- // The result type of `Partial()` with `NumSizes` arguments.
- template <size_t NumSizes>
- using PartialType = internal_layout::LayoutType<NumSizes, Ts...>;
-
- // `Layout` knows the element types of the arrays we want to lay out in
- // memory but not the number of elements in each array.
- // `Partial(size1, ..., sizeN)` allows us to specify the latter. The
- // resulting immutable object can be used to obtain pointers to the
- // individual arrays.
- //
- // It's allowed to pass fewer array sizes than the number of arrays. E.g.,
- // if all you need is to the offset of the second array, you only need to
- // pass one argument -- the number of elements in the first array.
- //
- // // int[3] followed by 4 bytes of padding and an unknown number of
- // // doubles.
- // auto x = Layout<int, double>::Partial(3);
- // // doubles start at byte 16.
- // assert(x.Offset<1>() == 16);
- //
- // If you know the number of elements in all arrays, you can still call
- // `Partial()` but it's more convenient to use the constructor of `Layout`.
- //
- // Layout<int, double> x(3, 5);
- //
- // Note: The sizes of the arrays must be specified in number of elements,
- // not in bytes.
- //
- // Requires: `sizeof...(Sizes) <= sizeof...(Ts)`.
- // Requires: all arguments are convertible to `size_t`.
- template <class... Sizes>
- static constexpr PartialType<sizeof...(Sizes)> Partial(Sizes&&... sizes) {
- static_assert(sizeof...(Sizes) <= sizeof...(Ts), "");
- return PartialType<sizeof...(Sizes)>(absl::forward<Sizes>(sizes)...);
- }
-
- // Creates a layout with the sizes of all arrays specified. If you know
- // only the sizes of the first N arrays (where N can be zero), you can use
- // `Partial()` defined above. The constructor is essentially equivalent to
- // calling `Partial()` and passing in all array sizes; the constructor is
- // provided as a convenient abbreviation.
- //
- // Note: The sizes of the arrays must be specified in number of elements,
- // not in bytes.
- constexpr explicit Layout(internal_layout::TypeToSize<Ts>... sizes)
- : internal_layout::LayoutType<sizeof...(Ts), Ts...>(sizes...) {}
-};
-
-} // namespace container_internal
-ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_CONTAINER_INTERNAL_LAYOUT_H_
diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_map.h b/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_map.h
index 2d5a8710ad..97182bc7bd 100644
--- a/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_map.h
+++ b/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_map.h
@@ -19,6 +19,8 @@
#include <type_traits>
#include <utility>
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/internal/throw_delegate.h"
#include "absl/container/internal/container_memory.h"
#include "absl/container/internal/raw_hash_set.h" // IWYU pragma: export
@@ -175,13 +177,20 @@ class raw_hash_map : public raw_hash_set<Policy, Hash, Eq, Alloc> {
template <class K = key_type, class P = Policy, K* = nullptr>
MappedReference<P> operator[](key_arg<K>&& key)
ABSL_ATTRIBUTE_LIFETIME_BOUND {
- return Policy::value(&*try_emplace(std::forward<K>(key)).first);
+ // It is safe to use unchecked_deref here because try_emplace
+ // will always return an iterator pointing to a valid item in the table,
+ // since it inserts if nothing is found for the given key.
+ return Policy::value(
+ &this->unchecked_deref(try_emplace(std::forward<K>(key)).first));
}
template <class K = key_type, class P = Policy>
MappedReference<P> operator[](const key_arg<K>& key)
ABSL_ATTRIBUTE_LIFETIME_BOUND {
- return Policy::value(&*try_emplace(key).first);
+ // It is safe to use unchecked_deref here because try_emplace
+ // will always return an iterator pointing to a valid item in the table,
+ // since it inserts if nothing is found for the given key.
+ return Policy::value(&this->unchecked_deref(try_emplace(key).first));
}
private:
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 2ff95b6182..9f8ea51987 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
@@ -17,11 +17,13 @@
#include <atomic>
#include <cassert>
#include <cstddef>
+#include <cstdint>
#include <cstring>
#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/dynamic_annotations.h"
+#include "absl/container/internal/container_memory.h"
#include "absl/hash/hash.h"
namespace absl {
@@ -67,6 +69,16 @@ inline size_t RandomSeed() {
return value ^ static_cast<size_t>(reinterpret_cast<uintptr_t>(&counter));
}
+bool ShouldRehashForBugDetection(const ctrl_t* ctrl, size_t capacity) {
+ // Note: we can't use the abseil-random library because abseil-random
+ // depends on swisstable. We want to return true with probability
+ // `min(1, RehashProbabilityConstant() / capacity())`. In order to do this,
+ // we probe based on a random hash and see if the offset is less than
+ // RehashProbabilityConstant().
+ return probe(ctrl, capacity, absl::HashOf(RandomSeed())).offset() <
+ RehashProbabilityConstant();
+}
+
} // namespace
GenerationType* EmptyGeneration() {
@@ -84,13 +96,12 @@ bool CommonFieldsGenerationInfoEnabled::
size_t capacity) const {
if (reserved_growth_ == kReservedGrowthJustRanOut) return true;
if (reserved_growth_ > 0) return false;
- // Note: we can't use the abseil-random library because abseil-random
- // depends on swisstable. We want to return true with probability
- // `min(1, RehashProbabilityConstant() / capacity())`. In order to do this,
- // we probe based on a random hash and see if the offset is less than
- // RehashProbabilityConstant().
- return probe(ctrl, capacity, absl::HashOf(RandomSeed())).offset() <
- RehashProbabilityConstant();
+ return ShouldRehashForBugDetection(ctrl, capacity);
+}
+
+bool CommonFieldsGenerationInfoEnabled::should_rehash_for_bug_detection_on_move(
+ const ctrl_t* ctrl, size_t capacity) const {
+ return ShouldRehashForBugDetection(ctrl, capacity);
}
bool ShouldInsertBackwards(size_t hash, const ctrl_t* ctrl) {
@@ -117,14 +128,6 @@ FindInfo find_first_non_full_outofline(const CommonFields& common,
return find_first_non_full(common, hash);
}
-// Returns the address of the ith slot in slots where each slot occupies
-// slot_size.
-static inline void* SlotAddress(void* slot_array, size_t slot,
- size_t slot_size) {
- return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(slot_array) +
- (slot * slot_size));
-}
-
// Returns the address of the slot just after slot assuming each slot has the
// specified size.
static inline void* NextSlot(void* slot, size_t slot_size) {
@@ -218,26 +221,35 @@ void DropDeletesWithoutResize(CommonFields& common,
common.infoz().RecordRehash(total_probe_length);
}
-void EraseMetaOnly(CommonFields& c, ctrl_t* it, size_t slot_size) {
- assert(IsFull(*it) && "erasing a dangling iterator");
- c.set_size(c.size() - 1);
- const auto index = static_cast<size_t>(it - c.control());
+static bool WasNeverFull(CommonFields& c, size_t index) {
+ if (is_single_group(c.capacity())) {
+ return true;
+ }
const size_t index_before = (index - Group::kWidth) & c.capacity();
- const auto empty_after = Group(it).MaskEmpty();
+ const auto empty_after = Group(c.control() + index).MaskEmpty();
const auto empty_before = Group(c.control() + index_before).MaskEmpty();
// We count how many consecutive non empties we have to the right and to the
// left of `it`. If the sum is >= kWidth then there is at least one probe
// window that might have seen a full group.
- bool was_never_full = empty_before && empty_after &&
- static_cast<size_t>(empty_after.TrailingZeros()) +
- empty_before.LeadingZeros() <
- Group::kWidth;
-
- SetCtrl(c, index, was_never_full ? ctrl_t::kEmpty : ctrl_t::kDeleted,
- slot_size);
- c.set_growth_left(c.growth_left() + (was_never_full ? 1 : 0));
+ return empty_before && empty_after &&
+ static_cast<size_t>(empty_after.TrailingZeros()) +
+ empty_before.LeadingZeros() <
+ Group::kWidth;
+}
+
+void EraseMetaOnly(CommonFields& c, size_t index, size_t slot_size) {
+ assert(IsFull(c.control()[index]) && "erasing a dangling iterator");
+ c.decrement_size();
c.infoz().RecordErase();
+
+ if (WasNeverFull(c, index)) {
+ SetCtrl(c, index, ctrl_t::kEmpty, slot_size);
+ c.set_growth_left(c.growth_left() + 1);
+ return;
+ }
+
+ SetCtrl(c, index, ctrl_t::kDeleted, slot_size);
}
void ClearBackingArray(CommonFields& c, const PolicyFunctions& policy,
@@ -245,19 +257,124 @@ void ClearBackingArray(CommonFields& c, const PolicyFunctions& policy,
c.set_size(0);
if (reuse) {
ResetCtrl(c, policy.slot_size);
+ ResetGrowthLeft(c);
c.infoz().RecordStorageChanged(0, c.capacity());
} else {
+ // We need to record infoz before calling dealloc, which will unregister
+ // infoz.
+ c.infoz().RecordClearedReservation();
+ c.infoz().RecordStorageChanged(0, 0);
(*policy.dealloc)(c, policy);
c.set_control(EmptyGroup());
c.set_generation_ptr(EmptyGeneration());
c.set_slots(nullptr);
c.set_capacity(0);
- c.infoz().RecordClearedReservation();
- assert(c.size() == 0);
- c.infoz().RecordStorageChanged(0, 0);
}
}
+void HashSetResizeHelper::GrowIntoSingleGroupShuffleControlBytes(
+ ctrl_t* new_ctrl, size_t new_capacity) const {
+ assert(is_single_group(new_capacity));
+ constexpr size_t kHalfWidth = Group::kWidth / 2;
+ assert(old_capacity_ < kHalfWidth);
+
+ const size_t half_old_capacity = old_capacity_ / 2;
+
+ // NOTE: operations are done with compile time known size = kHalfWidth.
+ // Compiler optimizes that into single ASM operation.
+
+ // Copy second half of bytes to the beginning.
+ // 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_ctrl = 0S0EEEEEEE...
+ // new_ctrl = S0EEEEEEEE...
+ //
+ // old_ctrl = 01S01EEEEE...
+ // new_ctrl = 1S01EEEEEE...
+ //
+ // old_ctrl = 0123456S0123456EE...
+ // new_ctrl = 456S0123?????????...
+ std::memcpy(new_ctrl, old_ctrl_ + half_old_capacity + 1, kHalfWidth);
+ // Clean up copied kSentinel from old_ctrl.
+ new_ctrl[half_old_capacity] = ctrl_t::kEmpty;
+
+ // Clean up damaged or uninitialized bytes.
+
+ // Clean bytes after the intended size of the copy.
+ // Example:
+ // new_ctrl = 1E01EEEEEEE????
+ // *new_ctrl= 1E0EEEEEEEE????
+ // position /
+ std::memset(new_ctrl + old_capacity_ + 1, static_cast<int8_t>(ctrl_t::kEmpty),
+ kHalfWidth);
+ // Clean non-mirrored bytes that are not initialized.
+ // For small old_capacity that may be inside of mirrored bytes zone.
+ // Examples:
+ // new_ctrl = 1E0EEEEEEEE??????????....
+ // *new_ctrl= 1E0EEEEEEEEEEEEE?????....
+ // position /
+ //
+ // new_ctrl = 456E0123???????????...
+ // *new_ctrl= 456E0123EEEEEEEE???...
+ // position /
+ std::memset(new_ctrl + kHalfWidth, static_cast<int8_t>(ctrl_t::kEmpty),
+ kHalfWidth);
+ // Clean last mirrored bytes that are not initialized
+ // and will not be overwritten by mirroring.
+ // Examples:
+ // new_ctrl = 1E0EEEEEEEEEEEEE????????
+ // *new_ctrl= 1E0EEEEEEEEEEEEEEEEEEEEE
+ // position S /
+ //
+ // new_ctrl = 456E0123EEEEEEEE???????????????
+ // *new_ctrl= 456E0123EEEEEEEE???????EEEEEEEE
+ // position S /
+ std::memset(new_ctrl + new_capacity + kHalfWidth,
+ static_cast<int8_t>(ctrl_t::kEmpty), kHalfWidth);
+
+ // Create mirrored bytes. old_capacity_ < kHalfWidth
+ // Example:
+ // new_ctrl = 456E0123EEEEEEEE???????EEEEEEEE
+ // *new_ctrl= 456E0123EEEEEEEE456E0123EEEEEEE
+ // position S/
+ ctrl_t g[kHalfWidth];
+ std::memcpy(g, new_ctrl, kHalfWidth);
+ std::memcpy(new_ctrl + new_capacity + 1, g, kHalfWidth);
+
+ // Finally set sentinel to its place.
+ new_ctrl[new_capacity] = ctrl_t::kSentinel;
+}
+
+void HashSetResizeHelper::GrowIntoSingleGroupShuffleTransferableSlots(
+ void* old_slots, void* new_slots, size_t slot_size) const {
+ assert(old_capacity_ > 0);
+ const size_t half_old_capacity = old_capacity_ / 2;
+
+ 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));
+}
+
+void HashSetResizeHelper::GrowSizeIntoSingleGroupTransferable(
+ CommonFields& c, void* old_slots, size_t slot_size) {
+ assert(old_capacity_ < Group::kWidth / 2);
+ assert(is_single_group(c.capacity()));
+ assert(IsGrowingIntoSingleGroupApplicable(old_capacity_, c.capacity()));
+
+ GrowIntoSingleGroupShuffleControlBytes(c.control(), c.capacity());
+ GrowIntoSingleGroupShuffleTransferableSlots(old_slots, c.slot_array(),
+ slot_size);
+
+ // We poison since GrowIntoSingleGroupShuffleTransferableSlots
+ // may leave empty slots unpoisoned.
+ PoisonSingleGroupEmptySlots(c, slot_size);
+}
+
} // 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 5f89d8efee..3518bc3404 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
@@ -62,6 +62,9 @@
// pseudo-struct:
//
// struct BackingArray {
+// // Sampling handler. This field isn't present when the sampling is
+// // disabled or this allocation hasn't been selected for sampling.
+// HashtablezInfoHandle infoz_;
// // The number of elements we can insert before growing the capacity.
// size_t growth_left;
// // Control bytes for the "real" slots.
@@ -175,25 +178,29 @@
#define ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_
#include <algorithm>
+#include <cassert>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <cstring>
+#include <initializer_list>
#include <iterator>
#include <limits>
#include <memory>
-#include <string>
#include <tuple>
#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/raw_logging.h"
+#include "absl/base/macros.h"
#include "absl/base/optimization.h"
+#include "absl/base/options.h"
#include "absl/base/port.h"
#include "absl/base/prefetch.h"
-#include "absl/container/internal/common.h"
+#include "absl/container/internal/common.h" // IWYU pragma: export // for node_handle
#include "absl/container/internal/compressed_tuple.h"
#include "absl/container/internal/container_memory.h"
#include "absl/container/internal/hash_policy_traits.h"
@@ -227,6 +234,7 @@ namespace container_internal {
#ifdef ABSL_SWISSTABLE_ENABLE_GENERATIONS
#error ABSL_SWISSTABLE_ENABLE_GENERATIONS cannot be directly set
#elif defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
+ defined(ABSL_HAVE_HWADDRESS_SANITIZER) || \
defined(ABSL_HAVE_MEMORY_SANITIZER)
// When compiled in sanitizer mode, we add generation integers to the backing
// array and iterators. In the backing array, we store the generation between
@@ -262,8 +270,21 @@ void SwapAlloc(AllocType& lhs, AllocType& rhs,
swap(lhs, rhs);
}
template <typename AllocType>
-void SwapAlloc(AllocType& /*lhs*/, AllocType& /*rhs*/,
- std::false_type /* propagate_on_container_swap */) {}
+void SwapAlloc(AllocType& lhs, AllocType& rhs,
+ std::false_type /* propagate_on_container_swap */) {
+ (void)lhs;
+ (void)rhs;
+ assert(lhs == rhs &&
+ "It's UB to call swap with unequal non-propagating allocators.");
+}
+
+template <typename AllocType>
+void CopyAlloc(AllocType& lhs, AllocType& rhs,
+ std::true_type /* propagate_alloc */) {
+ lhs = rhs;
+}
+template <typename AllocType>
+void CopyAlloc(AllocType&, AllocType&, std::false_type /* propagate_alloc */) {}
// The state for a probe sequence.
//
@@ -361,7 +382,7 @@ uint32_t TrailingZeros(T x) {
// width of an abstract bit in the representation.
// This mask provides operations for any number of real bits set in an abstract
// bit. To add iteration on top of that, implementation must guarantee no more
-// than one real bit is set in an abstract bit.
+// than the most significant real bit is set in a set abstract bit.
template <class T, int SignificantBits, int Shift = 0>
class NonIterableBitMask {
public:
@@ -388,7 +409,9 @@ class NonIterableBitMask {
uint32_t LeadingZeros() const {
constexpr int total_significant_bits = SignificantBits << Shift;
constexpr int extra_bits = sizeof(T) * 8 - total_significant_bits;
- return static_cast<uint32_t>(countl_zero(mask_ << extra_bits)) >> Shift;
+ return static_cast<uint32_t>(
+ countl_zero(static_cast<T>(mask_ << extra_bits))) >>
+ Shift;
}
T mask_;
@@ -418,6 +441,10 @@ class BitMask : public NonIterableBitMask<T, SignificantBits, Shift> {
using const_iterator = BitMask;
BitMask& operator++() {
+ if (Shift == 3) {
+ constexpr uint64_t msbs = 0x8080808080808080ULL;
+ this->mask_ &= msbs;
+ }
this->mask_ &= (this->mask_ - 1);
return *this;
}
@@ -590,29 +617,39 @@ struct GroupSse2Impl {
}
// Returns a bitmask representing the positions of slots that match hash.
- BitMask<uint32_t, kWidth> Match(h2_t hash) const {
+ BitMask<uint16_t, kWidth> Match(h2_t hash) const {
auto match = _mm_set1_epi8(static_cast<char>(hash));
- return BitMask<uint32_t, kWidth>(
- static_cast<uint32_t>(_mm_movemask_epi8(_mm_cmpeq_epi8(match, ctrl))));
+ BitMask<uint16_t, kWidth> result = BitMask<uint16_t, kWidth>(0);
+ result = 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.
- NonIterableBitMask<uint32_t, kWidth> MaskEmpty() const {
+ NonIterableBitMask<uint16_t, kWidth> MaskEmpty() const {
#ifdef ABSL_INTERNAL_HAVE_SSSE3
// This only works because ctrl_t::kEmpty is -128.
- return NonIterableBitMask<uint32_t, kWidth>(
- static_cast<uint32_t>(_mm_movemask_epi8(_mm_sign_epi8(ctrl, ctrl))));
+ return NonIterableBitMask<uint16_t, kWidth>(
+ static_cast<uint16_t>(_mm_movemask_epi8(_mm_sign_epi8(ctrl, ctrl))));
#else
auto match = _mm_set1_epi8(static_cast<char>(ctrl_t::kEmpty));
- return NonIterableBitMask<uint32_t, kWidth>(
- static_cast<uint32_t>(_mm_movemask_epi8(_mm_cmpeq_epi8(match, ctrl))));
+ return NonIterableBitMask<uint16_t, kWidth>(
+ static_cast<uint16_t>(_mm_movemask_epi8(_mm_cmpeq_epi8(match, ctrl))));
#endif
}
+ // Returns a bitmask representing the positions of full slots.
+ // Note: for `is_small()` tables group may contain the "same" slot twice:
+ // original and mirrored.
+ BitMask<uint16_t, kWidth> MaskFull() const {
+ return BitMask<uint16_t, kWidth>(
+ static_cast<uint16_t>(_mm_movemask_epi8(ctrl) ^ 0xffff));
+ }
+
// Returns a bitmask representing the positions of empty or deleted slots.
- NonIterableBitMask<uint32_t, kWidth> MaskEmptyOrDeleted() const {
+ NonIterableBitMask<uint16_t, kWidth> MaskEmptyOrDeleted() const {
auto special = _mm_set1_epi8(static_cast<char>(ctrl_t::kSentinel));
- return NonIterableBitMask<uint32_t, kWidth>(static_cast<uint32_t>(
+ return NonIterableBitMask<uint16_t, kWidth>(static_cast<uint16_t>(
_mm_movemask_epi8(_mm_cmpgt_epi8_fixed(special, ctrl))));
}
@@ -651,9 +688,8 @@ struct GroupAArch64Impl {
BitMask<uint64_t, kWidth, 3> Match(h2_t hash) const {
uint8x8_t dup = vdup_n_u8(hash);
auto mask = vceq_u8(ctrl, dup);
- constexpr uint64_t msbs = 0x8080808080808080ULL;
return BitMask<uint64_t, kWidth, 3>(
- vget_lane_u64(vreinterpret_u64_u8(mask), 0) & msbs);
+ vget_lane_u64(vreinterpret_u64_u8(mask), 0));
}
NonIterableBitMask<uint64_t, kWidth, 3> MaskEmpty() const {
@@ -665,6 +701,17 @@ struct GroupAArch64Impl {
return NonIterableBitMask<uint64_t, kWidth, 3>(mask);
}
+ // Returns a bitmask representing the positions of full slots.
+ // Note: for `is_small()` tables group may contain the "same" slot twice:
+ // original and mirrored.
+ BitMask<uint64_t, kWidth, 3> MaskFull() const {
+ uint64_t mask = vget_lane_u64(
+ vreinterpret_u64_u8(vcge_s8(vreinterpret_s8_u8(ctrl),
+ vdup_n_s8(static_cast<int8_t>(0)))),
+ 0);
+ return BitMask<uint64_t, kWidth, 3>(mask);
+ }
+
NonIterableBitMask<uint64_t, kWidth, 3> MaskEmptyOrDeleted() const {
uint64_t mask =
vget_lane_u64(vreinterpret_u64_u8(vcgt_s8(
@@ -729,13 +776,21 @@ struct GroupPortableImpl {
NonIterableBitMask<uint64_t, kWidth, 3> MaskEmpty() const {
constexpr uint64_t msbs = 0x8080808080808080ULL;
- return NonIterableBitMask<uint64_t, kWidth, 3>((ctrl & (~ctrl << 6)) &
+ return NonIterableBitMask<uint64_t, kWidth, 3>((ctrl & ~(ctrl << 6)) &
msbs);
}
+ // Returns a bitmask representing the positions of full slots.
+ // Note: for `is_small()` tables group may contain the "same" slot twice:
+ // original and mirrored.
+ BitMask<uint64_t, kWidth, 3> MaskFull() const {
+ constexpr uint64_t msbs = 0x8080808080808080ULL;
+ return BitMask<uint64_t, kWidth, 3>((ctrl ^ msbs) & msbs);
+ }
+
NonIterableBitMask<uint64_t, kWidth, 3> MaskEmptyOrDeleted() const {
constexpr uint64_t msbs = 0x8080808080808080ULL;
- return NonIterableBitMask<uint64_t, kWidth, 3>((ctrl & (~ctrl << 7)) &
+ return NonIterableBitMask<uint64_t, kWidth, 3>((ctrl & ~(ctrl << 7)) &
msbs);
}
@@ -760,10 +815,21 @@ struct GroupPortableImpl {
#ifdef ABSL_INTERNAL_HAVE_SSE2
using Group = GroupSse2Impl;
+using GroupEmptyOrDeleted = GroupSse2Impl;
#elif defined(ABSL_INTERNAL_HAVE_ARM_NEON) && defined(ABSL_IS_LITTLE_ENDIAN)
using Group = GroupAArch64Impl;
+// For Aarch64, we use the portable implementation for counting and masking
+// empty or deleted group elements. This is to avoid the latency of moving
+// between data GPRs and Neon registers when it does not provide a benefit.
+// Using Neon is profitable when we call Match(), but is not when we don't,
+// which is the case when we do *EmptyOrDeleted operations. It is difficult to
+// make a similar approach beneficial on other architectures such as x86 since
+// they have much lower GPR <-> vector register transfer latency and 16-wide
+// Groups.
+using GroupEmptyOrDeleted = GroupPortableImpl;
#else
using Group = GroupPortableImpl;
+using GroupEmptyOrDeleted = GroupPortableImpl;
#endif
// When there is an insertion with no reserved growth, we rehash with
@@ -802,15 +868,19 @@ class CommonFieldsGenerationInfoEnabled {
// whenever reserved_growth_ is zero.
bool should_rehash_for_bug_detection_on_insert(const ctrl_t* ctrl,
size_t capacity) const;
+ // Similar to above, except that we don't depend on reserved_growth_.
+ bool should_rehash_for_bug_detection_on_move(const ctrl_t* ctrl,
+ size_t capacity) const;
void maybe_increment_generation_on_insert() {
if (reserved_growth_ == kReservedGrowthJustRanOut) reserved_growth_ = 0;
if (reserved_growth_ > 0) {
if (--reserved_growth_ == 0) reserved_growth_ = kReservedGrowthJustRanOut;
} else {
- *generation_ = NextGeneration(*generation_);
+ increment_generation();
}
}
+ void increment_generation() { *generation_ = NextGeneration(*generation_); }
void reset_reserved_growth(size_t reservation, size_t size) {
reserved_growth_ = reservation - size;
}
@@ -856,7 +926,11 @@ class CommonFieldsGenerationInfoDisabled {
bool should_rehash_for_bug_detection_on_insert(const ctrl_t*, size_t) const {
return false;
}
+ bool should_rehash_for_bug_detection_on_move(const ctrl_t*, size_t) const {
+ return false;
+ }
void maybe_increment_generation_on_insert() {}
+ void increment_generation() {}
void reset_reserved_growth(size_t, size_t) {}
size_t reserved_growth() const { return 0; }
void set_reserved_growth(size_t) {}
@@ -909,9 +983,11 @@ using HashSetIteratorGenerationInfo = HashSetIteratorGenerationInfoDisabled;
// A valid capacity is a non-zero integer `2^m - 1`.
inline bool IsValidCapacity(size_t n) { return ((n + 1) & n) == 0 && n > 0; }
-// Computes the offset from the start of the backing allocation of the control
-// bytes. growth_left is stored at the beginning of the backing array.
-inline size_t ControlOffset() { return sizeof(size_t); }
+// Computes the offset from the start of the backing allocation of control.
+// infoz and growth_left are stored at the beginning of the backing array.
+inline size_t ControlOffset(bool has_infoz) {
+ return (has_infoz ? sizeof(HashtablezInfoHandle) : 0) + sizeof(size_t);
+}
// Returns the number of "cloned control bytes".
//
@@ -922,24 +998,26 @@ constexpr size_t NumClonedBytes() { return Group::kWidth - 1; }
// Given the capacity of a table, computes the offset (from the start of the
// backing allocation) of the generation counter (if it exists).
-inline size_t GenerationOffset(size_t capacity) {
+inline size_t GenerationOffset(size_t capacity, bool has_infoz) {
assert(IsValidCapacity(capacity));
const size_t num_control_bytes = capacity + 1 + NumClonedBytes();
- return ControlOffset() + num_control_bytes;
+ return ControlOffset(has_infoz) + num_control_bytes;
}
// Given the capacity of a table, computes the offset (from the start of the
// backing allocation) at which the slots begin.
-inline size_t SlotOffset(size_t capacity, size_t slot_align) {
+inline size_t SlotOffset(size_t capacity, size_t slot_align, bool has_infoz) {
assert(IsValidCapacity(capacity));
- return (GenerationOffset(capacity) + NumGenerationBytes() + slot_align - 1) &
+ return (GenerationOffset(capacity, has_infoz) + NumGenerationBytes() +
+ slot_align - 1) &
(~slot_align + 1);
}
// Given the capacity of a table, computes the total size of the backing
// array.
-inline size_t AllocSize(size_t capacity, size_t slot_size, size_t slot_align) {
- return SlotOffset(capacity, slot_align) + capacity * slot_size;
+inline size_t AllocSize(size_t capacity, size_t slot_size, size_t slot_align,
+ bool has_infoz) {
+ return SlotOffset(capacity, slot_align, has_infoz) + capacity * slot_size;
}
// CommonFields hold the fields in raw_hash_set that do not depend
@@ -954,28 +1032,15 @@ class CommonFields : public CommonFieldsGenerationInfo {
CommonFields& operator=(const CommonFields&) = delete;
// Movable
- CommonFields(CommonFields&& that)
- : CommonFieldsGenerationInfo(
- std::move(static_cast<CommonFieldsGenerationInfo&&>(that))),
- // Explicitly copying fields into "this" and then resetting "that"
- // fields generates less code then calling absl::exchange per field.
- control_(that.control()),
- slots_(that.slot_array()),
- capacity_(that.capacity()),
- compressed_tuple_(that.size(), std::move(that.infoz())) {
- that.set_control(EmptyGroup());
- that.set_slots(nullptr);
- that.set_capacity(0);
- that.set_size(0);
- }
+ CommonFields(CommonFields&& that) = default;
CommonFields& operator=(CommonFields&&) = default;
ctrl_t* control() const { return control_; }
void set_control(ctrl_t* c) { control_ = c; }
void* backing_array_start() const {
- // growth_left is stored before control bytes.
+ // growth_left (and maybe infoz) is stored before control bytes.
assert(reinterpret_cast<uintptr_t>(control()) % alignof(size_t) == 0);
- return control() - sizeof(size_t);
+ return control() - ControlOffset(has_infoz());
}
// Note: we can't use slots() because Qt defines "slots" as a macro.
@@ -983,8 +1048,18 @@ class CommonFields : public CommonFieldsGenerationInfo {
void set_slots(void* s) { slots_ = s; }
// The number of filled slots.
- size_t size() const { return compressed_tuple_.template get<0>(); }
- void set_size(size_t s) { compressed_tuple_.template get<0>() = s; }
+ size_t size() const { return size_ >> HasInfozShift(); }
+ void set_size(size_t s) {
+ size_ = (s << HasInfozShift()) | (size_ & HasInfozMask());
+ }
+ void increment_size() {
+ assert(size() < capacity());
+ size_ += size_t{1} << HasInfozShift();
+ }
+ void decrement_size() {
+ assert(size() > 0);
+ size_ -= size_t{1} << HasInfozShift();
+ }
// The total number of available slots.
size_t capacity() const { return capacity_; }
@@ -996,28 +1071,52 @@ class CommonFields : public CommonFieldsGenerationInfo {
// The number of slots we can still fill without needing to rehash.
// This is stored in the heap allocation before the control bytes.
size_t growth_left() const {
- return *reinterpret_cast<size_t*>(backing_array_start());
+ const size_t* gl_ptr = reinterpret_cast<size_t*>(control()) - 1;
+ assert(reinterpret_cast<uintptr_t>(gl_ptr) % alignof(size_t) == 0);
+ return *gl_ptr;
}
void set_growth_left(size_t gl) {
- *reinterpret_cast<size_t*>(backing_array_start()) = gl;
+ size_t* gl_ptr = reinterpret_cast<size_t*>(control()) - 1;
+ assert(reinterpret_cast<uintptr_t>(gl_ptr) % alignof(size_t) == 0);
+ *gl_ptr = gl;
}
- HashtablezInfoHandle& infoz() { return compressed_tuple_.template get<1>(); }
- const HashtablezInfoHandle& infoz() const {
- return compressed_tuple_.template get<1>();
+ bool has_infoz() const {
+ return ABSL_PREDICT_FALSE((size_ & HasInfozMask()) != 0);
+ }
+ void set_has_infoz(bool has_infoz) {
+ size_ = (size() << HasInfozShift()) | static_cast<size_t>(has_infoz);
+ }
+
+ HashtablezInfoHandle infoz() {
+ return has_infoz()
+ ? *reinterpret_cast<HashtablezInfoHandle*>(backing_array_start())
+ : HashtablezInfoHandle();
+ }
+ void set_infoz(HashtablezInfoHandle infoz) {
+ assert(has_infoz());
+ *reinterpret_cast<HashtablezInfoHandle*>(backing_array_start()) = infoz;
}
bool should_rehash_for_bug_detection_on_insert() const {
return CommonFieldsGenerationInfo::
should_rehash_for_bug_detection_on_insert(control(), capacity());
}
+ bool should_rehash_for_bug_detection_on_move() const {
+ return CommonFieldsGenerationInfo::
+ should_rehash_for_bug_detection_on_move(control(), capacity());
+ }
+ void maybe_increment_generation_on_move() {
+ if (capacity() == 0) return;
+ increment_generation();
+ }
void reset_reserved_growth(size_t reservation) {
CommonFieldsGenerationInfo::reset_reserved_growth(reservation, size());
}
// The size of the backing array allocation.
size_t alloc_size(size_t slot_size, size_t slot_align) const {
- return AllocSize(capacity(), slot_size, slot_align);
+ return AllocSize(capacity(), slot_size, slot_align, has_infoz());
}
// Returns the number of control bytes set to kDeleted. For testing only.
@@ -1027,9 +1126,14 @@ class CommonFields : public CommonFieldsGenerationInfo {
}
private:
- // TODO(b/259599413): Investigate removing some of these fields:
+ // We store the has_infoz bit in the lowest bit of size_.
+ static constexpr size_t HasInfozShift() { return 1; }
+ static constexpr size_t HasInfozMask() {
+ return (size_t{1} << HasInfozShift()) - 1;
+ }
+
+ // TODO(b/182800944): Investigate removing some of these fields:
// - control/slots can be derived from each other
- // - we can use 6 bits for capacity since it's always a power of two minus 1
// The control bytes (and, also, a pointer near to the base of the backing
// array).
@@ -1044,12 +1148,16 @@ class CommonFields : public CommonFieldsGenerationInfo {
// `control`. May be null for empty tables.
void* slots_ = nullptr;
+ // The number of slots in the backing array. This is always 2^N-1 for an
+ // integer N. NOTE: we tried experimenting with compressing the capacity and
+ // storing it together with size_: (a) using 6 bits to store the corresponding
+ // power (N in 2^N-1), and (b) storing 2^N as the most significant bit of
+ // size_ and storing size in the low bits. Both of these experiments were
+ // regressions, presumably because we need capacity to do find operations.
size_t capacity_ = 0;
- // Bundle together size and HashtablezInfoHandle to ensure EBO for
- // HashtablezInfoHandle when sampling is turned off.
- absl::container_internal::CompressedTuple<size_t, HashtablezInfoHandle>
- compressed_tuple_{0u, HashtablezInfoHandle{}};
+ // The size and also has one bit that stores whether we have infoz.
+ size_t size_ = 0;
};
template <class Policy, class Hash, class Eq, class Alloc>
@@ -1139,35 +1247,39 @@ inline void AssertIsFull(const ctrl_t* ctrl, GenerationType generation,
const GenerationType* generation_ptr,
const char* operation) {
if (!SwisstableDebugEnabled()) return;
- if (ctrl == nullptr) {
- ABSL_INTERNAL_LOG(FATAL,
- std::string(operation) + " called on end() iterator.");
- }
- if (ctrl == EmptyGroup()) {
- ABSL_INTERNAL_LOG(FATAL, std::string(operation) +
- " called on default-constructed iterator.");
+ // `SwisstableDebugEnabled()` is also true for release builds with hardening
+ // enabled. To minimize their impact in those builds:
+ // - use `ABSL_PREDICT_FALSE()` to provide a compiler hint for code layout
+ // - use `ABSL_RAW_LOG()` with a format string to reduce code size and improve
+ // the chances that the hot paths will be inlined.
+ if (ABSL_PREDICT_FALSE(ctrl == nullptr)) {
+ ABSL_RAW_LOG(FATAL, "%s called on end() iterator.", operation);
+ }
+ if (ABSL_PREDICT_FALSE(ctrl == EmptyGroup())) {
+ ABSL_RAW_LOG(FATAL, "%s called on default-constructed iterator.",
+ operation);
}
if (SwisstableGenerationsEnabled()) {
- if (generation != *generation_ptr) {
- ABSL_INTERNAL_LOG(FATAL,
- std::string(operation) +
- " called on invalid iterator. The table could have "
- "rehashed since this iterator was initialized.");
+ if (ABSL_PREDICT_FALSE(generation != *generation_ptr)) {
+ ABSL_RAW_LOG(FATAL,
+ "%s called on invalid iterator. The table could have "
+ "rehashed or moved since this iterator was initialized.",
+ operation);
}
- if (!IsFull(*ctrl)) {
- ABSL_INTERNAL_LOG(
+ if (ABSL_PREDICT_FALSE(!IsFull(*ctrl))) {
+ ABSL_RAW_LOG(
FATAL,
- std::string(operation) +
- " called on invalid iterator. The element was likely erased.");
+ "%s called on invalid iterator. The element was likely erased.",
+ operation);
}
} else {
- if (!IsFull(*ctrl)) {
- ABSL_INTERNAL_LOG(
+ if (ABSL_PREDICT_FALSE(!IsFull(*ctrl))) {
+ ABSL_RAW_LOG(
FATAL,
- std::string(operation) +
- " called on invalid iterator. The element might have been erased "
- "or the table might have rehashed. Consider running with "
- "--config=asan to diagnose rehashing issues.");
+ "%s called on invalid iterator. The element might have been erased "
+ "or the table might have rehashed. Consider running with "
+ "--config=asan to diagnose rehashing issues.",
+ operation);
}
}
}
@@ -1180,13 +1292,13 @@ inline void AssertIsValidForComparison(const ctrl_t* ctrl,
const bool ctrl_is_valid_for_comparison =
ctrl == nullptr || ctrl == EmptyGroup() || IsFull(*ctrl);
if (SwisstableGenerationsEnabled()) {
- if (generation != *generation_ptr) {
- ABSL_INTERNAL_LOG(FATAL,
- "Invalid iterator comparison. The table could have "
- "rehashed since this iterator was initialized.");
+ if (ABSL_PREDICT_FALSE(generation != *generation_ptr)) {
+ ABSL_RAW_LOG(FATAL,
+ "Invalid iterator comparison. The table could have rehashed "
+ "or moved since this iterator was initialized.");
}
- if (!ctrl_is_valid_for_comparison) {
- ABSL_INTERNAL_LOG(
+ if (ABSL_PREDICT_FALSE(!ctrl_is_valid_for_comparison)) {
+ ABSL_RAW_LOG(
FATAL, "Invalid iterator comparison. The element was likely erased.");
}
} else {
@@ -1226,10 +1338,15 @@ inline void AssertSameContainer(const ctrl_t* ctrl_a, const ctrl_t* ctrl_b,
const GenerationType* generation_ptr_a,
const GenerationType* generation_ptr_b) {
if (!SwisstableDebugEnabled()) return;
+ // `SwisstableDebugEnabled()` is also true for release builds with hardening
+ // enabled. To minimize their impact in those builds:
+ // - use `ABSL_PREDICT_FALSE()` to provide a compiler hint for code layout
+ // - use `ABSL_RAW_LOG()` with a format string to reduce code size and improve
+ // the chances that the hot paths will be inlined.
const bool a_is_default = ctrl_a == EmptyGroup();
const bool b_is_default = ctrl_b == EmptyGroup();
- if (a_is_default != b_is_default) {
- ABSL_INTERNAL_LOG(
+ if (ABSL_PREDICT_FALSE(a_is_default != b_is_default)) {
+ ABSL_RAW_LOG(
FATAL,
"Invalid iterator comparison. Comparing default-constructed iterator "
"with non-default-constructed iterator.");
@@ -1237,36 +1354,36 @@ inline void AssertSameContainer(const ctrl_t* ctrl_a, const ctrl_t* ctrl_b,
if (a_is_default && b_is_default) return;
if (SwisstableGenerationsEnabled()) {
- if (generation_ptr_a == generation_ptr_b) return;
+ if (ABSL_PREDICT_TRUE(generation_ptr_a == generation_ptr_b)) return;
const bool a_is_empty = IsEmptyGeneration(generation_ptr_a);
const bool b_is_empty = IsEmptyGeneration(generation_ptr_b);
if (a_is_empty != b_is_empty) {
- ABSL_INTERNAL_LOG(FATAL,
- "Invalid iterator comparison. Comparing iterator from "
- "a non-empty hashtable with an iterator from an empty "
- "hashtable.");
+ ABSL_RAW_LOG(FATAL,
+ "Invalid iterator comparison. Comparing iterator from a "
+ "non-empty hashtable with an iterator from an empty "
+ "hashtable.");
}
if (a_is_empty && b_is_empty) {
- ABSL_INTERNAL_LOG(FATAL,
- "Invalid iterator comparison. Comparing iterators from "
- "different empty hashtables.");
+ ABSL_RAW_LOG(FATAL,
+ "Invalid iterator comparison. Comparing iterators from "
+ "different empty hashtables.");
}
const bool a_is_end = ctrl_a == nullptr;
const bool b_is_end = ctrl_b == nullptr;
if (a_is_end || b_is_end) {
- ABSL_INTERNAL_LOG(FATAL,
- "Invalid iterator comparison. Comparing iterator with "
- "an end() iterator from a different hashtable.");
+ ABSL_RAW_LOG(FATAL,
+ "Invalid iterator comparison. Comparing iterator with an "
+ "end() iterator from a different hashtable.");
}
- ABSL_INTERNAL_LOG(FATAL,
- "Invalid iterator comparison. Comparing non-end() "
- "iterators from different hashtables.");
+ ABSL_RAW_LOG(FATAL,
+ "Invalid iterator comparison. Comparing non-end() iterators "
+ "from different hashtables.");
} else {
ABSL_HARDENING_ASSERT(
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. Consider running "
- "with --config=asan to diagnose rehashing issues.");
+ "containers or the container might have rehashed or moved. Consider "
+ "running with --config=asan to diagnose issues.");
}
}
@@ -1289,6 +1406,12 @@ struct FindInfo {
// `ShouldInsertBackwards()` for small tables.
inline bool is_small(size_t capacity) { return capacity < Group::kWidth - 1; }
+// Whether a table fits entirely into a probing group.
+// Arbitrary order of elements in such tables is correct.
+inline bool is_single_group(size_t capacity) {
+ return capacity <= Group::kWidth;
+}
+
// Begins a probing operation on `common.control`, using `hash`.
inline probe_seq<Group::kWidth> probe(const ctrl_t* ctrl, const size_t capacity,
size_t hash) {
@@ -1310,7 +1433,7 @@ inline FindInfo find_first_non_full(const CommonFields& common, size_t hash) {
auto seq = probe(common, hash);
const ctrl_t* ctrl = common.control();
while (true) {
- Group g{ctrl + seq.offset()};
+ GroupEmptyOrDeleted g{ctrl + seq.offset()};
auto mask = g.MaskEmptyOrDeleted();
if (mask) {
#if !defined(NDEBUG)
@@ -1351,7 +1474,6 @@ inline void ResetCtrl(CommonFields& common, size_t slot_size) {
capacity + 1 + NumClonedBytes());
ctrl[capacity] = ctrl_t::kSentinel;
SanitizerPoisonMemoryRegion(common.slot_array(), slot_size * capacity);
- ResetGrowthLeft(common);
}
// Sets `ctrl[i]` to `h`.
@@ -1386,38 +1508,263 @@ constexpr size_t BackingArrayAlignment(size_t align_of_slot) {
return (std::max)(align_of_slot, alignof(size_t));
}
-template <typename Alloc, size_t SizeOfSlot, size_t AlignOfSlot>
-ABSL_ATTRIBUTE_NOINLINE void InitializeSlots(CommonFields& c, Alloc alloc) {
- assert(c.capacity());
- // Folks with custom allocators often make unwarranted assumptions about the
- // behavior of their classes vis-a-vis trivial destructability and what
- // calls they will or won't make. Avoid sampling for people with custom
- // allocators to get us out of this mess. This is not a hard guarantee but
- // a workaround while we plan the exact guarantee we want to provide.
- const size_t sample_size =
- (std::is_same<Alloc, std::allocator<char>>::value &&
- c.slot_array() == nullptr)
- ? SizeOfSlot
- : 0;
-
- const size_t cap = c.capacity();
- const size_t alloc_size = AllocSize(cap, SizeOfSlot, AlignOfSlot);
- // growth_left (which is a size_t) is stored with the backing array.
- char* mem = static_cast<char*>(
- Allocate<BackingArrayAlignment(AlignOfSlot)>(&alloc, alloc_size));
- const GenerationType old_generation = c.generation();
- c.set_generation_ptr(
- reinterpret_cast<GenerationType*>(mem + GenerationOffset(cap)));
- c.set_generation(NextGeneration(old_generation));
- c.set_control(reinterpret_cast<ctrl_t*>(mem + ControlOffset()));
- c.set_slots(mem + SlotOffset(cap, AlignOfSlot));
- ResetCtrl(c, SizeOfSlot);
- if (sample_size) {
- c.infoz() = Sample(sample_size);
- }
- c.infoz().RecordStorageChanged(c.size(), cap);
+// Returns the address of the ith slot in slots where each slot occupies
+// slot_size.
+inline void* SlotAddress(void* slot_array, size_t slot, size_t slot_size) {
+ return reinterpret_cast<void*>(reinterpret_cast<char*>(slot_array) +
+ (slot * slot_size));
}
+// Helper class to perform resize of the hash set.
+//
+// It contains special optimizations for small group resizes.
+// See GrowIntoSingleGroupShuffleControlBytes for details.
+class HashSetResizeHelper {
+ public:
+ explicit HashSetResizeHelper(CommonFields& c)
+ : old_ctrl_(c.control()),
+ old_capacity_(c.capacity()),
+ had_infoz_(c.has_infoz()) {}
+
+ // Optimized for small groups version of `find_first_non_full` applicable
+ // only right after calling `raw_hash_set::resize`.
+ // It has implicit assumption that `resize` will call
+ // `GrowSizeIntoSingleGroup*` in case `IsGrowingIntoSingleGroupApplicable`.
+ // Falls back to `find_first_non_full` in case of big groups, so it is
+ // safe to use after `rehash_and_grow_if_necessary`.
+ 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};
+ }
+
+ ctrl_t* old_ctrl() const { return old_ctrl_; }
+ size_t old_capacity() const { return old_capacity_; }
+
+ // Allocates a backing array for the hashtable.
+ // Reads `capacity` and updates all other fields based on the result of
+ // the allocation.
+ //
+ // It also may do the folowing actions:
+ // 1. initialize control bytes
+ // 2. initialize slots
+ // 3. deallocate old slots.
+ //
+ // We are bundling a lot of functionality
+ // in one ABSL_ATTRIBUTE_NOINLINE function in order to minimize binary code
+ // duplication in raw_hash_set<>::resize.
+ //
+ // `c.capacity()` must be nonzero.
+ // POSTCONDITIONS:
+ // 1. CommonFields is initialized.
+ //
+ // if IsGrowingIntoSingleGroupApplicable && TransferUsesMemcpy
+ // Both control bytes and slots are fully initialized.
+ // old_slots are deallocated.
+ // infoz.RecordRehash is called.
+ //
+ // if IsGrowingIntoSingleGroupApplicable && !TransferUsesMemcpy
+ // Control bytes are fully initialized.
+ // infoz.RecordRehash is called.
+ // GrowSizeIntoSingleGroup must be called to finish slots initialization.
+ //
+ // if !IsGrowingIntoSingleGroupApplicable
+ // Control bytes are initialized to empty table via ResetCtrl.
+ // raw_hash_set<>::resize must insert elements regularly.
+ // infoz.RecordRehash is called if old_capacity == 0.
+ //
+ // Returns IsGrowingIntoSingleGroupApplicable result to avoid recomputation.
+ template <typename Alloc, size_t SizeOfSlot, bool TransferUsesMemcpy,
+ size_t AlignOfSlot>
+ ABSL_ATTRIBUTE_NOINLINE bool InitializeSlots(CommonFields& c, void* old_slots,
+ Alloc alloc) {
+ assert(c.capacity());
+ // Folks with custom allocators often make unwarranted assumptions about the
+ // behavior of their classes vis-a-vis trivial destructability and what
+ // calls they will or won't make. Avoid sampling for people with custom
+ // allocators to get us out of this mess. This is not a hard guarantee but
+ // a workaround while we plan the exact guarantee we want to provide.
+ const size_t sample_size =
+ (std::is_same<Alloc, std::allocator<char>>::value &&
+ c.slot_array() == nullptr)
+ ? SizeOfSlot
+ : 0;
+ HashtablezInfoHandle infoz =
+ sample_size > 0 ? Sample(sample_size) : c.infoz();
+
+ const bool has_infoz = infoz.IsSampled();
+ const size_t cap = c.capacity();
+ const size_t alloc_size =
+ AllocSize(cap, SizeOfSlot, AlignOfSlot, has_infoz);
+ char* mem = static_cast<char*>(
+ Allocate<BackingArrayAlignment(AlignOfSlot)>(&alloc, alloc_size));
+ const GenerationType old_generation = c.generation();
+ c.set_generation_ptr(reinterpret_cast<GenerationType*>(
+ mem + GenerationOffset(cap, has_infoz)));
+ c.set_generation(NextGeneration(old_generation));
+ c.set_control(reinterpret_cast<ctrl_t*>(mem + ControlOffset(has_infoz)));
+ c.set_slots(mem + SlotOffset(cap, AlignOfSlot, has_infoz));
+ ResetGrowthLeft(c);
+
+ const bool grow_single_group =
+ IsGrowingIntoSingleGroupApplicable(old_capacity_, c.capacity());
+ if (old_capacity_ != 0 && grow_single_group) {
+ if (TransferUsesMemcpy) {
+ GrowSizeIntoSingleGroupTransferable(c, old_slots, SizeOfSlot);
+ DeallocateOld<AlignOfSlot>(alloc, SizeOfSlot, old_slots);
+ } else {
+ GrowIntoSingleGroupShuffleControlBytes(c.control(), c.capacity());
+ }
+ } else {
+ ResetCtrl(c, SizeOfSlot);
+ }
+
+ c.set_has_infoz(has_infoz);
+ if (has_infoz) {
+ infoz.RecordStorageChanged(c.size(), cap);
+ if (grow_single_group || old_capacity_ == 0) {
+ infoz.RecordRehash(0);
+ }
+ c.set_infoz(infoz);
+ }
+ return grow_single_group;
+ }
+
+ // Relocates slots into new single group consistent with
+ // GrowIntoSingleGroupShuffleControlBytes.
+ //
+ // PRECONDITIONS:
+ // 1. GrowIntoSingleGroupShuffleControlBytes was already called.
+ template <class PolicyTraits, class Alloc>
+ void GrowSizeIntoSingleGroup(CommonFields& c, Alloc& alloc_ref,
+ typename PolicyTraits::slot_type* old_slots) {
+ assert(old_capacity_ < Group::kWidth / 2);
+ assert(IsGrowingIntoSingleGroupApplicable(old_capacity_, c.capacity()));
+ using slot_type = typename PolicyTraits::slot_type;
+ assert(is_single_group(c.capacity()));
+
+ auto* new_slots = reinterpret_cast<slot_type*>(c.slot_array());
+
+ 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 + i);
+ }
+ }
+ PoisonSingleGroupEmptySlots(c, sizeof(slot_type));
+ }
+
+ // Deallocates old backing array.
+ template <size_t AlignOfSlot, class CharAlloc>
+ void DeallocateOld(CharAlloc alloc_ref, size_t slot_size, void* old_slots) {
+ SanitizerUnpoisonMemoryRegion(old_slots, slot_size * old_capacity_);
+ Deallocate<BackingArrayAlignment(AlignOfSlot)>(
+ &alloc_ref, old_ctrl_ - ControlOffset(had_infoz_),
+ AllocSize(old_capacity_, slot_size, AlignOfSlot, had_infoz_));
+ }
+
+ private:
+ // Returns true if `GrowSizeIntoSingleGroup` can be used for resizing.
+ static bool IsGrowingIntoSingleGroupApplicable(size_t old_capacity,
+ size_t new_capacity) {
+ // NOTE that `old_capacity < new_capacity` in order to have
+ // `old_capacity < Group::kWidth / 2` to make faster copies of 8 bytes.
+ return is_single_group(new_capacity) && old_capacity < new_capacity;
+ }
+
+ // Relocates control bytes and slots into new single group for
+ // transferable objects.
+ // Must be called only if IsGrowingIntoSingleGroupApplicable returned true.
+ void GrowSizeIntoSingleGroupTransferable(CommonFields& c, void* old_slots,
+ size_t slot_size);
+
+ // Shuffle control bits deterministically to the next capacity.
+ // Returns offset for newly added element with given hash.
+ //
+ // PRECONDITIONs:
+ // 1. new_ctrl is allocated for new_capacity,
+ // but not initialized.
+ // 2. new_capacity is a single group.
+ //
+ // 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.
+ //
+ // Examples:
+ // S = kSentinel, E = kEmpty
+ //
+ // old_ctrl = SEEEEEEEE...
+ // new_ctrl = ESEEEEEEE...
+ //
+ // old_ctrl = 0SEEEEEEE...
+ // new_ctrl = E0ESE0EEE...
+ //
+ // old_ctrl = 012S012EEEEEEEEE...
+ // new_ctrl = 2E01EEES2E01EEE...
+ //
+ // old_ctrl = 0123456S0123456EEEEEEEEEEE...
+ // new_ctrl = 456E0123EEEEEES456E0123EEE...
+ void GrowIntoSingleGroupShuffleControlBytes(ctrl_t* new_ctrl,
+ size_t new_capacity) const;
+
+ // Shuffle trivially transferable slots in the way consistent with
+ // GrowIntoSingleGroupShuffleControlBytes.
+ //
+ // PRECONDITIONs:
+ // 1. old_capacity must be non-zero.
+ // 2. new_ctrl is fully initialized using
+ // GrowIntoSingleGroupShuffleControlBytes.
+ // 3. new_slots is allocated and *not* poisoned.
+ //
+ // POSTCONDITIONS:
+ // 1. new_slots are transferred from old_slots_ consistent with
+ // GrowIntoSingleGroupShuffleControlBytes.
+ // 2. Empty new_slots are *not* poisoned.
+ void GrowIntoSingleGroupShuffleTransferableSlots(void* old_slots,
+ void* new_slots,
+ size_t slot_size) const;
+
+ // Poison empty slots that were transferred using the deterministic algorithm
+ // described above.
+ // PRECONDITIONs:
+ // 1. new_ctrl is fully initialized using
+ // GrowIntoSingleGroupShuffleControlBytes.
+ // 2. new_slots is fully initialized consistent with
+ // GrowIntoSingleGroupShuffleControlBytes.
+ void PoisonSingleGroupEmptySlots(CommonFields& c, size_t slot_size) const {
+ // poison non full items
+ for (size_t i = 0; i < c.capacity(); ++i) {
+ if (!IsFull(c.control()[i])) {
+ SanitizerPoisonMemoryRegion(SlotAddress(c.slot_array(), i, slot_size),
+ slot_size);
+ }
+ }
+ }
+
+ ctrl_t* old_ctrl_;
+ size_t old_capacity_;
+ bool had_infoz_;
+};
+
// PolicyFunctions bundles together some information for a particular
// raw_hash_set<T, ...> instantiation. This information is passed to
// type-erased functions that want to do small amounts of type-specific
@@ -1442,7 +1789,7 @@ void ClearBackingArray(CommonFields& c, const PolicyFunctions& policy,
bool reuse);
// Type-erased version of raw_hash_set::erase_meta_only.
-void EraseMetaOnly(CommonFields& c, ctrl_t* it, size_t slot_size);
+void EraseMetaOnly(CommonFields& c, size_t index, size_t slot_size);
// Function to place in PolicyFunctions::dealloc for raw_hash_sets
// that are using std::allocator. This allows us to share the same
@@ -1456,6 +1803,7 @@ ABSL_ATTRIBUTE_NOINLINE void DeallocateStandard(CommonFields& common,
policy.slot_size * common.capacity());
std::allocator<char> alloc;
+ common.infoz().Unregister();
Deallocate<BackingArrayAlignment(AlignOfSlot)>(
&alloc, common.backing_array_start(),
common.alloc_size(policy.slot_size, AlignOfSlot));
@@ -1534,6 +1882,11 @@ class raw_hash_set {
using AllocTraits = absl::allocator_traits<allocator_type>;
using SlotAlloc = typename absl::allocator_traits<
allocator_type>::template rebind_alloc<slot_type>;
+ // People are often sloppy with the exact type of their allocator (sometimes
+ // it has an extra const or is missing the pair, but rebinds made it work
+ // anyway).
+ using CharAlloc =
+ typename absl::allocator_traits<Alloc>::template rebind_alloc<char>;
using SlotAllocTraits = typename absl::allocator_traits<
allocator_type>::template rebind_traits<slot_type>;
@@ -1590,7 +1943,7 @@ class raw_hash_set {
// PRECONDITION: not an end() iterator.
reference operator*() const {
AssertIsFull(ctrl_, generation(), generation_ptr(), "operator*()");
- return PolicyTraits::element(slot_);
+ return unchecked_deref();
}
// PRECONDITION: not an end() iterator.
@@ -1645,13 +1998,17 @@ class raw_hash_set {
// If a sentinel is reached, we null `ctrl_` out instead.
void skip_empty_or_deleted() {
while (IsEmptyOrDeleted(*ctrl_)) {
- uint32_t shift = Group{ctrl_}.CountLeadingEmptyOrDeleted();
+ uint32_t shift =
+ GroupEmptyOrDeleted{ctrl_}.CountLeadingEmptyOrDeleted();
ctrl_ += shift;
slot_ += shift;
}
if (ABSL_PREDICT_FALSE(*ctrl_ == ctrl_t::kSentinel)) ctrl_ = nullptr;
}
+ ctrl_t* control() const { return ctrl_; }
+ slot_type* slot() const { return slot_; }
+
// We use EmptyGroup() for default-constructed iterators so that they can
// be distinguished from end iterators, which have nullptr ctrl_.
ctrl_t* ctrl_ = EmptyGroup();
@@ -1660,10 +2017,23 @@ class raw_hash_set {
union {
slot_type* slot_;
};
+
+ // An equality check which skips ABSL Hardening iterator invalidation
+ // checks.
+ // Should be used when the lifetimes of the iterators are well-enough
+ // understood to prove that they cannot be invalid.
+ bool unchecked_equals(const iterator& b) { return ctrl_ == b.control(); }
+
+ // Dereferences the iterator without ABSL Hardening iterator invalidation
+ // checks.
+ reference unchecked_deref() const { return PolicyTraits::element(slot_); }
};
class const_iterator {
friend class raw_hash_set;
+ template <class Container, typename Enabler>
+ friend struct absl::container_internal::hashtable_debug_internal::
+ HashtableDebugAccess;
public:
using iterator_category = typename iterator::iterator_category;
@@ -1697,8 +2067,14 @@ class raw_hash_set {
const GenerationType* gen)
: inner_(const_cast<ctrl_t*>(ctrl), const_cast<slot_type*>(slot), gen) {
}
+ ctrl_t* control() const { return inner_.control(); }
+ slot_type* slot() const { return inner_.slot(); }
iterator inner_;
+
+ bool unchecked_equals(const const_iterator& b) {
+ return inner_.unchecked_equals(b.inner_);
+ }
};
using node_type = node_handle<Policy, hash_policy_traits<Policy>, Alloc>;
@@ -1717,8 +2093,7 @@ class raw_hash_set {
const allocator_type& alloc = allocator_type())
: settings_(CommonFields{}, hash, eq, alloc) {
if (bucket_count) {
- common().set_capacity(NormalizeCapacity(bucket_count));
- initialize_slots();
+ resize(NormalizeCapacity(bucket_count));
}
}
@@ -1843,28 +2218,35 @@ 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.
- settings_(absl::exchange(that.common(), CommonFields{}),
- that.hash_ref(), that.eq_ref(), that.alloc_ref()) {}
+ // TODO(b/296061262): move instead of copying hash/eq/alloc.
+ // Note: we avoid using exchange for better generated code.
+ settings_(std::move(that.common()), that.hash_ref(), that.eq_ref(),
+ that.alloc_ref()) {
+ that.common() = CommonFields{};
+ maybe_increment_generation_or_rehash_on_move();
+ }
raw_hash_set(raw_hash_set&& that, const allocator_type& a)
: settings_(CommonFields{}, that.hash_ref(), that.eq_ref(), a) {
if (a == that.alloc_ref()) {
std::swap(common(), that.common());
+ maybe_increment_generation_or_rehash_on_move();
} else {
- reserve(that.size());
- // Note: this will copy elements of dense_set and unordered_set instead of
- // moving them. This can be fixed if it ever becomes an issue.
- for (auto& elem : that) insert(std::move(elem));
+ move_elements_allocs_unequal(std::move(that));
}
}
raw_hash_set& operator=(const raw_hash_set& that) {
- raw_hash_set tmp(that,
- AllocTraits::propagate_on_container_copy_assignment::value
- ? that.alloc_ref()
- : alloc_ref());
- swap(tmp);
- return *this;
+ if (ABSL_PREDICT_FALSE(this == &that)) return *this;
+ constexpr bool propagate_alloc =
+ AllocTraits::propagate_on_container_copy_assignment::value;
+ // TODO(ezb): maybe avoid allocating a new backing array if this->capacity()
+ // is an exact match for that.size(). If this->capacity() is too big, then
+ // it would make iteration very slow to reuse the allocation. Maybe we can
+ // do the same heuristic as clear() and reuse if it's small enough.
+ raw_hash_set tmp(that, propagate_alloc ? that.alloc_ref() : alloc_ref());
+ // NOLINTNEXTLINE: not returning *this for performance.
+ return assign_impl<propagate_alloc>(std::move(tmp));
}
raw_hash_set& operator=(raw_hash_set&& that) noexcept(
@@ -1879,19 +2261,7 @@ class raw_hash_set {
typename AllocTraits::propagate_on_container_move_assignment());
}
- ~raw_hash_set() {
- const size_t cap = capacity();
- if (!cap) return;
- destroy_slots();
-
- // Unpoison before returning the memory to the allocator.
- SanitizerUnpoisonMemoryRegion(slot_array(), sizeof(slot_type) * cap);
- Deallocate<BackingArrayAlignment(alignof(slot_type))>(
- &alloc_ref(), common().backing_array_start(),
- AllocSize(cap, sizeof(slot_type), alignof(slot_type)));
-
- infoz().Unregister();
- }
+ ~raw_hash_set() { destructor_impl(); }
iterator begin() ABSL_ATTRIBUTE_LIFETIME_BOUND {
auto it = iterator_at(0);
@@ -1937,17 +2307,6 @@ class raw_hash_set {
common().set_reservation_size(0);
}
- inline void destroy_slots() {
- const size_t cap = capacity();
- const ctrl_t* ctrl = control();
- slot_type* slot = slot_array();
- for (size_t i = 0; i != cap; ++i) {
- if (IsFull(ctrl[i])) {
- PolicyTraits::destroy(&alloc_ref(), slot + i);
- }
- }
- }
-
// This overload kicks in when the argument is an rvalue of insertable and
// decomposable type other than init_type.
//
@@ -2075,7 +2434,7 @@ class raw_hash_set {
alignas(slot_type) unsigned char raw[sizeof(slot_type)];
slot_type* slot = reinterpret_cast<slot_type*>(&raw);
- PolicyTraits::construct(&alloc_ref(), slot, std::forward<Args>(args)...);
+ construct(slot, std::forward<Args>(args)...);
const auto& elem = PolicyTraits::element(slot);
return PolicyTraits::apply(InsertSlot<true>{*this, std::move(*slot)}, elem);
}
@@ -2179,8 +2538,8 @@ class raw_hash_set {
// 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) {
- AssertIsFull(it.ctrl_, it.generation(), it.generation_ptr(), "erase()");
- PolicyTraits::destroy(&alloc_ref(), it.slot_);
+ AssertIsFull(it.control(), it.generation(), it.generation_ptr(), "erase()");
+ destroy(it.slot());
erase_meta_only(it);
}
@@ -2211,8 +2570,8 @@ class raw_hash_set {
assert(this != &src);
for (auto it = src.begin(), e = src.end(); it != e;) {
auto next = std::next(it);
- if (PolicyTraits::apply(InsertSlot<false>{*this, std::move(*it.slot_)},
- PolicyTraits::element(it.slot_))
+ if (PolicyTraits::apply(InsertSlot<false>{*this, std::move(*it.slot())},
+ PolicyTraits::element(it.slot()))
.second) {
src.erase_meta_only(it);
}
@@ -2226,10 +2585,9 @@ class raw_hash_set {
}
node_type extract(const_iterator position) {
- AssertIsFull(position.inner_.ctrl_, position.inner_.generation(),
+ AssertIsFull(position.control(), position.inner_.generation(),
position.inner_.generation_ptr(), "extract()");
- auto node =
- CommonAccess::Transfer<node_type>(alloc_ref(), position.inner_.slot_);
+ auto node = CommonAccess::Transfer<node_type>(alloc_ref(), position.slot());
erase_meta_only(position);
return node;
}
@@ -2364,7 +2722,11 @@ class raw_hash_set {
template <class K = key_type>
bool contains(const key_arg<K>& key) const {
- return find(key) != end();
+ // Here neither the iterator returned by `find()` nor `end()` can be invalid
+ // outside of potential thread-safety issues.
+ // `find()`'s return value is constructed, used, and then destructed
+ // all in this context.
+ return !find(key).unchecked_equals(end());
}
template <class K = key_type>
@@ -2400,8 +2762,10 @@ class raw_hash_set {
const raw_hash_set* outer = &a;
const raw_hash_set* inner = &b;
if (outer->capacity() > inner->capacity()) std::swap(outer, inner);
- for (const value_type& elem : *outer)
- if (!inner->has_element(elem)) return false;
+ for (const value_type& elem : *outer) {
+ auto it = PolicyTraits::apply(FindElement{*inner}, elem);
+ if (it == inner->end() || !(*it == elem)) return false;
+ }
return true;
}
@@ -2471,10 +2835,9 @@ class raw_hash_set {
std::pair<iterator, bool> operator()(const K& key, Args&&...) && {
auto res = s.find_or_prepare_insert(key);
if (res.second) {
- PolicyTraits::transfer(&s.alloc_ref(), s.slot_array() + res.first,
- &slot);
+ s.transfer(s.slot_array() + res.first, &slot);
} else if (do_destroy) {
- PolicyTraits::destroy(&s.alloc_ref(), &slot);
+ s.destroy(&slot);
}
return {s.iterator_at(res.first), res.second};
}
@@ -2483,58 +2846,111 @@ 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)...);
+ }
+ inline void destroy(slot_type* slot) {
+ PolicyTraits::destroy(&alloc_ref(), slot);
+ }
+ inline void transfer(slot_type* to, slot_type* from) {
+ PolicyTraits::transfer(&alloc_ref(), to, from);
+ }
+
+ inline void destroy_slots() {
+ const size_t cap = capacity();
+ const ctrl_t* ctrl = control();
+ slot_type* slot = slot_array();
+ for (size_t i = 0; i != cap; ++i) {
+ if (IsFull(ctrl[i])) {
+ destroy(slot + i);
+ }
+ }
+ }
+
+ inline void dealloc() {
+ assert(capacity() != 0);
+ // Unpoison before returning the memory to the allocator.
+ SanitizerUnpoisonMemoryRegion(slot_array(), sizeof(slot_type) * capacity());
+ infoz().Unregister();
+ Deallocate<BackingArrayAlignment(alignof(slot_type))>(
+ &alloc_ref(), common().backing_array_start(),
+ common().alloc_size(sizeof(slot_type), alignof(slot_type)));
+ }
+
+ inline void destructor_impl() {
+ if (capacity() == 0) return;
+ destroy_slots();
+ dealloc();
+ }
+
// Erases, but does not destroy, the value pointed to by `it`.
//
// 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) {
- EraseMetaOnly(common(), it.inner_.ctrl_, sizeof(slot_type));
+ EraseMetaOnly(common(), static_cast<size_t>(it.control() - control()),
+ sizeof(slot_type));
}
- // Allocates a backing array for `self` and initializes its control bytes.
- // This reads `capacity` and updates all other fields based on the result of
- // the allocation.
+ // Resizes table to the new capacity and move all elements to the new
+ // positions accordingly.
//
- // This does not free the currently held array; `capacity` must be nonzero.
- inline void initialize_slots() {
- // People are often sloppy with the exact type of their allocator (sometimes
- // it has an extra const or is missing the pair, but rebinds made it work
- // anyway).
- using CharAlloc =
- typename absl::allocator_traits<Alloc>::template rebind_alloc<char>;
- InitializeSlots<CharAlloc, sizeof(slot_type), alignof(slot_type)>(
- common(), CharAlloc(alloc_ref()));
- }
-
+ // Note that for better performance instead of
+ // find_first_non_full(common(), hash),
+ // HashSetResizeHelper::FindFirstNonFullAfterResize(
+ // common(), old_capacity, hash)
+ // can be called right after `resize`.
ABSL_ATTRIBUTE_NOINLINE void resize(size_t new_capacity) {
assert(IsValidCapacity(new_capacity));
- auto* old_ctrl = control();
+ HashSetResizeHelper resize_helper(common());
auto* old_slots = slot_array();
- const size_t old_capacity = common().capacity();
common().set_capacity(new_capacity);
- initialize_slots();
-
- auto* new_slots = slot_array();
- size_t total_probe_length = 0;
- for (size_t i = 0; i != old_capacity; ++i) {
- if (IsFull(old_ctrl[i])) {
- size_t hash = PolicyTraits::apply(HashElement{hash_ref()},
- PolicyTraits::element(old_slots + i));
- auto target = find_first_non_full(common(), hash);
- size_t new_i = target.offset;
- total_probe_length += target.probe_length;
- SetCtrl(common(), new_i, H2(hash), sizeof(slot_type));
- PolicyTraits::transfer(&alloc_ref(), new_slots + new_i, old_slots + i);
- }
+ // Note that `InitializeSlots` does different number initialization steps
+ // depending on the values of `transfer_uses_memcpy` and capacities.
+ // Refer to the comment in `InitializeSlots` for more details.
+ const bool grow_single_group =
+ resize_helper.InitializeSlots<CharAlloc, sizeof(slot_type),
+ PolicyTraits::transfer_uses_memcpy(),
+ alignof(slot_type)>(
+ common(), const_cast<std::remove_const_t<slot_type>*>(old_slots),
+ CharAlloc(alloc_ref()));
+
+ if (resize_helper.old_capacity() == 0) {
+ // InitializeSlots did all the work including infoz().RecordRehash().
+ return;
}
- if (old_capacity) {
- SanitizerUnpoisonMemoryRegion(old_slots,
- sizeof(slot_type) * old_capacity);
- Deallocate<BackingArrayAlignment(alignof(slot_type))>(
- &alloc_ref(), old_ctrl - ControlOffset(),
- AllocSize(old_capacity, sizeof(slot_type), alignof(slot_type)));
+
+ if (grow_single_group) {
+ if (PolicyTraits::transfer_uses_memcpy()) {
+ // InitializeSlots did all the work.
+ return;
+ }
+ // We want GrowSizeIntoSingleGroup to be called here in order to make
+ // InitializeSlots not depend on PolicyTraits.
+ resize_helper.GrowSizeIntoSingleGroup<PolicyTraits>(common(), alloc_ref(),
+ old_slots);
+ } else {
+ // InitializeSlots prepares control bytes to correspond to empty table.
+ auto* new_slots = slot_array();
+ size_t total_probe_length = 0;
+ for (size_t i = 0; i != resize_helper.old_capacity(); ++i) {
+ if (IsFull(resize_helper.old_ctrl()[i])) {
+ size_t hash = PolicyTraits::apply(
+ HashElement{hash_ref()}, PolicyTraits::element(old_slots + i));
+ auto target = find_first_non_full(common(), hash);
+ size_t new_i = target.offset;
+ total_probe_length += target.probe_length;
+ SetCtrl(common(), new_i, H2(hash), sizeof(slot_type));
+ transfer(new_slots + new_i, old_slots + i);
+ }
+ }
+ infoz().RecordRehash(total_probe_length);
}
- infoz().RecordRehash(total_probe_length);
+ resize_helper.DeallocateOld<alignof(slot_type)>(
+ CharAlloc(alloc_ref()), sizeof(slot_type),
+ const_cast<std::remove_const_t<slot_type>*>(old_slots));
}
// Prunes control bytes to remove as many tombstones as possible.
@@ -2604,36 +3020,64 @@ class raw_hash_set {
}
}
- bool has_element(const value_type& elem) const {
- size_t hash = PolicyTraits::apply(HashElement{hash_ref()}, elem);
- auto seq = probe(common(), hash);
- const ctrl_t* ctrl = control();
- while (true) {
- Group g{ctrl + seq.offset()};
- for (uint32_t i : g.Match(H2(hash))) {
- if (ABSL_PREDICT_TRUE(
- PolicyTraits::element(slot_array() + seq.offset(i)) == elem))
- return true;
- }
- if (ABSL_PREDICT_TRUE(g.MaskEmpty())) return false;
- seq.next();
- assert(seq.index() <= capacity() && "full table!");
+ void maybe_increment_generation_or_rehash_on_move() {
+ common().maybe_increment_generation_on_move();
+ if (!empty() && common().should_rehash_for_bug_detection_on_move()) {
+ resize(capacity());
}
- return false;
}
- // TODO(alkis): Optimize this assuming *this and that don't overlap.
- raw_hash_set& move_assign(raw_hash_set&& that, std::true_type) {
- raw_hash_set tmp(std::move(that));
- swap(tmp);
+ template<bool propagate_alloc>
+ raw_hash_set& assign_impl(raw_hash_set&& that) {
+ // We don't bother checking for this/that aliasing. We just need to avoid
+ // breaking the invariants in that case.
+ destructor_impl();
+ 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{};
+ maybe_increment_generation_or_rehash_on_move();
return *this;
}
- raw_hash_set& move_assign(raw_hash_set&& that, std::false_type) {
- raw_hash_set tmp(std::move(that), alloc_ref());
- swap(tmp);
+
+ raw_hash_set& move_elements_allocs_unequal(raw_hash_set&& that) {
+ const size_t size = that.size();
+ if (size == 0) return *this;
+ reserve(size);
+ for (iterator it = that.begin(); it != that.end(); ++it) {
+ insert(std::move(PolicyTraits::element(it.slot())));
+ that.destroy(it.slot());
+ }
+ that.dealloc();
+ that.common() = CommonFields{};
+ maybe_increment_generation_or_rehash_on_move();
return *this;
}
+ raw_hash_set& move_assign(raw_hash_set&& that,
+ std::true_type /*propagate_alloc*/) {
+ return assign_impl<true>(std::move(that));
+ }
+ raw_hash_set& move_assign(raw_hash_set&& that,
+ std::false_type /*propagate_alloc*/) {
+ if (alloc_ref() == that.alloc_ref()) {
+ return assign_impl<false>(std::move(that));
+ }
+ // Aliasing can't happen here because allocs would compare equal above.
+ assert(this != &that);
+ destructor_impl();
+ // 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));
+ }
+
protected:
// Attempts to find `key` in the table; if it isn't found, returns a slot that
// the value can be inserted into, with the control byte already set to
@@ -2675,10 +3119,19 @@ class raw_hash_set {
if (!rehash_for_bug_detection &&
ABSL_PREDICT_FALSE(growth_left() == 0 &&
!IsDeleted(control()[target.offset]))) {
+ size_t old_capacity = capacity();
rehash_and_grow_if_necessary();
- target = find_first_non_full(common(), hash);
+ // NOTE: It is safe to use `FindFirstNonFullAfterResize`.
+ // `FindFirstNonFullAfterResize` must be called right after resize.
+ // `rehash_and_grow_if_necessary` may *not* call `resize`
+ // and perform `drop_deletes_without_resize` instead. But this
+ // could happen only on big tables.
+ // For big tables `FindFirstNonFullAfterResize` will always
+ // fallback to normal `find_first_non_full`, so it is safe to use it.
+ target = HashSetResizeHelper::FindFirstNonFullAfterResize(
+ common(), old_capacity, hash);
}
- common().set_size(common().size() + 1);
+ common().increment_size();
set_growth_left(growth_left() - IsEmpty(control()[target.offset]));
SetCtrl(common(), target.offset, H2(hash), sizeof(slot_type));
common().maybe_increment_generation_on_insert();
@@ -2696,8 +3149,7 @@ class raw_hash_set {
// POSTCONDITION: *m.iterator_at(i) == value_type(forward<Args>(args)...).
template <class... Args>
void emplace_at(size_t i, Args&&... args) {
- PolicyTraits::construct(&alloc_ref(), slot_array() + i,
- std::forward<Args>(args)...);
+ construct(slot_array() + i, std::forward<Args>(args)...);
assert(PolicyTraits::apply(FindElement{*this}, *iterator_at(i)) ==
iterator_at(i) &&
@@ -2711,6 +3163,8 @@ class raw_hash_set {
return {control() + i, slot_array() + i, common().generation_ptr()};
}
+ reference unchecked_deref(iterator it) { return it.unchecked_deref(); }
+
private:
friend struct RawHashSetTestOnlyAccess;
@@ -2743,7 +3197,7 @@ class raw_hash_set {
slot_type* slot_array() const {
return static_cast<slot_type*>(common().slot_array());
}
- HashtablezInfoHandle& infoz() { return common().infoz(); }
+ HashtablezInfoHandle infoz() { return common().infoz(); }
hasher& hash_ref() { return settings_.template get<1>(); }
const hasher& hash_ref() const { return settings_.template get<1>(); }
@@ -2763,8 +3217,7 @@ class raw_hash_set {
}
static void transfer_slot_fn(void* set, void* dst, void* src) {
auto* h = static_cast<raw_hash_set*>(set);
- PolicyTraits::transfer(&h->alloc_ref(), static_cast<slot_type*>(dst),
- static_cast<slot_type*>(src));
+ h->transfer(static_cast<slot_type*>(dst), static_cast<slot_type*>(src));
}
// Note: dealloc_fn will only be used if we have a non-standard allocator.
static void dealloc_fn(CommonFields& common, const PolicyFunctions&) {
@@ -2774,6 +3227,7 @@ class raw_hash_set {
SanitizerUnpoisonMemoryRegion(common.slot_array(),
sizeof(slot_type) * common.capacity());
+ common.infoz().Unregister();
Deallocate<BackingArrayAlignment(alignof(slot_type))>(
&set->alloc_ref(), common.backing_array_start(),
common.alloc_size(sizeof(slot_type), alignof(slot_type)));
@@ -2847,33 +3301,18 @@ struct HashtableDebugAccess<Set, absl::void_t<typename Set::raw_hash_set>> {
static size_t AllocatedByteSize(const Set& c) {
size_t capacity = c.capacity();
if (capacity == 0) return 0;
- size_t m = AllocSize(capacity, sizeof(Slot), alignof(Slot));
+ size_t m = c.common().alloc_size(sizeof(Slot), alignof(Slot));
size_t per_slot = Traits::space_used(static_cast<const Slot*>(nullptr));
if (per_slot != ~size_t{}) {
m += per_slot * c.size();
} else {
- const ctrl_t* ctrl = c.control();
- for (size_t i = 0; i != capacity; ++i) {
- if (container_internal::IsFull(ctrl[i])) {
- m += Traits::space_used(c.slot_array() + i);
- }
+ for (auto it = c.begin(); it != c.end(); ++it) {
+ m += Traits::space_used(it.slot());
}
}
return m;
}
-
- static size_t LowerBoundAllocatedByteSize(size_t size) {
- size_t capacity = GrowthToLowerboundCapacity(size);
- if (capacity == 0) return 0;
- size_t m =
- AllocSize(NormalizeCapacity(capacity), sizeof(Slot), alignof(Slot));
- size_t per_slot = Traits::space_used(static_cast<const Slot*>(nullptr));
- if (per_slot != ~size_t{}) {
- m += per_slot * size;
- }
- return m;
- }
};
} // namespace hashtable_debug_internal
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 838380854f..d7eedd1ca4 100644
--- a/contrib/restricted/abseil-cpp/absl/crc/internal/cpu_detect.cc
+++ b/contrib/restricted/abseil-cpp/absl/crc/internal/cpu_detect.cc
@@ -189,8 +189,14 @@ CpuType GetAmdCpuType() {
break;
case 0x19:
switch (model_num) {
+ case 0x0: // Stepping Ax
case 0x1: // Stepping B0
return CpuType::kAmdMilan;
+ case 0x10: // Stepping A0
+ case 0x11: // Stepping B0
+ return CpuType::kAmdGenoa;
+ case 0x44: // Stepping A0
+ return CpuType::kAmdRyzenV3000;
default:
return CpuType::kUnknown;
}
@@ -237,8 +243,26 @@ CpuType GetCpuType() {
ABSL_INTERNAL_AARCH64_ID_REG_READ(MIDR_EL1, midr);
uint32_t implementer = (midr >> 24) & 0xff;
uint32_t part_number = (midr >> 4) & 0xfff;
- if (implementer == 0x41 && part_number == 0xd0c) {
- return CpuType::kArmNeoverseN1;
+ switch (implementer) {
+ case 0x41:
+ switch (part_number) {
+ case 0xd0c: return CpuType::kArmNeoverseN1;
+ case 0xd40: return CpuType::kArmNeoverseV1;
+ case 0xd49: return CpuType::kArmNeoverseN2;
+ case 0xd4f: return CpuType::kArmNeoverseV2;
+ default:
+ return CpuType::kUnknown;
+ }
+ break;
+ case 0xc0:
+ switch (part_number) {
+ case 0xac3: return CpuType::kAmpereSiryn;
+ default:
+ return CpuType::kUnknown;
+ }
+ break;
+ default:
+ return CpuType::kUnknown;
}
}
return CpuType::kUnknown;
diff --git a/contrib/restricted/abseil-cpp/absl/crc/internal/cpu_detect.h b/contrib/restricted/abseil-cpp/absl/crc/internal/cpu_detect.h
index 6054f6960d..01e19590ca 100644
--- a/contrib/restricted/abseil-cpp/absl/crc/internal/cpu_detect.h
+++ b/contrib/restricted/abseil-cpp/absl/crc/internal/cpu_detect.h
@@ -29,6 +29,8 @@ enum class CpuType {
kAmdRome,
kAmdNaples,
kAmdMilan,
+ kAmdGenoa,
+ kAmdRyzenV3000,
kIntelCascadelakeXeon,
kIntelSkylakeXeon,
kIntelBroadwell,
@@ -37,6 +39,10 @@ enum class CpuType {
kIntelSandybridge,
kIntelWestmere,
kArmNeoverseN1,
+ kArmNeoverseV1,
+ kAmpereSiryn,
+ kArmNeoverseN2,
+ kArmNeoverseV2
};
// Returns the type of host CPU this code is running on. Returns kUnknown if
diff --git a/contrib/restricted/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h b/contrib/restricted/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h
index 39e53dd08e..59995ae3e2 100644
--- a/contrib/restricted/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h
+++ b/contrib/restricted/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h
@@ -59,6 +59,8 @@ namespace crc_internal {
#if defined(ABSL_CRC_INTERNAL_HAVE_ARM_SIMD)
using V128 = uint64x2_t;
#else
+// Note: Do not use __m128i_u, it is not portable.
+// Use V128_LoadU() perform an unaligned load from __m128i*.
using V128 = __m128i;
#endif
@@ -78,6 +80,9 @@ V128 V128_Load(const V128* src);
// Load 128 bits of integer data. |src| does not need to be aligned.
V128 V128_LoadU(const V128* src);
+// Store 128 bits of integer data. |src| must be 16-byte aligned.
+void V128_Store(V128* dst, V128 data);
+
// Polynomially multiplies the high 64 bits of |l| and |r|.
V128 V128_PMulHi(const V128 l, const V128 r);
@@ -109,6 +114,10 @@ V128 V128_ShiftRight(const V128 l);
template <int imm>
int V128_Extract32(const V128 l);
+// Extracts a 64-bit integer from |l|, selected with |imm|.
+template <int imm>
+uint64_t V128_Extract64(const V128 l);
+
// Extracts the low 64 bits from V128.
int64_t V128_Low64(const V128 l);
@@ -139,6 +148,8 @@ inline V128 V128_Load(const V128* src) { return _mm_load_si128(src); }
inline V128 V128_LoadU(const V128* src) { return _mm_loadu_si128(src); }
+inline void V128_Store(V128* dst, V128 data) { _mm_store_si128(dst, data); }
+
inline V128 V128_PMulHi(const V128 l, const V128 r) {
return _mm_clmulepi64_si128(l, r, 0x11);
}
@@ -173,6 +184,11 @@ inline int V128_Extract32(const V128 l) {
return _mm_extract_epi32(l, imm);
}
+template <int imm>
+inline uint64_t V128_Extract64(const V128 l) {
+ return static_cast<uint64_t>(_mm_extract_epi64(l, imm));
+}
+
inline int64_t V128_Low64(const V128 l) { return _mm_cvtsi128_si64(l); }
inline V128 V128_ShiftLeft64(const V128 l, const V128 r) {
@@ -203,10 +219,14 @@ inline V128 V128_LoadU(const V128* src) {
return vld1q_u64(reinterpret_cast<const uint64_t*>(src));
}
+inline void V128_Store(V128* dst, V128 data) {
+ vst1q_u64(reinterpret_cast<uint64_t*>(dst), data);
+}
+
// Using inline assembly as clang does not generate the pmull2 instruction and
// performance drops by 15-20%.
-// TODO(b/193678732): Investigate why the compiler decides not to generate
-// such instructions and why it becomes so much worse.
+// TODO(b/193678732): Investigate why there is a slight performance hit when
+// using intrinsics instead of inline assembly.
inline V128 V128_PMulHi(const V128 l, const V128 r) {
uint64x2_t res;
__asm__ __volatile__("pmull2 %0.1q, %1.2d, %2.2d \n\t"
@@ -215,10 +235,14 @@ inline V128 V128_PMulHi(const V128 l, const V128 r) {
return res;
}
+// TODO(b/193678732): Investigate why the compiler decides to move the constant
+// loop multiplicands from GPR to Neon registers every loop iteration.
inline V128 V128_PMulLow(const V128 l, const V128 r) {
- return reinterpret_cast<V128>(vmull_p64(
- reinterpret_cast<poly64_t>(vget_low_p64(vreinterpretq_p64_u64(l))),
- reinterpret_cast<poly64_t>(vget_low_p64(vreinterpretq_p64_u64(r)))));
+ uint64x2_t res;
+ __asm__ __volatile__("pmull %0.1q, %1.1d, %2.1d \n\t"
+ : "=w"(res)
+ : "w"(l), "w"(r));
+ return res;
}
inline V128 V128_PMul01(const V128 l, const V128 r) {
@@ -252,6 +276,11 @@ inline int V128_Extract32(const V128 l) {
return vgetq_lane_s32(vreinterpretq_s32_u64(l), imm);
}
+template <int imm>
+inline uint64_t V128_Extract64(const V128 l) {
+ return vgetq_lane_u64(l, imm);
+}
+
inline int64_t V128_Low64(const V128 l) {
return vgetq_lane_s64(vreinterpretq_s64_u64(l), 0);
}
diff --git a/contrib/restricted/abseil-cpp/absl/crc/internal/crc_memcpy.h b/contrib/restricted/abseil-cpp/absl/crc/internal/crc_memcpy.h
index 4909d43366..a0fed65afa 100644
--- a/contrib/restricted/abseil-cpp/absl/crc/internal/crc_memcpy.h
+++ b/contrib/restricted/abseil-cpp/absl/crc/internal/crc_memcpy.h
@@ -20,12 +20,15 @@
#include "absl/base/config.h"
#include "absl/crc/crc32c.h"
+#include "absl/crc/internal/crc32_x86_arm_combined_simd.h"
// Defined if the class AcceleratedCrcMemcpyEngine exists.
-#if defined(__x86_64__) && defined(__SSE4_2__)
-#define ABSL_INTERNAL_HAVE_X86_64_ACCELERATED_CRC_MEMCPY_ENGINE 1
-#elif defined(_MSC_VER) && defined(__AVX__)
+// TODO(b/299127771): Consider relaxing the pclmul requirement once the other
+// intrinsics are conditionally compiled without it.
+#if defined(ABSL_CRC_INTERNAL_HAVE_X86_SIMD)
#define ABSL_INTERNAL_HAVE_X86_64_ACCELERATED_CRC_MEMCPY_ENGINE 1
+#elif defined(ABSL_CRC_INTERNAL_HAVE_ARM_SIMD)
+#define ABSL_INTERNAL_HAVE_ARM_ACCELERATED_CRC_MEMCPY_ENGINE 1
#endif
namespace absl {
diff --git a/contrib/restricted/abseil-cpp/absl/crc/internal/crc_memcpy_fallback.cc b/contrib/restricted/abseil-cpp/absl/crc/internal/crc_memcpy_fallback.cc
index 15b4b05594..07795504e3 100644
--- a/contrib/restricted/abseil-cpp/absl/crc/internal/crc_memcpy_fallback.cc
+++ b/contrib/restricted/abseil-cpp/absl/crc/internal/crc_memcpy_fallback.cc
@@ -54,7 +54,8 @@ absl::crc32c_t FallbackCrcMemcpyEngine::Compute(void* __restrict dst,
}
// Compile the following only if we don't have
-#ifndef ABSL_INTERNAL_HAVE_X86_64_ACCELERATED_CRC_MEMCPY_ENGINE
+#if !defined(ABSL_INTERNAL_HAVE_X86_64_ACCELERATED_CRC_MEMCPY_ENGINE) && \
+ !defined(ABSL_INTERNAL_HAVE_ARM_ACCELERATED_CRC_MEMCPY_ENGINE)
CrcMemcpy::ArchSpecificEngines CrcMemcpy::GetArchSpecificEngines() {
CrcMemcpy::ArchSpecificEngines engines;
@@ -68,7 +69,8 @@ std::unique_ptr<CrcMemcpyEngine> CrcMemcpy::GetTestEngine(int /*vector*/,
return std::make_unique<FallbackCrcMemcpyEngine>();
}
-#endif // ABSL_INTERNAL_HAVE_X86_64_ACCELERATED_CRC_MEMCPY_ENGINE
+#endif // !ABSL_INTERNAL_HAVE_X86_64_ACCELERATED_CRC_MEMCPY_ENGINE &&
+ // !ABSL_INTERNAL_HAVE_ARM_ACCELERATED_CRC_MEMCPY_ENGINE
} // namespace crc_internal
ABSL_NAMESPACE_END
diff --git a/contrib/restricted/abseil-cpp/absl/crc/internal/crc_memcpy_x86_64.cc b/contrib/restricted/abseil-cpp/absl/crc/internal/crc_memcpy_x86_arm_combined.cc
index d42b08dc9f..968e9ae359 100644
--- a/contrib/restricted/abseil-cpp/absl/crc/internal/crc_memcpy_x86_64.cc
+++ b/contrib/restricted/abseil-cpp/absl/crc/internal/crc_memcpy_x86_arm_combined.cc
@@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// Simultaneous memcopy and CRC-32C for x86-64. Uses integer registers because
-// XMM registers do not support the CRC instruction (yet). While copying,
-// compute the running CRC of the data being copied.
+// Simultaneous memcopy and CRC-32C for x86-64 and ARM 64. Uses integer
+// registers because XMM registers do not support the CRC instruction (yet).
+// While copying, compute the running CRC of the data being copied.
//
// It is assumed that any CPU running this code has SSE4.2 instructions
// available (for CRC32C). This file will do nothing if that is not true.
@@ -49,17 +49,20 @@
#include <array>
#include <cstddef>
#include <cstdint>
-#include <type_traits>
+#include <cstring>
+#include <memory>
-#include "absl/base/dynamic_annotations.h"
+#include "absl/base/config.h"
#include "absl/base/optimization.h"
#include "absl/base/prefetch.h"
#include "absl/crc/crc32c.h"
#include "absl/crc/internal/cpu_detect.h"
+#include "absl/crc/internal/crc32_x86_arm_combined_simd.h"
#include "absl/crc/internal/crc_memcpy.h"
#include "absl/strings/string_view.h"
-#ifdef ABSL_INTERNAL_HAVE_X86_64_ACCELERATED_CRC_MEMCPY_ENGINE
+#if defined(ABSL_INTERNAL_HAVE_X86_64_ACCELERATED_CRC_MEMCPY_ENGINE) || \
+ defined(ABSL_INTERNAL_HAVE_ARM_ACCELERATED_CRC_MEMCPY_ENGINE)
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -74,7 +77,7 @@ inline crc32c_t ShortCrcCopy(char* dst, const char* src, std::size_t length,
uint32_t crc_uint32 = static_cast<uint32_t>(crc);
for (std::size_t i = 0; i < length; i++) {
uint8_t data = *reinterpret_cast<const uint8_t*>(src);
- crc_uint32 = _mm_crc32_u8(crc_uint32, data);
+ crc_uint32 = CRC32_u8(crc_uint32, data);
*reinterpret_cast<uint8_t*>(dst) = data;
++src;
++dst;
@@ -82,36 +85,35 @@ inline crc32c_t ShortCrcCopy(char* dst, const char* src, std::size_t length,
return crc32c_t{crc_uint32};
}
-constexpr size_t kIntLoadsPerVec = sizeof(__m128i) / sizeof(uint64_t);
+constexpr size_t kIntLoadsPerVec = sizeof(V128) / sizeof(uint64_t);
// Common function for copying the tails of multiple large regions.
template <size_t vec_regions, size_t int_regions>
inline void LargeTailCopy(crc32c_t* crcs, char** dst, const char** src,
size_t region_size, size_t copy_rounds) {
- std::array<__m128i, vec_regions> data;
+ std::array<V128, vec_regions> data;
std::array<uint64_t, kIntLoadsPerVec * int_regions> int_data;
while (copy_rounds > 0) {
for (size_t i = 0; i < vec_regions; i++) {
size_t region = i;
- auto* vsrc =
- reinterpret_cast<const __m128i*>(*src + region_size * region);
- auto* vdst = reinterpret_cast<__m128i*>(*dst + region_size * region);
+ auto* vsrc = reinterpret_cast<const V128*>(*src + region_size * region);
+ auto* vdst = reinterpret_cast<V128*>(*dst + region_size * region);
// Load the blocks, unaligned
- data[i] = _mm_loadu_si128(vsrc);
+ data[i] = V128_LoadU(vsrc);
// Store the blocks, aligned
- _mm_store_si128(vdst, data[i]);
+ V128_Store(vdst, data[i]);
// Compute the running CRC
crcs[region] = crc32c_t{static_cast<uint32_t>(
- _mm_crc32_u64(static_cast<uint32_t>(crcs[region]),
- static_cast<uint64_t>(_mm_extract_epi64(data[i], 0))))};
+ CRC32_u64(static_cast<uint32_t>(crcs[region]),
+ static_cast<uint64_t>(V128_Extract64<0>(data[i]))))};
crcs[region] = crc32c_t{static_cast<uint32_t>(
- _mm_crc32_u64(static_cast<uint32_t>(crcs[region]),
- static_cast<uint64_t>(_mm_extract_epi64(data[i], 1))))};
+ CRC32_u64(static_cast<uint32_t>(crcs[region]),
+ static_cast<uint64_t>(V128_Extract64<1>(data[i]))))};
}
for (size_t i = 0; i < int_regions; i++) {
@@ -125,7 +127,7 @@ inline void LargeTailCopy(crc32c_t* crcs, char** dst, const char** src,
size_t data_index = i * kIntLoadsPerVec + j;
int_data[data_index] = *(usrc + j);
- crcs[region] = crc32c_t{static_cast<uint32_t>(_mm_crc32_u64(
+ crcs[region] = crc32c_t{static_cast<uint32_t>(CRC32_u64(
static_cast<uint32_t>(crcs[region]), int_data[data_index]))};
*(udst + j) = int_data[data_index];
@@ -133,8 +135,8 @@ inline void LargeTailCopy(crc32c_t* crcs, char** dst, const char** src,
}
// Increment pointers
- *src += sizeof(__m128i);
- *dst += sizeof(__m128i);
+ *src += sizeof(V128);
+ *dst += sizeof(V128);
--copy_rounds;
}
}
@@ -158,8 +160,9 @@ crc32c_t AcceleratedCrcMemcpyEngine<vec_regions, int_regions>::Compute(
void* __restrict dst, const void* __restrict src, std::size_t length,
crc32c_t initial_crc) const {
constexpr std::size_t kRegions = vec_regions + int_regions;
+ static_assert(kRegions > 0, "Must specify at least one region.");
constexpr uint32_t kCrcDataXor = uint32_t{0xffffffff};
- constexpr std::size_t kBlockSize = sizeof(__m128i);
+ constexpr std::size_t kBlockSize = sizeof(V128);
constexpr std::size_t kCopyRoundSize = kRegions * kBlockSize;
// Number of blocks per cacheline.
@@ -235,7 +238,7 @@ crc32c_t AcceleratedCrcMemcpyEngine<vec_regions, int_regions>::Compute(
const std::size_t tail_size = length - (kRegions * region_size);
// Holding registers for data in each region.
- std::array<__m128i, vec_regions> vec_data;
+ std::array<V128, vec_regions> vec_data;
std::array<uint64_t, int_regions * kIntLoadsPerVec> int_data;
// Main loop.
@@ -243,7 +246,10 @@ crc32c_t AcceleratedCrcMemcpyEngine<vec_regions, int_regions>::Compute(
// Prefetch kPrefetchAhead bytes ahead of each pointer.
for (size_t i = 0; i < kRegions; i++) {
absl::PrefetchToLocalCache(src_bytes + kPrefetchAhead + region_size * i);
+#ifdef ABSL_INTERNAL_HAVE_X86_64_ACCELERATED_CRC_MEMCPY_ENGINE
+ // TODO(b/297082454): investigate dropping prefetch on x86.
absl::PrefetchToLocalCache(dst_bytes + kPrefetchAhead + region_size * i);
+#endif
}
// Load and store data, computing CRC on the way.
@@ -256,21 +262,20 @@ crc32c_t AcceleratedCrcMemcpyEngine<vec_regions, int_regions>::Compute(
size_t region = (j + i) % kRegions;
auto* vsrc =
- reinterpret_cast<const __m128i*>(src_bytes + region_size * region);
- auto* vdst =
- reinterpret_cast<__m128i*>(dst_bytes + region_size * region);
+ reinterpret_cast<const V128*>(src_bytes + region_size * region);
+ auto* vdst = reinterpret_cast<V128*>(dst_bytes + region_size * region);
// Load and CRC data.
- vec_data[j] = _mm_loadu_si128(vsrc + i);
- crcs[region] = crc32c_t{static_cast<uint32_t>(_mm_crc32_u64(
- static_cast<uint32_t>(crcs[region]),
- static_cast<uint64_t>(_mm_extract_epi64(vec_data[j], 0))))};
- crcs[region] = crc32c_t{static_cast<uint32_t>(_mm_crc32_u64(
- static_cast<uint32_t>(crcs[region]),
- static_cast<uint64_t>(_mm_extract_epi64(vec_data[j], 1))))};
+ vec_data[j] = V128_LoadU(vsrc + i);
+ crcs[region] = crc32c_t{static_cast<uint32_t>(
+ CRC32_u64(static_cast<uint32_t>(crcs[region]),
+ static_cast<uint64_t>(V128_Extract64<0>(vec_data[j]))))};
+ crcs[region] = crc32c_t{static_cast<uint32_t>(
+ CRC32_u64(static_cast<uint32_t>(crcs[region]),
+ static_cast<uint64_t>(V128_Extract64<1>(vec_data[j]))))};
// Store the data.
- _mm_store_si128(vdst + i, vec_data[j]);
+ V128_Store(vdst + i, vec_data[j]);
}
// Preload the partial CRCs for the CLMUL subregions.
@@ -290,7 +295,7 @@ crc32c_t AcceleratedCrcMemcpyEngine<vec_regions, int_regions>::Compute(
// Load and CRC the data.
int_data[data_index] = *(usrc + i * kIntLoadsPerVec + k);
- crcs[region] = crc32c_t{static_cast<uint32_t>(_mm_crc32_u64(
+ crcs[region] = crc32c_t{static_cast<uint32_t>(CRC32_u64(
static_cast<uint32_t>(crcs[region]), int_data[data_index]))};
// Store the data.
@@ -313,6 +318,21 @@ crc32c_t AcceleratedCrcMemcpyEngine<vec_regions, int_regions>::Compute(
src_bytes += region_size * (kRegions - 1);
dst_bytes += region_size * (kRegions - 1);
+ // Copy and CRC the tail through the XMM registers.
+ std::size_t tail_blocks = tail_size / kBlockSize;
+ LargeTailCopy<0, 1>(&crcs[kRegions - 1], &dst_bytes, &src_bytes, 0,
+ tail_blocks);
+
+ // Final tail copy for under 16 bytes.
+ crcs[kRegions - 1] =
+ ShortCrcCopy(dst_bytes, src_bytes, tail_size - tail_blocks * kBlockSize,
+ crcs[kRegions - 1]);
+
+ if (kRegions == 1) {
+ // If there is only one region, finalize and return its CRC.
+ return crc32c_t{static_cast<uint32_t>(crcs[0]) ^ kCrcDataXor};
+ }
+
// Finalize the first CRCs: XOR the internal CRCs by the XOR mask to undo the
// XOR done before doing block copy + CRCs.
for (size_t i = 0; i + 1 < kRegions; i++) {
@@ -325,16 +345,6 @@ crc32c_t AcceleratedCrcMemcpyEngine<vec_regions, int_regions>::Compute(
full_crc = ConcatCrc32c(full_crc, crcs[i], region_size);
}
- // Copy and CRC the tail through the XMM registers.
- std::size_t tail_blocks = tail_size / kBlockSize;
- LargeTailCopy<0, 1>(&crcs[kRegions - 1], &dst_bytes, &src_bytes, 0,
- tail_blocks);
-
- // Final tail copy for under 16 bytes.
- crcs[kRegions - 1] =
- ShortCrcCopy(dst_bytes, src_bytes, tail_size - tail_blocks * kBlockSize,
- crcs[kRegions - 1]);
-
// Finalize and concatenate the final CRC, then return.
crcs[kRegions - 1] =
crc32c_t{static_cast<uint32_t>(crcs[kRegions - 1]) ^ kCrcDataXor};
@@ -347,9 +357,11 @@ CrcMemcpy::ArchSpecificEngines CrcMemcpy::GetArchSpecificEngines() {
// Get the underlying architecture.
CpuType cpu_type = GetCpuType();
switch (cpu_type) {
- case CpuType::kUnknown:
case CpuType::kAmdRome:
case CpuType::kAmdNaples:
+ case CpuType::kAmdMilan:
+ case CpuType::kAmdGenoa:
+ case CpuType::kAmdRyzenV3000:
case CpuType::kIntelCascadelakeXeon:
case CpuType::kIntelSkylakeXeon:
case CpuType::kIntelSkylake:
@@ -385,6 +397,9 @@ CrcMemcpy::ArchSpecificEngines CrcMemcpy::GetArchSpecificEngines() {
// strided access to each region, and do the right thing.
case CpuType::kAmdRome:
case CpuType::kAmdNaples:
+ case CpuType::kAmdMilan:
+ case CpuType::kAmdGenoa:
+ case CpuType::kAmdRyzenV3000:
return {
/*.temporal=*/new AcceleratedCrcMemcpyEngine<1, 2>(),
/*.non_temporal=*/new CrcNonTemporalMemcpyAVXEngine(),
@@ -421,6 +436,8 @@ std::unique_ptr<CrcMemcpyEngine> CrcMemcpy::GetTestEngine(int vector,
return std::make_unique<AcceleratedCrcMemcpyEngine<3, 0>>();
} else if (vector == 1 && integer == 2) {
return std::make_unique<AcceleratedCrcMemcpyEngine<1, 2>>();
+ } else if (vector == 1 && integer == 0) {
+ return std::make_unique<AcceleratedCrcMemcpyEngine<1, 0>>();
}
return nullptr;
}
@@ -429,4 +446,5 @@ std::unique_ptr<CrcMemcpyEngine> CrcMemcpy::GetTestEngine(int vector,
ABSL_NAMESPACE_END
} // namespace absl
-#endif // ABSL_INTERNAL_HAVE_X86_64_ACCELERATED_CRC_MEMCPY_ENGINE
+#endif // ABSL_INTERNAL_HAVE_X86_64_ACCELERATED_CRC_MEMCPY_ENGINE ||
+ // ABSL_INTERNAL_HAVE_ARM_ACCELERATED_CRC_MEMCPY_ENGINE
diff --git a/contrib/restricted/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc b/contrib/restricted/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc
index ef521d22d1..51eff4eddc 100644
--- a/contrib/restricted/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc
+++ b/contrib/restricted/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc
@@ -16,14 +16,14 @@
#include <cstddef>
#include <cstdint>
+#include <memory>
+#include <vector>
#include "absl/base/attributes.h"
#include "absl/base/config.h"
-#include "absl/base/dynamic_annotations.h"
#include "absl/base/internal/endian.h"
#include "absl/base/prefetch.h"
#include "absl/crc/internal/cpu_detect.h"
-#include "absl/crc/internal/crc.h"
#include "absl/crc/internal/crc32_x86_arm_combined_simd.h"
#include "absl/crc/internal/crc_internal.h"
#include "absl/memory/memory.h"
@@ -634,8 +634,16 @@ CRCImpl* TryNewCRC32AcceleratedX86ARMCombined() {
return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
3, 0, CutoffStrategy::Fold3>();
case CpuType::kArmNeoverseN1:
+ case CpuType::kArmNeoverseN2:
+ case CpuType::kArmNeoverseV1:
return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
1, 1, CutoffStrategy::Unroll64CRC>();
+ case CpuType::kAmpereSiryn:
+ return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
+ 3, 2, CutoffStrategy::Fold3>();
+ case CpuType::kArmNeoverseV2:
+ return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
+ 1, 2, CutoffStrategy::Unroll64CRC>();
#if defined(__aarch64__)
default:
// Not all ARM processors support the needed instructions, so check here
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 992c89c390..570d1e504d 100644
--- a/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.cc
+++ b/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.cc
@@ -54,7 +54,7 @@
#include "absl/debugging/internal/examine_stack.h"
#include "absl/debugging/stacktrace.h"
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__wasi__)
#define ABSL_HAVE_SIGACTION
// Apple WatchOS and TVOS don't allow sigaltstack
// Apple macOS has sigaltstack, but using it makes backtrace() unusable.
diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/address_is_readable.cc b/contrib/restricted/abseil-cpp/absl/debugging/internal/address_is_readable.cc
index 91eaa76f8a..be17a10591 100644
--- a/contrib/restricted/abseil-cpp/absl/debugging/internal/address_is_readable.cc
+++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/address_is_readable.cc
@@ -50,8 +50,10 @@ namespace debugging_internal {
// NOTE: any new system calls here may also require sandbox reconfiguration.
//
bool AddressIsReadable(const void *addr) {
- // Align address on 8-byte boundary. On aarch64, checking last
- // byte before inaccessible page returned unexpected EFAULT.
+ // rt_sigprocmask below checks 8 contiguous bytes. If addr resides in the
+ // last 7 bytes of a page (unaligned), rt_sigprocmask would additionally
+ // check the readability of the next page, which is not desired. Align
+ // address on 8-byte boundary to check only the current page.
const uintptr_t u_addr = reinterpret_cast<uintptr_t>(addr) & ~uintptr_t{7};
addr = reinterpret_cast<const void *>(u_addr);
diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.cc b/contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.cc
index f2832915bf..381a2b504b 100644
--- a/contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.cc
+++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.cc
@@ -21,7 +21,15 @@
#include <cstdint>
#include <cstdio>
+#include <cstdlib>
#include <limits>
+#include <string>
+
+#include "absl/base/config.h"
+
+#if ABSL_INTERNAL_HAS_CXA_DEMANGLE
+#include <cxxabi.h>
+#endif
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -1983,6 +1991,22 @@ bool Demangle(const char* mangled, char* out, size_t out_size) {
state.parse_state.out_cur_idx > 0;
}
+std::string DemangleString(const char* mangled) {
+ std::string out;
+ int status = 0;
+ char* demangled = nullptr;
+#if ABSL_INTERNAL_HAS_CXA_DEMANGLE
+ demangled = abi::__cxa_demangle(mangled, nullptr, nullptr, &status);
+#endif
+ if (status == 0 && demangled != nullptr) {
+ out.append(demangled);
+ free(demangled);
+ } else {
+ out.append(mangled);
+ }
+ return out;
+}
+
} // namespace debugging_internal
ABSL_NAMESPACE_END
} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.h b/contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.h
index e1f156989f..146d1150ef 100644
--- a/contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.h
+++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.h
@@ -12,13 +12,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// An async-signal-safe and thread-safe demangler for Itanium C++ ABI
-// (aka G++ V3 ABI).
+#ifndef ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_
+#define ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_
+
+#include <string>
+#include "absl/base/config.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace debugging_internal {
+
+// Demangle `mangled`. On success, return true and write the
+// demangled symbol name to `out`. Otherwise, return false.
+// `out` is modified even if demangling is unsuccessful.
//
-// The demangler is implemented to be used in async signal handlers to
-// symbolize stack traces. We cannot use libstdc++'s
-// abi::__cxa_demangle() in such signal handlers since it's not async
-// signal safe (it uses malloc() internally).
+// This function provides an alternative to libstdc++'s abi::__cxa_demangle,
+// which is not async signal safe (it uses malloc internally). It's intended to
+// be used in async signal handlers to symbolize stack traces.
//
// Note that this demangler doesn't support full demangling. More
// specifically, it doesn't print types of function parameters and
@@ -30,40 +40,32 @@
//
// Example:
//
-// | Mangled Name | The Demangler | abi::__cxa_demangle()
-// |---------------|---------------|-----------------------
-// | _Z1fv | f() | f()
-// | _Z1fi | f() | f(int)
-// | _Z3foo3bar | foo() | foo(bar)
-// | _Z1fIiEvi | f<>() | void f<int>(int)
-// | _ZN1N1fE | N::f | N::f
-// | _ZN3Foo3BarEv | Foo::Bar() | Foo::Bar()
-// | _Zrm1XS_" | operator%() | operator%(X, X)
-// | _ZN3FooC1Ev | Foo::Foo() | Foo::Foo()
-// | _Z1fSs | f() | f(std::basic_string<char,
-// | | | std::char_traits<char>,
-// | | | std::allocator<char> >)
+// | Mangled Name | Demangle | DemangleString
+// |---------------|-------------|-----------------------
+// | _Z1fv | f() | f()
+// | _Z1fi | f() | f(int)
+// | _Z3foo3bar | foo() | foo(bar)
+// | _Z1fIiEvi | f<>() | void f<int>(int)
+// | _ZN1N1fE | N::f | N::f
+// | _ZN3Foo3BarEv | Foo::Bar() | Foo::Bar()
+// | _Zrm1XS_" | operator%() | operator%(X, X)
+// | _ZN3FooC1Ev | Foo::Foo() | Foo::Foo()
+// | _Z1fSs | f() | f(std::basic_string<char,
+// | | | std::char_traits<char>,
+// | | | std::allocator<char> >)
//
// See the unit test for more examples.
//
// Note: we might want to write demanglers for ABIs other than Itanium
// C++ ABI in the future.
-//
-
-#ifndef ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_
-#define ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_
-
-#include "absl/base/config.h"
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-namespace debugging_internal {
-
-// Demangle `mangled`. On success, return true and write the
-// demangled symbol name to `out`. Otherwise, return false.
-// `out` is modified even if demangling is unsuccessful.
bool Demangle(const char* mangled, char* out, size_t out_size);
+// A wrapper around `abi::__cxa_demangle()`. On success, returns the demangled
+// name. On failure, returns the input mangled name.
+//
+// This function is not async-signal-safe.
+std::string DemangleString(const char* mangled);
+
} // namespace debugging_internal
ABSL_NAMESPACE_END
} // namespace absl
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 3f08716202..1caf7bbe35 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
@@ -4,6 +4,7 @@
// Generate stack tracer for aarch64
#if defined(__linux__)
+#include <signal.h>
#include <sys/mman.h>
#include <ucontext.h>
#include <unistd.h>
@@ -70,7 +71,7 @@ static const unsigned char* GetKernelRtSigreturnAddress() {
// Compute the size of a stack frame in [low..high). We assume that
// low < high. Return size of kUnknownFrameSize.
template<typename T>
-static inline size_t ComputeStackFrameSize(const T* low,
+static size_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);
@@ -78,6 +79,20 @@ static inline size_t ComputeStackFrameSize(const T* low,
: kUnknownFrameSize;
}
+// Saves stack info that is expensive to calculate to avoid recalculating per frame.
+struct StackInfo {
+ uintptr_t stack_low;
+ uintptr_t stack_high;
+ uintptr_t sig_stack_low;
+ uintptr_t sig_stack_high;
+};
+
+static bool InsideSignalStack(void** ptr, const StackInfo* stack_info) {
+ uintptr_t comparable_ptr = reinterpret_cast<uintptr_t>(ptr);
+ return (comparable_ptr >= stack_info->sig_stack_low &&
+ comparable_ptr < stack_info->sig_stack_high);
+}
+
// Given a pointer to a stack frame, locate and return the calling
// stackframe, or return null if no stackframe can be found. Perform sanity
// checks (the strictness of which is controlled by the boolean parameter
@@ -86,9 +101,8 @@ template<bool STRICT_UNWINDING, bool WITH_CONTEXT>
ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack.
ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack.
static void **NextStackFrame(void **old_frame_pointer, const void *uc,
- size_t stack_low, size_t stack_high) {
+ const StackInfo *stack_info) {
void **new_frame_pointer = reinterpret_cast<void**>(*old_frame_pointer);
- bool check_frame_size = true;
#if defined(__linux__)
if (WITH_CONTEXT && uc != nullptr) {
@@ -114,10 +128,6 @@ static void **NextStackFrame(void **old_frame_pointer, const void *uc,
if (!absl::debugging_internal::AddressIsReadable(
new_frame_pointer))
return nullptr;
-
- // Skip frame size check if we return from a signal. We may be using a
- // an alternate stack for signals.
- check_frame_size = false;
}
}
#endif
@@ -126,9 +136,11 @@ static void **NextStackFrame(void **old_frame_pointer, const void *uc,
if ((reinterpret_cast<uintptr_t>(new_frame_pointer) & 7) != 0)
return nullptr;
- // Check frame size. In strict mode, we assume frames to be under
- // 100,000 bytes. In non-strict mode, we relax the limit to 1MB.
- if (check_frame_size) {
+ // Only check the size if both frames are in the same stack.
+ if (InsideSignalStack(new_frame_pointer, stack_info) ==
+ InsideSignalStack(old_frame_pointer, stack_info)) {
+ // 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 size_t max_size = STRICT_UNWINDING ? 100000 : 1000000;
const size_t frame_size =
ComputeStackFrameSize(old_frame_pointer, new_frame_pointer);
@@ -136,15 +148,21 @@ static void **NextStackFrame(void **old_frame_pointer, const void *uc,
return nullptr;
// A very large frame may mean corrupt memory or an erroneous frame
// pointer. But also maybe just a plain-old large frame. Assume that if the
- // frame is within the known stack, then it is valid.
+ // frame is within a known stack, then it is valid.
if (frame_size > max_size) {
- if (stack_high < kUnknownStackEnd &&
+ size_t stack_low = stack_info->stack_low;
+ size_t stack_high = stack_info->stack_high;
+ if (InsideSignalStack(new_frame_pointer, stack_info)) {
+ stack_low = stack_info->sig_stack_low;
+ stack_high = stack_info->sig_stack_high;
+ }
+ if (stack_high < kUnknownStackEnd &&
static_cast<size_t>(getpagesize()) < stack_low) {
const uintptr_t new_fp_u =
reinterpret_cast<uintptr_t>(new_frame_pointer);
// Stack bounds are known.
if (!(stack_low < new_fp_u && new_fp_u <= stack_high)) {
- // new_frame_pointer is not within the known stack.
+ // new_frame_pointer is not within a known stack.
return nullptr;
}
} else {
@@ -158,6 +176,9 @@ static void **NextStackFrame(void **old_frame_pointer, const void *uc,
}
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
+ABSL_ATTRIBUTE_NOINLINE
ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack.
ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack.
static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count,
@@ -171,8 +192,11 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count,
int n = 0;
// Assume that the first page is not stack.
- size_t stack_low = static_cast<size_t>(getpagesize());
- size_t stack_high = kUnknownStackEnd;
+ StackInfo stack_info;
+ stack_info.stack_low = static_cast<uintptr_t>(getpagesize());
+ stack_info.stack_high = kUnknownStackEnd;
+ stack_info.sig_stack_low = stack_info.stack_low;
+ stack_info.sig_stack_high = kUnknownStackEnd;
// The frame pointer points to low address of a frame. The first 64-bit
// word of a frame points to the next frame up the call chain, which normally
@@ -207,7 +231,7 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count,
// that is as complete as possible (even if it contains a few bogus
// entries in some rare cases).
frame_pointer = NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(
- frame_pointer, ucp, stack_low, stack_high);
+ frame_pointer, ucp, &stack_info);
}
if (min_dropped_frames != nullptr) {
@@ -222,7 +246,7 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count,
num_dropped_frames++;
}
frame_pointer = NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(
- frame_pointer, ucp, stack_low, stack_high);
+ frame_pointer, ucp, &stack_info);
}
*min_dropped_frames = num_dropped_frames;
}
diff --git a/contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc b/contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc
index 30638cb2dc..ae75cd4153 100644
--- a/contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc
+++ b/contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc
@@ -289,6 +289,30 @@ ObjFile *AddrMap::Add() {
return new (&obj_[size_++]) ObjFile;
}
+class CachingFile {
+ public:
+ // Setup reader for fd that uses buf[0, buf_size-1] as a cache.
+ CachingFile(int fd, char *buf, size_t buf_size)
+ : fd_(fd),
+ cache_(buf),
+ cache_size_(buf_size),
+ cache_start_(0),
+ cache_limit_(0) {}
+
+ int fd() const { return fd_; }
+ ssize_t ReadFromOffset(void *buf, size_t count, off_t offset);
+ bool ReadFromOffsetExact(void *buf, size_t count, off_t offset);
+
+ private:
+ // Bytes [cache_start_, cache_limit_-1] from fd_ are stored in
+ // a prefix of cache_[0, cache_size_-1].
+ int fd_;
+ char *cache_;
+ size_t cache_size_;
+ off_t cache_start_;
+ off_t cache_limit_;
+};
+
// ---------------------------------------------------------------
enum FindSymbolResult { SYMBOL_NOT_FOUND = 1, SYMBOL_TRUNCATED, SYMBOL_FOUND };
@@ -330,6 +354,7 @@ class Symbolizer {
SYMBOL_BUF_SIZE = 3072,
TMP_BUF_SIZE = 1024,
SYMBOL_CACHE_LINES = 128,
+ FILE_CACHE_SIZE = 8192,
};
AddrMap addr_map_;
@@ -338,6 +363,7 @@ class Symbolizer {
bool addr_map_read_;
char symbol_buf_[SYMBOL_BUF_SIZE];
+ char file_cache_[FILE_CACHE_SIZE];
// tmp_buf_ will be used to store arrays of ElfW(Shdr) and ElfW(Sym)
// so we ensure that tmp_buf_ is properly aligned to store either.
@@ -436,34 +462,58 @@ static ssize_t ReadPersistent(int fd, void *buf, size_t count) {
return static_cast<ssize_t>(num_bytes);
}
-// Read up to "count" bytes from "offset" in the file pointed by file
-// descriptor "fd" into the buffer starting at "buf". On success,
-// return the number of bytes read. Otherwise, return -1.
-static ssize_t ReadFromOffset(const int fd, void *buf, const size_t count,
- const off_t offset) {
- off_t off = lseek(fd, offset, SEEK_SET);
- if (off == (off_t)-1) {
- ABSL_RAW_LOG(WARNING, "lseek(%d, %jd, SEEK_SET) failed: errno=%d", fd,
- static_cast<intmax_t>(offset), errno);
- return -1;
+// Read up to "count" bytes from "offset" into the buffer starting at "buf",
+// while handling short reads and EINTR. On success, return the number of bytes
+// read. Otherwise, return -1.
+ssize_t CachingFile::ReadFromOffset(void *buf, size_t count, off_t offset) {
+ char *dst = static_cast<char *>(buf);
+ size_t read = 0;
+ while (read < count) {
+ // Look in cache first.
+ if (offset >= cache_start_ && offset < cache_limit_) {
+ const char *hit_start = &cache_[offset - cache_start_];
+ const size_t n =
+ std::min(count - read, static_cast<size_t>(cache_limit_ - offset));
+ memcpy(dst, hit_start, n);
+ dst += n;
+ read += static_cast<size_t>(n);
+ offset += static_cast<off_t>(n);
+ continue;
+ }
+
+ cache_start_ = 0;
+ cache_limit_ = 0;
+ ssize_t n = pread(fd_, cache_, cache_size_, offset);
+ if (n < 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+ ABSL_RAW_LOG(WARNING, "read failed: errno=%d", errno);
+ return -1;
+ }
+ if (n == 0) { // Reached EOF.
+ break;
+ }
+
+ cache_start_ = offset;
+ cache_limit_ = offset + static_cast<off_t>(n);
+ // Next iteration will copy from cache into dst.
}
- return ReadPersistent(fd, buf, count);
+ return static_cast<ssize_t>(read);
}
-// Try reading exactly "count" bytes from "offset" bytes in a file
-// pointed by "fd" into the buffer starting at "buf" while handling
-// short reads and EINTR. On success, return true. Otherwise, return
-// false.
-static bool ReadFromOffsetExact(const int fd, void *buf, const size_t count,
- const off_t offset) {
- ssize_t len = ReadFromOffset(fd, buf, count, offset);
+// Try reading exactly "count" bytes from "offset" bytes into the buffer
+// starting at "buf" while handling short reads and EINTR. On success, return
+// true. Otherwise, return false.
+bool CachingFile::ReadFromOffsetExact(void *buf, size_t count, off_t offset) {
+ ssize_t len = ReadFromOffset(buf, count, offset);
return len >= 0 && static_cast<size_t>(len) == count;
}
// Returns elf_header.e_type if the file pointed by fd is an ELF binary.
-static int FileGetElfType(const int fd) {
+static int FileGetElfType(CachingFile *file) {
ElfW(Ehdr) elf_header;
- if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
+ if (!file->ReadFromOffsetExact(&elf_header, sizeof(elf_header), 0)) {
return -1;
}
if (memcmp(elf_header.e_ident, ELFMAG, SELFMAG) != 0) {
@@ -478,8 +528,8 @@ static int FileGetElfType(const int fd) {
// To keep stack consumption low, we would like this function to not get
// inlined.
static ABSL_ATTRIBUTE_NOINLINE bool GetSectionHeaderByType(
- const int fd, ElfW(Half) sh_num, const off_t sh_offset, ElfW(Word) type,
- ElfW(Shdr) * out, char *tmp_buf, size_t tmp_buf_size) {
+ CachingFile *file, ElfW(Half) sh_num, const off_t sh_offset,
+ ElfW(Word) type, ElfW(Shdr) * out, char *tmp_buf, size_t tmp_buf_size) {
ElfW(Shdr) *buf = reinterpret_cast<ElfW(Shdr) *>(tmp_buf);
const size_t buf_entries = tmp_buf_size / sizeof(buf[0]);
const size_t buf_bytes = buf_entries * sizeof(buf[0]);
@@ -490,7 +540,7 @@ static ABSL_ATTRIBUTE_NOINLINE bool GetSectionHeaderByType(
const size_t num_bytes_to_read =
(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 = ReadFromOffset(fd, buf, num_bytes_to_read, offset);
+ const ssize_t len = file->ReadFromOffset(buf, num_bytes_to_read, offset);
if (len < 0) {
ABSL_RAW_LOG(
WARNING,
@@ -524,11 +574,17 @@ static ABSL_ATTRIBUTE_NOINLINE bool GetSectionHeaderByType(
// but there has (as yet) been no need for anything longer either.
const int kMaxSectionNameLen = 64;
+// Small cache to use for miscellaneous file reads.
+const int kSmallFileCacheSize = 100;
+
bool ForEachSection(int fd,
const std::function<bool(absl::string_view name,
const ElfW(Shdr) &)> &callback) {
+ char buf[kSmallFileCacheSize];
+ CachingFile file(fd, buf, sizeof(buf));
+
ElfW(Ehdr) elf_header;
- if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
+ if (!file.ReadFromOffsetExact(&elf_header, sizeof(elf_header), 0)) {
return false;
}
@@ -540,7 +596,7 @@ bool ForEachSection(int fd,
ElfW(Shdr) shstrtab;
off_t shstrtab_offset = static_cast<off_t>(elf_header.e_shoff) +
elf_header.e_shentsize * elf_header.e_shstrndx;
- if (!ReadFromOffsetExact(fd, &shstrtab, sizeof(shstrtab), shstrtab_offset)) {
+ if (!file.ReadFromOffsetExact(&shstrtab, sizeof(shstrtab), shstrtab_offset)) {
return false;
}
@@ -548,13 +604,13 @@ bool ForEachSection(int fd,
ElfW(Shdr) out;
off_t section_header_offset =
static_cast<off_t>(elf_header.e_shoff) + elf_header.e_shentsize * i;
- if (!ReadFromOffsetExact(fd, &out, sizeof(out), section_header_offset)) {
+ if (!file.ReadFromOffsetExact(&out, sizeof(out), section_header_offset)) {
return false;
}
off_t name_offset = static_cast<off_t>(shstrtab.sh_offset) + out.sh_name;
char header_name[kMaxSectionNameLen];
ssize_t n_read =
- ReadFromOffset(fd, &header_name, kMaxSectionNameLen, name_offset);
+ file.ReadFromOffset(&header_name, kMaxSectionNameLen, name_offset);
if (n_read < 0) {
return false;
} else if (n_read > kMaxSectionNameLen) {
@@ -584,8 +640,10 @@ bool GetSectionHeaderByName(int fd, const char *name, size_t name_len,
return false;
}
+ char buf[kSmallFileCacheSize];
+ CachingFile file(fd, buf, sizeof(buf));
ElfW(Ehdr) elf_header;
- if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
+ if (!file.ReadFromOffsetExact(&elf_header, sizeof(elf_header), 0)) {
return false;
}
@@ -597,18 +655,18 @@ bool GetSectionHeaderByName(int fd, const char *name, size_t name_len,
ElfW(Shdr) shstrtab;
off_t shstrtab_offset = static_cast<off_t>(elf_header.e_shoff) +
elf_header.e_shentsize * elf_header.e_shstrndx;
- if (!ReadFromOffsetExact(fd, &shstrtab, sizeof(shstrtab), shstrtab_offset)) {
+ if (!file.ReadFromOffsetExact(&shstrtab, sizeof(shstrtab), shstrtab_offset)) {
return false;
}
for (int i = 0; i < elf_header.e_shnum; ++i) {
off_t section_header_offset =
static_cast<off_t>(elf_header.e_shoff) + elf_header.e_shentsize * i;
- if (!ReadFromOffsetExact(fd, out, sizeof(*out), section_header_offset)) {
+ if (!file.ReadFromOffsetExact(out, sizeof(*out), section_header_offset)) {
return false;
}
off_t name_offset = static_cast<off_t>(shstrtab.sh_offset) + out->sh_name;
- ssize_t n_read = ReadFromOffset(fd, &header_name, name_len, name_offset);
+ ssize_t n_read = file.ReadFromOffset(&header_name, name_len, name_offset);
if (n_read < 0) {
return false;
} else if (static_cast<size_t>(n_read) != name_len) {
@@ -683,7 +741,7 @@ static const char *ComputeOffset(const char *base, ptrdiff_t offset) {
// To keep stack consumption low, we would like this function to not get
// inlined.
static ABSL_ATTRIBUTE_NOINLINE FindSymbolResult FindSymbol(
- const void *const pc, const int fd, char *out, size_t out_size,
+ const void *const pc, CachingFile *file, char *out, size_t out_size,
ptrdiff_t relocation, const ElfW(Shdr) * strtab, const ElfW(Shdr) * symtab,
const ElfW(Shdr) * opd, char *tmp_buf, size_t tmp_buf_size) {
if (symtab == nullptr) {
@@ -716,7 +774,7 @@ static ABSL_ATTRIBUTE_NOINLINE FindSymbolResult FindSymbol(
const size_t entries_in_chunk =
std::min(num_remaining_symbols, buf_entries);
const size_t bytes_in_chunk = entries_in_chunk * sizeof(buf[0]);
- const ssize_t len = ReadFromOffset(fd, buf, bytes_in_chunk, offset);
+ const ssize_t len = file->ReadFromOffset(buf, bytes_in_chunk, offset);
SAFE_ASSERT(len >= 0);
SAFE_ASSERT(static_cast<size_t>(len) % sizeof(buf[0]) == 0);
const size_t num_symbols_in_buf = static_cast<size_t>(len) / sizeof(buf[0]);
@@ -772,12 +830,12 @@ static ABSL_ATTRIBUTE_NOINLINE FindSymbolResult FindSymbol(
if (found_match) {
const off_t off =
static_cast<off_t>(strtab->sh_offset) + best_match.st_name;
- const ssize_t n_read = ReadFromOffset(fd, out, out_size, off);
+ const ssize_t n_read = file->ReadFromOffset(out, out_size, off);
if (n_read <= 0) {
// This should never happen.
ABSL_RAW_LOG(WARNING,
- "Unable to read from fd %d at offset %lld: n_read = %zd", fd,
- static_cast<long long>(off), n_read);
+ "Unable to read from fd %d at offset %lld: n_read = %zd",
+ file->fd(), static_cast<long long>(off), n_read);
return SYMBOL_NOT_FOUND;
}
ABSL_RAW_CHECK(static_cast<size_t>(n_read) <= out_size,
@@ -827,22 +885,24 @@ FindSymbolResult Symbolizer::GetSymbolFromObjectFile(
}
}
+ CachingFile file(obj.fd, file_cache_, sizeof(file_cache_));
+
// Consult a regular symbol table, then fall back to the dynamic symbol table.
for (const auto symbol_table_type : {SHT_SYMTAB, SHT_DYNSYM}) {
- if (!GetSectionHeaderByType(obj.fd, obj.elf_header.e_shnum,
+ if (!GetSectionHeaderByType(&file, obj.elf_header.e_shnum,
static_cast<off_t>(obj.elf_header.e_shoff),
static_cast<ElfW(Word)>(symbol_table_type),
&symtab, tmp_buf, tmp_buf_size)) {
continue;
}
- if (!ReadFromOffsetExact(
- obj.fd, &strtab, sizeof(strtab),
+ if (!file.ReadFromOffsetExact(
+ &strtab, sizeof(strtab),
static_cast<off_t>(obj.elf_header.e_shoff +
symtab.sh_link * sizeof(symtab)))) {
continue;
}
const FindSymbolResult rc =
- FindSymbol(pc, obj.fd, out, out_size, relocation, &strtab, &symtab,
+ FindSymbol(pc, &file, out, out_size, relocation, &strtab, &symtab,
opd_ptr, tmp_buf, tmp_buf_size);
if (rc != SYMBOL_NOT_FOUND) {
return rc;
@@ -1323,15 +1383,19 @@ static bool MaybeInitializeObjFile(ObjFile *obj) {
ABSL_RAW_LOG(WARNING, "%s: open failed: errno=%d", obj->filename, errno);
return false;
}
- obj->elf_type = FileGetElfType(obj->fd);
+
+ char buf[kSmallFileCacheSize];
+ CachingFile file(obj->fd, buf, sizeof(buf));
+
+ obj->elf_type = FileGetElfType(&file);
if (obj->elf_type < 0) {
ABSL_RAW_LOG(WARNING, "%s: wrong elf type: %d", obj->filename,
obj->elf_type);
return false;
}
- if (!ReadFromOffsetExact(obj->fd, &obj->elf_header, sizeof(obj->elf_header),
- 0)) {
+ if (!file.ReadFromOffsetExact(&obj->elf_header, sizeof(obj->elf_header),
+ 0)) {
ABSL_RAW_LOG(WARNING, "%s: failed to read elf header", obj->filename);
return false;
}
@@ -1341,7 +1405,7 @@ static bool MaybeInitializeObjFile(ObjFile *obj) {
size_t num_interesting_load_segments = 0;
for (int j = 0; j < phnum; j++) {
ElfW(Phdr) phdr;
- if (!ReadFromOffsetExact(obj->fd, &phdr, sizeof(phdr), phoff)) {
+ if (!file.ReadFromOffsetExact(&phdr, sizeof(phdr), phoff)) {
ABSL_RAW_LOG(WARNING, "%s: failed to read program header %d",
obj->filename, j);
return false;
diff --git a/contrib/restricted/abseil-cpp/absl/flags/declare.h b/contrib/restricted/abseil-cpp/absl/flags/declare.h
index d1437bb9f6..8d2a856e3b 100644
--- a/contrib/restricted/abseil-cpp/absl/flags/declare.h
+++ b/contrib/restricted/abseil-cpp/absl/flags/declare.h
@@ -40,13 +40,8 @@ class Flag;
// Flag
//
// Forward declaration of the `absl::Flag` type for use in defining the macro.
-#if defined(_MSC_VER) && !defined(__clang__)
-template <typename T>
-class Flag;
-#else
template <typename T>
using Flag = flags_internal::Flag<T>;
-#endif
ABSL_NAMESPACE_END
} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/flags/flag.h b/contrib/restricted/abseil-cpp/absl/flags/flag.h
index b7f94be7c5..06ea6932f9 100644
--- a/contrib/restricted/abseil-cpp/absl/flags/flag.h
+++ b/contrib/restricted/abseil-cpp/absl/flags/flag.h
@@ -71,12 +71,9 @@ ABSL_NAMESPACE_BEGIN
// For type support of Abseil Flags, see the marshalling.h header file, which
// discusses supported standard types, optional flags, and additional Abseil
// type support.
-#if !defined(_MSC_VER) || defined(__clang__)
+
template <typename T>
using Flag = flags_internal::Flag<T>;
-#else
-#include "absl/flags/internal/flag_msvc.inc"
-#endif
// GetFlag()
//
@@ -196,18 +193,12 @@ ABSL_NAMESPACE_END
// -----------------------------------------------------------------------------
// ABSL_FLAG_IMPL macro definition conditional on ABSL_FLAGS_STRIP_NAMES
-#if !defined(_MSC_VER) || defined(__clang__)
#define ABSL_FLAG_IMPL_FLAG_PTR(flag) flag
#define ABSL_FLAG_IMPL_HELP_ARG(name) \
absl::flags_internal::HelpArg<AbslFlagHelpGenFor##name>( \
FLAGS_help_storage_##name)
#define ABSL_FLAG_IMPL_DEFAULT_ARG(Type, name) \
absl::flags_internal::DefaultArg<Type, AbslFlagDefaultGenFor##name>(0)
-#else
-#define ABSL_FLAG_IMPL_FLAG_PTR(flag) flag.GetImpl()
-#define ABSL_FLAG_IMPL_HELP_ARG(name) &AbslFlagHelpGenFor##name::NonConst
-#define ABSL_FLAG_IMPL_DEFAULT_ARG(Type, name) &AbslFlagDefaultGenFor##name::Gen
-#endif
#if ABSL_FLAGS_STRIP_NAMES
#define ABSL_FLAG_IMPL_FLAGNAME(txt) ""
diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/flag.h b/contrib/restricted/abseil-cpp/absl/flags/internal/flag.h
index b41f9a69f8..2e6e6b8742 100644
--- a/contrib/restricted/abseil-cpp/absl/flags/internal/flag.h
+++ b/contrib/restricted/abseil-cpp/absl/flags/internal/flag.h
@@ -54,13 +54,8 @@ template <typename T>
class Flag;
} // namespace flags_internal
-#if defined(_MSC_VER) && !defined(__clang__)
-template <typename T>
-class Flag;
-#else
template <typename T>
using Flag = flags_internal::Flag<T>;
-#endif
template <typename T>
ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag);
diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/flag_msvc.inc b/contrib/restricted/abseil-cpp/absl/flags/internal/flag_msvc.inc
deleted file mode 100644
index 614d09fd1a..0000000000
--- a/contrib/restricted/abseil-cpp/absl/flags/internal/flag_msvc.inc
+++ /dev/null
@@ -1,116 +0,0 @@
-//
-// Copyright 2021 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Do not include this file directly.
-// Include absl/flags/flag.h instead.
-
-// MSVC debug builds do not implement initialization with constexpr constructors
-// correctly. To work around this we add a level of indirection, so that the
-// class `absl::Flag` contains an `internal::Flag*` (instead of being an alias
-// to that class) and dynamically allocates an instance when necessary. We also
-// forward all calls to internal::Flag methods via trampoline methods. In this
-// setup the `absl::Flag` class does not have constructor and virtual methods,
-// all the data members are public and thus MSVC is able to initialize it at
-// link time. To deal with multiple threads accessing the flag for the first
-// time concurrently we use an atomic boolean indicating if flag object is
-// initialized. We also employ the double-checked locking pattern where the
-// second level of protection is a global Mutex, so if two threads attempt to
-// construct the flag concurrently only one wins.
-//
-// This solution is based on a recommendation here:
-// https://developercommunity.visualstudio.com/content/problem/336946/class-with-constexpr-constructor-not-using-static.html?childToView=648454#comment-648454
-
-namespace flags_internal {
-absl::Mutex* GetGlobalConstructionGuard();
-} // namespace flags_internal
-
-// Public methods of `absl::Flag<T>` are NOT part of the Abseil Flags API.
-// See https://abseil.io/docs/cpp/guides/flags
-template <typename T>
-class Flag {
- public:
- // No constructor and destructor to ensure this is an aggregate type.
- // Visual Studio 2015 still requires the constructor for class to be
- // constexpr initializable.
-#if _MSC_VER <= 1900
- constexpr Flag(const char* name, const char* filename,
- const flags_internal::HelpGenFunc help_gen,
- const flags_internal::FlagDfltGenFunc default_value_gen)
- : name_(name),
- filename_(filename),
- help_gen_(help_gen),
- default_value_gen_(default_value_gen),
- inited_(false),
- impl_(nullptr) {}
-#endif
-
- flags_internal::Flag<T>& GetImpl() const {
- if (!inited_.load(std::memory_order_acquire)) {
- absl::MutexLock l(flags_internal::GetGlobalConstructionGuard());
-
- if (inited_.load(std::memory_order_acquire)) {
- return *impl_;
- }
-
- impl_ = new flags_internal::Flag<T>(
- name_, filename_,
- {flags_internal::FlagHelpMsg(help_gen_),
- flags_internal::FlagHelpKind::kGenFunc},
- {flags_internal::FlagDefaultSrc(default_value_gen_),
- flags_internal::FlagDefaultKind::kGenFunc});
- inited_.store(true, std::memory_order_release);
- }
-
- return *impl_;
- }
-
- // Public methods of `absl::Flag<T>` are NOT part of the Abseil Flags API.
- // See https://abseil.io/docs/cpp/guides/flags
- bool IsRetired() const { return GetImpl().IsRetired(); }
- absl::string_view Name() const { return GetImpl().Name(); }
- std::string Help() const { return GetImpl().Help(); }
- bool IsModified() const { return GetImpl().IsModified(); }
- bool IsSpecifiedOnCommandLine() const {
- return GetImpl().IsSpecifiedOnCommandLine();
- }
- std::string Filename() const { return GetImpl().Filename(); }
- std::string DefaultValue() const { return GetImpl().DefaultValue(); }
- std::string CurrentValue() const { return GetImpl().CurrentValue(); }
- template <typename U>
- inline bool IsOfType() const {
- return GetImpl().template IsOfType<U>();
- }
- T Get() const {
- return flags_internal::FlagImplPeer::InvokeGet<T>(GetImpl());
- }
- void Set(const T& v) {
- flags_internal::FlagImplPeer::InvokeSet(GetImpl(), v);
- }
- void InvokeCallback() { GetImpl().InvokeCallback(); }
-
- const CommandLineFlag& Reflect() const {
- return flags_internal::FlagImplPeer::InvokeReflect(GetImpl());
- }
-
- // The data members are logically private, but they need to be public for
- // this to be an aggregate type.
- const char* name_;
- const char* filename_;
- const flags_internal::HelpGenFunc help_gen_;
- const flags_internal::FlagDfltGenFunc default_value_gen_;
-
- mutable std::atomic<bool> inited_;
- mutable flags_internal::Flag<T>* impl_;
-};
diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/usage.cc b/contrib/restricted/abseil-cpp/absl/flags/internal/usage.cc
index 13852e1467..8b169bcdc2 100644
--- a/contrib/restricted/abseil-cpp/absl/flags/internal/usage.cc
+++ b/contrib/restricted/abseil-cpp/absl/flags/internal/usage.cc
@@ -27,7 +27,10 @@
#include <utility>
#include <vector>
+#include "absl/base/attributes.h"
#include "absl/base/config.h"
+#include "absl/base/const_init.h"
+#include "absl/base/thread_annotations.h"
#include "absl/flags/commandlineflag.h"
#include "absl/flags/flag.h"
#include "absl/flags/internal/flag.h"
@@ -40,6 +43,8 @@
#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
+#include "absl/strings/strip.h"
+#include "absl/synchronization/mutex.h"
// Dummy global variables to prevent anyone else defining these.
bool FLAGS_help = false;
diff --git a/contrib/restricted/abseil-cpp/absl/flags/marshalling.cc b/contrib/restricted/abseil-cpp/absl/flags/marshalling.cc
index dc69754f00..ca4a130572 100644
--- a/contrib/restricted/abseil-cpp/absl/flags/marshalling.cc
+++ b/contrib/restricted/abseil-cpp/absl/flags/marshalling.cc
@@ -247,6 +247,14 @@ bool AbslParseFlag(absl::string_view text, absl::LogSeverity* dst,
*err = "no value provided";
return false;
}
+ if (absl::EqualsIgnoreCase(text, "dfatal")) {
+ *dst = absl::kLogDebugFatal;
+ return true;
+ }
+ if (absl::EqualsIgnoreCase(text, "klogdebugfatal")) {
+ *dst = absl::kLogDebugFatal;
+ return true;
+ }
if (text.front() == 'k' || text.front() == 'K') text.remove_prefix(1);
if (absl::EqualsIgnoreCase(text, "info")) {
*dst = absl::LogSeverity::kInfo;
@@ -269,7 +277,8 @@ bool AbslParseFlag(absl::string_view text, absl::LogSeverity* dst,
*dst = static_cast<absl::LogSeverity>(numeric_value);
return true;
}
- *err = "only integers and absl::LogSeverity enumerators are accepted";
+ *err =
+ "only integers, absl::LogSeverity enumerators, and DFATAL are accepted";
return false;
}
diff --git a/contrib/restricted/abseil-cpp/absl/flags/parse.cc b/contrib/restricted/abseil-cpp/absl/flags/parse.cc
index 4cdd9d0ad3..526b61d1d1 100644
--- a/contrib/restricted/abseil-cpp/absl/flags/parse.cc
+++ b/contrib/restricted/abseil-cpp/absl/flags/parse.cc
@@ -637,7 +637,7 @@ void ReportUnrecognizedFlags(
// --------------------------------------------------------------------
bool WasPresentOnCommandLine(absl::string_view flag_name) {
- absl::MutexLock l(&specified_flags_guard);
+ absl::ReaderMutexLock l(&specified_flags_guard);
ABSL_INTERNAL_CHECK(specified_flags != nullptr,
"ParseCommandLine is not invoked yet");
diff --git a/contrib/restricted/abseil-cpp/absl/flags/reflection.cc b/contrib/restricted/abseil-cpp/absl/flags/reflection.cc
index dbce4032ab..841921a926 100644
--- a/contrib/restricted/abseil-cpp/absl/flags/reflection.cc
+++ b/contrib/restricted/abseil-cpp/absl/flags/reflection.cc
@@ -21,6 +21,7 @@
#include <string>
#include "absl/base/config.h"
+#include "absl/base/no_destructor.h"
#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_map.h"
#include "absl/flags/commandlineflag.h"
@@ -169,7 +170,7 @@ void FlagRegistry::RegisterFlag(CommandLineFlag& flag, const char* filename) {
}
FlagRegistry& FlagRegistry::GlobalRegistry() {
- static FlagRegistry* global_registry = new FlagRegistry;
+ static absl::NoDestructor<FlagRegistry> global_registry;
return *global_registry;
}
diff --git a/contrib/restricted/abseil-cpp/absl/flags/ya.make b/contrib/restricted/abseil-cpp/absl/flags/ya.make
index f0006d104f..7e6fae43d6 100644
--- a/contrib/restricted/abseil-cpp/absl/flags/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/flags/ya.make
@@ -30,7 +30,6 @@ NO_UTIL()
SRCS(
commandlineflag.cc
- flag.cc
internal/commandlineflag.cc
internal/flag.cc
internal/private_handle_accessor.cc
diff --git a/contrib/restricted/abseil-cpp/absl/functional/function_ref.h b/contrib/restricted/abseil-cpp/absl/functional/function_ref.h
index 2b9139d374..96cece551b 100644
--- a/contrib/restricted/abseil-cpp/absl/functional/function_ref.h
+++ b/contrib/restricted/abseil-cpp/absl/functional/function_ref.h
@@ -137,6 +137,14 @@ class FunctionRef<R(Args...)> {
absl::functional_internal::Invoker<R, Args...> invoker_;
};
+// Allow const qualified function signatures. Since FunctionRef requires
+// constness anyway we can just make this a no-op.
+template <typename R, typename... Args>
+class FunctionRef<R(Args...) const> : public FunctionRef<R(Args...)> {
+ public:
+ using FunctionRef<R(Args...)>::FunctionRef;
+};
+
ABSL_NAMESPACE_END
} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/functional/internal/any_invocable.h b/contrib/restricted/abseil-cpp/absl/functional/internal/any_invocable.h
index f096bb02e1..b04436d1d6 100644
--- a/contrib/restricted/abseil-cpp/absl/functional/internal/any_invocable.h
+++ b/contrib/restricted/abseil-cpp/absl/functional/internal/any_invocable.h
@@ -215,8 +215,8 @@ T& ObjectInLocalStorage(TypeErasedState* const state) {
// behavior, which works as intended on Abseil's officially supported
// platforms as of Q2 2022.
#if !defined(__clang__) && defined(__GNUC__)
-#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
return *reinterpret_cast<T*>(&state->storage);
#if !defined(__clang__) && defined(__GNUC__)
@@ -526,10 +526,10 @@ class CoreImpl {
// Since this is template-heavy code, we prefer to disable these warnings
// locally instead of adding yet another overload of this function.
#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Waddress"
#pragma GCC diagnostic ignored "-Wnonnull-compare"
-#pragma GCC diagnostic push
#endif
if (static_cast<RemoveCVRef<QualDecayedTRef>>(f) == nullptr) {
#if !defined(__clang__) && defined(__GNUC__)
diff --git a/contrib/restricted/abseil-cpp/absl/functional/ya.make b/contrib/restricted/abseil-cpp/absl/functional/ya.make
index 3b66e3e400..3f9af85fe6 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(20230802.1)
+VERSION(20240116.0)
-ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20230802.1.tar.gz)
+ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20240116.0.tar.gz)
NO_RUNTIME()
diff --git a/contrib/restricted/abseil-cpp/absl/hash/internal/hash.h b/contrib/restricted/abseil-cpp/absl/hash/internal/hash.h
index ef3f366471..f4a94f9129 100644
--- a/contrib/restricted/abseil-cpp/absl/hash/internal/hash.h
+++ b/contrib/restricted/abseil-cpp/absl/hash/internal/hash.h
@@ -19,6 +19,11 @@
#ifndef ABSL_HASH_INTERNAL_HASH_H_
#define ABSL_HASH_INTERNAL_HASH_H_
+#ifdef __APPLE__
+#include <Availability.h>
+#include <TargetConditionals.h>
+#endif
+
#include <algorithm>
#include <array>
#include <bitset>
@@ -56,6 +61,11 @@
#include "absl/types/variant.h"
#include "absl/utility/utility.h"
+#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L && \
+ !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
+#include <filesystem> // NOLINT
+#endif
+
#ifdef ABSL_HAVE_STD_STRING_VIEW
#include <string_view>
#endif
@@ -409,9 +419,23 @@ AbslHashValue(H hash_state, LongDouble value) {
return H::combine(std::move(hash_state), category);
}
+// Without this overload, an array decays to a pointer and we hash that, which
+// is not likely to be what the caller intended.
+template <typename H, typename T, size_t N>
+H AbslHashValue(H hash_state, T (&)[N]) {
+ static_assert(
+ sizeof(T) == -1,
+ "Hashing C arrays is not allowed. For string literals, wrap the literal "
+ "in absl::string_view(). To hash the array contents, use "
+ "absl::MakeSpan() or make the array an std::array. To hash the array "
+ "address, use &array[0].");
+ return hash_state;
+}
+
// AbslHashValue() for hashing pointers
template <typename H, typename T>
-H AbslHashValue(H hash_state, T* ptr) {
+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.
@@ -564,6 +588,29 @@ 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)
+
+#define ABSL_INTERNAL_STD_FILESYSTEM_PATH_HASH_AVAILABLE 1
+
+// Support std::filesystem::path. The SFINAE is required because some string
+// types are implicitly convertible to std::filesystem::path.
+template <typename Path, typename H,
+ typename = absl::enable_if_t<
+ std::is_same_v<Path, std::filesystem::path>>>
+H AbslHashValue(H hash_state, const Path& path) {
+ // This is implemented by deferring to the standard library to compute the
+ // hash. The standard library requires that for two paths, `p1 == p2`, then
+ // `hash_value(p1) == hash_value(p2)`. `AbslHashValue` has the same
+ // requirement. Since `operator==` does platform specific matching, deferring
+ // to the standard library is the simplest approach.
+ return H::combine(std::move(hash_state), std::filesystem::hash_value(path));
+}
+
+#endif // ABSL_INTERNAL_STD_FILESYSTEM_PATH_HASH_AVAILABLE
+
// -----------------------------------------------------------------------------
// AbslHashValue for Sequence Containers
// -----------------------------------------------------------------------------
@@ -818,7 +865,7 @@ AbslHashValue(H hash_state, const absl::variant<T...>& v) {
template <typename H, size_t N>
H AbslHashValue(H hash_state, const std::bitset<N>& set) {
typename H::AbslInternalPiecewiseCombiner combiner;
- for (int i = 0; i < N; i++) {
+ for (size_t i = 0; i < N; i++) {
unsigned char c = static_cast<unsigned char>(set[i]);
hash_state = combiner.add_buffer(std::move(hash_state), &c, sizeof(c));
}
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
new file mode 100644
index 0000000000..29096b4857
--- /dev/null
+++ b/contrib/restricted/abseil-cpp/absl/log/absl_vlog_is_on.h
@@ -0,0 +1,93 @@
+// Copyright 2022 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/absl_vlog_is_on.h
+// -----------------------------------------------------------------------------
+//
+// This header defines the `ABSL_VLOG_IS_ON()` macro that controls the
+// variable-verbosity conditional logging.
+//
+// It's used by `VLOG` in log.h, or it can also be used directly like this:
+//
+// if (ABSL_VLOG_IS_ON(2)) {
+// foo_server.RecomputeStatisticsExpensive();
+// LOG(INFO) << foo_server.LastStatisticsAsString();
+// }
+//
+// Each source file has an effective verbosity level that's a non-negative
+// integer computed from the `--vmodule` and `--v` flags.
+// `ABSL_VLOG_IS_ON(n)` is true, and `VLOG(n)` logs, if that effective verbosity
+// level is greater than or equal to `n`.
+//
+// `--vmodule` takes a comma-delimited list of key=value pairs. Each key is a
+// pattern matched against filenames, and the values give the effective severity
+// level applied to matching files. '?' and '*' characters in patterns are
+// interpreted as single-character and zero-or-more-character wildcards.
+// Patterns including a slash character are matched against full pathnames,
+// while those without are matched against basenames only. One suffix (i.e. the
+// last . and everything after it) is stripped from each filename prior to
+// matching, as is the special suffix "-inl".
+//
+// Files are matched against globs in `--vmodule` in order, and the first match
+// determines the verbosity level.
+//
+// Files which do not match any pattern in `--vmodule` use the value of `--v` as
+// their effective verbosity level. The default is 0.
+//
+// SetVLOGLevel helper function is provided to do limited dynamic control over
+// V-logging by appending to `--vmodule`. Because these go at the beginning of
+// the list, they take priority over any globs previously added.
+//
+// Resetting --vmodule will override all previous modifications to `--vmodule`,
+// including via SetVLOGLevel.
+
+#ifndef ABSL_LOG_ABSL_VLOG_IS_ON_H_
+#define ABSL_LOG_ABSL_VLOG_IS_ON_H_
+
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/log/internal/vlog_config.h" // IWYU pragma: export
+#include "absl/strings/string_view.h"
+
+// IWYU pragma: private, include "absl/log/log.h"
+
+// This is expanded at the callsite to allow the compiler to optimize
+// always-false cases out of the build.
+// An ABSL_MAX_VLOG_VERBOSITY of 2 means that VLOG(3) and above should never
+// log.
+#ifdef ABSL_MAX_VLOG_VERBOSITY
+#define ABSL_LOG_INTERNAL_MAX_LOG_VERBOSITY_CHECK(x) \
+ ((x) <= ABSL_MAX_VLOG_VERBOSITY)&&
+#else
+#define ABSL_LOG_INTERNAL_MAX_LOG_VERBOSITY_CHECK(x)
+#endif
+
+// Each ABSL_VLOG_IS_ON call site gets its own VLogSite that registers with the
+// global linked list of sites to asynchronously update its verbosity level on
+// changes to --v or --vmodule. The verbosity can also be set by manually
+// calling SetVLOGLevel.
+//
+// ABSL_VLOG_IS_ON is not async signal safe, but it is guaranteed not to
+// allocate new memory.
+#define ABSL_VLOG_IS_ON(verbose_level) \
+ (ABSL_LOG_INTERNAL_MAX_LOG_VERBOSITY_CHECK(verbose_level)[]() \
+ ->::absl::log_internal::VLogSite * \
+ { \
+ ABSL_CONST_INIT static ::absl::log_internal::VLogSite site(__FILE__); \
+ return &site; \
+ }() \
+ ->IsEnabled(verbose_level))
+
+#endif // ABSL_LOG_ABSL_VLOG_IS_ON_H_
diff --git a/contrib/restricted/abseil-cpp/absl/log/flags.cc b/contrib/restricted/abseil-cpp/absl/log/flags.cc
index 215b7bd580..287b3e96c7 100644
--- a/contrib/restricted/abseil-cpp/absl/log/flags.cc
+++ b/contrib/restricted/abseil-cpp/absl/log/flags.cc
@@ -28,6 +28,7 @@
#include "absl/flags/marshalling.h"
#include "absl/log/globals.h"
#include "absl/log/internal/config.h"
+#include "absl/log/internal/vlog_config.h"
#include "absl/strings/numbers.h"
#include "absl/strings/string_view.h"
@@ -118,3 +119,25 @@ ABSL_FLAG(bool, log_prefix, true,
.OnUpdate([] {
absl::log_internal::RawEnableLogPrefix(absl::GetFlag(FLAGS_log_prefix));
});
+
+ABSL_FLAG(int, v, 0,
+ "Show all VLOG(m) messages for m <= this. Overridable by --vmodule.")
+ .OnUpdate([] {
+ absl::log_internal::UpdateGlobalVLogLevel(absl::GetFlag(FLAGS_v));
+ });
+
+ABSL_FLAG(
+ std::string, vmodule, "",
+ "per-module log verbosity level."
+ " Argument is a comma-separated list of <module name>=<log level>."
+ " <module name> is a glob pattern, matched against the filename base"
+ " (that is, name ignoring .cc/.h./-inl.h)."
+ " A pattern without slashes matches just the file name portion, otherwise"
+ " the whole file path below the workspace root"
+ " (still without .cc/.h./-inl.h) is matched."
+ " ? and * in the glob pattern match any single or sequence of characters"
+ " respectively including slashes."
+ " <log level> overrides any value given by --v.")
+ .OnUpdate([] {
+ absl::log_internal::UpdateVModule(absl::GetFlag(FLAGS_vmodule));
+ });
diff --git a/contrib/restricted/abseil-cpp/absl/log/globals.h b/contrib/restricted/abseil-cpp/absl/log/globals.h
index bc3864c110..b36e47e6d1 100644
--- a/contrib/restricted/abseil-cpp/absl/log/globals.h
+++ b/contrib/restricted/abseil-cpp/absl/log/globals.h
@@ -24,6 +24,7 @@
#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/log_severity.h"
+#include "absl/log/internal/vlog_config.h"
#include "absl/strings/string_view.h"
namespace absl {
@@ -153,6 +154,28 @@ ABSL_MUST_USE_RESULT bool ShouldPrependLogPrefix();
void EnableLogPrefix(bool on_off);
//------------------------------------------------------------------------------
+// Set Global VLOG Level
+//------------------------------------------------------------------------------
+//
+// Sets the global `(ABSL_)VLOG(_IS_ON)` level to `log_level`. This level is
+// applied to any sites whose filename doesn't match any `module_pattern`.
+// Returns the prior value.
+inline int SetGlobalVLogLevel(int log_level) {
+ return absl::log_internal::UpdateGlobalVLogLevel(log_level);
+}
+
+//------------------------------------------------------------------------------
+// Set VLOG Level
+//------------------------------------------------------------------------------
+//
+// Sets `(ABSL_)VLOG(_IS_ON)` level for `module_pattern` to `log_level`. This
+// allows programmatic control of what is normally set by the --vmodule flag.
+// Returns the level that previously applied to `module_pattern`.
+inline int SetVLogLevel(absl::string_view module_pattern, int log_level) {
+ return absl::log_internal::PrependVModule(module_pattern, log_level);
+}
+
+//------------------------------------------------------------------------------
// Configure Android Native Log Tag
//------------------------------------------------------------------------------
//
diff --git a/contrib/restricted/abseil-cpp/absl/log/initialize.cc b/contrib/restricted/abseil-cpp/absl/log/initialize.cc
index a3f6d6c142..ef5d31469a 100644
--- a/contrib/restricted/abseil-cpp/absl/log/initialize.cc
+++ b/contrib/restricted/abseil-cpp/absl/log/initialize.cc
@@ -21,14 +21,18 @@
namespace absl {
ABSL_NAMESPACE_BEGIN
-void InitializeLog() {
+namespace {
+void InitializeLogImpl(absl::TimeZone time_zone) {
// This comes first since it is used by RAW_LOG.
- absl::log_internal::SetTimeZone(absl::LocalTimeZone());
+ absl::log_internal::SetTimeZone(time_zone);
// Note that initialization is complete, so logs can now be sent to their
// proper destinations rather than stderr.
log_internal::SetInitialized();
}
+} // namespace
+
+void InitializeLog() { InitializeLogImpl(absl::LocalTimeZone()); }
ABSL_NAMESPACE_END
} // namespace absl
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 20b01b5e84..11f0f4078b 100644
--- a/contrib/restricted/abseil-cpp/absl/log/internal/check_op.h
+++ b/contrib/restricted/abseil-cpp/absl/log/internal/check_op.h
@@ -65,6 +65,7 @@
::absl::log_internal::GetReferenceableValue(val2), \
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) \
@@ -74,6 +75,7 @@
::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()
#define ABSL_LOG_INTERNAL_CHECK_STROP(func, op, expected, s1, s1_text, s2, \
s2_text) \
@@ -82,6 +84,7 @@
(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) \
.InternalStream()
#define ABSL_LOG_INTERNAL_QCHECK_STROP(func, op, expected, s1, s1_text, s2, \
@@ -91,6 +94,7 @@
(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) \
.InternalStream()
// This one is tricky:
@@ -113,6 +117,10 @@
// * As usual, no braces so we can stream into the expansion with `operator<<`.
// * Also as usual, it must expand to a single (partial) statement with no
// ambiguous-else problems.
+// * When stripped by `ABSL_MIN_LOG_LEVEL`, we must discard the `<expr> is OK`
+// 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; \
@@ -126,22 +134,24 @@
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) \
.InternalStream()
-#define ABSL_LOG_INTERNAL_QCHECK_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_QCHECK(*absl_log_internal_check_ok_goo.second) \
+#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) \
.InternalStream()
namespace absl {
@@ -152,8 +162,8 @@ template <typename T>
class StatusOr;
namespace status_internal {
-std::string* MakeCheckFailString(const absl::Status* status,
- const char* prefix);
+ABSL_ATTRIBUTE_PURE_FUNCTION std::string* MakeCheckFailString(
+ const absl::Status* status, const char* prefix);
} // namespace status_internal
namespace log_internal {
@@ -314,6 +324,20 @@ ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const unsigned char*);
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const void*);
#undef ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN
+// `ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT` skips formatting the Check_OP result
+// string iff `ABSL_MIN_LOG_LEVEL` exceeds `kFatal`, instead returning an empty
+// string.
+#ifdef ABSL_MIN_LOG_LEVEL
+#define ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT(U1, U2, v1, v2, exprtext) \
+ ((::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)
+#endif
+
// Helper functions for `ABSL_LOG_INTERNAL_CHECK_OP` macro family. The
// `(int, int)` override works around the issue that the compiler will not
// instantiate the template version of the function on values of unnamed enum
@@ -326,7 +350,8 @@ ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const void*);
using U2 = CheckOpStreamType<T2>; \
return ABSL_PREDICT_TRUE(v1 op v2) \
? nullptr \
- : MakeCheckOpString<U1, U2>(v1, v2, exprtext); \
+ : ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT(U1, U2, v1, v2, \
+ exprtext); \
} \
inline constexpr ::std::string* name##Impl(int v1, int v2, \
const char* exprtext) { \
@@ -339,6 +364,7 @@ ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_LE, <=)
ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_LT, <)
ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_GE, >=)
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,
diff --git a/contrib/restricted/abseil-cpp/absl/log/internal/conditions.h b/contrib/restricted/abseil-cpp/absl/log/internal/conditions.h
index f576d6500b..645f3c23ea 100644
--- a/contrib/restricted/abseil-cpp/absl/log/internal/conditions.h
+++ b/contrib/restricted/abseil-cpp/absl/log/internal/conditions.h
@@ -57,7 +57,7 @@
// (dangling else, missing switch case) and preserving noreturn semantics (e.g.
// on `LOG(FATAL)`) without requiring braces.
//
-// The `switch` ensures that this expansion is the begnning of a statement (as
+// The `switch` ensures that this expansion is the beginning of a statement (as
// opposed to an expression) and prevents shenanigans like
// `AFunction(LOG(INFO))` and `decltype(LOG(INFO))`. The apparently-redundant
// `default` case makes the condition more amenable to Clang dataflow analysis.
@@ -68,7 +68,7 @@
!(condition) ? (void)0 : ::absl::log_internal::Voidify()&&
// `ABSL_LOG_INTERNAL_STATEFUL_CONDITION` applies a condition like
-// `ABSL_LOG_INTERNAL_CONDITION` but adds to that a series of variable
+// `ABSL_LOG_INTERNAL_STATELESS_CONDITION` but adds to that a series of variable
// declarations, including a local static object which stores the state needed
// to implement the stateful macros like `LOG_EVERY_N`.
//
@@ -137,21 +137,30 @@
? true \
: (::absl::log_internal::ExitQuietly(), false)) \
: false))
-
-#define ABSL_LOG_INTERNAL_CONDITION_LEVEL(severity) \
- for (int log_internal_severity_loop = 1; log_internal_severity_loop; \
- log_internal_severity_loop = 0) \
- for (const absl::LogSeverity log_internal_severity = \
- ::absl::NormalizeLogSeverity(severity); \
- log_internal_severity_loop; log_internal_severity_loop = 0) \
+#define ABSL_LOG_INTERNAL_CONDITION_DFATAL(type, condition) \
+ ABSL_LOG_INTERNAL_##type##_CONDITION( \
+ (ABSL_ASSUME(absl::kLogDebugFatal == absl::LogSeverity::kError || \
+ absl::kLogDebugFatal == absl::LogSeverity::kFatal), \
+ (condition) && \
+ (::absl::kLogDebugFatal >= \
+ static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) || \
+ (::absl::kLogDebugFatal == ::absl::LogSeverity::kFatal && \
+ (::absl::log_internal::AbortQuietly(), false)))))
+
+#define ABSL_LOG_INTERNAL_CONDITION_LEVEL(severity) \
+ for (int absl_log_internal_severity_loop = 1; \
+ absl_log_internal_severity_loop; absl_log_internal_severity_loop = 0) \
+ for (const absl::LogSeverity absl_log_internal_severity = \
+ ::absl::NormalizeLogSeverity(severity); \
+ absl_log_internal_severity_loop; absl_log_internal_severity_loop = 0) \
ABSL_LOG_INTERNAL_CONDITION_LEVEL_IMPL
-#define ABSL_LOG_INTERNAL_CONDITION_LEVEL_IMPL(type, condition) \
- ABSL_LOG_INTERNAL_##type##_CONDITION( \
- (condition) && \
- (log_internal_severity >= \
- static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) || \
- (log_internal_severity == ::absl::LogSeverity::kFatal && \
- (::absl::log_internal::AbortQuietly(), false))))
+#define ABSL_LOG_INTERNAL_CONDITION_LEVEL_IMPL(type, condition) \
+ ABSL_LOG_INTERNAL_##type##_CONDITION(( \
+ (condition) && \
+ (absl_log_internal_severity >= \
+ static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) || \
+ (absl_log_internal_severity == ::absl::LogSeverity::kFatal && \
+ (::absl::log_internal::AbortQuietly(), false)))))
#else // ndef ABSL_MIN_LOG_LEVEL
#define ABSL_LOG_INTERNAL_CONDITION_INFO(type, condition) \
ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
@@ -163,12 +172,14 @@
ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
#define ABSL_LOG_INTERNAL_CONDITION_QFATAL(type, condition) \
ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
-#define ABSL_LOG_INTERNAL_CONDITION_LEVEL(severity) \
- for (int log_internal_severity_loop = 1; log_internal_severity_loop; \
- log_internal_severity_loop = 0) \
- for (const absl::LogSeverity log_internal_severity = \
- ::absl::NormalizeLogSeverity(severity); \
- log_internal_severity_loop; log_internal_severity_loop = 0) \
+#define ABSL_LOG_INTERNAL_CONDITION_DFATAL(type, condition) \
+ ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
+#define ABSL_LOG_INTERNAL_CONDITION_LEVEL(severity) \
+ for (int absl_log_internal_severity_loop = 1; \
+ absl_log_internal_severity_loop; absl_log_internal_severity_loop = 0) \
+ for (const absl::LogSeverity absl_log_internal_severity = \
+ ::absl::NormalizeLogSeverity(severity); \
+ absl_log_internal_severity_loop; absl_log_internal_severity_loop = 0) \
ABSL_LOG_INTERNAL_CONDITION_LEVEL_IMPL
#define ABSL_LOG_INTERNAL_CONDITION_LEVEL_IMPL(type, condition) \
ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
diff --git a/contrib/restricted/abseil-cpp/absl/log/internal/flags.h b/contrib/restricted/abseil-cpp/absl/log/internal/flags.h
index 0c5e81edee..c4539785ad 100644
--- a/contrib/restricted/abseil-cpp/absl/log/internal/flags.h
+++ b/contrib/restricted/abseil-cpp/absl/log/internal/flags.h
@@ -33,7 +33,7 @@
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Log messages at this severity or above are sent to stderr in *addition* to
-// logfiles. Defaults to `ERROR`. See log_severity.h for numeric values of
+// `LogSink`s. Defaults to `ERROR`. See log_severity.h for numeric values of
// severity levels.
ABSL_DECLARE_FLAG(int, stderrthreshold);
@@ -50,4 +50,10 @@ ABSL_DECLARE_FLAG(std::string, log_backtrace_at);
// each message logged. Defaults to true.
ABSL_DECLARE_FLAG(bool, log_prefix);
+// Global log verbosity level. Default is 0.
+ABSL_DECLARE_FLAG(int, v);
+
+// Per-module log verbosity level. By default is empty and is unused.
+ABSL_DECLARE_FLAG(std::string, vmodule);
+
#endif // ABSL_LOG_INTERNAL_FLAGS_H_
diff --git a/contrib/restricted/abseil-cpp/absl/log/internal/fnmatch.cc b/contrib/restricted/abseil-cpp/absl/log/internal/fnmatch.cc
new file mode 100644
index 0000000000..26e1e57fe4
--- /dev/null
+++ b/contrib/restricted/abseil-cpp/absl/log/internal/fnmatch.cc
@@ -0,0 +1,73 @@
+// Copyright 2023 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/fnmatch.h"
+
+#include <cstddef>
+
+#include "absl/base/config.h"
+#include "absl/strings/string_view.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace log_internal {
+bool FNMatch(absl::string_view pattern, absl::string_view str) {
+ bool in_wildcard_match = false;
+ while (true) {
+ if (pattern.empty()) {
+ // `pattern` is exhausted; succeed if all of `str` was consumed matching
+ // it.
+ return in_wildcard_match || str.empty();
+ }
+ if (str.empty()) {
+ // `str` is exhausted; succeed if `pattern` is empty or all '*'s.
+ return pattern.find_first_not_of('*') == pattern.npos;
+ }
+ switch (pattern.front()) {
+ case '*':
+ pattern.remove_prefix(1);
+ in_wildcard_match = true;
+ break;
+ case '?':
+ pattern.remove_prefix(1);
+ str.remove_prefix(1);
+ break;
+ default:
+ if (in_wildcard_match) {
+ absl::string_view fixed_portion = pattern;
+ const size_t end = fixed_portion.find_first_of("*?");
+ if (end != fixed_portion.npos) {
+ fixed_portion = fixed_portion.substr(0, end);
+ }
+ const size_t match = str.find(fixed_portion);
+ if (match == str.npos) {
+ return false;
+ }
+ pattern.remove_prefix(fixed_portion.size());
+ str.remove_prefix(match + fixed_portion.size());
+ in_wildcard_match = false;
+ } else {
+ if (pattern.front() != str.front()) {
+ return false;
+ }
+ pattern.remove_prefix(1);
+ str.remove_prefix(1);
+ }
+ break;
+ }
+ }
+}
+} // namespace log_internal
+ABSL_NAMESPACE_END
+} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/flags/flag.cc b/contrib/restricted/abseil-cpp/absl/log/internal/fnmatch.h
index 531df1287a..4ea147cc6f 100644
--- a/contrib/restricted/abseil-cpp/absl/flags/flag.cc
+++ b/contrib/restricted/abseil-cpp/absl/log/internal/fnmatch.h
@@ -1,11 +1,10 @@
-//
-// Copyright 2019 The Abseil Authors.
+// Copyright 2023 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
+// 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,
@@ -13,26 +12,24 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "absl/flags/flag.h"
+#ifndef ABSL_LOG_INTERNAL_FNMATCH_H_
+#define ABSL_LOG_INTERNAL_FNMATCH_H_
#include "absl/base/config.h"
+#include "absl/strings/string_view.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
-
-// This global mutex protects on-demand construction of flag objects in MSVC
-// builds.
-#if defined(_MSC_VER) && !defined(__clang__)
-
-namespace flags_internal {
-
-ABSL_CONST_INIT static absl::Mutex construction_guard(absl::kConstInit);
-
-absl::Mutex* GetGlobalConstructionGuard() { return &construction_guard; }
-
-} // namespace flags_internal
-
-#endif
-
+namespace log_internal {
+// Like POSIX `fnmatch`, but:
+// * accepts `string_view`
+// * does not allocate any dynamic memory
+// * only supports * and ? wildcards and not bracket expressions [...]
+// * wildcards may match /
+// * no backslash-escaping
+bool FNMatch(absl::string_view pattern, absl::string_view str);
+} // namespace log_internal
ABSL_NAMESPACE_END
} // namespace absl
+
+#endif // ABSL_LOG_INTERNAL_FNMATCH_H_
diff --git a/contrib/restricted/abseil-cpp/absl/log/internal/log_impl.h b/contrib/restricted/abseil-cpp/absl/log/internal/log_impl.h
index 9326780dc6..99de6dbb24 100644
--- a/contrib/restricted/abseil-cpp/absl/log/internal/log_impl.h
+++ b/contrib/restricted/abseil-cpp/absl/log/internal/log_impl.h
@@ -15,6 +15,7 @@
#ifndef ABSL_LOG_INTERNAL_LOG_IMPL_H_
#define ABSL_LOG_INTERNAL_LOG_IMPL_H_
+#include "absl/log/absl_vlog_is_on.h"
#include "absl/log/internal/conditions.h"
#include "absl/log/internal/log_message.h"
#include "absl/log/internal/strip.h"
@@ -41,6 +42,35 @@
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
#endif
+// The `switch` ensures that this expansion is the begnning of a statement (as
+// opposed to an expression). The use of both `case 0` and `default` is to
+// suppress a compiler warning.
+#define ABSL_LOG_INTERNAL_VLOG_IMPL(verbose_level) \
+ switch (const int absl_logging_internal_verbose_level = (verbose_level)) \
+ case 0: \
+ default: \
+ ABSL_LOG_INTERNAL_LOG_IF_IMPL( \
+ _INFO, ABSL_VLOG_IS_ON(absl_logging_internal_verbose_level)) \
+ .WithVerbosity(absl_logging_internal_verbose_level)
+
+#ifndef NDEBUG
+#define ABSL_LOG_INTERNAL_DVLOG_IMPL(verbose_level) \
+ switch (const int absl_logging_internal_verbose_level = (verbose_level)) \
+ case 0: \
+ default: \
+ ABSL_LOG_INTERNAL_LOG_IF_IMPL( \
+ _INFO, ABSL_VLOG_IS_ON(absl_logging_internal_verbose_level)) \
+ .WithVerbosity(absl_logging_internal_verbose_level)
+#else
+#define ABSL_LOG_INTERNAL_DVLOG_IMPL(verbose_level) \
+ switch (const int absl_logging_internal_verbose_level = (verbose_level)) \
+ case 0: \
+ default: \
+ ABSL_LOG_INTERNAL_LOG_IF_IMPL( \
+ _INFO, false && ABSL_VLOG_IS_ON(absl_logging_internal_verbose_level)) \
+ .WithVerbosity(absl_logging_internal_verbose_level)
+#endif
+
#define ABSL_LOG_INTERNAL_LOG_IF_IMPL(severity, condition) \
ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, condition) \
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
@@ -134,6 +164,42 @@
(EveryNSec, n_seconds) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
#endif // def NDEBUG
+#define ABSL_LOG_INTERNAL_VLOG_EVERY_N_IMPL(verbose_level, n) \
+ switch (const int absl_logging_internal_verbose_level = (verbose_level)) \
+ case 0: \
+ default: \
+ ABSL_LOG_INTERNAL_CONDITION_INFO( \
+ STATEFUL, ABSL_VLOG_IS_ON(absl_logging_internal_verbose_level)) \
+ (EveryN, n) ABSL_LOGGING_INTERNAL_LOG_INFO.InternalStream().WithVerbosity( \
+ absl_logging_internal_verbose_level)
+
+#define ABSL_LOG_INTERNAL_VLOG_FIRST_N_IMPL(verbose_level, n) \
+ switch (const int absl_logging_internal_verbose_level = (verbose_level)) \
+ case 0: \
+ default: \
+ ABSL_LOG_INTERNAL_CONDITION_INFO( \
+ STATEFUL, ABSL_VLOG_IS_ON(absl_logging_internal_verbose_level)) \
+ (FirstN, n) ABSL_LOGGING_INTERNAL_LOG_INFO.InternalStream().WithVerbosity( \
+ absl_logging_internal_verbose_level)
+
+#define ABSL_LOG_INTERNAL_VLOG_EVERY_POW_2_IMPL(verbose_level) \
+ switch (const int absl_logging_internal_verbose_level = (verbose_level)) \
+ case 0: \
+ default: \
+ ABSL_LOG_INTERNAL_CONDITION_INFO( \
+ STATEFUL, ABSL_VLOG_IS_ON(absl_logging_internal_verbose_level)) \
+ (EveryPow2) ABSL_LOGGING_INTERNAL_LOG_INFO.InternalStream().WithVerbosity( \
+ absl_logging_internal_verbose_level)
+
+#define ABSL_LOG_INTERNAL_VLOG_EVERY_N_SEC_IMPL(verbose_level, n_seconds) \
+ switch (const int absl_logging_internal_verbose_level = (verbose_level)) \
+ case 0: \
+ default: \
+ ABSL_LOG_INTERNAL_CONDITION_INFO( \
+ STATEFUL, ABSL_VLOG_IS_ON(absl_logging_internal_verbose_level)) \
+ (EveryNSec, n_seconds) ABSL_LOGGING_INTERNAL_LOG_INFO.InternalStream() \
+ .WithVerbosity(absl_logging_internal_verbose_level)
+
#define ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_IMPL(severity, condition, n) \
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryN, n) \
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
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 46937728cb..4ecb8a1498 100644
--- a/contrib/restricted/abseil-cpp/absl/log/internal/log_message.h
+++ b/contrib/restricted/abseil-cpp/absl/log/internal/log_message.h
@@ -40,7 +40,7 @@
#include "absl/log/internal/nullguard.h"
#include "absl/log/log_entry.h"
#include "absl/log/log_sink.h"
-#include "absl/strings/internal/has_absl_stringify.h"
+#include "absl/strings/has_absl_stringify.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
@@ -170,15 +170,15 @@ class LogMessage {
// Types that support `AbslStringify()` are serialized that way.
template <typename T,
- typename std::enable_if<
- strings_internal::HasAbslStringify<T>::value, int>::type = 0>
+ typename std::enable_if<absl::HasAbslStringify<T>::value,
+ int>::type = 0>
LogMessage& operator<<(const T& v) ABSL_ATTRIBUTE_NOINLINE;
// Types that don't support `AbslStringify()` but do support streaming into a
// `std::ostream&` are serialized that way.
template <typename T,
- typename std::enable_if<
- !strings_internal::HasAbslStringify<T>::value, int>::type = 0>
+ typename std::enable_if<!absl::HasAbslStringify<T>::value,
+ int>::type = 0>
LogMessage& operator<<(const T& v) ABSL_ATTRIBUTE_NOINLINE;
// Note: We explicitly do not support `operator<<` for non-const references
@@ -283,8 +283,7 @@ class StringifySink final {
// Note: the following is declared `ABSL_ATTRIBUTE_NOINLINE`
template <typename T,
- typename std::enable_if<strings_internal::HasAbslStringify<T>::value,
- int>::type>
+ typename std::enable_if<absl::HasAbslStringify<T>::value, int>::type>
LogMessage& LogMessage::operator<<(const T& v) {
StringifySink sink(*this);
// Replace with public API.
@@ -294,8 +293,7 @@ LogMessage& LogMessage::operator<<(const T& v) {
// Note: the following is declared `ABSL_ATTRIBUTE_NOINLINE`
template <typename T,
- typename std::enable_if<!strings_internal::HasAbslStringify<T>::value,
- int>::type>
+ typename std::enable_if<!absl::HasAbslStringify<T>::value, int>::type>
LogMessage& LogMessage::operator<<(const T& v) {
OstreamView view(*data_);
view.stream() << log_internal::NullGuard<T>().Guard(v);
diff --git a/contrib/restricted/abseil-cpp/absl/log/internal/log_sink_set.cc b/contrib/restricted/abseil-cpp/absl/log/internal/log_sink_set.cc
index b7cbe36455..3d5c69952c 100644
--- a/contrib/restricted/abseil-cpp/absl/log/internal/log_sink_set.cc
+++ b/contrib/restricted/abseil-cpp/absl/log/internal/log_sink_set.cc
@@ -35,6 +35,7 @@
#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/log_severity.h"
+#include "absl/base/no_destructor.h"
#include "absl/base/thread_annotations.h"
#include "absl/cleanup/cleanup.h"
#include "absl/log/globals.h"
@@ -168,17 +169,16 @@ class GlobalLogSinkSet final {
#if defined(__myriad2__) || defined(__Fuchsia__)
// myriad2 and Fuchsia do not log to stderr by default.
#else
- static StderrLogSink* stderr_log_sink = new StderrLogSink;
- AddLogSink(stderr_log_sink);
+ static absl::NoDestructor<StderrLogSink> stderr_log_sink;
+ AddLogSink(stderr_log_sink.get());
#endif
#ifdef __ANDROID__
- static AndroidLogSink* android_log_sink = new AndroidLogSink;
- AddLogSink(android_log_sink);
+ static absl::NoDestructor<AndroidLogSink> android_log_sink;
+ AddLogSink(android_log_sink.get());
#endif
#if defined(_WIN32)
- static WindowsDebuggerLogSink* debugger_log_sink =
- new WindowsDebuggerLogSink;
- AddLogSink(debugger_log_sink);
+ static absl::NoDestructor<WindowsDebuggerLogSink> debugger_log_sink;
+ AddLogSink(debugger_log_sink.get());
#endif // !defined(_WIN32)
}
@@ -268,7 +268,7 @@ class GlobalLogSinkSet final {
// Returns reference to the global LogSinks set.
GlobalLogSinkSet& GlobalSinks() {
- static GlobalLogSinkSet* global_sinks = new GlobalLogSinkSet;
+ static absl::NoDestructor<GlobalLogSinkSet> global_sinks;
return *global_sinks;
}
diff --git a/contrib/restricted/abseil-cpp/absl/log/internal/strip.h b/contrib/restricted/abseil-cpp/absl/log/internal/strip.h
index adc86ffdfa..f8d2786939 100644
--- a/contrib/restricted/abseil-cpp/absl/log/internal/strip.h
+++ b/contrib/restricted/abseil-cpp/absl/log/internal/strip.h
@@ -37,7 +37,7 @@
#define ABSL_LOGGING_INTERNAL_LOG_DFATAL \
::absl::log_internal::NullStreamMaybeFatal(::absl::kLogDebugFatal)
#define ABSL_LOGGING_INTERNAL_LOG_LEVEL(severity) \
- ::absl::log_internal::NullStreamMaybeFatal(log_internal_severity)
+ ::absl::log_internal::NullStreamMaybeFatal(absl_log_internal_severity)
#define ABSL_LOG_INTERNAL_CHECK(failure_message) ABSL_LOGGING_INTERNAL_LOG_FATAL
#define ABSL_LOG_INTERNAL_QCHECK(failure_message) \
ABSL_LOGGING_INTERNAL_LOG_QFATAL
@@ -57,8 +57,9 @@
::absl::log_internal::LogMessageQuietlyFatal(__FILE__, __LINE__)
#define ABSL_LOGGING_INTERNAL_LOG_DFATAL \
::absl::log_internal::LogMessage(__FILE__, __LINE__, ::absl::kLogDebugFatal)
-#define ABSL_LOGGING_INTERNAL_LOG_LEVEL(severity) \
- ::absl::log_internal::LogMessage(__FILE__, __LINE__, log_internal_severity)
+#define ABSL_LOGGING_INTERNAL_LOG_LEVEL(severity) \
+ ::absl::log_internal::LogMessage(__FILE__, __LINE__, \
+ absl_log_internal_severity)
// These special cases dispatch to special-case constructors that allow us to
// avoid an extra function call and shrink non-LTO binaries by a percent or so.
#define ABSL_LOG_INTERNAL_CHECK(failure_message) \
diff --git a/contrib/restricted/abseil-cpp/absl/log/internal/vlog_config.cc b/contrib/restricted/abseil-cpp/absl/log/internal/vlog_config.cc
new file mode 100644
index 0000000000..b578850041
--- /dev/null
+++ b/contrib/restricted/abseil-cpp/absl/log/internal/vlog_config.cc
@@ -0,0 +1,340 @@
+// Copyright 2022 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/vlog_config.h"
+
+#include <stddef.h>
+
+#include <algorithm>
+#include <atomic>
+#include <functional>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/base/const_init.h"
+#include "absl/base/internal/spinlock.h"
+#include "absl/base/no_destructor.h"
+#include "absl/base/optimization.h"
+#include "absl/base/thread_annotations.h"
+#include "absl/log/internal/fnmatch.h"
+#include "absl/memory/memory.h"
+#include "absl/strings/numbers.h"
+#include "absl/strings/str_split.h"
+#include "absl/strings/string_view.h"
+#include "absl/strings/strip.h"
+#include "absl/synchronization/mutex.h"
+#include "absl/types/optional.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace log_internal {
+
+namespace {
+bool ModuleIsPath(absl::string_view module_pattern) {
+#ifdef _WIN32
+ return module_pattern.find_first_of("/\\") != module_pattern.npos;
+#else
+ return module_pattern.find('/') != module_pattern.npos;
+#endif
+}
+} // namespace
+
+bool VLogSite::SlowIsEnabled(int stale_v, int level) {
+ if (ABSL_PREDICT_TRUE(stale_v != kUninitialized)) {
+ // Because of the prerequisites to this function, we know that stale_v is
+ // either uninitialized or >= level. If it's not uninitialized, that means
+ // it must be >= level, thus we should log.
+ return true;
+ }
+ stale_v = log_internal::RegisterAndInitialize(this);
+ return ABSL_PREDICT_FALSE(stale_v >= level);
+}
+
+bool VLogSite::SlowIsEnabled0(int stale_v) { return SlowIsEnabled(stale_v, 0); }
+bool VLogSite::SlowIsEnabled1(int stale_v) { return SlowIsEnabled(stale_v, 1); }
+bool VLogSite::SlowIsEnabled2(int stale_v) { return SlowIsEnabled(stale_v, 2); }
+bool VLogSite::SlowIsEnabled3(int stale_v) { return SlowIsEnabled(stale_v, 3); }
+bool VLogSite::SlowIsEnabled4(int stale_v) { return SlowIsEnabled(stale_v, 4); }
+bool VLogSite::SlowIsEnabled5(int stale_v) { return SlowIsEnabled(stale_v, 5); }
+
+namespace {
+struct VModuleInfo final {
+ std::string module_pattern;
+ bool module_is_path; // i.e. it contains a path separator.
+ int vlog_level;
+
+ // Allocates memory.
+ VModuleInfo(absl::string_view module_pattern_arg, bool module_is_path_arg,
+ int vlog_level_arg)
+ : module_pattern(std::string(module_pattern_arg)),
+ module_is_path(module_is_path_arg),
+ vlog_level(vlog_level_arg) {}
+};
+
+// `mutex` guards all of the data structures that aren't lock-free.
+// To avoid problems with the heap checker which calls into `VLOG`, `mutex` must
+// be a `SpinLock` that prevents fiber scheduling instead of a `Mutex`.
+ABSL_CONST_INIT absl::base_internal::SpinLock mutex(
+ absl::kConstInit, absl::base_internal::SCHEDULE_KERNEL_ONLY);
+
+// `GetUpdateSitesMutex()` serializes updates to all of the sites (i.e. those in
+// `site_list_head`) themselves.
+absl::Mutex* GetUpdateSitesMutex() {
+ // Chromium requires no global destructors, so we can't use the
+ // absl::kConstInit idiom since absl::Mutex as a non-trivial destructor.
+ static absl::NoDestructor<absl::Mutex> update_sites_mutex ABSL_ACQUIRED_AFTER(
+ mutex);
+ return update_sites_mutex.get();
+}
+
+ABSL_CONST_INIT int global_v ABSL_GUARDED_BY(mutex) = 0;
+// `site_list_head` is the head of a singly-linked list. Traversal, insertion,
+// and reads are atomic, so no locks are required, but updates to existing
+// elements are guarded by `GetUpdateSitesMutex()`.
+ABSL_CONST_INIT std::atomic<VLogSite*> site_list_head{nullptr};
+ABSL_CONST_INIT std::vector<VModuleInfo>* vmodule_info ABSL_GUARDED_BY(mutex)
+ ABSL_PT_GUARDED_BY(mutex){nullptr};
+
+// Only used for lisp.
+ABSL_CONST_INIT std::vector<std::function<void()>>* update_callbacks
+ ABSL_GUARDED_BY(GetUpdateSitesMutex())
+ ABSL_PT_GUARDED_BY(GetUpdateSitesMutex()){nullptr};
+
+// Allocates memory.
+std::vector<VModuleInfo>& get_vmodule_info()
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex) {
+ if (!vmodule_info) vmodule_info = new std::vector<VModuleInfo>;
+ return *vmodule_info;
+}
+
+// Does not allocate or take locks.
+int VLogLevel(absl::string_view file, const std::vector<VModuleInfo>* infos,
+ int current_global_v) {
+ // `infos` is null during a call to `VLOG` prior to setting `vmodule` (e.g. by
+ // parsing flags). We can't allocate in `VLOG`, so we treat null as empty
+ // here and press on.
+ if (!infos || infos->empty()) return current_global_v;
+ // Get basename for file
+ absl::string_view basename = file;
+ {
+ const size_t sep = basename.rfind('/');
+ if (sep != basename.npos) {
+ basename.remove_prefix(sep + 1);
+#ifdef _WIN32
+ } else {
+ const size_t sep = basename.rfind('\\');
+ if (sep != basename.npos) basename.remove_prefix(sep + 1);
+#endif
+ }
+ }
+
+ absl::string_view stem = file, stem_basename = basename;
+ {
+ const size_t sep = stem_basename.find('.');
+ if (sep != stem_basename.npos) {
+ stem.remove_suffix(stem_basename.size() - sep);
+ stem_basename.remove_suffix(stem_basename.size() - sep);
+ }
+ if (absl::ConsumeSuffix(&stem_basename, "-inl")) {
+ stem.remove_suffix(absl::string_view("-inl").size());
+ }
+ }
+ for (const auto& info : *infos) {
+ if (info.module_is_path) {
+ // If there are any slashes in the pattern, try to match the full
+ // name.
+ if (FNMatch(info.module_pattern, stem)) {
+ return info.vlog_level == kUseFlag ? current_global_v : info.vlog_level;
+ }
+ } else if (FNMatch(info.module_pattern, stem_basename)) {
+ return info.vlog_level == kUseFlag ? current_global_v : info.vlog_level;
+ }
+ }
+
+ return current_global_v;
+}
+
+// Allocates memory.
+int AppendVModuleLocked(absl::string_view module_pattern, int log_level)
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex) {
+ for (const auto& info : get_vmodule_info()) {
+ if (FNMatch(info.module_pattern, module_pattern)) {
+ // This is a memory optimization to avoid storing patterns that will never
+ // match due to exit early semantics. Primarily optimized for our own unit
+ // tests.
+ return info.vlog_level;
+ }
+ }
+ bool module_is_path = ModuleIsPath(module_pattern);
+ get_vmodule_info().emplace_back(std::string(module_pattern), module_is_path,
+ log_level);
+ return global_v;
+}
+
+// Allocates memory.
+int PrependVModuleLocked(absl::string_view module_pattern, int log_level)
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex) {
+ absl::optional<int> old_log_level;
+ for (const auto& info : get_vmodule_info()) {
+ if (FNMatch(info.module_pattern, module_pattern)) {
+ old_log_level = info.vlog_level;
+ break;
+ }
+ }
+ bool module_is_path = ModuleIsPath(module_pattern);
+ auto iter = get_vmodule_info().emplace(get_vmodule_info().cbegin(),
+ std::string(module_pattern),
+ module_is_path, log_level);
+
+ // This is a memory optimization to avoid storing patterns that will never
+ // match due to exit early semantics. Primarily optimized for our own unit
+ // tests.
+ get_vmodule_info().erase(
+ std::remove_if(++iter, get_vmodule_info().end(),
+ [module_pattern](const VModuleInfo& info) {
+ return FNMatch(info.module_pattern, module_pattern);
+ }),
+ get_vmodule_info().cend());
+ return old_log_level.value_or(global_v);
+}
+} // namespace
+
+int VLogLevel(absl::string_view file) ABSL_LOCKS_EXCLUDED(mutex) {
+ absl::base_internal::SpinLockHolder l(&mutex);
+ return VLogLevel(file, vmodule_info, global_v);
+}
+
+int RegisterAndInitialize(VLogSite* v) ABSL_LOCKS_EXCLUDED(mutex) {
+ // std::memory_order_seq_cst is overkill in this function, but given that this
+ // path is intended to be slow, it's not worth the brain power to relax that.
+ VLogSite* h = site_list_head.load(std::memory_order_seq_cst);
+
+ VLogSite* old = nullptr;
+ if (v->next_.compare_exchange_strong(old, h, std::memory_order_seq_cst,
+ std::memory_order_seq_cst)) {
+ // Multiple threads may attempt to register this site concurrently.
+ // By successfully setting `v->next` this thread commits to being *the*
+ // thread that installs `v` in the list.
+ while (!site_list_head.compare_exchange_weak(
+ h, v, std::memory_order_seq_cst, std::memory_order_seq_cst)) {
+ v->next_.store(h, std::memory_order_seq_cst);
+ }
+ }
+
+ int old_v = VLogSite::kUninitialized;
+ int new_v = VLogLevel(v->file_);
+ // No loop, if someone else set this, we should respect their evaluation of
+ // `VLogLevel`. This may mean we return a stale `v`, but `v` itself will
+ // always arrive at the freshest value. Otherwise, we could be writing a
+ // stale value and clobbering the fresher one.
+ if (v->v_.compare_exchange_strong(old_v, new_v, std::memory_order_seq_cst,
+ std::memory_order_seq_cst)) {
+ return new_v;
+ }
+ return old_v;
+}
+
+void UpdateVLogSites() ABSL_UNLOCK_FUNCTION(mutex)
+ ABSL_LOCKS_EXCLUDED(GetUpdateSitesMutex()) {
+ std::vector<VModuleInfo> infos = get_vmodule_info();
+ int current_global_v = global_v;
+ // We need to grab `GetUpdateSitesMutex()` before we release `mutex` to ensure
+ // that updates are not interleaved (resulting in an inconsistent final state)
+ // and to ensure that the final state in the sites matches the final state of
+ // `vmodule_info`. We unlock `mutex` to ensure that uninitialized sites don't
+ // have to wait on all updates in order to acquire `mutex` and initialize
+ // themselves.
+ absl::MutexLock ul(GetUpdateSitesMutex());
+ mutex.Unlock();
+ VLogSite* n = site_list_head.load(std::memory_order_seq_cst);
+ // Because sites are added to the list in the order they are executed, there
+ // tend to be clusters of entries with the same file.
+ const char* last_file = nullptr;
+ int last_file_level = 0;
+ while (n != nullptr) {
+ if (n->file_ != last_file) {
+ last_file = n->file_;
+ last_file_level = VLogLevel(n->file_, &infos, current_global_v);
+ }
+ n->v_.store(last_file_level, std::memory_order_seq_cst);
+ n = n->next_.load(std::memory_order_seq_cst);
+ }
+ if (update_callbacks) {
+ for (auto& cb : *update_callbacks) {
+ cb();
+ }
+ }
+}
+
+void UpdateVModule(absl::string_view vmodule)
+ ABSL_LOCKS_EXCLUDED(mutex, GetUpdateSitesMutex()) {
+ std::vector<std::pair<absl::string_view, int>> glob_levels;
+ for (absl::string_view glob_level : absl::StrSplit(vmodule, ',')) {
+ const size_t eq = glob_level.rfind('=');
+ if (eq == glob_level.npos) continue;
+ const absl::string_view glob = glob_level.substr(0, eq);
+ int level;
+ if (!absl::SimpleAtoi(glob_level.substr(eq + 1), &level)) continue;
+ glob_levels.emplace_back(glob, level);
+ }
+ mutex.Lock(); // Unlocked by UpdateVLogSites().
+ get_vmodule_info().clear();
+ for (const auto& it : glob_levels) {
+ const absl::string_view glob = it.first;
+ const int level = it.second;
+ AppendVModuleLocked(glob, level);
+ }
+ UpdateVLogSites();
+}
+
+int UpdateGlobalVLogLevel(int v)
+ ABSL_LOCKS_EXCLUDED(mutex, GetUpdateSitesMutex()) {
+ mutex.Lock(); // Unlocked by UpdateVLogSites().
+ const int old_global_v = global_v;
+ if (v == global_v) {
+ mutex.Unlock();
+ return old_global_v;
+ }
+ global_v = v;
+ UpdateVLogSites();
+ return old_global_v;
+}
+
+int PrependVModule(absl::string_view module_pattern, int log_level)
+ ABSL_LOCKS_EXCLUDED(mutex, GetUpdateSitesMutex()) {
+ mutex.Lock(); // Unlocked by UpdateVLogSites().
+ int old_v = PrependVModuleLocked(module_pattern, log_level);
+ UpdateVLogSites();
+ return old_v;
+}
+
+void OnVLogVerbosityUpdate(std::function<void()> cb)
+ ABSL_LOCKS_EXCLUDED(GetUpdateSitesMutex()) {
+ absl::MutexLock ul(GetUpdateSitesMutex());
+ if (!update_callbacks)
+ update_callbacks = new std::vector<std::function<void()>>;
+ update_callbacks->push_back(std::move(cb));
+}
+
+VLogSite* SetVModuleListHeadForTestOnly(VLogSite* v) {
+ return site_list_head.exchange(v, std::memory_order_seq_cst);
+}
+
+} // namespace log_internal
+ABSL_NAMESPACE_END
+} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/log/internal/vlog_config.h b/contrib/restricted/abseil-cpp/absl/log/internal/vlog_config.h
new file mode 100644
index 0000000000..b6e322c468
--- /dev/null
+++ b/contrib/restricted/abseil-cpp/absl/log/internal/vlog_config.h
@@ -0,0 +1,163 @@
+// Copyright 2022 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.
+//
+// -----------------------------------------------------------------------------
+// vlog_config.h
+// -----------------------------------------------------------------------------
+//
+// This header file defines `VLogSite`, a public primitive that represents
+// a callsite for the `VLOG` family of macros and related libraries.
+// It also declares and defines multiple internal utilities used to implement
+// `VLOG`, such as `VLogSiteManager`.
+
+#ifndef ABSL_LOG_INTERNAL_VLOG_CONFIG_H_
+#define ABSL_LOG_INTERNAL_VLOG_CONFIG_H_
+
+// IWYU pragma: private, include "absl/log/log.h"
+
+#include <atomic>
+#include <cstdint>
+#include <functional>
+#include <limits>
+#include <type_traits>
+
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/base/optimization.h"
+#include "absl/base/thread_annotations.h"
+#include "absl/strings/string_view.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace log_internal {
+
+class SyntheticBinary;
+class VLogSite;
+
+int RegisterAndInitialize(VLogSite* v);
+void UpdateVLogSites();
+constexpr int kUseFlag = (std::numeric_limits<int16_t>::min)();
+
+// Represents a unique callsite for a `VLOG()` or `VLOG_IS_ON()` call.
+//
+// Libraries that provide `VLOG`-like functionality should use this to
+// efficiently handle --vmodule.
+//
+// VLogSite objects must not be destroyed until the program exits. Doing so will
+// probably yield nasty segfaults in VLogSiteManager::UpdateLogSites(). The
+// recommendation is to make all such objects function-local statics.
+class VLogSite final {
+ public:
+ // `f` must not be destroyed until the program exits.
+ explicit constexpr VLogSite(const char* f)
+ : file_(f), v_(kUninitialized), next_(nullptr) {}
+ VLogSite(const VLogSite&) = delete;
+ VLogSite& operator=(const VLogSite&) = delete;
+
+ // Inlining the function yields a ~3x performance improvement at the cost of a
+ // 1.5x code size increase at the call site.
+ // Takes locks but does not allocate memory.
+ ABSL_ATTRIBUTE_ALWAYS_INLINE
+ bool IsEnabled(int level) {
+ int stale_v = v_.load(std::memory_order_relaxed);
+ if (ABSL_PREDICT_TRUE(level > stale_v)) {
+ return false;
+ }
+
+ // We put everything other than the fast path, i.e. vlogging is initialized
+ // but not on, behind an out-of-line function to reduce code size.
+ // "level" is almost always a call-site constant, so we can save a bit
+ // of code space by special-casing for a few common levels.
+#if ABSL_HAVE_BUILTIN(__builtin_constant_p) || defined(__GNUC__)
+ if (__builtin_constant_p(level)) {
+ if (level == 0) return SlowIsEnabled0(stale_v);
+ if (level == 1) return SlowIsEnabled1(stale_v);
+ if (level == 2) return SlowIsEnabled2(stale_v);
+ if (level == 3) return SlowIsEnabled3(stale_v);
+ if (level == 4) return SlowIsEnabled4(stale_v);
+ if (level == 5) return SlowIsEnabled5(stale_v);
+ }
+#endif
+ return SlowIsEnabled(stale_v, level);
+ }
+
+ private:
+ friend int log_internal::RegisterAndInitialize(VLogSite* v);
+ friend void log_internal::UpdateVLogSites();
+ friend class log_internal::SyntheticBinary;
+ static constexpr int kUninitialized = (std::numeric_limits<int>::max)();
+
+ // SlowIsEnabled performs slower checks to determine whether a log site is
+ // enabled. Because it is expected to be called somewhat rarely
+ // (comparatively), it is not inlined to save on code size.
+ //
+ // Prerequisites to calling SlowIsEnabled:
+ // 1) stale_v is uninitialized OR
+ // 2) stale_v is initialized and >= level (meaning we must log).
+ // Takes locks but does not allocate memory.
+ ABSL_ATTRIBUTE_NOINLINE
+ bool SlowIsEnabled(int stale_v, int level);
+ ABSL_ATTRIBUTE_NOINLINE bool SlowIsEnabled0(int stale_v);
+ ABSL_ATTRIBUTE_NOINLINE bool SlowIsEnabled1(int stale_v);
+ ABSL_ATTRIBUTE_NOINLINE bool SlowIsEnabled2(int stale_v);
+ ABSL_ATTRIBUTE_NOINLINE bool SlowIsEnabled3(int stale_v);
+ ABSL_ATTRIBUTE_NOINLINE bool SlowIsEnabled4(int stale_v);
+ ABSL_ATTRIBUTE_NOINLINE bool SlowIsEnabled5(int stale_v);
+
+ // This object is too size-sensitive to use absl::string_view.
+ const char* const file_;
+ std::atomic<int> v_;
+ std::atomic<VLogSite*> next_;
+};
+static_assert(std::is_trivially_destructible<VLogSite>::value,
+ "VLogSite must be trivially destructible");
+
+// Returns the current verbose log level of `file`.
+// Does not allocate memory.
+int VLogLevel(absl::string_view file);
+
+// Registers a site `v` to get updated as `vmodule` and `v` change. Also
+// initializes the site based on their current values, and returns that result.
+// Does not allocate memory.
+int RegisterAndInitialize(VLogSite* v);
+
+// Allocates memory.
+void UpdateVLogSites();
+
+// Completely overwrites the saved value of `vmodule`.
+// Allocates memory.
+void UpdateVModule(absl::string_view vmodule);
+
+// Updates the global verbosity level to `v` and returns the prior value.
+// Allocates memory.
+int UpdateGlobalVLogLevel(int v);
+
+// Atomically prepends `module_pattern=log_level` to the start of vmodule.
+// Returns the prior value for `module_pattern` if there was an exact match and
+// `global_v` otherwise.
+// Allocates memory.
+int PrependVModule(absl::string_view module_pattern, int log_level);
+
+// Registers `on_update` to be called whenever `v` or `vmodule` change.
+// Allocates memory.
+void OnVLogVerbosityUpdate(std::function<void()> cb);
+
+// Does not allocate memory.
+VLogSite* SetVModuleListHeadForTestOnly(VLogSite* v);
+
+} // namespace log_internal
+ABSL_NAMESPACE_END
+} // namespace absl
+
+#endif // ABSL_LOG_INTERNAL_VLOG_CONFIG_H_
diff --git a/contrib/restricted/abseil-cpp/absl/log/log.h b/contrib/restricted/abseil-cpp/absl/log/log.h
index 602b5acf07..b721b087cc 100644
--- a/contrib/restricted/abseil-cpp/absl/log/log.h
+++ b/contrib/restricted/abseil-cpp/absl/log/log.h
@@ -32,6 +32,8 @@
// * The `QFATAL` pseudo-severity level is equivalent to `FATAL` but triggers
// quieter termination messages, e.g. without a full stack trace, and skips
// running registered error handlers.
+// * The `DFATAL` pseudo-severity level is defined as `FATAL` in debug mode and
+// as `ERROR` otherwise.
// Some preprocessor shenanigans are used to ensure that e.g. `LOG(INFO)` has
// the same meaning even if a local symbol or preprocessor macro named `INFO` is
// defined. To specify a severity level using an expression instead of a
@@ -51,6 +53,14 @@
// * .NoPrefix()
// Omits the prefix from this line. The prefix includes metadata about the
// logged data such as source code location and timestamp.
+// * .WithVerbosity(int verbose_level)
+// Sets the verbosity field of the logged message as if it was logged by
+// `VLOG(verbose_level)`. Unlike `VLOG`, this method does not affect
+// evaluation of the statement when the specified `verbose_level` has been
+// disabled. The only effect is on `LogSink` implementations which make use
+// of the `absl::LogSink::verbosity()` value. The value
+// `absl::LogEntry::kNoVerbosityLevel` can be specified to mark the message
+// not verbose.
// * .WithTimestamp(absl::Time timestamp)
// Uses the specified timestamp instead of one collected at the time of
// execution.
@@ -188,6 +198,7 @@
#define ABSL_LOG_LOG_H_
#include "absl/log/internal/log_impl.h"
+#include "absl/log/vlog_is_on.h" // IWYU pragma: export
// LOG()
//
@@ -211,11 +222,32 @@
// terminate the program if `NDEBUG` is defined.
#define DLOG(severity) ABSL_LOG_INTERNAL_DLOG_IMPL(_##severity)
+// `VLOG` uses numeric levels to provide verbose logging that can configured at
+// runtime, including at a per-module level. `VLOG` statements are logged at
+// `INFO` severity if they are logged at all; the numeric levels are on a
+// different scale than the proper severity levels. Positive levels are
+// disabled by default. Negative levels should not be used.
+// Example:
+//
+// VLOG(1) << "I print when you run the program with --v=1 or higher";
+// VLOG(2) << "I print when you run the program with --v=2 or higher";
+//
+// See vlog_is_on.h for further documentation, including the usage of the
+// --vmodule flag to log at different levels in different source files.
+#define VLOG(severity) ABSL_LOG_INTERNAL_VLOG_IMPL(severity)
+
+// `DVLOG` behaves like `VLOG` in debug mode (i.e. `#ifndef NDEBUG`).
+// Otherwise, it compiles away and does nothing.
+#define DVLOG(severity) ABSL_LOG_INTERNAL_DVLOG_IMPL(severity)
+
// `LOG_IF` and friends add a second argument which specifies a condition. If
// the condition is false, nothing is logged.
// Example:
//
// LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
+//
+// There is no `VLOG_IF` because the order of evaluation of the arguments is
+// ambiguous and the alternate spelling with an `if`-statement is trivial.
#define LOG_IF(severity, condition) \
ABSL_LOG_INTERNAL_LOG_IF_IMPL(_##severity, condition)
#define PLOG_IF(severity, condition) \
@@ -283,6 +315,15 @@
#define DLOG_EVERY_N_SEC(severity, n_seconds) \
ABSL_LOG_INTERNAL_DLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)
+#define VLOG_EVERY_N(severity, n) \
+ ABSL_LOG_INTERNAL_VLOG_EVERY_N_IMPL(severity, n)
+#define VLOG_FIRST_N(severity, n) \
+ ABSL_LOG_INTERNAL_VLOG_FIRST_N_IMPL(severity, n)
+#define VLOG_EVERY_POW_2(severity) \
+ ABSL_LOG_INTERNAL_VLOG_EVERY_POW_2_IMPL(severity)
+#define VLOG_EVERY_N_SEC(severity, n_seconds) \
+ ABSL_LOG_INTERNAL_VLOG_EVERY_N_SEC_IMPL(severity, n_seconds)
+
// `LOG_IF_EVERY_N` and friends behave as the corresponding `LOG_EVERY_N`
// but neither increment a counter nor log a message if condition is false (as
// `LOG_IF`).
diff --git a/contrib/restricted/abseil-cpp/absl/log/log_entry.cc b/contrib/restricted/abseil-cpp/absl/log/log_entry.cc
index 19c3b3f1be..fe58a576b5 100644
--- a/contrib/restricted/abseil-cpp/absl/log/log_entry.cc
+++ b/contrib/restricted/abseil-cpp/absl/log/log_entry.cc
@@ -25,5 +25,17 @@ constexpr int LogEntry::kNoVerbosityLevel;
constexpr int LogEntry::kNoVerboseLevel;
#endif
+// https://github.com/abseil/abseil-cpp/issues/1465
+// CMake builds on Apple platforms error when libraries are empty.
+// Our CMake configuration can avoid this error on header-only libraries,
+// but since this library is conditionally empty, including a single
+// variable is an easy workaround.
+#ifdef __APPLE__
+namespace log_internal {
+extern const char kAvoidEmptyLogEntryLibraryWarning;
+const char kAvoidEmptyLogEntryLibraryWarning = 0;
+} // namespace log_internal
+#endif // __APPLE__
+
ABSL_NAMESPACE_END
} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/log/log_entry.h b/contrib/restricted/abseil-cpp/absl/log/log_entry.h
index 9e4ae8eb76..7a55dfe29e 100644
--- a/contrib/restricted/abseil-cpp/absl/log/log_entry.h
+++ b/contrib/restricted/abseil-cpp/absl/log/log_entry.h
@@ -96,7 +96,8 @@ class LogEntry final {
// LogEntry::verbosity()
//
// Returns this entry's verbosity, or `kNoVerbosityLevel` for a non-verbose
- // entry. Verbosity control is not available outside of Google yet.
+ // entry. Taken from the argument to `VLOG` or from
+ // `LOG(...).WithVerbosity(...)`.
int verbosity() const { return verbose_level_; }
// LogEntry::timestamp()
diff --git a/contrib/restricted/abseil-cpp/absl/log/vlog_is_on.h b/contrib/restricted/abseil-cpp/absl/log/vlog_is_on.h
new file mode 100644
index 0000000000..7898651380
--- /dev/null
+++ b/contrib/restricted/abseil-cpp/absl/log/vlog_is_on.h
@@ -0,0 +1,72 @@
+// Copyright 2022 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/vlog_is_on.h
+// -----------------------------------------------------------------------------
+//
+// This header defines the `VLOG_IS_ON()` macro that controls the
+// variable-verbosity conditional logging.
+//
+// It's used by `VLOG` in log.h, or it can also be used directly like this:
+//
+// if (VLOG_IS_ON(2)) {
+// foo_server.RecomputeStatisticsExpensive();
+// LOG(INFO) << foo_server.LastStatisticsAsString();
+// }
+//
+// Each source file has an effective verbosity level that's a non-negative
+// integer computed from the `--vmodule` and `--v` flags.
+// `VLOG_IS_ON(n)` is true, and `VLOG(n)` logs, if that effective verbosity
+// level is greater than or equal to `n`.
+//
+// `--vmodule` takes a comma-delimited list of key=value pairs. Each key is a
+// pattern matched against filenames, and the values give the effective severity
+// level applied to matching files. '?' and '*' characters in patterns are
+// interpreted as single-character and zero-or-more-character wildcards.
+// Patterns including a slash character are matched against full pathnames,
+// while those without are matched against basenames only. One suffix (i.e. the
+// last . and everything after it) is stripped from each filename prior to
+// matching, as is the special suffix "-inl".
+//
+// Files are matched against globs in `--vmodule` in order, and the first match
+// determines the verbosity level.
+//
+// Files which do not match any pattern in `--vmodule` use the value of `--v` as
+// their effective verbosity level. The default is 0.
+//
+// SetVLOGLevel helper function is provided to do limited dynamic control over
+// V-logging by appending to `--vmodule`. Because these go at the beginning of
+// the list, they take priority over any globs previously added.
+//
+// Resetting --vmodule will override all previous modifications to `--vmodule`,
+// including via SetVLOGLevel.
+
+#ifndef ABSL_LOG_VLOG_IS_ON_H_
+#define ABSL_LOG_VLOG_IS_ON_H_
+
+#include "absl/log/absl_vlog_is_on.h" // IWYU pragma: export
+
+// IWYU pragma: private, include "absl/log/log.h"
+
+// Each VLOG_IS_ON call site gets its own VLogSite that registers with the
+// global linked list of sites to asynchronously update its verbosity level on
+// changes to --v or --vmodule. The verbosity can also be set by manually
+// calling SetVLOGLevel.
+//
+// VLOG_IS_ON is not async signal safe, but it is guaranteed not to allocate
+// new memory.
+#define VLOG_IS_ON(verbose_level) ABSL_VLOG_IS_ON(verbose_level)
+
+#endif // ABSL_LOG_VLOG_IS_ON_H_
diff --git a/contrib/restricted/abseil-cpp/absl/log/ya.make b/contrib/restricted/abseil-cpp/absl/log/ya.make
index cb73fdb2b2..f35baf8a56 100644
--- a/contrib/restricted/abseil-cpp/absl/log/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/log/ya.make
@@ -35,12 +35,14 @@ SRCS(
initialize.cc
internal/check_op.cc
internal/conditions.cc
+ internal/fnmatch.cc
internal/globals.cc
internal/log_format.cc
internal/log_message.cc
internal/log_sink_set.cc
internal/nullguard.cc
internal/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 2d3aab1c79..4f191bfa0b 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(20230802.1)
+VERSION(20240116.0)
-ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20230802.1.tar.gz)
+ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20240116.0.tar.gz)
PEERDIR(
contrib/restricted/abseil-cpp/absl/meta
diff --git a/contrib/restricted/abseil-cpp/absl/meta/ya.make b/contrib/restricted/abseil-cpp/absl/meta/ya.make
index 39b472c0fa..8a0016666e 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(20230802.1)
+VERSION(20240116.0)
-ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20230802.1.tar.gz)
+ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20240116.0.tar.gz)
PEERDIR(
contrib/restricted/abseil-cpp/absl/base
diff --git a/contrib/restricted/abseil-cpp/absl/numeric/bits.h b/contrib/restricted/abseil-cpp/absl/numeric/bits.h
index 5ed36f5296..c76454c8fb 100644
--- a/contrib/restricted/abseil-cpp/absl/numeric/bits.h
+++ b/contrib/restricted/abseil-cpp/absl/numeric/bits.h
@@ -49,9 +49,19 @@
namespace absl {
ABSL_NAMESPACE_BEGIN
-#if !(defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L)
-// rotating
+// https://github.com/llvm/llvm-project/issues/64544
+// libc++ had the wrong signature for std::rotl and std::rotr
+// prior to libc++ 18.0.
+//
+#if (defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L) && \
+ (!defined(_LIBCPP_VERSION) || _LIBCPP_VERSION >= 180000)
+using std::rotl;
+using std::rotr;
+
+#else
+
+// Rotating functions
template <class T>
ABSL_MUST_USE_RESULT constexpr
typename std::enable_if<std::is_unsigned<T>::value, T>::type
@@ -66,6 +76,22 @@ ABSL_MUST_USE_RESULT constexpr
return numeric_internal::RotateRight(x, s);
}
+#endif
+
+// https://github.com/llvm/llvm-project/issues/64544
+// libc++ had the wrong signature for std::rotl and std::rotr
+// prior to libc++ 18.0.
+//
+#if (defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L)
+
+using std::countl_one;
+using std::countl_zero;
+using std::countr_one;
+using std::countr_zero;
+using std::popcount;
+
+#else
+
// Counting functions
//
// While these functions are typically constexpr, on some platforms, they may
@@ -107,19 +133,18 @@ ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline
popcount(T x) noexcept {
return numeric_internal::Popcount(x);
}
-#else // defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L
-
-using std::countl_one;
-using std::countl_zero;
-using std::countr_one;
-using std::countr_zero;
-using std::popcount;
-using std::rotl;
-using std::rotr;
#endif
-#if !(defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L)
+#if (defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L)
+
+using std::bit_ceil;
+using std::bit_floor;
+using std::bit_width;
+using std::has_single_bit;
+
+#else
+
// Returns: true if x is an integral power of two; false otherwise.
template <class T>
constexpr inline typename std::enable_if<std::is_unsigned<T>::value, bool>::type
@@ -162,12 +187,6 @@ ABSL_INTERNAL_CONSTEXPR_CLZ inline
return has_single_bit(x) ? T{1} << (bit_width(x) - 1)
: numeric_internal::BitCeilNonPowerOf2(x);
}
-#else // defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L
-
-using std::bit_ceil;
-using std::bit_floor;
-using std::bit_width;
-using std::has_single_bit;
#endif
diff --git a/contrib/restricted/abseil-cpp/absl/status/internal/status_internal.cc b/contrib/restricted/abseil-cpp/absl/status/internal/status_internal.cc
new file mode 100644
index 0000000000..a91567549e
--- /dev/null
+++ b/contrib/restricted/abseil-cpp/absl/status/internal/status_internal.cc
@@ -0,0 +1,248 @@
+// Copyright 2023 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/status/internal/status_internal.h"
+
+#include <atomic>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <cstring>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/base/macros.h"
+#include "absl/base/nullability.h"
+#include "absl/debugging/stacktrace.h"
+#include "absl/debugging/symbolize.h"
+#include "absl/memory/memory.h"
+#include "absl/status/status.h"
+#include "absl/status/status_payload_printer.h"
+#include "absl/strings/cord.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_format.h"
+#include "absl/strings/str_split.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace status_internal {
+
+void StatusRep::Unref() const {
+ // Fast path: if ref==1, there is no need for a RefCountDec (since
+ // this is the only reference and therefore no other thread is
+ // allowed to be mucking with r).
+ if (ref_.load(std::memory_order_acquire) == 1 ||
+ ref_.fetch_sub(1, std::memory_order_acq_rel) - 1 == 0) {
+ delete this;
+ }
+}
+
+static absl::optional<size_t> FindPayloadIndexByUrl(
+ const Payloads* payloads, absl::string_view type_url) {
+ if (payloads == nullptr) return absl::nullopt;
+
+ for (size_t i = 0; i < payloads->size(); ++i) {
+ if ((*payloads)[i].type_url == type_url) return i;
+ }
+
+ return absl::nullopt;
+}
+
+absl::optional<absl::Cord> StatusRep::GetPayload(
+ absl::string_view type_url) const {
+ absl::optional<size_t> index =
+ status_internal::FindPayloadIndexByUrl(payloads_.get(), type_url);
+ if (index.has_value()) return (*payloads_)[index.value()].payload;
+
+ return absl::nullopt;
+}
+
+void StatusRep::SetPayload(absl::string_view type_url, absl::Cord payload) {
+ if (payloads_ == nullptr) {
+ payloads_ = absl::make_unique<status_internal::Payloads>();
+ }
+
+ absl::optional<size_t> index =
+ status_internal::FindPayloadIndexByUrl(payloads_.get(), type_url);
+ if (index.has_value()) {
+ (*payloads_)[index.value()].payload = std::move(payload);
+ return;
+ }
+
+ payloads_->push_back({std::string(type_url), std::move(payload)});
+}
+
+StatusRep::EraseResult StatusRep::ErasePayload(absl::string_view type_url) {
+ absl::optional<size_t> index =
+ status_internal::FindPayloadIndexByUrl(payloads_.get(), type_url);
+ if (!index.has_value()) return {false, Status::PointerToRep(this)};
+ payloads_->erase(payloads_->begin() + index.value());
+ if (payloads_->empty() && message_.empty()) {
+ // Special case: If this can be represented inlined, it MUST be inlined
+ // (== depends on this behavior).
+ EraseResult result = {true, Status::CodeToInlinedRep(code_)};
+ Unref();
+ return result;
+ }
+ return {true, Status::PointerToRep(this)};
+}
+
+void StatusRep::ForEachPayload(
+ absl::FunctionRef<void(absl::string_view, const absl::Cord&)> visitor)
+ const {
+ if (auto* payloads = payloads_.get()) {
+ bool in_reverse =
+ payloads->size() > 1 && reinterpret_cast<uintptr_t>(payloads) % 13 > 6;
+
+ for (size_t index = 0; index < payloads->size(); ++index) {
+ const auto& elem =
+ (*payloads)[in_reverse ? payloads->size() - 1 - index : index];
+
+#ifdef NDEBUG
+ visitor(elem.type_url, elem.payload);
+#else
+ // In debug mode invalidate the type url to prevent users from relying on
+ // this string lifetime.
+
+ // NOLINTNEXTLINE intentional extra conversion to force temporary.
+ visitor(std::string(elem.type_url), elem.payload);
+#endif // NDEBUG
+ }
+ }
+}
+
+std::string StatusRep::ToString(StatusToStringMode mode) const {
+ std::string text;
+ absl::StrAppend(&text, absl::StatusCodeToString(code()), ": ", message());
+
+ const bool with_payload = (mode & StatusToStringMode::kWithPayload) ==
+ StatusToStringMode::kWithPayload;
+
+ if (with_payload) {
+ status_internal::StatusPayloadPrinter printer =
+ status_internal::GetStatusPayloadPrinter();
+ this->ForEachPayload([&](absl::string_view type_url,
+ const absl::Cord& payload) {
+ absl::optional<std::string> result;
+ if (printer) result = printer(type_url, payload);
+ absl::StrAppend(
+ &text, " [", type_url, "='",
+ result.has_value() ? *result : absl::CHexEscape(std::string(payload)),
+ "']");
+ });
+ }
+
+ return text;
+}
+
+bool StatusRep::operator==(const StatusRep& other) const {
+ assert(this != &other);
+ if (code_ != other.code_) return false;
+ if (message_ != other.message_) return false;
+ const status_internal::Payloads* this_payloads = payloads_.get();
+ const status_internal::Payloads* other_payloads = other.payloads_.get();
+
+ const status_internal::Payloads no_payloads;
+ const status_internal::Payloads* larger_payloads =
+ this_payloads ? this_payloads : &no_payloads;
+ const status_internal::Payloads* smaller_payloads =
+ other_payloads ? other_payloads : &no_payloads;
+ if (larger_payloads->size() < smaller_payloads->size()) {
+ std::swap(larger_payloads, smaller_payloads);
+ }
+ if ((larger_payloads->size() - smaller_payloads->size()) > 1) return false;
+ // Payloads can be ordered differently, so we can't just compare payload
+ // vectors.
+ for (const auto& payload : *larger_payloads) {
+
+ bool found = false;
+ for (const auto& other_payload : *smaller_payloads) {
+ if (payload.type_url == other_payload.type_url) {
+ if (payload.payload != other_payload.payload) {
+ return false;
+ }
+ found = true;
+ break;
+ }
+ }
+ if (!found) return false;
+ }
+ return true;
+}
+
+absl::Nonnull<StatusRep*> StatusRep::CloneAndUnref() const {
+ // Optimization: no need to create a clone if we already have a refcount of 1.
+ if (ref_.load(std::memory_order_acquire) == 1) {
+ // All StatusRep instances are heap allocated and mutable, therefore this
+ // const_cast will never cast away const from a stack instance.
+ //
+ // CloneAndUnref is the only method that doesn't involve an external cast to
+ // get a mutable StatusRep* from the uintptr_t rep stored in Status.
+ return const_cast<StatusRep*>(this);
+ }
+ std::unique_ptr<status_internal::Payloads> payloads;
+ if (payloads_) {
+ payloads = absl::make_unique<status_internal::Payloads>(*payloads_);
+ }
+ auto* new_rep = new StatusRep(code_, message_, std::move(payloads));
+ Unref();
+ return new_rep;
+}
+
+// Convert canonical code to a value known to this binary.
+absl::StatusCode MapToLocalCode(int value) {
+ absl::StatusCode code = static_cast<absl::StatusCode>(value);
+ switch (code) {
+ case absl::StatusCode::kOk:
+ case absl::StatusCode::kCancelled:
+ case absl::StatusCode::kUnknown:
+ case absl::StatusCode::kInvalidArgument:
+ case absl::StatusCode::kDeadlineExceeded:
+ case absl::StatusCode::kNotFound:
+ case absl::StatusCode::kAlreadyExists:
+ case absl::StatusCode::kPermissionDenied:
+ case absl::StatusCode::kResourceExhausted:
+ case absl::StatusCode::kFailedPrecondition:
+ case absl::StatusCode::kAborted:
+ case absl::StatusCode::kOutOfRange:
+ case absl::StatusCode::kUnimplemented:
+ case absl::StatusCode::kInternal:
+ case absl::StatusCode::kUnavailable:
+ case absl::StatusCode::kDataLoss:
+ case absl::StatusCode::kUnauthenticated:
+ return code;
+ default:
+ return absl::StatusCode::kUnknown;
+ }
+}
+
+absl::Nonnull<std::string*> MakeCheckFailString(
+ absl::Nonnull<const absl::Status*> status,
+ absl::Nonnull<const char*> prefix) {
+ return new std::string(
+ absl::StrCat(prefix, " (",
+ status->ToString(StatusToStringMode::kWithEverything), ")"));
+}
+
+} // namespace status_internal
+
+ABSL_NAMESPACE_END
+} // namespace absl
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 6198e726b3..c9f4383272 100644
--- a/contrib/restricted/abseil-cpp/absl/status/internal/status_internal.h
+++ b/contrib/restricted/abseil-cpp/absl/status/internal/status_internal.h
@@ -14,13 +14,19 @@
#ifndef ABSL_STATUS_INTERNAL_STATUS_INTERNAL_H_
#define ABSL_STATUS_INTERNAL_STATUS_INTERNAL_H_
+#include <atomic>
+#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/base/nullability.h"
#include "absl/container/inlined_vector.h"
#include "absl/strings/cord.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
#ifndef SWIG
// Disabled for SWIG as it doesn't parse attributes correctly.
@@ -32,9 +38,9 @@ ABSL_NAMESPACE_BEGIN
// TODO(b/176172494): ABSL_MUST_USE_RESULT should expand to the more strict
// [[nodiscard]]. For now, just use [[nodiscard]] directly when it is available.
#if ABSL_HAVE_CPP_ATTRIBUTE(nodiscard)
-class [[nodiscard]] Status;
+class [[nodiscard]] ABSL_ATTRIBUTE_TRIVIAL_ABI Status;
#else
-class ABSL_MUST_USE_RESULT Status;
+class ABSL_MUST_USE_RESULT ABSL_ATTRIBUTE_TRIVIAL_ABI Status;
#endif
ABSL_NAMESPACE_END
} // namespace absl
@@ -44,6 +50,7 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
enum class StatusCode : int;
+enum class StatusToStringMode : int;
namespace status_internal {
@@ -56,22 +63,54 @@ struct Payload {
using Payloads = absl::InlinedVector<Payload, 1>;
// Reference-counted representation of Status data.
-struct StatusRep {
+class StatusRep {
+ public:
StatusRep(absl::StatusCode code_arg, absl::string_view message_arg,
std::unique_ptr<status_internal::Payloads> payloads_arg)
- : ref(int32_t{1}),
- code(code_arg),
- message(message_arg),
- payloads(std::move(payloads_arg)) {}
-
- std::atomic<int32_t> ref;
- absl::StatusCode code;
+ : ref_(int32_t{1}),
+ code_(code_arg),
+ message_(message_arg),
+ payloads_(std::move(payloads_arg)) {}
+
+ absl::StatusCode code() const { return code_; }
+ const std::string& message() const { return message_; }
+
+ // Ref and unref are const to allow access through a const pointer, and are
+ // used during copying operations.
+ void Ref() const { ref_.fetch_add(1, std::memory_order_relaxed); }
+ void Unref() const;
+
+ // Payload methods correspond to the same methods in absl::Status.
+ absl::optional<absl::Cord> GetPayload(absl::string_view type_url) const;
+ void SetPayload(absl::string_view type_url, absl::Cord payload);
+ struct EraseResult {
+ bool erased;
+ uintptr_t new_rep;
+ };
+ EraseResult ErasePayload(absl::string_view type_url);
+ void ForEachPayload(
+ absl::FunctionRef<void(absl::string_view, const absl::Cord&)> visitor)
+ const;
+
+ std::string ToString(StatusToStringMode mode) const;
+
+ bool operator==(const StatusRep& other) const;
+ bool operator!=(const StatusRep& other) const { return !(*this == other); }
+
+ // Returns an equivalent heap allocated StatusRep with refcount 1.
+ //
+ // `this` is not safe to be used after calling as it may have been deleted.
+ absl::Nonnull<StatusRep*> CloneAndUnref() const;
+
+ private:
+ mutable std::atomic<int32_t> ref_;
+ absl::StatusCode code_;
// As an internal implementation detail, we guarantee that if status.message()
// is non-empty, then the resulting string_view is null terminated.
// This is required to implement 'StatusMessageAsCStr(...)'
- std::string message;
- std::unique_ptr<status_internal::Payloads> payloads;
+ std::string message_;
+ std::unique_ptr<status_internal::Payloads> payloads_;
};
absl::StatusCode MapToLocalCode(int value);
@@ -80,8 +119,10 @@ absl::StatusCode MapToLocalCode(int value);
// suitable for output as an error message in assertion/`CHECK()` failures.
//
// This is an internal implementation detail for Abseil logging.
-std::string* MakeCheckFailString(const absl::Status* status,
- const char* prefix);
+ABSL_ATTRIBUTE_PURE_FUNCTION
+absl::Nonnull<std::string*> MakeCheckFailString(
+ absl::Nonnull<const absl::Status*> status,
+ absl::Nonnull<const char*> prefix);
} // namespace status_internal
diff --git a/contrib/restricted/abseil-cpp/absl/status/internal/statusor_internal.h b/contrib/restricted/abseil-cpp/absl/status/internal/statusor_internal.h
index 49cead7a7f..5be94903b7 100644
--- a/contrib/restricted/abseil-cpp/absl/status/internal/statusor_internal.h
+++ b/contrib/restricted/abseil-cpp/absl/status/internal/statusor_internal.h
@@ -14,12 +14,15 @@
#ifndef ABSL_STATUS_INTERNAL_STATUSOR_INTERNAL_H_
#define ABSL_STATUS_INTERNAL_STATUSOR_INTERNAL_H_
+#include <cstdint>
#include <type_traits>
#include <utility>
#include "absl/base/attributes.h"
+#include "absl/base/nullability.h"
#include "absl/meta/type_traits.h"
#include "absl/status/status.h"
+#include "absl/strings/string_view.h"
#include "absl/utility/utility.h"
namespace absl {
@@ -123,7 +126,7 @@ using IsForwardingAssignmentValid = absl::disjunction<
class Helper {
public:
// Move type-agnostic error handling to the .cc.
- static void HandleInvalidStatusCtorArg(Status*);
+ static void HandleInvalidStatusCtorArg(absl::Nonnull<Status*>);
ABSL_ATTRIBUTE_NORETURN static void Crash(const absl::Status& status);
};
@@ -131,7 +134,8 @@ class Helper {
// the constructor.
// This abstraction is here mostly for the gcc performance fix.
template <typename T, typename... Args>
-ABSL_ATTRIBUTE_NONNULL(1) void PlacementNew(void* p, Args&&... args) {
+ABSL_ATTRIBUTE_NONNULL(1)
+void PlacementNew(absl::Nonnull<void*> p, Args&&... args) {
new (p) T(std::forward<Args>(args)...);
}
@@ -377,6 +381,53 @@ struct MoveAssignBase<T, false> {
ABSL_ATTRIBUTE_NORETURN void ThrowBadStatusOrAccess(absl::Status status);
+// Used to introduce jitter into the output of printing functions for
+// `StatusOr` (i.e. `AbslStringify` and `operator<<`).
+class StringifyRandom {
+ enum BracesType {
+ kBareParens = 0,
+ kSpaceParens,
+ kBareBrackets,
+ kSpaceBrackets,
+ };
+
+ // Returns a random `BracesType` determined once per binary load.
+ static BracesType RandomBraces() {
+ static const BracesType kRandomBraces = static_cast<BracesType>(
+ (reinterpret_cast<uintptr_t>(&kRandomBraces) >> 4) % 4);
+ return kRandomBraces;
+ }
+
+ public:
+ static inline absl::string_view OpenBrackets() {
+ switch (RandomBraces()) {
+ case kBareParens:
+ return "(";
+ case kSpaceParens:
+ return "( ";
+ case kBareBrackets:
+ return "[";
+ case kSpaceBrackets:
+ return "[ ";
+ }
+ return "(";
+ }
+
+ static inline absl::string_view CloseBrackets() {
+ switch (RandomBraces()) {
+ case kBareParens:
+ return ")";
+ case kSpaceParens:
+ return " )";
+ case kBareBrackets:
+ return "]";
+ case kSpaceBrackets:
+ return " ]";
+ }
+ return ")";
+ }
+};
+
} // namespace internal_statusor
ABSL_NAMESPACE_END
} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/status/status.cc b/contrib/restricted/abseil-cpp/absl/status/status.cc
index 26e68294ac..4dd5ae06ce 100644
--- a/contrib/restricted/abseil-cpp/absl/status/status.cc
+++ b/contrib/restricted/abseil-cpp/absl/status/status.cc
@@ -15,23 +15,37 @@
#include <errno.h>
-#include <cassert>
-#include <utility>
-
+#include <atomic>
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <memory>
+#include <ostream>
+#include <string>
+
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/internal/strerror.h"
#include "absl/base/macros.h"
+#include "absl/base/no_destructor.h"
+#include "absl/base/nullability.h"
#include "absl/debugging/stacktrace.h"
#include "absl/debugging/symbolize.h"
-#include "absl/status/status_payload_printer.h"
-#include "absl/strings/escaping.h"
+#include "absl/status/internal/status_internal.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/str_split.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
+static_assert(
+ alignof(status_internal::StatusRep) >= 4,
+ "absl::Status assumes it can use the bottom 2 bits of a StatusRep*.");
+
std::string StatusCodeToString(StatusCode code) {
switch (code) {
case StatusCode::kOk:
@@ -77,146 +91,18 @@ std::ostream& operator<<(std::ostream& os, StatusCode code) {
return os << StatusCodeToString(code);
}
-namespace status_internal {
-
-static absl::optional<size_t> FindPayloadIndexByUrl(
- const Payloads* payloads, absl::string_view type_url) {
- if (payloads == nullptr) return absl::nullopt;
-
- for (size_t i = 0; i < payloads->size(); ++i) {
- if ((*payloads)[i].type_url == type_url) return i;
- }
-
- return absl::nullopt;
-}
-
-// Convert canonical code to a value known to this binary.
-absl::StatusCode MapToLocalCode(int value) {
- absl::StatusCode code = static_cast<absl::StatusCode>(value);
- switch (code) {
- case absl::StatusCode::kOk:
- case absl::StatusCode::kCancelled:
- case absl::StatusCode::kUnknown:
- case absl::StatusCode::kInvalidArgument:
- case absl::StatusCode::kDeadlineExceeded:
- case absl::StatusCode::kNotFound:
- case absl::StatusCode::kAlreadyExists:
- case absl::StatusCode::kPermissionDenied:
- case absl::StatusCode::kResourceExhausted:
- case absl::StatusCode::kFailedPrecondition:
- case absl::StatusCode::kAborted:
- case absl::StatusCode::kOutOfRange:
- case absl::StatusCode::kUnimplemented:
- case absl::StatusCode::kInternal:
- case absl::StatusCode::kUnavailable:
- case absl::StatusCode::kDataLoss:
- case absl::StatusCode::kUnauthenticated:
- return code;
- default:
- return absl::StatusCode::kUnknown;
- }
-}
-} // namespace status_internal
-
-absl::optional<absl::Cord> Status::GetPayload(
- absl::string_view type_url) const {
- const auto* payloads = GetPayloads();
- absl::optional<size_t> index =
- status_internal::FindPayloadIndexByUrl(payloads, type_url);
- if (index.has_value()) return (*payloads)[index.value()].payload;
-
- return absl::nullopt;
-}
-
-void Status::SetPayload(absl::string_view type_url, absl::Cord payload) {
- if (ok()) return;
-
- PrepareToModify();
-
- status_internal::StatusRep* rep = RepToPointer(rep_);
- if (!rep->payloads) {
- rep->payloads = absl::make_unique<status_internal::Payloads>();
- }
-
- absl::optional<size_t> index =
- status_internal::FindPayloadIndexByUrl(rep->payloads.get(), type_url);
- if (index.has_value()) {
- (*rep->payloads)[index.value()].payload = std::move(payload);
- return;
- }
-
- rep->payloads->push_back({std::string(type_url), std::move(payload)});
-}
-
-bool Status::ErasePayload(absl::string_view type_url) {
- absl::optional<size_t> index =
- status_internal::FindPayloadIndexByUrl(GetPayloads(), type_url);
- if (index.has_value()) {
- PrepareToModify();
- GetPayloads()->erase(GetPayloads()->begin() + index.value());
- if (GetPayloads()->empty() && message().empty()) {
- // Special case: If this can be represented inlined, it MUST be
- // inlined (EqualsSlow depends on this behavior).
- StatusCode c = static_cast<StatusCode>(raw_code());
- Unref(rep_);
- rep_ = CodeToInlinedRep(c);
- }
- return true;
- }
-
- return false;
-}
-
-void Status::ForEachPayload(
- absl::FunctionRef<void(absl::string_view, const absl::Cord&)> visitor)
- const {
- if (auto* payloads = GetPayloads()) {
- bool in_reverse =
- payloads->size() > 1 && reinterpret_cast<uintptr_t>(payloads) % 13 > 6;
-
- for (size_t index = 0; index < payloads->size(); ++index) {
- const auto& elem =
- (*payloads)[in_reverse ? payloads->size() - 1 - index : index];
-
-#ifdef NDEBUG
- visitor(elem.type_url, elem.payload);
-#else
- // In debug mode invalidate the type url to prevent users from relying on
- // this string lifetime.
-
- // NOLINTNEXTLINE intentional extra conversion to force temporary.
- visitor(std::string(elem.type_url), elem.payload);
-#endif // NDEBUG
- }
- }
-}
-
-const std::string* Status::EmptyString() {
- static union EmptyString {
- std::string str;
- ~EmptyString() {}
- } empty = {{}};
- return &empty.str;
+absl::Nonnull<const std::string*> Status::EmptyString() {
+ static const absl::NoDestructor<std::string> kEmpty;
+ return kEmpty.get();
}
#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
constexpr const char Status::kMovedFromString[];
#endif
-const std::string* Status::MovedFromString() {
- static std::string* moved_from_string = new std::string(kMovedFromString);
- return moved_from_string;
-}
-
-void Status::UnrefNonInlined(uintptr_t rep) {
- status_internal::StatusRep* r = RepToPointer(rep);
- // Fast path: if ref==1, there is no need for a RefCountDec (since
- // this is the only reference and therefore no other thread is
- // allowed to be mucking with r).
- if (r->ref.load(std::memory_order_acquire) == 1 ||
- r->ref.fetch_sub(1, std::memory_order_acq_rel) - 1 == 0) {
- delete r;
- }
+absl::Nonnull<const std::string*> Status::MovedFromString() {
+ static const absl::NoDestructor<std::string> kMovedFrom(kMovedFromString);
+ return kMovedFrom.get();
}
Status::Status(absl::StatusCode code, absl::string_view msg)
@@ -226,97 +112,20 @@ Status::Status(absl::StatusCode code, absl::string_view msg)
}
}
-int Status::raw_code() const {
- if (IsInlined(rep_)) {
- return static_cast<int>(InlinedRepToCode(rep_));
+absl::Nonnull<status_internal::StatusRep*> Status::PrepareToModify(
+ uintptr_t rep) {
+ if (IsInlined(rep)) {
+ return new status_internal::StatusRep(InlinedRepToCode(rep),
+ absl::string_view(), nullptr);
}
- status_internal::StatusRep* rep = RepToPointer(rep_);
- return static_cast<int>(rep->code);
+ return RepToPointer(rep)->CloneAndUnref();
}
-absl::StatusCode Status::code() const {
- return status_internal::MapToLocalCode(raw_code());
-}
-
-void Status::PrepareToModify() {
- ABSL_RAW_CHECK(!ok(), "PrepareToModify shouldn't be called on OK status.");
- if (IsInlined(rep_)) {
- rep_ = PointerToRep(new status_internal::StatusRep(
- static_cast<absl::StatusCode>(raw_code()), absl::string_view(),
- nullptr));
- return;
+std::string Status::ToStringSlow(uintptr_t rep, StatusToStringMode mode) {
+ if (IsInlined(rep)) {
+ return absl::StrCat(absl::StatusCodeToString(InlinedRepToCode(rep)), ": ");
}
-
- uintptr_t rep_i = rep_;
- status_internal::StatusRep* rep = RepToPointer(rep_);
- if (rep->ref.load(std::memory_order_acquire) != 1) {
- std::unique_ptr<status_internal::Payloads> payloads;
- if (rep->payloads) {
- payloads = absl::make_unique<status_internal::Payloads>(*rep->payloads);
- }
- status_internal::StatusRep* const new_rep = new status_internal::StatusRep(
- rep->code, message(), std::move(payloads));
- rep_ = PointerToRep(new_rep);
- UnrefNonInlined(rep_i);
- }
-}
-
-bool Status::EqualsSlow(const absl::Status& a, const absl::Status& b) {
- if (IsInlined(a.rep_) != IsInlined(b.rep_)) return false;
- if (a.message() != b.message()) return false;
- if (a.raw_code() != b.raw_code()) return false;
- if (a.GetPayloads() == b.GetPayloads()) return true;
-
- const status_internal::Payloads no_payloads;
- const status_internal::Payloads* larger_payloads =
- a.GetPayloads() ? a.GetPayloads() : &no_payloads;
- const status_internal::Payloads* smaller_payloads =
- b.GetPayloads() ? b.GetPayloads() : &no_payloads;
- if (larger_payloads->size() < smaller_payloads->size()) {
- std::swap(larger_payloads, smaller_payloads);
- }
- if ((larger_payloads->size() - smaller_payloads->size()) > 1) return false;
- // Payloads can be ordered differently, so we can't just compare payload
- // vectors.
- for (const auto& payload : *larger_payloads) {
-
- bool found = false;
- for (const auto& other_payload : *smaller_payloads) {
- if (payload.type_url == other_payload.type_url) {
- if (payload.payload != other_payload.payload) {
- return false;
- }
- found = true;
- break;
- }
- }
- if (!found) return false;
- }
- return true;
-}
-
-std::string Status::ToStringSlow(StatusToStringMode mode) const {
- std::string text;
- absl::StrAppend(&text, absl::StatusCodeToString(code()), ": ", message());
-
- const bool with_payload = (mode & StatusToStringMode::kWithPayload) ==
- StatusToStringMode::kWithPayload;
-
- if (with_payload) {
- status_internal::StatusPayloadPrinter printer =
- status_internal::GetStatusPayloadPrinter();
- this->ForEachPayload([&](absl::string_view type_url,
- const absl::Cord& payload) {
- absl::optional<std::string> result;
- if (printer) result = printer(type_url, payload);
- absl::StrAppend(
- &text, " [", type_url, "='",
- result.has_value() ? *result : absl::CHexEscape(std::string(payload)),
- "']");
- });
- }
-
- return text;
+ return RepToPointer(rep)->ToString(mode);
}
std::ostream& operator<<(std::ostream& os, const Status& x) {
@@ -605,18 +414,7 @@ Status ErrnoToStatus(int error_number, absl::string_view message) {
MessageForErrnoToStatus(error_number, message));
}
-namespace status_internal {
-
-std::string* MakeCheckFailString(const absl::Status* status,
- const char* prefix) {
- return new std::string(
- absl::StrCat(prefix, " (",
- status->ToString(StatusToStringMode::kWithEverything), ")"));
-}
-
-} // namespace status_internal
-
-const char* StatusMessageAsCStr(const Status& status) {
+absl::Nonnull<const char*> StatusMessageAsCStr(const Status& status) {
// As an internal implementation detail, we guarantee that if status.message()
// is non-empty, then the resulting string_view is null terminated.
auto sv_message = status.message();
diff --git a/contrib/restricted/abseil-cpp/absl/status/status.h b/contrib/restricted/abseil-cpp/absl/status/status.h
index 595064c0f1..9ce16db961 100644
--- a/contrib/restricted/abseil-cpp/absl/status/status.h
+++ b/contrib/restricted/abseil-cpp/absl/status/status.h
@@ -51,10 +51,17 @@
#ifndef ABSL_STATUS_STATUS_H_
#define ABSL_STATUS_STATUS_H_
+#include <cassert>
+#include <cstdint>
#include <ostream>
#include <string>
#include <utility>
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/base/macros.h"
+#include "absl/base/nullability.h"
+#include "absl/base/optimization.h"
#include "absl/functional/function_ref.h"
#include "absl/status/internal/status_internal.h"
#include "absl/strings/cord.h"
@@ -421,7 +428,7 @@ inline StatusToStringMode& operator^=(StatusToStringMode& lhs,
// Returned Status objects may not be ignored. status_internal.h has a forward
// declaration of the form
// class ABSL_MUST_USE_RESULT Status;
-class Status final {
+class ABSL_ATTRIBUTE_TRIVIAL_ABI Status final {
public:
// Constructors
@@ -516,6 +523,12 @@ class Status final {
std::string ToString(
StatusToStringMode mode = StatusToStringMode::kDefault) const;
+ // Support `absl::StrCat`, `absl::StrFormat`, etc.
+ template <typename Sink>
+ friend void AbslStringify(Sink& sink, const Status& status) {
+ sink.Append(status.ToString(StatusToStringMode::kWithEverything));
+ }
+
// Status::IgnoreError()
//
// Ignores any errors. This method does nothing except potentially suppress
@@ -602,56 +615,57 @@ class Status final {
// code, and an empty error message.
explicit Status(absl::StatusCode code);
- static void UnrefNonInlined(uintptr_t rep);
+ // Underlying constructor for status from a rep_.
+ explicit Status(uintptr_t rep) : rep_(rep) {}
+
static void Ref(uintptr_t rep);
static void Unref(uintptr_t rep);
// REQUIRES: !ok()
- // Ensures rep_ is not shared with any other Status.
- void PrepareToModify();
-
- const status_internal::Payloads* GetPayloads() const;
- status_internal::Payloads* GetPayloads();
-
- static bool EqualsSlow(const absl::Status& a, const absl::Status& b);
+ // Ensures rep is not inlined or shared with any other Status.
+ static absl::Nonnull<status_internal::StatusRep*> PrepareToModify(
+ uintptr_t rep);
// MSVC 14.0 limitation requires the const.
static constexpr const char kMovedFromString[] =
"Status accessed after move.";
- static const std::string* EmptyString();
- static const std::string* MovedFromString();
+ static absl::Nonnull<const std::string*> EmptyString();
+ static absl::Nonnull<const std::string*> MovedFromString();
// Returns whether rep contains an inlined representation.
// See rep_ for details.
- static bool IsInlined(uintptr_t rep);
+ static constexpr bool IsInlined(uintptr_t rep);
// Indicates whether this Status was the rhs of a move operation. See rep_
// for details.
- static bool IsMovedFrom(uintptr_t rep);
- static uintptr_t MovedFromRep();
+ static constexpr bool IsMovedFrom(uintptr_t rep);
+ static constexpr uintptr_t MovedFromRep();
// Convert between error::Code and the inlined uintptr_t representation used
// by rep_. See rep_ for details.
- static uintptr_t CodeToInlinedRep(absl::StatusCode code);
- static absl::StatusCode InlinedRepToCode(uintptr_t rep);
+ static constexpr uintptr_t CodeToInlinedRep(absl::StatusCode code);
+ static constexpr absl::StatusCode InlinedRepToCode(uintptr_t rep);
// 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 status_internal::StatusRep* RepToPointer(uintptr_t r);
+ static absl::Nonnull<const status_internal::StatusRep*> RepToPointer(
+ uintptr_t r);
- std::string ToStringSlow(StatusToStringMode mode) const;
+ static std::string ToStringSlow(uintptr_t rep, StatusToStringMode mode);
// Status supports two different representations.
- // - When the low bit is off it is an inlined representation.
+ // - When the low bit is set it is an inlined representation.
// It uses the canonical error space, no message or payload.
// The error code is (rep_ >> 2).
// The (rep_ & 2) bit is the "moved from" indicator, used in IsMovedFrom().
- // - When the low bit is on it is an external representation.
+ // - When the low bit is off it is an external representation.
// In this case all the data comes from a heap allocated Rep object.
- // (rep_ - 1) is a status_internal::StatusRep* pointer to that structure.
+ // rep_ is a status_internal::StatusRep* pointer to that structure.
uintptr_t rep_;
+
+ friend class status_internal::StatusRep;
};
// OkStatus()
@@ -755,11 +769,11 @@ Status ErrnoToStatus(int error_number, absl::string_view message);
// Implementation details follow
//------------------------------------------------------------------------------
-inline Status::Status() : rep_(CodeToInlinedRep(absl::StatusCode::kOk)) {}
+inline Status::Status() : Status(absl::StatusCode::kOk) {}
-inline Status::Status(absl::StatusCode code) : rep_(CodeToInlinedRep(code)) {}
+inline Status::Status(absl::StatusCode code) : Status(CodeToInlinedRep(code)) {}
-inline Status::Status(const Status& x) : rep_(x.rep_) { Ref(rep_); }
+inline Status::Status(const Status& x) : Status(x.rep_) { Ref(rep_); }
inline Status& Status::operator=(const Status& x) {
uintptr_t old_rep = rep_;
@@ -771,7 +785,7 @@ inline Status& Status::operator=(const Status& x) {
return *this;
}
-inline Status::Status(Status&& x) noexcept : rep_(x.rep_) {
+inline Status::Status(Status&& x) noexcept : Status(x.rep_) {
x.rep_ = MovedFromRep();
}
@@ -803,15 +817,27 @@ inline bool Status::ok() const {
return rep_ == CodeToInlinedRep(absl::StatusCode::kOk);
}
+inline absl::StatusCode Status::code() const {
+ return status_internal::MapToLocalCode(raw_code());
+}
+
+inline int Status::raw_code() const {
+ if (IsInlined(rep_)) return static_cast<int>(InlinedRepToCode(rep_));
+ return static_cast<int>(RepToPointer(rep_)->code());
+}
+
inline absl::string_view Status::message() const {
return !IsInlined(rep_)
- ? RepToPointer(rep_)->message
+ ? RepToPointer(rep_)->message()
: (IsMovedFrom(rep_) ? absl::string_view(kMovedFromString)
: absl::string_view());
}
inline bool operator==(const Status& lhs, const Status& rhs) {
- return lhs.rep_ == rhs.rep_ || Status::EqualsSlow(lhs, rhs);
+ if (lhs.rep_ == rhs.rep_) return true;
+ if (Status::IsInlined(lhs.rep_)) return false;
+ if (Status::IsInlined(rhs.rep_)) return false;
+ return *Status::RepToPointer(lhs.rep_) == *Status::RepToPointer(rhs.rep_);
}
inline bool operator!=(const Status& lhs, const Status& rhs) {
@@ -819,7 +845,7 @@ inline bool operator!=(const Status& lhs, const Status& rhs) {
}
inline std::string Status::ToString(StatusToStringMode mode) const {
- return ok() ? "OK" : ToStringSlow(mode);
+ return ok() ? "OK" : ToStringSlow(rep_, mode);
}
inline void Status::IgnoreError() const {
@@ -831,52 +857,68 @@ inline void swap(absl::Status& a, absl::Status& b) {
swap(a.rep_, b.rep_);
}
-inline const status_internal::Payloads* Status::GetPayloads() const {
- return IsInlined(rep_) ? nullptr : RepToPointer(rep_)->payloads.get();
+inline absl::optional<absl::Cord> Status::GetPayload(
+ absl::string_view type_url) const {
+ if (IsInlined(rep_)) return absl::nullopt;
+ return RepToPointer(rep_)->GetPayload(type_url);
}
-inline status_internal::Payloads* Status::GetPayloads() {
- return IsInlined(rep_) ? nullptr : RepToPointer(rep_)->payloads.get();
+inline void Status::SetPayload(absl::string_view type_url, absl::Cord payload) {
+ if (ok()) return;
+ status_internal::StatusRep* rep = PrepareToModify(rep_);
+ rep->SetPayload(type_url, std::move(payload));
+ rep_ = PointerToRep(rep);
}
-inline bool Status::IsInlined(uintptr_t rep) { return (rep & 1) == 0; }
-
-inline bool Status::IsMovedFrom(uintptr_t rep) {
- return IsInlined(rep) && (rep & 2) != 0;
+inline bool Status::ErasePayload(absl::string_view type_url) {
+ if (IsInlined(rep_)) return false;
+ status_internal::StatusRep* rep = PrepareToModify(rep_);
+ auto res = rep->ErasePayload(type_url);
+ rep_ = res.new_rep;
+ return res.erased;
}
-inline uintptr_t Status::MovedFromRep() {
- return CodeToInlinedRep(absl::StatusCode::kInternal) | 2;
+inline void Status::ForEachPayload(
+ absl::FunctionRef<void(absl::string_view, const absl::Cord&)> visitor)
+ const {
+ if (IsInlined(rep_)) return;
+ RepToPointer(rep_)->ForEachPayload(visitor);
}
-inline uintptr_t Status::CodeToInlinedRep(absl::StatusCode code) {
- return static_cast<uintptr_t>(code) << 2;
+constexpr bool Status::IsInlined(uintptr_t rep) { return (rep & 1) != 0; }
+
+constexpr bool Status::IsMovedFrom(uintptr_t rep) { return (rep & 2) != 0; }
+
+constexpr uintptr_t Status::CodeToInlinedRep(absl::StatusCode code) {
+ return (static_cast<uintptr_t>(code) << 2) + 1;
}
-inline absl::StatusCode Status::InlinedRepToCode(uintptr_t rep) {
- assert(IsInlined(rep));
+constexpr absl::StatusCode Status::InlinedRepToCode(uintptr_t rep) {
+ ABSL_ASSERT(IsInlined(rep));
return static_cast<absl::StatusCode>(rep >> 2);
}
-inline status_internal::StatusRep* Status::RepToPointer(uintptr_t rep) {
+constexpr uintptr_t Status::MovedFromRep() {
+ return CodeToInlinedRep(absl::StatusCode::kInternal) | 2;
+}
+
+inline absl::Nonnull<const status_internal::StatusRep*> Status::RepToPointer(
+ uintptr_t rep) {
assert(!IsInlined(rep));
- return reinterpret_cast<status_internal::StatusRep*>(rep - 1);
+ return reinterpret_cast<const status_internal::StatusRep*>(rep);
}
-inline uintptr_t Status::PointerToRep(status_internal::StatusRep* rep) {
- return reinterpret_cast<uintptr_t>(rep) + 1;
+inline uintptr_t Status::PointerToRep(
+ absl::Nonnull<status_internal::StatusRep*> rep) {
+ return reinterpret_cast<uintptr_t>(rep);
}
inline void Status::Ref(uintptr_t rep) {
- if (!IsInlined(rep)) {
- RepToPointer(rep)->ref.fetch_add(1, std::memory_order_relaxed);
- }
+ if (!IsInlined(rep)) RepToPointer(rep)->Ref();
}
inline void Status::Unref(uintptr_t rep) {
- if (!IsInlined(rep)) {
- UnrefNonInlined(rep);
- }
+ if (!IsInlined(rep)) RepToPointer(rep)->Unref();
}
inline Status OkStatus() { return Status(); }
@@ -892,7 +934,7 @@ inline Status CancelledError() { return Status(absl::StatusCode::kCancelled); }
// If the status's message is empty, the empty string is returned.
//
// StatusMessageAsCStr exists for C support. Use `status.message()` in C++.
-const char* StatusMessageAsCStr(
+absl::Nonnull<const char*> StatusMessageAsCStr(
const Status& status ABSL_ATTRIBUTE_LIFETIME_BOUND);
ABSL_NAMESPACE_END
diff --git a/contrib/restricted/abseil-cpp/absl/status/status_payload_printer.cc b/contrib/restricted/abseil-cpp/absl/status/status_payload_printer.cc
index a47aea11c2..98401e9072 100644
--- a/contrib/restricted/abseil-cpp/absl/status/status_payload_printer.cc
+++ b/contrib/restricted/abseil-cpp/absl/status/status_payload_printer.cc
@@ -13,9 +13,7 @@
// limitations under the License.
#include "absl/status/status_payload_printer.h"
-#include <atomic>
-
-#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/internal/atomic_hook.h"
namespace absl {
diff --git a/contrib/restricted/abseil-cpp/absl/status/status_payload_printer.h b/contrib/restricted/abseil-cpp/absl/status/status_payload_printer.h
index 5e0937f67d..f22255e1c6 100644
--- a/contrib/restricted/abseil-cpp/absl/status/status_payload_printer.h
+++ b/contrib/restricted/abseil-cpp/absl/status/status_payload_printer.h
@@ -16,6 +16,7 @@
#include <string>
+#include "absl/base/nullability.h"
#include "absl/strings/cord.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
@@ -34,8 +35,8 @@ namespace status_internal {
// NOTE: This is an internal API and the design is subject to change in the
// future in a non-backward-compatible way. Since it's only meant for debugging
// purpose, you should not rely on it in any critical logic.
-using StatusPayloadPrinter = absl::optional<std::string> (*)(absl::string_view,
- const absl::Cord&);
+using StatusPayloadPrinter = absl::Nullable<absl::optional<std::string> (*)(
+ absl::string_view, const absl::Cord&)>;
// Sets the global payload printer. Only one printer should be set per process.
// If multiple printers are set, it's undefined which one will be used.
diff --git a/contrib/restricted/abseil-cpp/absl/status/statusor.cc b/contrib/restricted/abseil-cpp/absl/status/statusor.cc
index 96642b340f..7e6b334c74 100644
--- a/contrib/restricted/abseil-cpp/absl/status/statusor.cc
+++ b/contrib/restricted/abseil-cpp/absl/status/statusor.cc
@@ -17,7 +17,10 @@
#include <utility>
#include "absl/base/call_once.h"
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
+#include "absl/base/nullability.h"
+#include "absl/status/internal/statusor_internal.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
@@ -52,7 +55,7 @@ BadStatusOrAccess& BadStatusOrAccess::operator=(BadStatusOrAccess&& other) {
BadStatusOrAccess::BadStatusOrAccess(BadStatusOrAccess&& other)
: status_(std::move(other.status_)) {}
-const char* BadStatusOrAccess::what() const noexcept {
+absl::Nonnull<const char*> BadStatusOrAccess::what() const noexcept {
InitWhat();
return what_.c_str();
}
@@ -67,7 +70,7 @@ void BadStatusOrAccess::InitWhat() const {
namespace internal_statusor {
-void Helper::HandleInvalidStatusCtorArg(absl::Status* status) {
+void Helper::HandleInvalidStatusCtorArg(absl::Nonnull<absl::Status*> status) {
const char* kMessage =
"An OK status is not a valid constructor argument to StatusOr<T>";
#ifdef NDEBUG
diff --git a/contrib/restricted/abseil-cpp/absl/status/statusor.h b/contrib/restricted/abseil-cpp/absl/status/statusor.h
index 54c7ce023f..cd35e5b436 100644
--- a/contrib/restricted/abseil-cpp/absl/status/statusor.h
+++ b/contrib/restricted/abseil-cpp/absl/status/statusor.h
@@ -39,15 +39,20 @@
#include <exception>
#include <initializer_list>
#include <new>
+#include <ostream>
#include <string>
#include <type_traits>
#include <utility>
#include "absl/base/attributes.h"
+#include "absl/base/nullability.h"
#include "absl/base/call_once.h"
#include "absl/meta/type_traits.h"
#include "absl/status/internal/statusor_internal.h"
#include "absl/status/status.h"
+#include "absl/strings/has_absl_stringify.h"
+#include "absl/strings/has_ostream_operator.h"
+#include "absl/strings/str_format.h"
#include "absl/types/variant.h"
#include "absl/utility/utility.h"
@@ -88,7 +93,7 @@ class BadStatusOrAccess : public std::exception {
//
// The pointer of this string is guaranteed to be valid until any non-const
// function is invoked on the exception object.
- const char* what() const noexcept override;
+ absl::Nonnull<const char*> what() const noexcept override;
// BadStatusOrAccess::status()
//
@@ -650,6 +655,41 @@ bool operator!=(const StatusOr<T>& lhs, const StatusOr<T>& rhs) {
return !(lhs == rhs);
}
+// Prints the `value` or the status in brackets to `os`.
+//
+// Requires `T` supports `operator<<`. Do not rely on the output format which
+// may change without notice.
+template <typename T, typename std::enable_if<
+ absl::HasOstreamOperator<T>::value, int>::type = 0>
+std::ostream& operator<<(std::ostream& os, const StatusOr<T>& status_or) {
+ if (status_or.ok()) {
+ os << status_or.value();
+ } else {
+ os << internal_statusor::StringifyRandom::OpenBrackets()
+ << status_or.status()
+ << internal_statusor::StringifyRandom::CloseBrackets();
+ }
+ return os;
+}
+
+// As above, but supports `StrCat`, `StrFormat`, etc.
+//
+// Requires `T` has `AbslStringify`. Do not rely on the output format which
+// may change without notice.
+template <
+ typename Sink, typename T,
+ typename std::enable_if<absl::HasAbslStringify<T>::value, int>::type = 0>
+void AbslStringify(Sink& sink, const StatusOr<T>& status_or) {
+ if (status_or.ok()) {
+ absl::Format(&sink, "%v", status_or.value());
+ } else {
+ absl::Format(&sink, "%s%v%s",
+ internal_statusor::StringifyRandom::OpenBrackets(),
+ status_or.status(),
+ internal_statusor::StringifyRandom::CloseBrackets());
+ }
+}
+
//------------------------------------------------------------------------------
// Implementation details for StatusOr<T>
//------------------------------------------------------------------------------
@@ -750,13 +790,13 @@ T&& StatusOr<T>::operator*() && {
}
template <typename T>
-const T* StatusOr<T>::operator->() const {
+absl::Nonnull<const T*> StatusOr<T>::operator->() const {
this->EnsureOk();
return &this->data_;
}
template <typename T>
-T* StatusOr<T>::operator->() {
+absl::Nonnull<T*> StatusOr<T>::operator->() {
this->EnsureOk();
return &this->data_;
}
diff --git a/contrib/restricted/abseil-cpp/absl/status/ya.make b/contrib/restricted/abseil-cpp/absl/status/ya.make
index f4a990c542..48ab349f07 100644
--- a/contrib/restricted/abseil-cpp/absl/status/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/status/ya.make
@@ -26,6 +26,7 @@ NO_COMPILER_WARNINGS()
NO_UTIL()
SRCS(
+ internal/status_internal.cc
status.cc
status_payload_printer.cc
)
diff --git a/contrib/restricted/abseil-cpp/absl/strings/ascii.cc b/contrib/restricted/abseil-cpp/absl/strings/ascii.cc
index 16c9689961..5460b2c6dc 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/ascii.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/ascii.cc
@@ -15,8 +15,13 @@
#include "absl/strings/ascii.h"
#include <climits>
+#include <cstdint>
#include <cstring>
#include <string>
+#include <type_traits>
+
+#include "absl/base/config.h"
+#include "absl/base/nullability.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -157,8 +162,74 @@ ABSL_DLL const char kToUpper[256] = {
};
// clang-format on
+template <class T>
+static constexpr T BroadcastByte(unsigned char value) {
+ static_assert(std::is_integral<T>::value && sizeof(T) <= sizeof(uint64_t) &&
+ std::is_unsigned<T>::value,
+ "only unsigned integers up to 64-bit allowed");
+ T result = value;
+ constexpr size_t result_bit_width = sizeof(result) * CHAR_BIT;
+ result |= result << ((CHAR_BIT << 0) & (result_bit_width - 1));
+ result |= result << ((CHAR_BIT << 1) & (result_bit_width - 1));
+ result |= result << ((CHAR_BIT << 2) & (result_bit_width - 1));
+ return result;
+}
+
+// Returns whether `c` is in the a-z/A-Z range (w.r.t. `ToUpper`).
+// Implemented by:
+// 1. Pushing the a-z/A-Z range to [SCHAR_MIN, SCHAR_MIN + 26).
+// 2. Comparing to SCHAR_MIN + 26.
+template <bool ToUpper>
+constexpr bool AsciiInAZRange(unsigned char c) {
+ constexpr unsigned char sub = (ToUpper ? 'a' : 'A') - SCHAR_MIN;
+ constexpr signed char threshold = SCHAR_MIN + 26; // 26 = alphabet size.
+ // Using unsigned arithmetic as overflows/underflows are well defined.
+ unsigned char u = c - sub;
+ // Using signed cmp, as SIMD unsigned cmp isn't available in many platforms.
+ return static_cast<signed char>(u) < threshold;
+}
+
template <bool ToUpper>
-constexpr void AsciiStrCaseFold(char* p, char* end) {
+static constexpr char* PartialAsciiStrCaseFold(absl::Nonnull<char*> p,
+ absl::Nonnull<char*> end) {
+ using vec_t = size_t;
+ const size_t n = static_cast<size_t>(end - p);
+
+ // SWAR algorithm: http://0x80.pl/notesen/2016-01-06-swar-swap-case.html
+ constexpr char ch_a = ToUpper ? 'a' : 'A', ch_z = ToUpper ? 'z' : 'Z';
+ char* const swar_end = p + (n / sizeof(vec_t)) * sizeof(vec_t);
+ while (p < swar_end) {
+ vec_t v = vec_t();
+
+ // memcpy the vector, but constexpr
+ for (size_t i = 0; i < sizeof(vec_t); ++i) {
+ v |= static_cast<vec_t>(static_cast<unsigned char>(p[i]))
+ << (i * CHAR_BIT);
+ }
+
+ constexpr unsigned int msb = 1u << (CHAR_BIT - 1);
+ const vec_t v_msb = v & BroadcastByte<vec_t>(msb);
+ const vec_t v_nonascii_mask = (v_msb << 1) - (v_msb >> (CHAR_BIT - 1));
+ const vec_t v_nonascii = v & v_nonascii_mask;
+ const vec_t v_ascii = v & ~v_nonascii_mask;
+ const vec_t a = v_ascii + BroadcastByte<vec_t>(msb - ch_a - 0),
+ z = v_ascii + BroadcastByte<vec_t>(msb - ch_z - 1);
+ v = v_nonascii | (v_ascii ^ ((a ^ z) & BroadcastByte<vec_t>(msb)) >> 2);
+
+ // memcpy the vector, but constexpr
+ for (size_t i = 0; i < sizeof(vec_t); ++i) {
+ p[i] = static_cast<char>(v >> (i * CHAR_BIT));
+ }
+
+ p += sizeof(v);
+ }
+
+ return p;
+}
+
+template <bool ToUpper>
+static constexpr void AsciiStrCaseFold(absl::Nonnull<char*> p,
+ absl::Nonnull<char*> end) {
// 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
@@ -166,16 +237,17 @@ constexpr void AsciiStrCaseFold(char* p, char* end) {
// have the same single bit difference.
constexpr unsigned char kAsciiCaseBitFlip = 'a' ^ 'A';
- constexpr char ch_a = ToUpper ? 'a' : 'A';
- constexpr char ch_z = ToUpper ? 'z' : 'Z';
- for (; p < end; ++p) {
+ using vec_t = size_t;
+ // TODO(b/316380338): When FDO becomes able to vectorize these,
+ // revert this manual optimization and just leave the naive loop.
+ if (static_cast<size_t>(end - p) >= sizeof(vec_t)) {
+ p = ascii_internal::PartialAsciiStrCaseFold<ToUpper>(p, end);
+ }
+ while (p < end) {
unsigned char v = static_cast<unsigned char>(*p);
- // We use & instead of && to ensure this always stays branchless
- // We use static_cast<int> to suppress -Wbitwise-instead-of-logical
- bool is_in_range = static_cast<bool>(static_cast<int>(ch_a <= v) &
- static_cast<int>(v <= ch_z));
- v ^= is_in_range ? kAsciiCaseBitFlip : 0;
+ v ^= AsciiInAZRange<ToUpper>(v) ? kAsciiCaseBitFlip : 0;
*p = static_cast<char>(v);
+ ++p;
}
}
@@ -205,17 +277,17 @@ static_assert(ValidateAsciiCasefold() == 0, "error in case conversion");
} // namespace ascii_internal
-void AsciiStrToLower(std::string* s) {
+void AsciiStrToLower(absl::Nonnull<std::string*> s) {
char* p = &(*s)[0]; // Guaranteed to be valid for empty strings
return ascii_internal::AsciiStrCaseFold<false>(p, p + s->size());
}
-void AsciiStrToUpper(std::string* s) {
+void AsciiStrToUpper(absl::Nonnull<std::string*> s) {
char* p = &(*s)[0]; // Guaranteed to be valid for empty strings
return ascii_internal::AsciiStrCaseFold<true>(p, p + s->size());
}
-void RemoveExtraAsciiWhitespace(std::string* str) {
+void RemoveExtraAsciiWhitespace(absl::Nonnull<std::string*> str) {
auto stripped = StripAsciiWhitespace(*str);
if (stripped.empty()) {
diff --git a/contrib/restricted/abseil-cpp/absl/strings/ascii.h b/contrib/restricted/abseil-cpp/absl/strings/ascii.h
index 42eadaea6c..c238f4de82 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/ascii.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/ascii.h
@@ -53,10 +53,12 @@
#define ABSL_STRINGS_ASCII_H_
#include <algorithm>
+#include <cstddef>
#include <string>
#include "absl/base/attributes.h"
#include "absl/base/config.h"
+#include "absl/base/nullability.h"
#include "absl/strings/string_view.h"
namespace absl {
@@ -165,7 +167,7 @@ inline char ascii_tolower(unsigned char c) {
}
// Converts the characters in `s` to lowercase, changing the contents of `s`.
-void AsciiStrToLower(std::string* s);
+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) {
@@ -183,7 +185,7 @@ inline char ascii_toupper(unsigned char c) {
}
// Converts the characters in `s` to uppercase, changing the contents of `s`.
-void AsciiStrToUpper(std::string* s);
+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) {
@@ -201,7 +203,7 @@ ABSL_MUST_USE_RESULT inline absl::string_view StripLeadingAsciiWhitespace(
}
// Strips in place whitespace from the beginning of the given string.
-inline void StripLeadingAsciiWhitespace(std::string* str) {
+inline void StripLeadingAsciiWhitespace(absl::Nonnull<std::string*> str) {
auto it = std::find_if_not(str->begin(), str->end(), absl::ascii_isspace);
str->erase(str->begin(), it);
}
@@ -215,7 +217,7 @@ ABSL_MUST_USE_RESULT inline absl::string_view StripTrailingAsciiWhitespace(
}
// Strips in place whitespace from the end of the given string
-inline void StripTrailingAsciiWhitespace(std::string* str) {
+inline void StripTrailingAsciiWhitespace(absl::Nonnull<std::string*> str) {
auto it = std::find_if_not(str->rbegin(), str->rend(), absl::ascii_isspace);
str->erase(static_cast<size_t>(str->rend() - it));
}
@@ -228,13 +230,13 @@ ABSL_MUST_USE_RESULT inline absl::string_view StripAsciiWhitespace(
}
// Strips in place whitespace from both ends of the given string
-inline void StripAsciiWhitespace(std::string* str) {
+inline void StripAsciiWhitespace(absl::Nonnull<std::string*> str) {
StripTrailingAsciiWhitespace(str);
StripLeadingAsciiWhitespace(str);
}
// Removes leading, trailing, and consecutive internal whitespace.
-void RemoveExtraAsciiWhitespace(std::string*);
+void RemoveExtraAsciiWhitespace(absl::Nonnull<std::string*> str);
ABSL_NAMESPACE_END
} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/strings/charconv.cc b/contrib/restricted/abseil-cpp/absl/strings/charconv.cc
index 778a1c75a5..0c9227f849 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/charconv.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/charconv.cc
@@ -16,12 +16,14 @@
#include <algorithm>
#include <cassert>
-#include <cmath>
-#include <cstring>
+#include <cstddef>
+#include <cstdint>
#include <limits>
+#include <system_error> // NOLINT(build/c++11)
#include "absl/base/casts.h"
#include "absl/base/config.h"
+#include "absl/base/nullability.h"
#include "absl/numeric/bits.h"
#include "absl/numeric/int128.h"
#include "absl/strings/internal/charconv_bigint.h"
@@ -118,7 +120,7 @@ struct FloatTraits<double> {
// Parsing a smaller N will produce something finite.
static constexpr int kEiselLemireMaxExclusiveExp10 = 309;
- static double MakeNan(const char* tagp) {
+ static double MakeNan(absl::Nonnull<const char*> tagp) {
#if ABSL_HAVE_BUILTIN(__builtin_nan)
// Use __builtin_nan() if available since it has a fix for
// https://bugs.llvm.org/show_bug.cgi?id=37778
@@ -191,7 +193,7 @@ struct FloatTraits<float> {
static constexpr int kEiselLemireMinInclusiveExp10 = -46 - 18;
static constexpr int kEiselLemireMaxExclusiveExp10 = 39;
- static float MakeNan(const char* tagp) {
+ static float MakeNan(absl::Nonnull<const char*> tagp) {
#if ABSL_HAVE_BUILTIN(__builtin_nanf)
// Use __builtin_nanf() if available since it has a fix for
// https://bugs.llvm.org/show_bug.cgi?id=37778
@@ -343,7 +345,7 @@ int NormalizedShiftSize(int mantissa_width, int binary_exponent) {
// `value` must be wider than the requested bit width.
//
// Returns the number of bits shifted.
-int TruncateToBitWidth(int bit_width, uint128* value) {
+int TruncateToBitWidth(int bit_width, absl::Nonnull<uint128*> value) {
const int current_bit_width = BitWidth(*value);
const int shift = current_bit_width - bit_width;
*value >>= shift;
@@ -355,7 +357,7 @@ int TruncateToBitWidth(int bit_width, uint128* value) {
// the appropriate double, and returns true.
template <typename FloatType>
bool HandleEdgeCase(const strings_internal::ParsedFloat& input, bool negative,
- FloatType* value) {
+ 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
@@ -404,7 +406,8 @@ bool HandleEdgeCase(const strings_internal::ParsedFloat& input, bool negative,
// number is stored in *value.
template <typename FloatType>
void EncodeResult(const CalculatedFloat& calculated, bool negative,
- absl::from_chars_result* result, FloatType* value) {
+ absl::Nonnull<absl::from_chars_result*> result,
+ absl::Nonnull<FloatType*> value) {
if (calculated.exponent == kOverflow) {
result->ec = std::errc::result_out_of_range;
*value = negative ? -std::numeric_limits<FloatType>::max()
@@ -450,7 +453,7 @@ void EncodeResult(const CalculatedFloat& calculated, bool negative,
// Zero and negative values of `shift` are accepted, in which case the word is
// shifted left, as necessary.
uint64_t ShiftRightAndRound(uint128 value, int shift, bool input_exact,
- bool* output_exact) {
+ absl::Nonnull<bool*> output_exact) {
if (shift <= 0) {
*output_exact = input_exact;
return static_cast<uint64_t>(value << -shift);
@@ -684,7 +687,8 @@ CalculatedFloat CalculateFromParsedDecimal(
// this function returns false) is both fast and correct.
template <typename FloatType>
bool EiselLemire(const strings_internal::ParsedFloat& input, bool negative,
- FloatType* value, std::errc* ec) {
+ absl::Nonnull<FloatType*> value,
+ absl::Nonnull<std::errc*> ec) {
uint64_t man = input.mantissa;
int exp10 = input.exponent;
if (exp10 < FloatTraits<FloatType>::kEiselLemireMinInclusiveExp10) {
@@ -857,7 +861,8 @@ bool EiselLemire(const strings_internal::ParsedFloat& input, bool negative,
}
template <typename FloatType>
-from_chars_result FromCharsImpl(const char* first, const char* last,
+from_chars_result FromCharsImpl(absl::Nonnull<const char*> first,
+ absl::Nonnull<const char*> last,
FloatType& value, chars_format fmt_flags) {
from_chars_result result;
result.ptr = first; // overwritten on successful parse
@@ -943,12 +948,14 @@ from_chars_result FromCharsImpl(const char* first, const char* last,
}
} // namespace
-from_chars_result from_chars(const char* first, const char* last, double& value,
+from_chars_result from_chars(absl::Nonnull<const char*> first,
+ absl::Nonnull<const char*> last, double& value,
chars_format fmt) {
return FromCharsImpl(first, last, value, fmt);
}
-from_chars_result from_chars(const char* first, const char* last, float& value,
+from_chars_result from_chars(absl::Nonnull<const char*> first,
+ absl::Nonnull<const char*> last, float& value,
chars_format fmt) {
return FromCharsImpl(first, last, value, fmt);
}
diff --git a/contrib/restricted/abseil-cpp/absl/strings/charconv.h b/contrib/restricted/abseil-cpp/absl/strings/charconv.h
index 111c7120de..be250902ad 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/charconv.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/charconv.h
@@ -18,6 +18,7 @@
#include <system_error> // NOLINT(build/c++11)
#include "absl/base/config.h"
+#include "absl/base/nullability.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -44,7 +45,7 @@ enum class chars_format {
// characters that were successfully parsed. If none was found, `ptr` is set
// to the `first` argument to from_chars.
struct from_chars_result {
- const char* ptr;
+ absl::Nonnull<const char*> ptr;
std::errc ec;
};
@@ -76,11 +77,13 @@ struct from_chars_result {
// format that strtod() accepts, except that a "0x" prefix is NOT matched.
// (In particular, in `hex` mode, the input "0xff" results in the largest
// matching pattern "0".)
-absl::from_chars_result from_chars(const char* first, const char* last,
+absl::from_chars_result from_chars(absl::Nonnull<const char*> first,
+ absl::Nonnull<const char*> last,
double& value, // NOLINT
chars_format fmt = chars_format::general);
-absl::from_chars_result from_chars(const char* first, const char* last,
+absl::from_chars_result from_chars(absl::Nonnull<const char*> first,
+ absl::Nonnull<const char*> last,
float& value, // NOLINT
chars_format fmt = chars_format::general);
diff --git a/contrib/restricted/abseil-cpp/absl/strings/charset.h b/contrib/restricted/abseil-cpp/absl/strings/charset.h
new file mode 100644
index 0000000000..ff4e81a41f
--- /dev/null
+++ b/contrib/restricted/abseil-cpp/absl/strings/charset.h
@@ -0,0 +1,164 @@
+// Copyright 2022 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: charset.h
+// -----------------------------------------------------------------------------
+//
+// This file contains absl::CharSet, a fast, bit-vector set of 8-bit unsigned
+// characters.
+//
+// Instances can be initialized as constexpr constants. For example:
+//
+// constexpr absl::CharSet kJustX = absl::CharSet::Char('x');
+// constexpr absl::CharSet kMySymbols = absl::CharSet("$@!");
+// constexpr absl::CharSet kLetters = absl::CharSet::Range('a', 'z');
+//
+// Multiple instances can be combined that still forms a constexpr expression.
+// For example:
+//
+// constexpr absl::CharSet kLettersAndNumbers =
+// absl::CharSet::Range('a', 'z') | absl::CharSet::Range('0', '9');
+//
+// Several pre-defined character classes are available that mirror the methods
+// from <cctype>. For example:
+//
+// constexpr absl::CharSet kLettersAndWhitespace =
+// absl::CharSet::AsciiAlphabet() | absl::CharSet::AsciiWhitespace();
+//
+// To check membership, use the .contains method, e.g.
+//
+// absl::CharSet hex_letters("abcdef");
+// hex_letters.contains('a'); // true
+// hex_letters.contains('g'); // false
+
+#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/strings/string_view.h"
+
+namespace absl {
+
+class CharSet {
+ public:
+ constexpr CharSet() : m_() {}
+
+ // Initializes with a given string_view.
+ constexpr explicit CharSet(absl::string_view str) : m_() {
+ for (char c : str) {
+ SetChar(static_cast<unsigned char>(c));
+ }
+ }
+
+ constexpr bool contains(char c) const {
+ return ((m_[static_cast<unsigned char>(c) / 64] >>
+ (static_cast<unsigned char>(c) % 64)) &
+ 0x1) == 0x1;
+ }
+
+ constexpr bool empty() const {
+ for (uint64_t c : m_) {
+ if (c != 0) return false;
+ }
+ return true;
+ }
+
+ // Containing only a single specified char.
+ static constexpr CharSet Char(char x) {
+ return CharSet(CharMaskForWord(x, 0), CharMaskForWord(x, 1),
+ CharMaskForWord(x, 2), CharMaskForWord(x, 3));
+ }
+
+ // Containing all the chars in the closed interval [lo,hi].
+ static constexpr CharSet Range(char lo, char hi) {
+ return CharSet(RangeForWord(lo, hi, 0), RangeForWord(lo, hi, 1),
+ RangeForWord(lo, hi, 2), RangeForWord(lo, hi, 3));
+ }
+
+ friend constexpr CharSet operator&(const CharSet& a, const CharSet& b) {
+ return CharSet(a.m_[0] & b.m_[0], a.m_[1] & b.m_[1], a.m_[2] & b.m_[2],
+ a.m_[3] & b.m_[3]);
+ }
+
+ friend constexpr CharSet operator|(const CharSet& a, const CharSet& b) {
+ return CharSet(a.m_[0] | b.m_[0], a.m_[1] | b.m_[1], a.m_[2] | b.m_[2],
+ a.m_[3] | b.m_[3]);
+ }
+
+ friend constexpr CharSet operator~(const CharSet& a) {
+ return CharSet(~a.m_[0], ~a.m_[1], ~a.m_[2], ~a.m_[3]);
+ }
+
+ // Mirrors the char-classifying predicates in <cctype>.
+ static constexpr CharSet AsciiUppercase() { return CharSet::Range('A', 'Z'); }
+ static constexpr CharSet AsciiLowercase() { return CharSet::Range('a', 'z'); }
+ static constexpr CharSet AsciiDigits() { return CharSet::Range('0', '9'); }
+ static constexpr CharSet AsciiAlphabet() {
+ return AsciiLowercase() | AsciiUppercase();
+ }
+ static constexpr CharSet AsciiAlphanumerics() {
+ return AsciiDigits() | AsciiAlphabet();
+ }
+ static constexpr CharSet AsciiHexDigits() {
+ return AsciiDigits() | CharSet::Range('A', 'F') | CharSet::Range('a', 'f');
+ }
+ static constexpr CharSet AsciiPrintable() {
+ return CharSet::Range(0x20, 0x7e);
+ }
+ static constexpr CharSet AsciiWhitespace() { return CharSet("\t\n\v\f\r "); }
+ static constexpr CharSet AsciiPunctuation() {
+ return AsciiPrintable() & ~AsciiWhitespace() & ~AsciiAlphanumerics();
+ }
+
+ private:
+ constexpr CharSet(uint64_t b0, uint64_t b1, uint64_t b2, uint64_t b3)
+ : m_{b0, b1, b2, b3} {}
+
+ static constexpr uint64_t RangeForWord(char lo, char hi, uint64_t word) {
+ return OpenRangeFromZeroForWord(static_cast<unsigned char>(hi) + 1, word) &
+ ~OpenRangeFromZeroForWord(static_cast<unsigned char>(lo), word);
+ }
+
+ // All the chars in the specified word of the range [0, upper).
+ static constexpr uint64_t OpenRangeFromZeroForWord(uint64_t upper,
+ uint64_t word) {
+ return (upper <= 64 * word) ? 0
+ : (upper >= 64 * (word + 1))
+ ? ~static_cast<uint64_t>(0)
+ : (~static_cast<uint64_t>(0) >> (64 - upper % 64));
+ }
+
+ static constexpr uint64_t CharMaskForWord(char x, uint64_t word) {
+ return (static_cast<unsigned char>(x) / 64 == word)
+ ? (static_cast<uint64_t>(1)
+ << (static_cast<unsigned char>(x) % 64))
+ : 0;
+ }
+
+ constexpr void SetChar(unsigned char c) {
+ m_[c / 64] |= static_cast<uint64_t>(1) << (c % 64);
+ }
+
+ uint64_t m_[4];
+};
+
+} // namespace absl
+
+#endif // ABSL_STRINGS_CHARSET_H_
diff --git a/contrib/restricted/abseil-cpp/absl/strings/cord.cc b/contrib/restricted/abseil-cpp/absl/strings/cord.cc
index 14976aef58..f67326fdef 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/cord.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/cord.cc
@@ -15,27 +15,33 @@
#include "absl/strings/cord.h"
#include <algorithm>
-#include <atomic>
+#include <cassert>
#include <cstddef>
+#include <cstdint>
#include <cstdio>
#include <cstdlib>
+#include <cstring>
#include <iomanip>
#include <ios>
#include <iostream>
#include <limits>
+#include <memory>
#include <ostream>
#include <sstream>
-#include <type_traits>
-#include <unordered_set>
-#include <vector>
+#include <string>
+#include <utility>
-#include "absl/base/casts.h"
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/base/internal/endian.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/macros.h"
-#include "absl/base/port.h"
-#include "absl/container/fixed_array.h"
+#include "absl/base/optimization.h"
+#include "absl/base/nullability.h"
#include "absl/container/inlined_vector.h"
+#include "absl/crc/crc32c.h"
#include "absl/crc/internal/crc_cord_state.h"
+#include "absl/functional/function_ref.h"
#include "absl/strings/cord_buffer.h"
#include "absl/strings/escaping.h"
#include "absl/strings/internal/cord_data_edge.h"
@@ -43,13 +49,14 @@
#include "absl/strings/internal/cord_rep_btree.h"
#include "absl/strings/internal/cord_rep_crc.h"
#include "absl/strings/internal/cord_rep_flat.h"
-#include "absl/strings/internal/cordz_statistics.h"
-#include "absl/strings/internal/cordz_update_scope.h"
#include "absl/strings/internal/cordz_update_tracker.h"
#include "absl/strings/internal/resize_uninitialized.h"
+#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
-#include "absl/strings/str_join.h"
#include "absl/strings/string_view.h"
+#include "absl/strings/strip.h"
+#include "absl/types/optional.h"
+#include "absl/types/span.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -68,29 +75,21 @@ using ::absl::cord_internal::kMinFlatLength;
using ::absl::cord_internal::kInlinedVectorSize;
using ::absl::cord_internal::kMaxBytesToCopy;
-static void DumpNode(CordRep* rep, bool include_data, std::ostream* os,
- int indent = 0);
-static bool VerifyNode(CordRep* root, CordRep* start_node,
- bool full_validation);
-
-static inline CordRep* VerifyTree(CordRep* node) {
- // Verification is expensive, so only do it in debug mode.
- // Even in debug mode we normally do only light validation.
- // If you are debugging Cord itself, you should define the
- // macro EXTRA_CORD_VALIDATION, e.g. by adding
- // --copt=-DEXTRA_CORD_VALIDATION to the blaze line.
-#ifdef EXTRA_CORD_VALIDATION
- assert(node == nullptr || VerifyNode(node, node, /*full_validation=*/true));
-#else // EXTRA_CORD_VALIDATION
- assert(node == nullptr || VerifyNode(node, node, /*full_validation=*/false));
-#endif // EXTRA_CORD_VALIDATION
- static_cast<void>(&VerifyNode);
+static void DumpNode(absl::Nonnull<CordRep*> rep, bool include_data,
+ absl::Nonnull<std::ostream*> os, int indent = 0);
+static bool VerifyNode(absl::Nonnull<CordRep*> root,
+ absl::Nonnull<CordRep*> start_node);
+static inline absl::Nullable<CordRep*> VerifyTree(
+ absl::Nullable<CordRep*> node) {
+ assert(node == nullptr || VerifyNode(node, node));
+ static_cast<void>(&VerifyNode);
return node;
}
-static CordRepFlat* CreateFlat(const char* data, size_t length,
- size_t alloc_hint) {
+static absl::Nonnull<CordRepFlat*> CreateFlat(absl::Nonnull<const char*> data,
+ size_t length,
+ size_t alloc_hint) {
CordRepFlat* flat = CordRepFlat::New(length + alloc_hint);
flat->length = length;
memcpy(flat->Data(), data, length);
@@ -99,7 +98,8 @@ static CordRepFlat* CreateFlat(const char* data, size_t length,
// Creates a new flat or Btree out of the specified array.
// The returned node has a refcount of 1.
-static CordRep* NewBtree(const char* data, size_t length, size_t alloc_hint) {
+static absl::Nonnull<CordRep*> NewBtree(absl::Nonnull<const char*> data,
+ size_t length, size_t alloc_hint) {
if (length <= kMaxFlatLength) {
return CreateFlat(data, length, alloc_hint);
}
@@ -112,14 +112,16 @@ static CordRep* NewBtree(const char* data, size_t length, size_t alloc_hint) {
// Create a new tree out of the specified array.
// The returned node has a refcount of 1.
-static CordRep* NewTree(const char* data, size_t length, size_t alloc_hint) {
+static absl::Nullable<CordRep*> NewTree(absl::Nullable<const char*> data,
+ size_t length, size_t alloc_hint) {
if (length == 0) return nullptr;
return NewBtree(data, length, alloc_hint);
}
namespace cord_internal {
-void InitializeCordRepExternal(absl::string_view data, CordRepExternal* rep) {
+void InitializeCordRepExternal(absl::string_view data,
+ absl::Nonnull<CordRepExternal*> rep) {
assert(!data.empty());
rep->length = data.size();
rep->tag = EXTERNAL;
@@ -133,7 +135,7 @@ void InitializeCordRepExternal(absl::string_view data, CordRepExternal* rep) {
// and not wasteful, we move the string into an external cord rep, preserving
// the already allocated string contents.
// Requires the provided string length to be larger than `kMaxInline`.
-static CordRep* CordRepFromString(std::string&& src) {
+static absl::Nonnull<CordRep*> CordRepFromString(std::string&& src) {
assert(src.length() > cord_internal::kMaxInline);
if (
// String is short: copy data to avoid external block overhead.
@@ -165,12 +167,13 @@ static CordRep* CordRepFromString(std::string&& src) {
constexpr unsigned char Cord::InlineRep::kMaxInline;
#endif
-inline void Cord::InlineRep::set_data(const char* data, size_t n) {
+inline void Cord::InlineRep::set_data(absl::Nonnull<const char*> data,
+ size_t n) {
static_assert(kMaxInline == 15, "set_data is hard-coded for a length of 15");
data_.set_inline_data(data, n);
}
-inline char* Cord::InlineRep::set_data(size_t n) {
+inline absl::Nonnull<char*> Cord::InlineRep::set_data(size_t n) {
assert(n <= kMaxInline);
ResetToEmpty();
set_inline_size(n);
@@ -194,13 +197,13 @@ inline void Cord::InlineRep::remove_prefix(size_t n) {
// Returns `rep` converted into a CordRepBtree.
// Directly returns `rep` if `rep` is already a CordRepBtree.
-static CordRepBtree* ForceBtree(CordRep* rep) {
+static absl::Nonnull<CordRepBtree*> ForceBtree(CordRep* rep) {
return rep->IsBtree()
? rep->btree()
: CordRepBtree::Create(cord_internal::RemoveCrcNode(rep));
}
-void Cord::InlineRep::AppendTreeToInlined(CordRep* tree,
+void Cord::InlineRep::AppendTreeToInlined(absl::Nonnull<CordRep*> tree,
MethodIdentifier method) {
assert(!is_tree());
if (!data_.is_empty()) {
@@ -210,14 +213,16 @@ void Cord::InlineRep::AppendTreeToInlined(CordRep* tree,
EmplaceTree(tree, method);
}
-void Cord::InlineRep::AppendTreeToTree(CordRep* tree, MethodIdentifier method) {
+void Cord::InlineRep::AppendTreeToTree(absl::Nonnull<CordRep*> tree,
+ MethodIdentifier method) {
assert(is_tree());
const CordzUpdateScope scope(data_.cordz_info(), method);
tree = CordRepBtree::Append(ForceBtree(data_.as_tree()), tree);
SetTree(tree, scope);
}
-void Cord::InlineRep::AppendTree(CordRep* tree, MethodIdentifier method) {
+void Cord::InlineRep::AppendTree(absl::Nonnull<CordRep*> tree,
+ MethodIdentifier method) {
assert(tree != nullptr);
assert(tree->length != 0);
assert(!tree->IsCrc());
@@ -228,7 +233,7 @@ void Cord::InlineRep::AppendTree(CordRep* tree, MethodIdentifier method) {
}
}
-void Cord::InlineRep::PrependTreeToInlined(CordRep* tree,
+void Cord::InlineRep::PrependTreeToInlined(absl::Nonnull<CordRep*> tree,
MethodIdentifier method) {
assert(!is_tree());
if (!data_.is_empty()) {
@@ -238,7 +243,7 @@ void Cord::InlineRep::PrependTreeToInlined(CordRep* tree,
EmplaceTree(tree, method);
}
-void Cord::InlineRep::PrependTreeToTree(CordRep* tree,
+void Cord::InlineRep::PrependTreeToTree(absl::Nonnull<CordRep*> tree,
MethodIdentifier method) {
assert(is_tree());
const CordzUpdateScope scope(data_.cordz_info(), method);
@@ -246,7 +251,8 @@ void Cord::InlineRep::PrependTreeToTree(CordRep* tree,
SetTree(tree, scope);
}
-void Cord::InlineRep::PrependTree(CordRep* tree, MethodIdentifier method) {
+void Cord::InlineRep::PrependTree(absl::Nonnull<CordRep*> tree,
+ MethodIdentifier method) {
assert(tree != nullptr);
assert(tree->length != 0);
assert(!tree->IsCrc());
@@ -261,8 +267,9 @@ void Cord::InlineRep::PrependTree(CordRep* tree, MethodIdentifier method) {
// suitable leaf is found, the function will update the length field for all
// nodes to account for the size increase. The append region address will be
// written to region and the actual size increase will be written to size.
-static inline bool PrepareAppendRegion(CordRep* root, char** region,
- size_t* size, size_t max_length) {
+static inline bool PrepareAppendRegion(
+ absl::Nonnull<CordRep*> root, absl::Nonnull<absl::Nullable<char*>*> region,
+ absl::Nonnull<size_t*> size, size_t max_length) {
if (root->IsBtree() && root->refcount.IsOne()) {
Span<char> span = root->btree()->GetAppendBuffer(max_length);
if (!span.empty()) {
@@ -465,11 +472,11 @@ void Cord::InlineRep::AppendArray(absl::string_view src,
CommitTree(root, rep, scope, method);
}
-inline CordRep* Cord::TakeRep() const& {
+inline absl::Nonnull<CordRep*> Cord::TakeRep() const& {
return CordRep::Ref(contents_.tree());
}
-inline CordRep* Cord::TakeRep() && {
+inline absl::Nonnull<CordRep*> Cord::TakeRep() && {
CordRep* rep = contents_.tree();
contents_.clear();
return rep;
@@ -527,7 +534,7 @@ inline void Cord::AppendImpl(C&& src) {
contents_.AppendTree(rep, CordzUpdateTracker::kAppendCord);
}
-static CordRep::ExtractResult ExtractAppendBuffer(CordRep* rep,
+static CordRep::ExtractResult ExtractAppendBuffer(absl::Nonnull<CordRep*> rep,
size_t min_capacity) {
switch (rep->tag) {
case cord_internal::BTREE:
@@ -573,13 +580,9 @@ CordBuffer Cord::GetAppendBufferSlowPath(size_t block_size, size_t capacity,
return CreateAppendBuffer(contents_.data_, block_size, capacity);
}
-void Cord::Append(const Cord& src) {
- AppendImpl(src);
-}
+void Cord::Append(const Cord& src) { AppendImpl(src); }
-void Cord::Append(Cord&& src) {
- AppendImpl(std::move(src));
-}
+void Cord::Append(Cord&& src) { AppendImpl(std::move(src)); }
template <typename T, Cord::EnableIfString<T>>
void Cord::Append(T&& src) {
@@ -778,8 +781,9 @@ int ClampResult(int memcmp_res) {
return static_cast<int>(memcmp_res > 0) - static_cast<int>(memcmp_res < 0);
}
-int CompareChunks(absl::string_view* lhs, absl::string_view* rhs,
- size_t* size_to_compare) {
+int CompareChunks(absl::Nonnull<absl::string_view*> lhs,
+ absl::Nonnull<absl::string_view*> rhs,
+ absl::Nonnull<size_t*> size_to_compare) {
size_t compared_size = std::min(lhs->size(), rhs->size());
assert(*size_to_compare >= compared_size);
*size_to_compare -= compared_size;
@@ -877,7 +881,8 @@ void Cord::SetExpectedChecksum(uint32_t crc) {
SetCrcCordState(std::move(state));
}
-const crc_internal::CrcCordState* Cord::MaybeGetCrcCordState() const {
+absl::Nullable<const crc_internal::CrcCordState*> Cord::MaybeGetCrcCordState()
+ const {
if (!contents_.is_tree() || !contents_.tree()->IsCrc()) {
return nullptr;
}
@@ -894,7 +899,8 @@ absl::optional<uint32_t> Cord::ExpectedChecksum() const {
inline int Cord::CompareSlowPath(absl::string_view rhs, size_t compared_size,
size_t size_to_compare) const {
- auto advance = [](Cord::ChunkIterator* it, absl::string_view* chunk) {
+ auto advance = [](absl::Nonnull<Cord::ChunkIterator*> it,
+ absl::Nonnull<absl::string_view*> chunk) {
if (!chunk->empty()) return true;
++*it;
if (it->bytes_remaining_ == 0) return false;
@@ -924,7 +930,8 @@ inline int Cord::CompareSlowPath(absl::string_view rhs, size_t compared_size,
inline int Cord::CompareSlowPath(const Cord& rhs, size_t compared_size,
size_t size_to_compare) const {
- auto advance = [](Cord::ChunkIterator* it, absl::string_view* chunk) {
+ auto advance = [](absl::Nonnull<Cord::ChunkIterator*> it,
+ absl::Nonnull<absl::string_view*> chunk) {
if (!chunk->empty()) return true;
++*it;
if (it->bytes_remaining_ == 0) return false;
@@ -1046,7 +1053,7 @@ Cord::operator std::string() const {
return s;
}
-void CopyCordToString(const Cord& src, std::string* dst) {
+void CopyCordToString(const Cord& src, absl::Nonnull<std::string*> dst) {
if (!src.contents_.is_tree()) {
src.contents_.CopyTo(dst);
} else {
@@ -1055,7 +1062,7 @@ void CopyCordToString(const Cord& src, std::string* dst) {
}
}
-void Cord::CopyToArraySlowPath(char* dst) const {
+void Cord::CopyToArraySlowPath(absl::Nonnull<char*> dst) const {
assert(contents_.is_tree());
absl::string_view fragment;
if (GetFlatAux(contents_.tree(), &fragment)) {
@@ -1165,6 +1172,194 @@ char Cord::operator[](size_t i) const {
}
}
+namespace {
+
+// Tests whether the sequence of chunks beginning at `position` starts with
+// `needle`.
+//
+// REQUIRES: remaining `absl::Cord` starting at `position` is greater than or
+// equal to `needle.size()`.
+bool IsSubstringInCordAt(absl::Cord::CharIterator position,
+ absl::string_view needle) {
+ auto haystack_chunk = absl::Cord::ChunkRemaining(position);
+ while (true) {
+ // Precondition is that `absl::Cord::ChunkRemaining(position)` is not
+ // empty. This assert will trigger if that is not true.
+ assert(!haystack_chunk.empty());
+ auto min_length = std::min(haystack_chunk.size(), needle.size());
+ if (!absl::ConsumePrefix(&needle, haystack_chunk.substr(0, min_length))) {
+ return false;
+ }
+ if (needle.empty()) {
+ return true;
+ }
+ absl::Cord::Advance(&position, min_length);
+ haystack_chunk = absl::Cord::ChunkRemaining(position);
+ }
+}
+
+} // namespace
+
+// A few options how this could be implemented:
+// (a) Flatten the Cord and find, i.e.
+// haystack.Flatten().find(needle)
+// For large 'haystack' (where Cord makes sense to be used), this copies
+// the whole 'haystack' and can be slow.
+// (b) Use std::search, i.e.
+// std::search(haystack.char_begin(), haystack.char_end(),
+// needle.begin(), needle.end())
+// This avoids the copy, but compares one byte at a time, and branches a
+// lot every time it has to advance. It is also not possible to use
+// std::search as is, because CharIterator is only an input iterator, not a
+// forward iterator.
+// (c) Use string_view::find in each fragment, and specifically handle fragment
+// boundaries.
+//
+// This currently implements option (b).
+absl::Cord::CharIterator absl::Cord::FindImpl(CharIterator it,
+ absl::string_view needle) const {
+ // Ensure preconditions are met by callers first.
+
+ // Needle must not be empty.
+ assert(!needle.empty());
+ // Haystack must be at least as large as needle.
+ assert(it.chunk_iterator_.bytes_remaining_ >= needle.size());
+
+ // Cord is a sequence of chunks. To find `needle` we go chunk by chunk looking
+ // for the first char of needle, up until we have advanced `N` defined as
+ // `haystack.size() - needle.size()`. If we find the first char of needle at
+ // `P` and `P` is less than `N`, we then call `IsSubstringInCordAt` to
+ // see if this is the needle. If not, we advance to `P + 1` and try again.
+ while (it.chunk_iterator_.bytes_remaining_ >= needle.size()) {
+ auto haystack_chunk = Cord::ChunkRemaining(it);
+ assert(!haystack_chunk.empty());
+ // Look for the first char of `needle` in the current chunk.
+ auto idx = haystack_chunk.find(needle.front());
+ if (idx == absl::string_view::npos) {
+ // No potential match in this chunk, advance past it.
+ Cord::Advance(&it, haystack_chunk.size());
+ continue;
+ }
+ // We found the start of a potential match in the chunk. Advance the
+ // iterator and haystack chunk to the match the position.
+ Cord::Advance(&it, idx);
+ // Check if there is enough haystack remaining to actually have a match.
+ if (it.chunk_iterator_.bytes_remaining_ < needle.size()) {
+ break;
+ }
+ // Check if this is `needle`.
+ if (IsSubstringInCordAt(it, needle)) {
+ return it;
+ }
+ // No match, increment the iterator for the next attempt.
+ Cord::Advance(&it, 1);
+ }
+ // If we got here, we did not find `needle`.
+ return char_end();
+}
+
+absl::Cord::CharIterator absl::Cord::Find(absl::string_view needle) const {
+ if (needle.empty()) {
+ return char_begin();
+ }
+ if (needle.size() > size()) {
+ return char_end();
+ }
+ if (needle.size() == size()) {
+ return *this == needle ? char_begin() : char_end();
+ }
+ return FindImpl(char_begin(), needle);
+}
+
+namespace {
+
+// Tests whether the sequence of chunks beginning at `haystack` starts with the
+// sequence of chunks beginning at `needle_begin` and extending to `needle_end`.
+//
+// REQUIRES: remaining `absl::Cord` starting at `position` is greater than or
+// equal to `needle_end - needle_begin` and `advance`.
+bool IsSubcordInCordAt(absl::Cord::CharIterator haystack,
+ absl::Cord::CharIterator needle_begin,
+ absl::Cord::CharIterator needle_end) {
+ while (needle_begin != needle_end) {
+ auto haystack_chunk = absl::Cord::ChunkRemaining(haystack);
+ assert(!haystack_chunk.empty());
+ auto needle_chunk = absl::Cord::ChunkRemaining(needle_begin);
+ auto min_length = std::min(haystack_chunk.size(), needle_chunk.size());
+ if (haystack_chunk.substr(0, min_length) !=
+ needle_chunk.substr(0, min_length)) {
+ return false;
+ }
+ absl::Cord::Advance(&haystack, min_length);
+ absl::Cord::Advance(&needle_begin, min_length);
+ }
+ return true;
+}
+
+// Tests whether the sequence of chunks beginning at `position` starts with the
+// cord `needle`.
+//
+// REQUIRES: remaining `absl::Cord` starting at `position` is greater than or
+// equal to `needle.size()`.
+bool IsSubcordInCordAt(absl::Cord::CharIterator position,
+ const absl::Cord& needle) {
+ return IsSubcordInCordAt(position, needle.char_begin(), needle.char_end());
+}
+
+} // namespace
+
+absl::Cord::CharIterator absl::Cord::Find(const absl::Cord& needle) const {
+ if (needle.empty()) {
+ return char_begin();
+ }
+ const auto needle_size = needle.size();
+ if (needle_size > size()) {
+ return char_end();
+ }
+ if (needle_size == size()) {
+ return *this == needle ? char_begin() : char_end();
+ }
+ const auto needle_chunk = Cord::ChunkRemaining(needle.char_begin());
+ auto haystack_it = char_begin();
+ while (true) {
+ haystack_it = FindImpl(haystack_it, needle_chunk);
+ if (haystack_it == char_end() ||
+ haystack_it.chunk_iterator_.bytes_remaining_ < needle_size) {
+ break;
+ }
+ // We found the first chunk of `needle` at `haystack_it` but not the entire
+ // subcord. Advance past the first chunk and check for the remainder.
+ auto haystack_advanced_it = haystack_it;
+ auto needle_it = needle.char_begin();
+ Cord::Advance(&haystack_advanced_it, needle_chunk.size());
+ Cord::Advance(&needle_it, needle_chunk.size());
+ if (IsSubcordInCordAt(haystack_advanced_it, needle_it, needle.char_end())) {
+ return haystack_it;
+ }
+ Cord::Advance(&haystack_it, 1);
+ if (haystack_it.chunk_iterator_.bytes_remaining_ < needle_size) {
+ break;
+ }
+ if (haystack_it.chunk_iterator_.bytes_remaining_ == needle_size) {
+ // Special case, if there is exactly `needle_size` bytes remaining, the
+ // subcord is either at `haystack_it` or not at all.
+ if (IsSubcordInCordAt(haystack_it, needle)) {
+ return haystack_it;
+ }
+ break;
+ }
+ }
+ return char_end();
+}
+
+bool Cord::Contains(absl::string_view rhs) const {
+ return rhs.empty() || Find(rhs) != char_end();
+}
+
+bool Cord::Contains(const absl::Cord& rhs) const {
+ return rhs.empty() || Find(rhs) != char_end();
+}
+
absl::string_view Cord::FlattenSlowPath() {
assert(contents_.is_tree());
size_t total_size = size();
@@ -1193,7 +1388,8 @@ absl::string_view Cord::FlattenSlowPath() {
return absl::string_view(new_buffer, total_size);
}
-/* static */ bool Cord::GetFlatAux(CordRep* rep, absl::string_view* fragment) {
+/* static */ bool Cord::GetFlatAux(absl::Nonnull<CordRep*> rep,
+ absl::Nonnull<absl::string_view*> fragment) {
assert(rep != nullptr);
if (rep->length == 0) {
*fragment = absl::string_view();
@@ -1227,7 +1423,7 @@ absl::string_view Cord::FlattenSlowPath() {
}
/* static */ void Cord::ForEachChunkAux(
- absl::cord_internal::CordRep* rep,
+ absl::Nonnull<absl::cord_internal::CordRep*> rep,
absl::FunctionRef<void(absl::string_view)> callback) {
assert(rep != nullptr);
if (rep->length == 0) return;
@@ -1252,8 +1448,8 @@ absl::string_view Cord::FlattenSlowPath() {
}
}
-static void DumpNode(CordRep* rep, bool include_data, std::ostream* os,
- int indent) {
+static void DumpNode(absl::Nonnull<CordRep*> rep, bool include_data,
+ absl::Nonnull<std::ostream*> os, int indent) {
const int kIndentStep = 1;
absl::InlinedVector<CordRep*, kInlinedVectorSize> stack;
absl::InlinedVector<int, kInlinedVectorSize> indents;
@@ -1289,7 +1485,7 @@ static void DumpNode(CordRep* rep, bool include_data, std::ostream* os,
*os << absl::CEscape(std::string(rep->flat()->Data(), rep->length));
*os << "]\n";
} else {
- CordRepBtree::Dump(rep, /*label=*/ "", include_data, *os);
+ CordRepBtree::Dump(rep, /*label=*/"", include_data, *os);
}
}
if (leaf) {
@@ -1303,16 +1499,17 @@ static void DumpNode(CordRep* rep, bool include_data, std::ostream* os,
ABSL_INTERNAL_CHECK(indents.empty(), "");
}
-static std::string ReportError(CordRep* root, CordRep* node) {
+static std::string ReportError(absl::Nonnull<CordRep*> root,
+ absl::Nonnull<CordRep*> node) {
std::ostringstream buf;
buf << "Error at node " << node << " in:";
DumpNode(root, true, &buf);
return buf.str();
}
-static bool VerifyNode(CordRep* root, CordRep* start_node,
- bool /* full_validation */) {
- absl::InlinedVector<CordRep*, 2> worklist;
+static bool VerifyNode(absl::Nonnull<CordRep*> root,
+ absl::Nonnull<CordRep*> start_node) {
+ absl::InlinedVector<absl::Nonnull<CordRep*>, 2> worklist;
worklist.push_back(start_node);
do {
CordRep* node = worklist.back();
diff --git a/contrib/restricted/abseil-cpp/absl/strings/cord.h b/contrib/restricted/abseil-cpp/absl/strings/cord.h
index 457ccf0609..b3e556b6b4 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/cord.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/cord.h
@@ -74,6 +74,7 @@
#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/port.h"
#include "absl/container/inlined_vector.h"
#include "absl/crc/internal/crc_cord_state.h"
@@ -86,7 +87,6 @@
#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/cord_rep_ring.h"
#include "absl/strings/internal/cordz_functions.h"
#include "absl/strings/internal/cordz_info.h"
#include "absl/strings/internal/cordz_statistics.h"
@@ -103,7 +103,7 @@ class Cord;
class CordTestPeer;
template <typename Releaser>
Cord MakeCordFromExternal(absl::string_view, Releaser&&);
-void CopyCordToString(const Cord& src, std::string* dst);
+void CopyCordToString(const Cord& src, absl::Nonnull<std::string*> dst);
// Cord memory accounting modes
enum class CordMemoryAccounting {
@@ -120,8 +120,8 @@ enum class CordMemoryAccounting {
//
// For example:
// absl::Cord cord;
- // cord.append(some_other_cord);
- // cord.append(some_other_cord);
+ // cord.Append(some_other_cord);
+ // cord.Append(some_other_cord);
// // Counts `some_other_cord` twice:
// cord.EstimatedMemoryUsage(kTotal);
// // Counts `some_other_cord` once:
@@ -362,7 +362,7 @@ class Cord {
// Cord::empty()
//
- // Determines whether the given Cord is empty, returning `true` is so.
+ // Determines whether the given Cord is empty, returning `true` if so.
bool empty() const;
// Cord::EstimatedMemoryUsage()
@@ -396,6 +396,12 @@ class Cord {
bool EndsWith(absl::string_view rhs) const;
bool EndsWith(const Cord& rhs) const;
+ // Cord::Contains()
+ //
+ // Determines whether the Cord contains the passed string data `rhs`.
+ bool Contains(absl::string_view rhs) const;
+ bool Contains(const Cord& rhs) const;
+
// Cord::operator std::string()
//
// Converts a Cord into a `std::string()`. This operator is marked explicit to
@@ -411,7 +417,8 @@ class Cord {
// guarantee that pointers previously returned by `dst->data()` remain valid
// even if `*dst` had enough capacity to hold `src`. If `*dst` is a new
// object, prefer to simply use the conversion operator to `std::string`.
- friend void CopyCordToString(const Cord& src, std::string* dst);
+ friend void CopyCordToString(const Cord& src,
+ absl::Nonnull<std::string*> dst);
class CharIterator;
@@ -448,7 +455,7 @@ class Cord {
using iterator_category = std::input_iterator_tag;
using value_type = absl::string_view;
using difference_type = ptrdiff_t;
- using pointer = const value_type*;
+ using pointer = absl::Nonnull<const value_type*>;
using reference = value_type;
ChunkIterator() = default;
@@ -468,14 +475,14 @@ class Cord {
using CordRepBtree = absl::cord_internal::CordRepBtree;
using CordRepBtreeReader = absl::cord_internal::CordRepBtreeReader;
- // Constructs a `begin()` iterator from `tree`. `tree` must not be null.
- explicit ChunkIterator(cord_internal::CordRep* tree);
+ // Constructs a `begin()` iterator from `tree`.
+ explicit ChunkIterator(absl::Nonnull<cord_internal::CordRep*> tree);
// Constructs a `begin()` iterator from `cord`.
- explicit ChunkIterator(const Cord* cord);
+ explicit ChunkIterator(absl::Nonnull<const Cord*> cord);
// Initializes this instance from a tree. Invoked by constructors.
- void InitTree(cord_internal::CordRep* tree);
+ void InitTree(absl::Nonnull<cord_internal::CordRep*> tree);
// Removes `n` bytes from `current_chunk_`. Expects `n` to be smaller than
// `current_chunk_.size()`.
@@ -493,7 +500,7 @@ class Cord {
// The current leaf, or `nullptr` if the iterator points to short data.
// If the current chunk is a substring node, current_leaf_ points to the
// underlying flat or external node.
- absl::cord_internal::CordRep* current_leaf_ = nullptr;
+ absl::Nullable<absl::cord_internal::CordRep*> current_leaf_ = nullptr;
// The number of bytes left in the `Cord` over which we are iterating.
size_t bytes_remaining_ = 0;
@@ -515,7 +522,7 @@ class Cord {
// absl::string_view s) {
// return std::find(c.chunk_begin(), c.chunk_end(), s);
// }
- ChunkIterator chunk_begin() const;
+ ChunkIterator chunk_begin() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
// Cord::chunk_end()
//
@@ -524,7 +531,7 @@ class Cord {
// Generally, prefer using `Cord::Chunks()` within a range-based for loop for
// iterating over the chunks of a Cord. This method may be useful for getting
// a `ChunkIterator` where range-based for-loops may not be available.
- ChunkIterator chunk_end() const;
+ ChunkIterator chunk_end() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
//----------------------------------------------------------------------------
// Cord::ChunkRange
@@ -550,13 +557,13 @@ class Cord {
using iterator = ChunkIterator;
using const_iterator = ChunkIterator;
- explicit ChunkRange(const Cord* cord) : cord_(cord) {}
+ explicit ChunkRange(absl::Nonnull<const Cord*> cord) : cord_(cord) {}
ChunkIterator begin() const;
ChunkIterator end() const;
private:
- const Cord* cord_;
+ absl::Nonnull<const Cord*> cord_;
};
// Cord::Chunks()
@@ -578,7 +585,7 @@ class Cord {
// // The temporary Cord returned by CordFactory has been destroyed!
// }
// }
- ChunkRange Chunks() const;
+ ChunkRange Chunks() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
//----------------------------------------------------------------------------
// Cord::CharIterator
@@ -609,7 +616,7 @@ class Cord {
using iterator_category = std::input_iterator_tag;
using value_type = char;
using difference_type = ptrdiff_t;
- using pointer = const char*;
+ using pointer = absl::Nonnull<const char*>;
using reference = const char&;
CharIterator() = default;
@@ -624,7 +631,8 @@ class Cord {
friend Cord;
private:
- explicit CharIterator(const Cord* cord) : chunk_iterator_(cord) {}
+ explicit CharIterator(absl::Nonnull<const Cord*> cord)
+ : chunk_iterator_(cord) {}
ChunkIterator chunk_iterator_;
};
@@ -635,14 +643,14 @@ class Cord {
// advanced as a separate `Cord`. `n_bytes` must be less than or equal to the
// number of bytes within the Cord; otherwise, behavior is undefined. It is
// valid to pass `char_end()` and `0`.
- static Cord AdvanceAndRead(CharIterator* it, size_t n_bytes);
+ static Cord AdvanceAndRead(absl::Nonnull<CharIterator*> it, size_t n_bytes);
// Cord::Advance()
//
// Advances the `Cord::CharIterator` by `n_bytes`. `n_bytes` must be less than
// or equal to the number of bytes remaining within the Cord; otherwise,
// behavior is undefined. It is valid to pass `char_end()` and `0`.
- static void Advance(CharIterator* it, size_t n_bytes);
+ static void Advance(absl::Nonnull<CharIterator*> it, size_t n_bytes);
// Cord::ChunkRemaining()
//
@@ -658,7 +666,7 @@ class Cord {
// Generally, prefer using `Cord::Chars()` within a range-based for loop for
// iterating over the chunks of a Cord. This method may be useful for getting
// a `CharIterator` where range-based for-loops may not be available.
- CharIterator char_begin() const;
+ CharIterator char_begin() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
// Cord::char_end()
//
@@ -667,7 +675,7 @@ class Cord {
// Generally, prefer using `Cord::Chars()` within a range-based for loop for
// iterating over the chunks of a Cord. This method may be useful for getting
// a `CharIterator` where range-based for-loops are not useful.
- CharIterator char_end() const;
+ CharIterator char_end() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
// Cord::CharRange
//
@@ -691,13 +699,13 @@ class Cord {
using iterator = CharIterator;
using const_iterator = CharIterator;
- explicit CharRange(const Cord* cord) : cord_(cord) {}
+ explicit CharRange(absl::Nonnull<const Cord*> cord) : cord_(cord) {}
CharIterator begin() const;
CharIterator end() const;
private:
- const Cord* cord_;
+ absl::Nonnull<const Cord*> cord_;
};
// Cord::Chars()
@@ -719,7 +727,7 @@ class Cord {
// // The temporary Cord returned by CordFactory has been destroyed!
// }
// }
- CharRange Chars() const;
+ CharRange Chars() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
// Cord::operator[]
//
@@ -737,20 +745,38 @@ class Cord {
//
// If this cord's representation is a single flat array, returns a
// string_view referencing that array. Otherwise returns nullopt.
- absl::optional<absl::string_view> TryFlat() const;
+ absl::optional<absl::string_view> TryFlat() const
+ ABSL_ATTRIBUTE_LIFETIME_BOUND;
// Cord::Flatten()
//
// Flattens the cord into a single array and returns a view of the data.
//
// If the cord was already flat, the contents are not modified.
- absl::string_view Flatten();
+ absl::string_view Flatten() ABSL_ATTRIBUTE_LIFETIME_BOUND;
+
+ // Cord::Find()
+ //
+ // Returns an iterator to the first occurrance of the substring `needle`.
+ //
+ // If the substring `needle` does not occur, `Cord::char_end()` is returned.
+ CharIterator Find(absl::string_view needle) const;
+ CharIterator Find(const absl::Cord& needle) const;
// Supports absl::Cord as a sink object for absl::Format().
- friend void AbslFormatFlush(absl::Cord* cord, absl::string_view part) {
+ friend void AbslFormatFlush(absl::Nonnull<absl::Cord*> cord,
+ absl::string_view part) {
cord->Append(part);
}
+ // Support automatic stringification with absl::StrCat and absl::StrFormat.
+ template <typename Sink>
+ friend void AbslStringify(Sink& sink, const absl::Cord& cord) {
+ for (absl::string_view chunk : cord.Chunks()) {
+ sink.Append(chunk);
+ }
+ }
+
// Cord::SetExpectedChecksum()
//
// Stores a checksum value with this non-empty cord instance, for later
@@ -809,7 +835,8 @@ class Cord {
friend bool operator==(const Cord& lhs, const Cord& rhs);
friend bool operator==(const Cord& lhs, absl::string_view rhs);
- friend const CordzInfo* GetCordzInfoForTesting(const Cord& cord);
+ friend absl::Nullable<const CordzInfo*> GetCordzInfoForTesting(
+ const Cord& cord);
// Calls the provided function once for each cord chunk, in order. Unlike
// Chunks(), this API will not allocate memory.
@@ -836,20 +863,22 @@ class Cord {
InlineRep& operator=(const InlineRep& src);
InlineRep& operator=(InlineRep&& src) noexcept;
- explicit constexpr InlineRep(absl::string_view sv, CordRep* rep);
+ explicit constexpr InlineRep(absl::string_view sv,
+ absl::Nullable<CordRep*> rep);
- void Swap(InlineRep* rhs);
- bool empty() const;
+ void Swap(absl::Nonnull<InlineRep*> rhs);
size_t size() const;
- const char* data() const; // Returns nullptr if holding pointer
- void set_data(const char* data, size_t n); // Discards pointer, if any
- char* set_data(size_t n); // Write data to the result
+ // Returns nullptr if holding pointer
+ absl::Nullable<const char*> data() const;
+ // Discards pointer, if any
+ void set_data(absl::Nonnull<const char*> data, size_t n);
+ absl::Nonnull<char*> set_data(size_t n); // Write data to the result
// Returns nullptr if holding bytes
- absl::cord_internal::CordRep* tree() const;
- absl::cord_internal::CordRep* as_tree() const;
- const char* as_chars() const;
+ absl::Nullable<absl::cord_internal::CordRep*> tree() const;
+ absl::Nonnull<absl::cord_internal::CordRep*> as_tree() const;
+ absl::Nonnull<const char*> as_chars() const;
// Returns non-null iff was holding a pointer
- absl::cord_internal::CordRep* clear();
+ absl::Nullable<absl::cord_internal::CordRep*> clear();
// Converts to pointer if necessary.
void reduce_size(size_t n); // REQUIRES: holding data
void remove_prefix(size_t n); // REQUIRES: holding data
@@ -858,46 +887,52 @@ class Cord {
// Creates a CordRepFlat instance from the current inlined data with `extra'
// bytes of desired additional capacity.
- CordRepFlat* MakeFlatWithExtraCapacity(size_t extra);
+ absl::Nonnull<CordRepFlat*> MakeFlatWithExtraCapacity(size_t extra);
// Sets the tree value for this instance. `rep` must not be null.
// Requires the current instance to hold a tree, and a lock to be held on
// any CordzInfo referenced by this instance. The latter is enforced through
// the CordzUpdateScope argument. If the current instance is sampled, then
// the CordzInfo instance is updated to reference the new `rep` value.
- void SetTree(CordRep* rep, const CordzUpdateScope& scope);
+ void SetTree(absl::Nonnull<CordRep*> rep, const CordzUpdateScope& scope);
// Identical to SetTree(), except that `rep` is allowed to be null, in
// which case the current instance is reset to an empty value.
- void SetTreeOrEmpty(CordRep* rep, const CordzUpdateScope& scope);
+ void SetTreeOrEmpty(absl::Nullable<CordRep*> rep,
+ const CordzUpdateScope& scope);
// Sets the tree value for this instance, and randomly samples this cord.
// This function disregards existing contents in `data_`, and should be
// called when a Cord is 'promoted' from an 'uninitialized' or 'inlined'
// value to a non-inlined (tree / ring) value.
- void EmplaceTree(CordRep* rep, MethodIdentifier method);
+ void EmplaceTree(absl::Nonnull<CordRep*> rep, MethodIdentifier method);
// Identical to EmplaceTree, except that it copies the parent stack from
// the provided `parent` data if the parent is sampled.
- void EmplaceTree(CordRep* rep, const InlineData& parent,
+ void EmplaceTree(absl::Nonnull<CordRep*> rep, const InlineData& parent,
MethodIdentifier method);
// Commits the change of a newly created, or updated `rep` root value into
// this cord. `old_rep` indicates the old (inlined or tree) value of the
// cord, and determines if the commit invokes SetTree() or EmplaceTree().
- void CommitTree(const CordRep* old_rep, CordRep* rep,
- const CordzUpdateScope& scope, MethodIdentifier method);
-
- void AppendTreeToInlined(CordRep* tree, MethodIdentifier method);
- void AppendTreeToTree(CordRep* tree, MethodIdentifier method);
- void AppendTree(CordRep* tree, MethodIdentifier method);
- void PrependTreeToInlined(CordRep* tree, MethodIdentifier method);
- void PrependTreeToTree(CordRep* tree, MethodIdentifier method);
- void PrependTree(CordRep* tree, MethodIdentifier method);
+ void CommitTree(absl::Nullable<const CordRep*> old_rep,
+ absl::Nonnull<CordRep*> rep, const CordzUpdateScope& scope,
+ MethodIdentifier method);
+
+ void AppendTreeToInlined(absl::Nonnull<CordRep*> tree,
+ MethodIdentifier method);
+ void AppendTreeToTree(absl::Nonnull<CordRep*> tree,
+ MethodIdentifier method);
+ void AppendTree(absl::Nonnull<CordRep*> tree, MethodIdentifier method);
+ void PrependTreeToInlined(absl::Nonnull<CordRep*> tree,
+ MethodIdentifier method);
+ void PrependTreeToTree(absl::Nonnull<CordRep*> tree,
+ MethodIdentifier method);
+ void PrependTree(absl::Nonnull<CordRep*> tree, MethodIdentifier method);
bool IsSame(const InlineRep& other) const { return data_ == other.data_; }
- void CopyTo(std::string* dst) const {
+ 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.
@@ -909,7 +944,7 @@ class Cord {
}
// Copies the inline contents into `dst`. Assumes the cord is not empty.
- void CopyToArray(char* dst) const;
+ void CopyToArray(absl::Nonnull<char*> dst) const;
bool is_tree() const { return data_.is_tree(); }
@@ -922,12 +957,12 @@ class Cord {
}
// Returns the profiled CordzInfo, or nullptr if not sampled.
- absl::cord_internal::CordzInfo* cordz_info() const {
+ absl::Nullable<absl::cord_internal::CordzInfo*> cordz_info() const {
return data_.cordz_info();
}
- // Sets the profiled CordzInfo. `cordz_info` must not be null.
- void set_cordz_info(cord_internal::CordzInfo* cordz_info) {
+ // Sets the profiled CordzInfo.
+ void set_cordz_info(absl::Nonnull<cord_internal::CordzInfo*> cordz_info) {
assert(cordz_info != nullptr);
data_.set_cordz_info(cordz_info);
}
@@ -959,19 +994,19 @@ class Cord {
InlineRep contents_;
// Helper for GetFlat() and TryFlat().
- static bool GetFlatAux(absl::cord_internal::CordRep* rep,
- absl::string_view* fragment);
+ static bool GetFlatAux(absl::Nonnull<absl::cord_internal::CordRep*> rep,
+ absl::Nonnull<absl::string_view*> fragment);
// Helper for ForEachChunk().
static void ForEachChunkAux(
- absl::cord_internal::CordRep* rep,
+ absl::Nonnull<absl::cord_internal::CordRep*> rep,
absl::FunctionRef<void(absl::string_view)> callback);
// The destructor for non-empty Cords.
void DestroyCordSlow();
// Out-of-line implementation of slower parts of logic.
- void CopyToArraySlowPath(char* dst) const;
+ void CopyToArraySlowPath(absl::Nonnull<char*> dst) const;
int CompareSlowPath(absl::string_view rhs, size_t compared_size,
size_t size_to_compare) const;
int CompareSlowPath(const Cord& rhs, size_t compared_size,
@@ -988,8 +1023,8 @@ class Cord {
// Returns a new reference to contents_.tree(), or steals an existing
// reference if called on an rvalue.
- absl::cord_internal::CordRep* TakeRep() const&;
- absl::cord_internal::CordRep* TakeRep() &&;
+ absl::Nonnull<absl::cord_internal::CordRep*> TakeRep() const&;
+ absl::Nonnull<absl::cord_internal::CordRep*> TakeRep() &&;
// Helper for Append().
template <typename C>
@@ -1026,7 +1061,10 @@ class Cord {
friend class CrcCord;
void SetCrcCordState(crc_internal::CrcCordState state);
- const crc_internal::CrcCordState* MaybeGetCrcCordState() const;
+ absl::Nullable<const crc_internal::CrcCordState*> MaybeGetCrcCordState()
+ const;
+
+ CharIterator FindImpl(CharIterator it, absl::string_view needle) const;
};
ABSL_NAMESPACE_END
@@ -1045,13 +1083,15 @@ namespace cord_internal {
// Does non-template-specific `CordRepExternal` initialization.
// Requires `data` to be non-empty.
-void InitializeCordRepExternal(absl::string_view data, CordRepExternal* rep);
+void InitializeCordRepExternal(absl::string_view data,
+ absl::Nonnull<CordRepExternal*> rep);
// Creates a new `CordRep` that owns `data` and `releaser` and returns a pointer
// to it. Requires `data` to be non-empty.
template <typename Releaser>
// NOLINTNEXTLINE - suppress clang-tidy raw pointer return.
-CordRep* NewExternalRep(absl::string_view data, Releaser&& releaser) {
+absl::Nonnull<CordRep*> NewExternalRep(absl::string_view data,
+ Releaser&& releaser) {
assert(!data.empty());
using ReleaserType = absl::decay_t<Releaser>;
CordRepExternal* rep = new CordRepExternalImpl<ReleaserType>(
@@ -1063,7 +1103,7 @@ CordRep* NewExternalRep(absl::string_view data, Releaser&& releaser) {
// Overload for function reference types that dispatches using a function
// pointer because there are no `alignof()` or `sizeof()` a function reference.
// NOLINTNEXTLINE - suppress clang-tidy raw pointer return.
-inline CordRep* NewExternalRep(absl::string_view data,
+inline absl::Nonnull<CordRep*> NewExternalRep(absl::string_view data,
void (&releaser)(absl::string_view)) {
return NewExternalRep(data, &releaser);
}
@@ -1086,7 +1126,8 @@ Cord MakeCordFromExternal(absl::string_view data, Releaser&& releaser) {
return cord;
}
-constexpr Cord::InlineRep::InlineRep(absl::string_view sv, CordRep* rep)
+constexpr Cord::InlineRep::InlineRep(absl::string_view sv,
+ absl::Nullable<CordRep*> rep)
: data_(sv, rep) {}
inline Cord::InlineRep::InlineRep(const Cord::InlineRep& src)
@@ -1125,28 +1166,30 @@ inline Cord::InlineRep& Cord::InlineRep::operator=(
return *this;
}
-inline void Cord::InlineRep::Swap(Cord::InlineRep* rhs) {
+inline void Cord::InlineRep::Swap(absl::Nonnull<Cord::InlineRep*> rhs) {
if (rhs == this) {
return;
}
std::swap(data_, rhs->data_);
}
-inline const char* Cord::InlineRep::data() const {
+inline absl::Nullable<const char*> Cord::InlineRep::data() const {
return is_tree() ? nullptr : data_.as_chars();
}
-inline const char* Cord::InlineRep::as_chars() const {
+inline absl::Nonnull<const char*> Cord::InlineRep::as_chars() const {
assert(!data_.is_tree());
return data_.as_chars();
}
-inline absl::cord_internal::CordRep* Cord::InlineRep::as_tree() const {
+inline absl::Nonnull<absl::cord_internal::CordRep*> Cord::InlineRep::as_tree()
+ const {
assert(data_.is_tree());
return data_.as_tree();
}
-inline absl::cord_internal::CordRep* Cord::InlineRep::tree() const {
+inline absl::Nullable<absl::cord_internal::CordRep*> Cord::InlineRep::tree()
+ const {
if (is_tree()) {
return as_tree();
} else {
@@ -1154,14 +1197,12 @@ inline absl::cord_internal::CordRep* Cord::InlineRep::tree() const {
}
}
-inline bool Cord::InlineRep::empty() const { return data_.is_empty(); }
-
inline size_t Cord::InlineRep::size() const {
return is_tree() ? as_tree()->length : inline_size();
}
-inline cord_internal::CordRepFlat* Cord::InlineRep::MakeFlatWithExtraCapacity(
- size_t extra) {
+inline absl::Nonnull<cord_internal::CordRepFlat*>
+Cord::InlineRep::MakeFlatWithExtraCapacity(size_t extra) {
static_assert(cord_internal::kMinFlatLength >= sizeof(data_), "");
size_t len = data_.inline_size();
auto* result = CordRepFlat::New(len + extra);
@@ -1170,20 +1211,21 @@ inline cord_internal::CordRepFlat* Cord::InlineRep::MakeFlatWithExtraCapacity(
return result;
}
-inline void Cord::InlineRep::EmplaceTree(CordRep* rep,
+inline void Cord::InlineRep::EmplaceTree(absl::Nonnull<CordRep*> rep,
MethodIdentifier method) {
assert(rep);
data_.make_tree(rep);
CordzInfo::MaybeTrackCord(data_, method);
}
-inline void Cord::InlineRep::EmplaceTree(CordRep* rep, const InlineData& parent,
+inline void Cord::InlineRep::EmplaceTree(absl::Nonnull<CordRep*> rep,
+ const InlineData& parent,
MethodIdentifier method) {
data_.make_tree(rep);
CordzInfo::MaybeTrackCord(data_, parent, method);
}
-inline void Cord::InlineRep::SetTree(CordRep* rep,
+inline void Cord::InlineRep::SetTree(absl::Nonnull<CordRep*> rep,
const CordzUpdateScope& scope) {
assert(rep);
assert(data_.is_tree());
@@ -1191,7 +1233,7 @@ inline void Cord::InlineRep::SetTree(CordRep* rep,
scope.SetCordRep(rep);
}
-inline void Cord::InlineRep::SetTreeOrEmpty(CordRep* rep,
+inline void Cord::InlineRep::SetTreeOrEmpty(absl::Nullable<CordRep*> rep,
const CordzUpdateScope& scope) {
assert(data_.is_tree());
if (rep) {
@@ -1202,7 +1244,8 @@ inline void Cord::InlineRep::SetTreeOrEmpty(CordRep* rep,
scope.SetCordRep(rep);
}
-inline void Cord::InlineRep::CommitTree(const CordRep* old_rep, CordRep* rep,
+inline void Cord::InlineRep::CommitTree(absl::Nullable<const CordRep*> old_rep,
+ absl::Nonnull<CordRep*> rep,
const CordzUpdateScope& scope,
MethodIdentifier method) {
if (old_rep) {
@@ -1212,7 +1255,7 @@ inline void Cord::InlineRep::CommitTree(const CordRep* old_rep, CordRep* rep,
}
}
-inline absl::cord_internal::CordRep* Cord::InlineRep::clear() {
+inline absl::Nullable<absl::cord_internal::CordRep*> Cord::InlineRep::clear() {
if (is_tree()) {
CordzInfo::MaybeUntrackCord(cordz_info());
}
@@ -1221,7 +1264,7 @@ inline absl::cord_internal::CordRep* Cord::InlineRep::clear() {
return result;
}
-inline void Cord::InlineRep::CopyToArray(char* dst) const {
+inline void Cord::InlineRep::CopyToArray(absl::Nonnull<char*> dst) const {
assert(!is_tree());
size_t n = inline_size();
assert(n != 0);
@@ -1402,7 +1445,8 @@ inline bool Cord::StartsWith(absl::string_view rhs) const {
return EqualsImpl(rhs, rhs_size);
}
-inline void Cord::ChunkIterator::InitTree(cord_internal::CordRep* tree) {
+inline void Cord::ChunkIterator::InitTree(
+ absl::Nonnull<cord_internal::CordRep*> tree) {
tree = cord_internal::SkipCrcNode(tree);
if (tree->tag == cord_internal::BTREE) {
current_chunk_ = btree_reader_.Init(tree->btree());
@@ -1412,12 +1456,13 @@ inline void Cord::ChunkIterator::InitTree(cord_internal::CordRep* tree) {
}
}
-inline Cord::ChunkIterator::ChunkIterator(cord_internal::CordRep* tree) {
+inline Cord::ChunkIterator::ChunkIterator(
+ absl::Nonnull<cord_internal::CordRep*> tree) {
bytes_remaining_ = tree->length;
InitTree(tree);
}
-inline Cord::ChunkIterator::ChunkIterator(const Cord* cord) {
+inline Cord::ChunkIterator::ChunkIterator(absl::Nonnull<const Cord*> cord) {
if (CordRep* tree = cord->contents_.tree()) {
bytes_remaining_ = tree->length;
if (ABSL_PREDICT_TRUE(bytes_remaining_ != 0)) {
@@ -1557,12 +1602,13 @@ inline Cord::CharIterator::pointer Cord::CharIterator::operator->() const {
return chunk_iterator_->data();
}
-inline Cord Cord::AdvanceAndRead(CharIterator* it, size_t n_bytes) {
+inline Cord Cord::AdvanceAndRead(absl::Nonnull<CharIterator*> it,
+ size_t n_bytes) {
assert(it != nullptr);
return it->chunk_iterator_.AdvanceAndReadBytes(n_bytes);
}
-inline void Cord::Advance(CharIterator* it, size_t n_bytes) {
+inline void Cord::Advance(absl::Nonnull<CharIterator*> it, size_t n_bytes) {
assert(it != nullptr);
it->chunk_iterator_.AdvanceBytes(n_bytes);
}
@@ -1618,7 +1664,7 @@ inline bool operator>=(const Cord& x, const Cord& y) {
// Nonmember Cord-to-absl::string_view relational operators.
//
// Due to implicit conversions, these also enable comparisons of Cord with
-// with std::string, ::string, and const char*.
+// std::string and const char*.
inline bool operator==(const Cord& lhs, absl::string_view rhs) {
size_t lhs_size = lhs.size();
size_t rhs_size = rhs.size();
diff --git a/contrib/restricted/abseil-cpp/absl/strings/cord_analysis.cc b/contrib/restricted/abseil-cpp/absl/strings/cord_analysis.cc
index e859b0db06..19b0fa4436 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/cord_analysis.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/cord_analysis.cc
@@ -14,23 +14,17 @@
#include "absl/strings/cord_analysis.h"
+#include <cassert>
#include <cstddef>
#include <cstdint>
#include <unordered_set>
-#include "absl/base/attributes.h"
#include "absl/base/config.h"
-#include "absl/container/inlined_vector.h"
+#include "absl/base/nullability.h"
#include "absl/strings/internal/cord_data_edge.h"
#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_btree.h"
#include "absl/strings/internal/cord_rep_crc.h"
-#include "absl/strings/internal/cord_rep_flat.h"
-#include "absl/strings/internal/cord_rep_ring.h"
-//
-#include "absl/base/macros.h"
-#include "absl/base/port.h"
-#include "absl/functional/function_ref.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -45,13 +39,15 @@ enum class Mode { kFairShare, kTotal, kTotalMorePrecise };
template <Mode mode>
struct CordRepRef {
// Instantiates a CordRepRef instance.
- explicit CordRepRef(const CordRep* r) : rep(r) {}
+ explicit CordRepRef(absl::Nonnull<const CordRep*> r) : rep(r) {}
// Creates a child reference holding the provided child.
// Overloaded to add cumulative reference count for kFairShare.
- CordRepRef Child(const CordRep* child) const { return CordRepRef(child); }
+ CordRepRef Child(absl::Nonnull<const CordRep*> child) const {
+ return CordRepRef(child);
+ }
- const CordRep* rep;
+ absl::Nonnull<const CordRep*> rep;
};
// RawUsage holds the computed total number of bytes.
@@ -70,11 +66,10 @@ template <>
struct RawUsage<Mode::kTotalMorePrecise> {
size_t total = 0;
// TODO(b/289250880): Replace this with a flat_hash_set.
- std::unordered_set<const CordRep*> counted;
+ std::unordered_set<absl::Nonnull<const CordRep*>> counted;
void Add(size_t size, CordRepRef<Mode::kTotalMorePrecise> repref) {
- if (counted.find(repref.rep) == counted.end()) {
- counted.insert(repref.rep);
+ if (counted.insert(repref.rep).second) {
total += size;
}
}
@@ -95,15 +90,15 @@ double MaybeDiv(double d, refcount_t refcount) {
template <>
struct CordRepRef<Mode::kFairShare> {
// Creates a CordRepRef with the provided rep and top (parent) fraction.
- explicit CordRepRef(const CordRep* r, double frac = 1.0)
+ explicit CordRepRef(absl::Nonnull<const CordRep*> r, double frac = 1.0)
: rep(r), fraction(MaybeDiv(frac, r->refcount.Get())) {}
// Returns a CordRepRef with a fraction of `this->fraction / child.refcount`
- CordRepRef Child(const CordRep* child) const {
+ CordRepRef Child(absl::Nonnull<const CordRep*> child) const {
return CordRepRef(child, fraction);
}
- const CordRep* rep;
+ absl::Nonnull<const CordRep*> rep;
double fraction;
};
@@ -138,16 +133,6 @@ void AnalyzeDataEdge(CordRepRef<mode> rep, RawUsage<mode>& raw_usage) {
raw_usage.Add(size, rep);
}
-// Computes the memory size of the provided Ring tree.
-template <Mode mode>
-void AnalyzeRing(CordRepRef<mode> rep, RawUsage<mode>& raw_usage) {
- const CordRepRing* ring = rep.rep->ring();
- raw_usage.Add(CordRepRing::AllocSize(ring->capacity()), rep);
- ring->ForEach([&](CordRepRing::index_type pos) {
- AnalyzeDataEdge(rep.Child(ring->entry_child(pos)), raw_usage);
- });
-}
-
// Computes the memory size of the provided Btree tree.
template <Mode mode>
void AnalyzeBtree(CordRepRef<mode> rep, RawUsage<mode>& raw_usage) {
@@ -165,7 +150,7 @@ void AnalyzeBtree(CordRepRef<mode> rep, RawUsage<mode>& raw_usage) {
}
template <Mode mode>
-size_t GetEstimatedUsage(const CordRep* rep) {
+size_t GetEstimatedUsage(absl::Nonnull<const CordRep*> rep) {
// Zero initialized memory usage totals.
RawUsage<mode> raw_usage;
@@ -175,6 +160,9 @@ size_t GetEstimatedUsage(const CordRep* rep) {
// Consume the top level CRC node if present.
if (repref.rep->tag == CRC) {
raw_usage.Add(sizeof(CordRepCrc), repref);
+ if (repref.rep->crc()->child == nullptr) {
+ return static_cast<size_t>(raw_usage.total);
+ }
repref = repref.Child(repref.rep->crc()->child);
}
@@ -182,8 +170,6 @@ size_t GetEstimatedUsage(const CordRep* rep) {
AnalyzeDataEdge(repref, raw_usage);
} else if (repref.rep->tag == BTREE) {
AnalyzeBtree(repref, raw_usage);
- } else if (repref.rep->tag == RING) {
- AnalyzeRing(repref, raw_usage);
} else {
assert(false);
}
@@ -193,15 +179,15 @@ size_t GetEstimatedUsage(const CordRep* rep) {
} // namespace
-size_t GetEstimatedMemoryUsage(const CordRep* rep) {
+size_t GetEstimatedMemoryUsage(absl::Nonnull<const CordRep*> rep) {
return GetEstimatedUsage<Mode::kTotal>(rep);
}
-size_t GetEstimatedFairShareMemoryUsage(const CordRep* rep) {
+size_t GetEstimatedFairShareMemoryUsage(absl::Nonnull<const CordRep*> rep) {
return GetEstimatedUsage<Mode::kFairShare>(rep);
}
-size_t GetMorePreciseMemoryUsage(const CordRep* rep) {
+size_t GetMorePreciseMemoryUsage(absl::Nonnull<const CordRep*> rep) {
return GetEstimatedUsage<Mode::kTotalMorePrecise>(rep);
}
diff --git a/contrib/restricted/abseil-cpp/absl/strings/cord_analysis.h b/contrib/restricted/abseil-cpp/absl/strings/cord_analysis.h
index 9b9527a57d..f8ce348984 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/cord_analysis.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/cord_analysis.h
@@ -19,6 +19,7 @@
#include <cstdint>
#include "absl/base/config.h"
+#include "absl/base/nullability.h"
#include "absl/strings/internal/cord_internal.h"
namespace absl {
@@ -28,7 +29,7 @@ namespace cord_internal {
// Returns the *approximate* number of bytes held in full or in part by this
// Cord (which may not remain the same between invocations). Cords that share
// memory could each be "charged" independently for the same shared memory.
-size_t GetEstimatedMemoryUsage(const CordRep* rep);
+size_t GetEstimatedMemoryUsage(absl::Nonnull<const CordRep*> rep);
// Returns the *approximate* number of bytes held in full or in part by this
// Cord for the distinct memory held by this cord. This is similar to
@@ -46,13 +47,13 @@ size_t GetEstimatedMemoryUsage(const CordRep* rep);
//
// This is more expensive than `GetEstimatedMemoryUsage()` as it requires
// deduplicating all memory references.
-size_t GetMorePreciseMemoryUsage(const CordRep* rep);
+size_t GetMorePreciseMemoryUsage(absl::Nonnull<const CordRep*> rep);
// Returns the *approximate* number of bytes held in full or in part by this
// CordRep weighted by the sharing ratio of that data. For example, if some data
// edge is shared by 4 different Cords, then each cord is attribute 1/4th of
// the total memory usage as a 'fair share' of the total memory usage.
-size_t GetEstimatedFairShareMemoryUsage(const CordRep* rep);
+size_t GetEstimatedFairShareMemoryUsage(absl::Nonnull<const CordRep*> rep);
} // namespace cord_internal
ABSL_NAMESPACE_END
diff --git a/contrib/restricted/abseil-cpp/absl/strings/escaping.cc b/contrib/restricted/abseil-cpp/absl/strings/escaping.cc
index 2827fbaa37..1c0eac42d7 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/escaping.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/escaping.cc
@@ -16,21 +16,22 @@
#include <algorithm>
#include <cassert>
+#include <cstddef>
#include <cstdint>
#include <cstring>
-#include <iterator>
#include <limits>
#include <string>
-#include "absl/base/internal/endian.h"
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/internal/unaligned_access.h"
-#include "absl/strings/internal/char_map.h"
+#include "absl/strings/ascii.h"
+#include "absl/strings/charset.h"
#include "absl/strings/internal/escaping.h"
#include "absl/strings/internal/resize_uninitialized.h"
#include "absl/strings/internal/utf8.h"
+#include "absl/strings/numbers.h"
#include "absl/strings/str_cat.h"
-#include "absl/strings/str_join.h"
#include "absl/strings/string_view.h"
namespace absl {
diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/has_absl_stringify.h b/contrib/restricted/abseil-cpp/absl/strings/has_absl_stringify.h
index 55a0850829..274a7865d1 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/internal/has_absl_stringify.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/has_absl_stringify.h
@@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef ABSL_STRINGS_INTERNAL_HAS_ABSL_STRINGIFY_H_
-#define ABSL_STRINGS_INTERNAL_HAS_ABSL_STRINGIFY_H_
-#include <string>
+#ifndef ABSL_STRINGS_HAS_ABSL_STRINGIFY_H_
+#define ABSL_STRINGS_HAS_ABSL_STRINGIFY_H_
+
#include <type_traits>
#include <utility>
@@ -38,6 +38,16 @@ class UnimplementedSink {
friend void AbslFormatFlush(UnimplementedSink* sink, absl::string_view v);
};
+} // namespace strings_internal
+
+// `HasAbslStringify<T>` detects if type `T` supports the `AbslStringify()`
+// customization point (see
+// https://abseil.io/docs/cpp/guides/format#abslstringify for the
+// documentation).
+//
+// Note that there are types that can be `StrCat`-ed that do not use the
+// `AbslStringify` customization point (for example, `int`).
+
template <typename T, typename = void>
struct HasAbslStringify : std::false_type {};
@@ -47,9 +57,7 @@ struct HasAbslStringify<
std::declval<strings_internal::UnimplementedSink&>(),
std::declval<const T&>()))>::value>> : std::true_type {};
-} // namespace strings_internal
-
ABSL_NAMESPACE_END
} // namespace absl
-#endif // ABSL_STRINGS_INTERNAL_HAS_ABSL_STRINGIFY_H_
+#endif // ABSL_STRINGS_HAS_ABSL_STRINGIFY_H_
diff --git a/contrib/restricted/abseil-cpp/absl/strings/has_ostream_operator.h b/contrib/restricted/abseil-cpp/absl/strings/has_ostream_operator.h
new file mode 100644
index 0000000000..156ffc743d
--- /dev/null
+++ b/contrib/restricted/abseil-cpp/absl/strings/has_ostream_operator.h
@@ -0,0 +1,42 @@
+// Copyright 2023 The Abseil Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_STRINGS_HAS_OSTREAM_OPERATOR_H_
+#define ABSL_STRINGS_HAS_OSTREAM_OPERATOR_H_
+
+#include <ostream>
+#include <type_traits>
+#include <utility>
+
+#include "absl/base/config.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+
+// Detects if type `T` supports streaming to `std::ostream`s with `operator<<`.
+
+template <typename T, typename = void>
+struct HasOstreamOperator : std::false_type {};
+
+template <typename T>
+struct HasOstreamOperator<
+ T, std::enable_if_t<std::is_same<
+ std::ostream&, decltype(std::declval<std::ostream&>()
+ << std::declval<const T&>())>::value>>
+ : std::true_type {};
+
+ABSL_NAMESPACE_END
+} // namespace absl
+
+#endif // ABSL_STRINGS_HAS_OSTREAM_OPERATOR_H_
diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/char_map.h b/contrib/restricted/abseil-cpp/absl/strings/internal/char_map.h
deleted file mode 100644
index 70a9034336..0000000000
--- a/contrib/restricted/abseil-cpp/absl/strings/internal/char_map.h
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// Character Map Class
-//
-// A fast, bit-vector map for 8-bit unsigned characters.
-// This class is useful for non-character purposes as well.
-
-#ifndef ABSL_STRINGS_INTERNAL_CHAR_MAP_H_
-#define ABSL_STRINGS_INTERNAL_CHAR_MAP_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <cstring>
-
-#include "absl/base/macros.h"
-#include "absl/base/port.h"
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-namespace strings_internal {
-
-class Charmap {
- public:
- constexpr Charmap() : m_() {}
-
- // Initializes with a given char*. Note that NUL is not treated as
- // a terminator, but rather a char to be flicked.
- Charmap(const char* str, int len) : m_() {
- while (len--) SetChar(*str++);
- }
-
- // Initializes with a given char*. NUL is treated as a terminator
- // and will not be in the charmap.
- explicit Charmap(const char* str) : m_() {
- while (*str) SetChar(*str++);
- }
-
- constexpr bool contains(unsigned char c) const {
- return (m_[c / 64] >> (c % 64)) & 0x1;
- }
-
- // Returns true if and only if a character exists in both maps.
- bool IntersectsWith(const Charmap& c) const {
- for (size_t i = 0; i < ABSL_ARRAYSIZE(m_); ++i) {
- if ((m_[i] & c.m_[i]) != 0) return true;
- }
- return false;
- }
-
- bool IsZero() const {
- for (uint64_t c : m_) {
- if (c != 0) return false;
- }
- return true;
- }
-
- // Containing only a single specified char.
- static constexpr Charmap Char(char x) {
- return Charmap(CharMaskForWord(x, 0), CharMaskForWord(x, 1),
- CharMaskForWord(x, 2), CharMaskForWord(x, 3));
- }
-
- // Containing all the chars in the C-string 's'.
- static constexpr Charmap FromString(const char* s) {
- Charmap ret;
- while (*s) ret = ret | Char(*s++);
- return ret;
- }
-
- // Containing all the chars in the closed interval [lo,hi].
- static constexpr Charmap Range(char lo, char hi) {
- return Charmap(RangeForWord(lo, hi, 0), RangeForWord(lo, hi, 1),
- RangeForWord(lo, hi, 2), RangeForWord(lo, hi, 3));
- }
-
- friend constexpr Charmap operator&(const Charmap& a, const Charmap& b) {
- return Charmap(a.m_[0] & b.m_[0], a.m_[1] & b.m_[1], a.m_[2] & b.m_[2],
- a.m_[3] & b.m_[3]);
- }
-
- friend constexpr Charmap operator|(const Charmap& a, const Charmap& b) {
- return Charmap(a.m_[0] | b.m_[0], a.m_[1] | b.m_[1], a.m_[2] | b.m_[2],
- a.m_[3] | b.m_[3]);
- }
-
- friend constexpr Charmap operator~(const Charmap& a) {
- return Charmap(~a.m_[0], ~a.m_[1], ~a.m_[2], ~a.m_[3]);
- }
-
- private:
- constexpr Charmap(uint64_t b0, uint64_t b1, uint64_t b2, uint64_t b3)
- : m_{b0, b1, b2, b3} {}
-
- static constexpr uint64_t RangeForWord(char lo, char hi, uint64_t word) {
- return OpenRangeFromZeroForWord(static_cast<unsigned char>(hi) + 1, word) &
- ~OpenRangeFromZeroForWord(static_cast<unsigned char>(lo), word);
- }
-
- // All the chars in the specified word of the range [0, upper).
- static constexpr uint64_t OpenRangeFromZeroForWord(uint64_t upper,
- uint64_t word) {
- return (upper <= 64 * word)
- ? 0
- : (upper >= 64 * (word + 1))
- ? ~static_cast<uint64_t>(0)
- : (~static_cast<uint64_t>(0) >> (64 - upper % 64));
- }
-
- static constexpr uint64_t CharMaskForWord(char x, uint64_t word) {
- const auto unsigned_x = static_cast<unsigned char>(x);
- return (unsigned_x / 64 == word)
- ? (static_cast<uint64_t>(1) << (unsigned_x % 64))
- : 0;
- }
-
- void SetChar(char c) {
- const auto unsigned_c = static_cast<unsigned char>(c);
- m_[unsigned_c / 64] |= static_cast<uint64_t>(1) << (unsigned_c % 64);
- }
-
- uint64_t m_[4];
-};
-
-// Mirror the char-classifying predicates in <cctype>
-constexpr Charmap UpperCharmap() { return Charmap::Range('A', 'Z'); }
-constexpr Charmap LowerCharmap() { return Charmap::Range('a', 'z'); }
-constexpr Charmap DigitCharmap() { return Charmap::Range('0', '9'); }
-constexpr Charmap AlphaCharmap() { return LowerCharmap() | UpperCharmap(); }
-constexpr Charmap AlnumCharmap() { return DigitCharmap() | AlphaCharmap(); }
-constexpr Charmap XDigitCharmap() {
- return DigitCharmap() | Charmap::Range('A', 'F') | Charmap::Range('a', 'f');
-}
-constexpr Charmap PrintCharmap() { return Charmap::Range(0x20, 0x7e); }
-constexpr Charmap SpaceCharmap() { return Charmap::FromString("\t\n\v\f\r "); }
-constexpr Charmap CntrlCharmap() {
- return Charmap::Range(0, 0x7f) & ~PrintCharmap();
-}
-constexpr Charmap BlankCharmap() { return Charmap::FromString("\t "); }
-constexpr Charmap GraphCharmap() { return PrintCharmap() & ~SpaceCharmap(); }
-constexpr Charmap PunctCharmap() { return GraphCharmap() & ~AlnumCharmap(); }
-
-} // namespace strings_internal
-ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_STRINGS_INTERNAL_CHAR_MAP_H_
diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.cc
index b7874385de..57d9d385b3 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.cc
@@ -22,15 +22,12 @@
#include "absl/strings/internal/cord_rep_btree.h"
#include "absl/strings/internal/cord_rep_crc.h"
#include "absl/strings/internal/cord_rep_flat.h"
-#include "absl/strings/internal/cord_rep_ring.h"
#include "absl/strings/str_cat.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {
-ABSL_CONST_INIT std::atomic<bool> cord_ring_buffer_enabled(
- kCordEnableRingBufferDefault);
ABSL_CONST_INIT std::atomic<bool> shallow_subcords_enabled(
kCordShallowSubcordsDefault);
@@ -47,9 +44,6 @@ void CordRep::Destroy(CordRep* rep) {
if (rep->tag == BTREE) {
CordRepBtree::Destroy(rep->btree());
return;
- } else if (rep->tag == RING) {
- CordRepRing::Destroy(rep->ring());
- return;
} else if (rep->tag == EXTERNAL) {
CordRepExternal::Delete(rep);
return;
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 20dd008cfa..8744540e2a 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.h
@@ -55,24 +55,15 @@ struct CordRepExternal;
struct CordRepFlat;
struct CordRepSubstring;
struct CordRepCrc;
-class CordRepRing;
class CordRepBtree;
class CordzInfo;
// Default feature enable states for cord ring buffers
-enum CordFeatureDefaults {
- kCordEnableRingBufferDefault = false,
- kCordShallowSubcordsDefault = false
-};
+enum CordFeatureDefaults { kCordShallowSubcordsDefault = false };
-extern std::atomic<bool> cord_ring_buffer_enabled;
extern std::atomic<bool> shallow_subcords_enabled;
-inline void enable_cord_ring_buffer(bool enable) {
- cord_ring_buffer_enabled.store(enable, std::memory_order_relaxed);
-}
-
inline void enable_shallow_subcords(bool enable) {
shallow_subcords_enabled.store(enable, std::memory_order_relaxed);
}
@@ -110,8 +101,16 @@ inline void SmallMemmove(char* dst, const char* src, size_t n) {
if (nullify_tail) {
memset(dst + 7, 0, 8);
}
+ // GCC 12 has a false-positive -Wstringop-overflow warning here.
+#if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(12, 0)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstringop-overflow"
+#endif
memcpy(dst, &buf1, 8);
memcpy(dst + n - 8, &buf2, 8);
+#if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(12, 0)
+#pragma GCC diagnostic pop
+#endif
} else if (n >= 4) {
uint32_t buf1;
uint32_t buf2;
@@ -158,18 +157,18 @@ class RefcountAndFlags {
// false. Always returns false when the immortal bit is set.
inline bool Decrement() {
int32_t refcount = count_.load(std::memory_order_acquire);
- assert((refcount & kRefcountMask) > 0 || refcount & kImmortalFlag);
+ assert(refcount > 0 || refcount & kImmortalFlag);
return refcount != kRefIncrement &&
- (count_.fetch_sub(kRefIncrement, std::memory_order_acq_rel) &
- kHighRefcountMask) != 0;
+ count_.fetch_sub(kRefIncrement, std::memory_order_acq_rel) !=
+ kRefIncrement;
}
// Same as Decrement but expect that refcount is greater than 1.
inline bool DecrementExpectHighRefcount() {
int32_t refcount =
count_.fetch_sub(kRefIncrement, std::memory_order_acq_rel);
- assert((refcount & kRefcountMask) > 0 || refcount & kImmortalFlag);
- return (refcount & kHighRefcountMask) != 0;
+ assert(refcount > 0 || refcount & kImmortalFlag);
+ return refcount != kRefIncrement;
}
// Returns the current reference count using acquire semantics.
@@ -185,10 +184,9 @@ class RefcountAndFlags {
// This call performs the test for a reference count of one, and
// performs the memory barrier needed for the owning thread
// to act on the object, knowing that it has exclusive access to the
- // object. Always returns false when the immortal bit is set.
+ // object. Always returns false when the immortal bit is set.
inline bool IsOne() {
- return (count_.load(std::memory_order_acquire) & kRefcountMask) ==
- kRefIncrement;
+ return count_.load(std::memory_order_acquire) == kRefIncrement;
}
bool IsImmortal() const {
@@ -196,32 +194,15 @@ class RefcountAndFlags {
}
private:
- // We reserve the bottom bits for flags.
+ // We reserve the bottom bit for flag.
// kImmortalBit indicates that this entity should never be collected; it is
// used for the StringConstant constructor to avoid collecting immutable
// constant cords.
- // kReservedFlag is reserved for future use.
enum Flags {
- kNumFlags = 2,
+ kNumFlags = 1,
kImmortalFlag = 0x1,
- kReservedFlag = 0x2,
kRefIncrement = (1 << kNumFlags),
-
- // Bitmask to use when checking refcount by equality. This masks out
- // all flags except kImmortalFlag, which is part of the refcount for
- // purposes of equality. (A refcount of 0 or 1 does not count as 0 or 1
- // if the immortal bit is set.)
- kRefcountMask = ~kReservedFlag,
-
- // Bitmask to use when checking if refcount is equal to 1 and not
- // immortal when decrementing the refcount. This masks out kRefIncrement and
- // all flags except kImmortalFlag. If the masked RefcountAndFlags is 0, we
- // assume the refcount is equal to 1, since we know it's not immortal and
- // not greater than 1. If the masked RefcountAndFlags is not 0, we can
- // assume the refcount is not equal to 1 since either a higher bit in the
- // refcount is set, or kImmortal is set.
- kHighRefcountMask = kRefcountMask & ~kRefIncrement,
};
std::atomic<int32_t> count_;
@@ -233,7 +214,7 @@ enum CordRepKind {
SUBSTRING = 1,
CRC = 2,
BTREE = 3,
- RING = 4,
+ UNUSED_4 = 4,
EXTERNAL = 5,
// We have different tags for different sized flat arrays,
@@ -252,12 +233,8 @@ enum CordRepKind {
// There are various locations where we want to check if some rep is a 'plain'
// data edge, i.e. an external or flat rep. By having FLAT == EXTERNAL + 1, we
// can perform this check in a single branch as 'tag >= EXTERNAL'
-// Likewise, we have some locations where we check for 'ring or external/flat',
-// so likewise align RING to EXTERNAL.
// Note that we can leave this optimization to the compiler. The compiler will
// DTRT when it sees a condition like `tag == EXTERNAL || tag >= FLAT`.
-static_assert(RING == BTREE + 1, "BTREE and RING not consecutive");
-static_assert(EXTERNAL == RING + 1, "BTREE and EXTERNAL not consecutive");
static_assert(FLAT == EXTERNAL + 1, "EXTERNAL and FLAT not consecutive");
struct CordRep {
@@ -301,15 +278,12 @@ struct CordRep {
// # LINT.ThenChange(cord_rep_btree.h:copy_raw)
// Returns true if this instance's tag matches the requested type.
- constexpr bool IsRing() const { return tag == RING; }
constexpr bool IsSubstring() const { return tag == SUBSTRING; }
constexpr bool IsCrc() const { return tag == CRC; }
constexpr bool IsExternal() const { return tag == EXTERNAL; }
constexpr bool IsFlat() const { return tag >= FLAT; }
constexpr bool IsBtree() const { return tag == BTREE; }
- inline CordRepRing* ring();
- inline const CordRepRing* ring() const;
inline CordRepSubstring* substring();
inline const CordRepSubstring* substring() const;
inline CordRepCrc* crc();
diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_ring.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_ring.cc
deleted file mode 100644
index af2fc7683d..0000000000
--- a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_ring.cc
+++ /dev/null
@@ -1,773 +0,0 @@
-// Copyright 2020 The Abseil Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-#include "absl/strings/internal/cord_rep_ring.h"
-
-#include <cassert>
-#include <cstddef>
-#include <cstdint>
-#include <iostream>
-#include <limits>
-#include <memory>
-#include <string>
-
-#include "absl/base/internal/raw_logging.h"
-#include "absl/base/internal/throw_delegate.h"
-#include "absl/base/macros.h"
-#include "absl/container/inlined_vector.h"
-#include "absl/strings/internal/cord_internal.h"
-#include "absl/strings/internal/cord_rep_consume.h"
-#include "absl/strings/internal/cord_rep_flat.h"
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-namespace cord_internal {
-
-namespace {
-
-using index_type = CordRepRing::index_type;
-
-enum class Direction { kForward, kReversed };
-
-inline bool IsFlatOrExternal(CordRep* rep) {
- return rep->IsFlat() || rep->IsExternal();
-}
-
-// Verifies that n + extra <= kMaxCapacity: throws std::length_error otherwise.
-inline void CheckCapacity(size_t n, size_t extra) {
- if (ABSL_PREDICT_FALSE(extra > CordRepRing::kMaxCapacity - n)) {
- base_internal::ThrowStdLengthError("Maximum capacity exceeded");
- }
-}
-
-// Creates a flat from the provided string data, allocating up to `extra`
-// capacity in the returned flat depending on kMaxFlatLength limitations.
-// Requires `len` to be less or equal to `kMaxFlatLength`
-CordRepFlat* CreateFlat(const char* s, size_t n, size_t extra = 0) { // NOLINT
- assert(n <= kMaxFlatLength);
- auto* rep = CordRepFlat::New(n + extra);
- rep->length = n;
- memcpy(rep->Data(), s, n);
- return rep;
-}
-
-// Unrefs the entries in `[head, tail)`.
-// Requires all entries to be a FLAT or EXTERNAL node.
-void UnrefEntries(const CordRepRing* rep, index_type head, index_type tail) {
- rep->ForEach(head, tail, [rep](index_type ix) {
- CordRep* child = rep->entry_child(ix);
- if (!child->refcount.Decrement()) {
- if (child->tag >= FLAT) {
- CordRepFlat::Delete(child->flat());
- } else {
- CordRepExternal::Delete(child->external());
- }
- }
- });
-}
-
-} // namespace
-
-std::ostream& operator<<(std::ostream& s, const CordRepRing& rep) {
- // Note: 'pos' values are defined as size_t (for overflow reasons), but that
- // prints really awkward for small prepended values such as -5. ssize_t is not
- // portable (POSIX), so we use ptrdiff_t instead to cast to signed values.
- s << " CordRepRing(" << &rep << ", length = " << rep.length
- << ", head = " << rep.head_ << ", tail = " << rep.tail_
- << ", cap = " << rep.capacity_ << ", rc = " << rep.refcount.Get()
- << ", begin_pos_ = " << static_cast<ptrdiff_t>(rep.begin_pos_) << ") {\n";
- CordRepRing::index_type head = rep.head();
- do {
- CordRep* child = rep.entry_child(head);
- s << " entry[" << head << "] length = " << rep.entry_length(head)
- << ", child " << child << ", clen = " << child->length
- << ", tag = " << static_cast<int>(child->tag)
- << ", rc = " << child->refcount.Get()
- << ", offset = " << rep.entry_data_offset(head)
- << ", end_pos = " << static_cast<ptrdiff_t>(rep.entry_end_pos(head))
- << "\n";
- head = rep.advance(head);
- } while (head != rep.tail());
- return s << "}\n";
-}
-
-void CordRepRing::AddDataOffset(index_type index, size_t n) {
- entry_data_offset()[index] += static_cast<offset_type>(n);
-}
-
-void CordRepRing::SubLength(index_type index, size_t n) {
- entry_end_pos()[index] -= n;
-}
-
-class CordRepRing::Filler {
- public:
- Filler(CordRepRing* rep, index_type pos) : rep_(rep), head_(pos), pos_(pos) {}
-
- index_type head() const { return head_; }
- index_type pos() const { return pos_; }
-
- void Add(CordRep* child, size_t offset, pos_type end_pos) {
- rep_->entry_end_pos()[pos_] = end_pos;
- rep_->entry_child()[pos_] = child;
- rep_->entry_data_offset()[pos_] = static_cast<offset_type>(offset);
- pos_ = rep_->advance(pos_);
- }
-
- private:
- CordRepRing* rep_;
- index_type head_;
- index_type pos_;
-};
-
-#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
-constexpr size_t CordRepRing::kMaxCapacity;
-#endif
-
-bool CordRepRing::IsValid(std::ostream& output) const {
- if (capacity_ == 0) {
- output << "capacity == 0";
- return false;
- }
-
- if (head_ >= capacity_ || tail_ >= capacity_) {
- output << "head " << head_ << " and/or tail " << tail_ << "exceed capacity "
- << capacity_;
- return false;
- }
-
- const index_type back = retreat(tail_);
- size_t pos_length = Distance(begin_pos_, entry_end_pos(back));
- if (pos_length != length) {
- output << "length " << length << " does not match positional length "
- << pos_length << " from begin_pos " << begin_pos_ << " and entry["
- << back << "].end_pos " << entry_end_pos(back);
- return false;
- }
-
- index_type head = head_;
- pos_type begin_pos = begin_pos_;
- do {
- pos_type end_pos = entry_end_pos(head);
- size_t entry_length = Distance(begin_pos, end_pos);
- if (entry_length == 0) {
- output << "entry[" << head << "] has an invalid length " << entry_length
- << " from begin_pos " << begin_pos << " and end_pos " << end_pos;
- return false;
- }
-
- CordRep* child = entry_child(head);
- if (child == nullptr) {
- output << "entry[" << head << "].child == nullptr";
- return false;
- }
- if (child->tag < FLAT && child->tag != EXTERNAL) {
- output << "entry[" << head << "].child has an invalid tag "
- << static_cast<int>(child->tag);
- return false;
- }
-
- size_t offset = entry_data_offset(head);
- if (offset >= child->length || entry_length > child->length - offset) {
- output << "entry[" << head << "] has offset " << offset
- << " and entry length " << entry_length
- << " which are outside of the child's length of " << child->length;
- return false;
- }
-
- begin_pos = end_pos;
- head = advance(head);
- } while (head != tail_);
-
- return true;
-}
-
-#ifdef EXTRA_CORD_RING_VALIDATION
-CordRepRing* CordRepRing::Validate(CordRepRing* rep, const char* file,
- int line) {
- if (!rep->IsValid(std::cerr)) {
- std::cerr << "\nERROR: CordRepRing corrupted";
- if (line) std::cerr << " at line " << line;
- if (file) std::cerr << " in file " << file;
- std::cerr << "\nContent = " << *rep;
- abort();
- }
- return rep;
-}
-#endif // EXTRA_CORD_RING_VALIDATION
-
-CordRepRing* CordRepRing::New(size_t capacity, size_t extra) {
- CheckCapacity(capacity, extra);
-
- size_t size = AllocSize(capacity += extra);
- void* mem = ::operator new(size);
- auto* rep = new (mem) CordRepRing(static_cast<index_type>(capacity));
- rep->tag = RING;
- rep->capacity_ = static_cast<index_type>(capacity);
- rep->begin_pos_ = 0;
- return rep;
-}
-
-void CordRepRing::SetCapacityForTesting(size_t capacity) {
- // Adjust for the changed layout
- assert(capacity <= capacity_);
- assert(head() == 0 || head() < tail());
- memmove(Layout::Partial(capacity).Pointer<1>(data_) + head(),
- Layout::Partial(capacity_).Pointer<1>(data_) + head(),
- entries() * sizeof(Layout::ElementType<1>));
- memmove(Layout::Partial(capacity, capacity).Pointer<2>(data_) + head(),
- Layout::Partial(capacity_, capacity_).Pointer<2>(data_) + head(),
- entries() * sizeof(Layout::ElementType<2>));
- capacity_ = static_cast<index_type>(capacity);
-}
-
-void CordRepRing::Delete(CordRepRing* rep) {
- assert(rep != nullptr && rep->IsRing());
-#if defined(__cpp_sized_deallocation)
- size_t size = AllocSize(rep->capacity_);
- rep->~CordRepRing();
- ::operator delete(rep, size);
-#else
- rep->~CordRepRing();
- ::operator delete(rep);
-#endif
-}
-
-void CordRepRing::Destroy(CordRepRing* rep) {
- UnrefEntries(rep, rep->head(), rep->tail());
- Delete(rep);
-}
-
-template <bool ref>
-void CordRepRing::Fill(const CordRepRing* src, index_type head,
- index_type tail) {
- this->length = src->length;
- head_ = 0;
- tail_ = advance(0, src->entries(head, tail));
- begin_pos_ = src->begin_pos_;
-
- // TODO(mvels): there may be opportunities here for large buffers.
- auto* dst_pos = entry_end_pos();
- auto* dst_child = entry_child();
- auto* dst_offset = entry_data_offset();
- src->ForEach(head, tail, [&](index_type index) {
- *dst_pos++ = src->entry_end_pos(index);
- CordRep* child = src->entry_child(index);
- *dst_child++ = ref ? CordRep::Ref(child) : child;
- *dst_offset++ = src->entry_data_offset(index);
- });
-}
-
-CordRepRing* CordRepRing::Copy(CordRepRing* rep, index_type head,
- index_type tail, size_t extra) {
- CordRepRing* newrep = CordRepRing::New(rep->entries(head, tail), extra);
- newrep->Fill<true>(rep, head, tail);
- CordRep::Unref(rep);
- return newrep;
-}
-
-CordRepRing* CordRepRing::Mutable(CordRepRing* rep, size_t extra) {
- // Get current number of entries, and check for max capacity.
- size_t entries = rep->entries();
-
- if (!rep->refcount.IsOne()) {
- return Copy(rep, rep->head(), rep->tail(), extra);
- } else if (entries + extra > rep->capacity()) {
- const size_t min_grow = rep->capacity() + rep->capacity() / 2;
- const size_t min_extra = (std::max)(extra, min_grow - entries);
- CordRepRing* newrep = CordRepRing::New(entries, min_extra);
- newrep->Fill<false>(rep, rep->head(), rep->tail());
- CordRepRing::Delete(rep);
- return newrep;
- } else {
- return rep;
- }
-}
-
-Span<char> CordRepRing::GetAppendBuffer(size_t size) {
- assert(refcount.IsOne());
- index_type back = retreat(tail_);
- CordRep* child = entry_child(back);
- if (child->tag >= FLAT && child->refcount.IsOne()) {
- size_t capacity = child->flat()->Capacity();
- pos_type end_pos = entry_end_pos(back);
- size_t data_offset = entry_data_offset(back);
- size_t entry_length = Distance(entry_begin_pos(back), end_pos);
- size_t used = data_offset + entry_length;
- if (size_t n = (std::min)(capacity - used, size)) {
- child->length = data_offset + entry_length + n;
- entry_end_pos()[back] = end_pos + n;
- this->length += n;
- return {child->flat()->Data() + used, n};
- }
- }
- return {nullptr, 0};
-}
-
-Span<char> CordRepRing::GetPrependBuffer(size_t size) {
- assert(refcount.IsOne());
- CordRep* child = entry_child(head_);
- size_t data_offset = entry_data_offset(head_);
- if (data_offset && child->refcount.IsOne() && child->tag >= FLAT) {
- size_t n = (std::min)(data_offset, size);
- this->length += n;
- begin_pos_ -= n;
- data_offset -= n;
- entry_data_offset()[head_] = static_cast<offset_type>(data_offset);
- return {child->flat()->Data() + data_offset, n};
- }
- return {nullptr, 0};
-}
-
-CordRepRing* CordRepRing::CreateFromLeaf(CordRep* child, size_t offset,
- size_t len, size_t extra) {
- CordRepRing* rep = CordRepRing::New(1, extra);
- rep->head_ = 0;
- rep->tail_ = rep->advance(0);
- rep->length = len;
- rep->entry_end_pos()[0] = len;
- rep->entry_child()[0] = child;
- rep->entry_data_offset()[0] = static_cast<offset_type>(offset);
- return Validate(rep);
-}
-
-CordRepRing* CordRepRing::CreateSlow(CordRep* child, size_t extra) {
- CordRepRing* rep = nullptr;
- Consume(child, [&](CordRep* child_arg, size_t offset, size_t len) {
- if (IsFlatOrExternal(child_arg)) {
- rep = rep ? AppendLeaf(rep, child_arg, offset, len)
- : CreateFromLeaf(child_arg, offset, len, extra);
- } else if (rep) {
- rep = AddRing<AddMode::kAppend>(rep, child_arg->ring(), offset, len);
- } else if (offset == 0 && child_arg->length == len) {
- rep = Mutable(child_arg->ring(), extra);
- } else {
- rep = SubRing(child_arg->ring(), offset, len, extra);
- }
- });
- return Validate(rep, nullptr, __LINE__);
-}
-
-CordRepRing* CordRepRing::Create(CordRep* child, size_t extra) {
- size_t length = child->length;
- if (IsFlatOrExternal(child)) {
- return CreateFromLeaf(child, 0, length, extra);
- }
- if (child->IsRing()) {
- return Mutable(child->ring(), extra);
- }
- return CreateSlow(child, extra);
-}
-
-template <CordRepRing::AddMode mode>
-CordRepRing* CordRepRing::AddRing(CordRepRing* rep, CordRepRing* ring,
- size_t offset, size_t len) {
- assert(offset < ring->length);
- constexpr bool append = mode == AddMode::kAppend;
- Position head = ring->Find(offset);
- Position tail = ring->FindTail(head.index, offset + len);
- const index_type entries = ring->entries(head.index, tail.index);
-
- rep = Mutable(rep, entries);
-
- // The delta for making ring[head].end_pos into 'len - offset'
- const pos_type delta_length =
- (append ? rep->begin_pos_ + rep->length : rep->begin_pos_ - len) -
- ring->entry_begin_pos(head.index) - head.offset;
-
- // Start filling at `tail`, or `entries` before `head`
- Filler filler(rep, append ? rep->tail_ : rep->retreat(rep->head_, entries));
-
- if (ring->refcount.IsOne()) {
- // Copy entries from source stealing the ref and adjusting the end position.
- // Commit the filler as this is no-op.
- ring->ForEach(head.index, tail.index, [&](index_type ix) {
- filler.Add(ring->entry_child(ix), ring->entry_data_offset(ix),
- ring->entry_end_pos(ix) + delta_length);
- });
-
- // Unref entries we did not copy over, and delete source.
- if (head.index != ring->head_) UnrefEntries(ring, ring->head_, head.index);
- if (tail.index != ring->tail_) UnrefEntries(ring, tail.index, ring->tail_);
- CordRepRing::Delete(ring);
- } else {
- ring->ForEach(head.index, tail.index, [&](index_type ix) {
- CordRep* child = ring->entry_child(ix);
- filler.Add(child, ring->entry_data_offset(ix),
- ring->entry_end_pos(ix) + delta_length);
- CordRep::Ref(child);
- });
- CordRepRing::Unref(ring);
- }
-
- if (head.offset) {
- // Increase offset of first 'source' entry appended or prepended.
- // This is always the entry in `filler.head()`
- rep->AddDataOffset(filler.head(), head.offset);
- }
-
- if (tail.offset) {
- // Reduce length of last 'source' entry appended or prepended.
- // This is always the entry tailed by `filler.pos()`
- rep->SubLength(rep->retreat(filler.pos()), tail.offset);
- }
-
- // Commit changes
- rep->length += len;
- if (append) {
- rep->tail_ = filler.pos();
- } else {
- rep->head_ = filler.head();
- rep->begin_pos_ -= len;
- }
-
- return Validate(rep);
-}
-
-CordRepRing* CordRepRing::AppendSlow(CordRepRing* rep, CordRep* child) {
- Consume(child, [&rep](CordRep* child_arg, size_t offset, size_t len) {
- if (child_arg->IsRing()) {
- rep = AddRing<AddMode::kAppend>(rep, child_arg->ring(), offset, len);
- } else {
- rep = AppendLeaf(rep, child_arg, offset, len);
- }
- });
- return rep;
-}
-
-CordRepRing* CordRepRing::AppendLeaf(CordRepRing* rep, CordRep* child,
- size_t offset, size_t len) {
- rep = Mutable(rep, 1);
- index_type back = rep->tail_;
- const pos_type begin_pos = rep->begin_pos_ + rep->length;
- rep->tail_ = rep->advance(rep->tail_);
- rep->length += len;
- rep->entry_end_pos()[back] = begin_pos + len;
- rep->entry_child()[back] = child;
- rep->entry_data_offset()[back] = static_cast<offset_type>(offset);
- return Validate(rep, nullptr, __LINE__);
-}
-
-CordRepRing* CordRepRing::Append(CordRepRing* rep, CordRep* child) {
- size_t length = child->length;
- if (IsFlatOrExternal(child)) {
- return AppendLeaf(rep, child, 0, length);
- }
- if (child->IsRing()) {
- return AddRing<AddMode::kAppend>(rep, child->ring(), 0, length);
- }
- return AppendSlow(rep, child);
-}
-
-CordRepRing* CordRepRing::PrependSlow(CordRepRing* rep, CordRep* child) {
- ReverseConsume(child, [&](CordRep* child_arg, size_t offset, size_t len) {
- if (IsFlatOrExternal(child_arg)) {
- rep = PrependLeaf(rep, child_arg, offset, len);
- } else {
- rep = AddRing<AddMode::kPrepend>(rep, child_arg->ring(), offset, len);
- }
- });
- return Validate(rep);
-}
-
-CordRepRing* CordRepRing::PrependLeaf(CordRepRing* rep, CordRep* child,
- size_t offset, size_t len) {
- rep = Mutable(rep, 1);
- index_type head = rep->retreat(rep->head_);
- pos_type end_pos = rep->begin_pos_;
- rep->head_ = head;
- rep->length += len;
- rep->begin_pos_ -= len;
- rep->entry_end_pos()[head] = end_pos;
- rep->entry_child()[head] = child;
- rep->entry_data_offset()[head] = static_cast<offset_type>(offset);
- return Validate(rep);
-}
-
-CordRepRing* CordRepRing::Prepend(CordRepRing* rep, CordRep* child) {
- size_t length = child->length;
- if (IsFlatOrExternal(child)) {
- return PrependLeaf(rep, child, 0, length);
- }
- if (child->IsRing()) {
- return AddRing<AddMode::kPrepend>(rep, child->ring(), 0, length);
- }
- return PrependSlow(rep, child);
-}
-
-CordRepRing* CordRepRing::Append(CordRepRing* rep, absl::string_view data,
- size_t extra) {
- if (rep->refcount.IsOne()) {
- Span<char> avail = rep->GetAppendBuffer(data.length());
- if (!avail.empty()) {
- memcpy(avail.data(), data.data(), avail.length());
- data.remove_prefix(avail.length());
- }
- }
- if (data.empty()) return Validate(rep);
-
- const size_t flats = (data.length() - 1) / kMaxFlatLength + 1;
- rep = Mutable(rep, flats);
-
- Filler filler(rep, rep->tail_);
- pos_type pos = rep->begin_pos_ + rep->length;
-
- while (data.length() >= kMaxFlatLength) {
- auto* flat = CreateFlat(data.data(), kMaxFlatLength);
- filler.Add(flat, 0, pos += kMaxFlatLength);
- data.remove_prefix(kMaxFlatLength);
- }
-
- if (data.length()) {
- auto* flat = CreateFlat(data.data(), data.length(), extra);
- filler.Add(flat, 0, pos += data.length());
- }
-
- rep->length = pos - rep->begin_pos_;
- rep->tail_ = filler.pos();
-
- return Validate(rep);
-}
-
-CordRepRing* CordRepRing::Prepend(CordRepRing* rep, absl::string_view data,
- size_t extra) {
- if (rep->refcount.IsOne()) {
- Span<char> avail = rep->GetPrependBuffer(data.length());
- if (!avail.empty()) {
- const char* tail = data.data() + data.length() - avail.length();
- memcpy(avail.data(), tail, avail.length());
- data.remove_suffix(avail.length());
- }
- }
- if (data.empty()) return rep;
-
- const size_t flats = (data.length() - 1) / kMaxFlatLength + 1;
- rep = Mutable(rep, flats);
- pos_type pos = rep->begin_pos_;
- Filler filler(rep, rep->retreat(rep->head_, static_cast<index_type>(flats)));
-
- size_t first_size = data.size() - (flats - 1) * kMaxFlatLength;
- CordRepFlat* flat = CordRepFlat::New(first_size + extra);
- flat->length = first_size + extra;
- memcpy(flat->Data() + extra, data.data(), first_size);
- data.remove_prefix(first_size);
- filler.Add(flat, extra, pos);
- pos -= first_size;
-
- while (!data.empty()) {
- assert(data.size() >= kMaxFlatLength);
- flat = CreateFlat(data.data(), kMaxFlatLength);
- filler.Add(flat, 0, pos);
- pos -= kMaxFlatLength;
- data.remove_prefix(kMaxFlatLength);
- }
-
- rep->head_ = filler.head();
- rep->length += rep->begin_pos_ - pos;
- rep->begin_pos_ = pos;
-
- return Validate(rep);
-}
-
-// 32 entries is 32 * sizeof(pos_type) = 4 cache lines on x86
-static constexpr index_type kBinarySearchThreshold = 32;
-static constexpr index_type kBinarySearchEndCount = 8;
-
-template <bool wrap>
-CordRepRing::index_type CordRepRing::FindBinary(index_type head,
- index_type tail,
- size_t offset) const {
- index_type count = tail + (wrap ? capacity_ : 0) - head;
- do {
- count = (count - 1) / 2;
- assert(count < entries(head, tail_));
- index_type mid = wrap ? advance(head, count) : head + count;
- index_type after_mid = wrap ? advance(mid) : mid + 1;
- bool larger = (offset >= entry_end_offset(mid));
- head = larger ? after_mid : head;
- tail = larger ? tail : mid;
- assert(head != tail);
- } while (ABSL_PREDICT_TRUE(count > kBinarySearchEndCount));
- return head;
-}
-
-CordRepRing::Position CordRepRing::FindSlow(index_type head,
- size_t offset) const {
- index_type tail = tail_;
-
- // Binary search until we are good for linear search
- // Optimize for branchless / non wrapping ops
- if (tail > head) {
- index_type count = tail - head;
- if (count > kBinarySearchThreshold) {
- head = FindBinary<false>(head, tail, offset);
- }
- } else {
- index_type count = capacity_ + tail - head;
- if (count > kBinarySearchThreshold) {
- head = FindBinary<true>(head, tail, offset);
- }
- }
-
- pos_type pos = entry_begin_pos(head);
- pos_type end_pos = entry_end_pos(head);
- while (offset >= Distance(begin_pos_, end_pos)) {
- head = advance(head);
- pos = end_pos;
- end_pos = entry_end_pos(head);
- }
-
- return {head, offset - Distance(begin_pos_, pos)};
-}
-
-CordRepRing::Position CordRepRing::FindTailSlow(index_type head,
- size_t offset) const {
- index_type tail = tail_;
- const size_t tail_offset = offset - 1;
-
- // Binary search until we are good for linear search
- // Optimize for branchless / non wrapping ops
- if (tail > head) {
- index_type count = tail - head;
- if (count > kBinarySearchThreshold) {
- head = FindBinary<false>(head, tail, tail_offset);
- }
- } else {
- index_type count = capacity_ + tail - head;
- if (count > kBinarySearchThreshold) {
- head = FindBinary<true>(head, tail, tail_offset);
- }
- }
-
- size_t end_offset = entry_end_offset(head);
- while (tail_offset >= end_offset) {
- head = advance(head);
- end_offset = entry_end_offset(head);
- }
-
- return {advance(head), end_offset - offset};
-}
-
-char CordRepRing::GetCharacter(size_t offset) const {
- assert(offset < length);
-
- Position pos = Find(offset);
- size_t data_offset = entry_data_offset(pos.index) + pos.offset;
- return GetRepData(entry_child(pos.index))[data_offset];
-}
-
-CordRepRing* CordRepRing::SubRing(CordRepRing* rep, size_t offset,
- size_t len, size_t extra) {
- assert(offset <= rep->length);
- assert(offset <= rep->length - len);
-
- if (len == 0) {
- CordRep::Unref(rep);
- return nullptr;
- }
-
- // Find position of first byte
- Position head = rep->Find(offset);
- Position tail = rep->FindTail(head.index, offset + len);
- const size_t new_entries = rep->entries(head.index, tail.index);
-
- if (rep->refcount.IsOne() && extra <= (rep->capacity() - new_entries)) {
- // We adopt a privately owned rep and no extra entries needed.
- if (head.index != rep->head_) UnrefEntries(rep, rep->head_, head.index);
- if (tail.index != rep->tail_) UnrefEntries(rep, tail.index, rep->tail_);
- rep->head_ = head.index;
- rep->tail_ = tail.index;
- } else {
- // Copy subset to new rep
- rep = Copy(rep, head.index, tail.index, extra);
- head.index = rep->head_;
- tail.index = rep->tail_;
- }
-
- // Adjust begin_pos and length
- rep->length = len;
- rep->begin_pos_ += offset;
-
- // Adjust head and tail blocks
- if (head.offset) {
- rep->AddDataOffset(head.index, head.offset);
- }
- if (tail.offset) {
- rep->SubLength(rep->retreat(tail.index), tail.offset);
- }
-
- return Validate(rep);
-}
-
-CordRepRing* CordRepRing::RemovePrefix(CordRepRing* rep, size_t len,
- size_t extra) {
- assert(len <= rep->length);
- if (len == rep->length) {
- CordRep::Unref(rep);
- return nullptr;
- }
-
- Position head = rep->Find(len);
- if (rep->refcount.IsOne()) {
- if (head.index != rep->head_) UnrefEntries(rep, rep->head_, head.index);
- rep->head_ = head.index;
- } else {
- rep = Copy(rep, head.index, rep->tail_, extra);
- head.index = rep->head_;
- }
-
- // Adjust begin_pos and length
- rep->length -= len;
- rep->begin_pos_ += len;
-
- // Adjust head block
- if (head.offset) {
- rep->AddDataOffset(head.index, head.offset);
- }
-
- return Validate(rep);
-}
-
-CordRepRing* CordRepRing::RemoveSuffix(CordRepRing* rep, size_t len,
- size_t extra) {
- assert(len <= rep->length);
-
- if (len == rep->length) {
- CordRep::Unref(rep);
- return nullptr;
- }
-
- Position tail = rep->FindTail(rep->length - len);
- if (rep->refcount.IsOne()) {
- // We adopt a privately owned rep, scrub.
- if (tail.index != rep->tail_) UnrefEntries(rep, tail.index, rep->tail_);
- rep->tail_ = tail.index;
- } else {
- // Copy subset to new rep
- rep = Copy(rep, rep->head_, tail.index, extra);
- tail.index = rep->tail_;
- }
-
- // Adjust length
- rep->length -= len;
-
- // Adjust tail block
- if (tail.offset) {
- rep->SubLength(rep->retreat(tail.index), tail.offset);
- }
-
- return Validate(rep);
-}
-
-} // namespace cord_internal
-ABSL_NAMESPACE_END
-} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_ring.h b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_ring.h
deleted file mode 100644
index 79a2fdb1c3..0000000000
--- a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_rep_ring.h
+++ /dev/null
@@ -1,607 +0,0 @@
-// Copyright 2020 The Abseil Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_RING_H_
-#define ABSL_STRINGS_INTERNAL_CORD_REP_RING_H_
-
-#include <cassert>
-#include <cstddef>
-#include <cstdint>
-#include <iosfwd>
-#include <limits>
-#include <memory>
-
-#include "absl/container/internal/layout.h"
-#include "absl/strings/internal/cord_internal.h"
-#include "absl/strings/internal/cord_rep_flat.h"
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-namespace cord_internal {
-
-// All operations modifying a ring buffer are implemented as static methods
-// requiring a CordRepRing instance with a reference adopted by the method.
-//
-// The methods return the modified ring buffer, which may be equal to the input
-// if the input was not shared, and having large enough capacity to accommodate
-// any newly added node(s). Otherwise, a copy of the input rep with the new
-// node(s) added is returned.
-//
-// Any modification on non shared ring buffers with enough capacity will then
-// require minimum atomic operations. Caller should where possible provide
-// reasonable `extra` hints for both anticipated extra `flat` byte space, as
-// well as anticipated extra nodes required for complex operations.
-//
-// Example of code creating a ring buffer, adding some data to it,
-// and discarding the buffer when done:
-//
-// void FunWithRings() {
-// // Create ring with 3 flats
-// CordRep* flat = CreateFlat("Hello");
-// CordRepRing* ring = CordRepRing::Create(flat, 2);
-// ring = CordRepRing::Append(ring, CreateFlat(" "));
-// ring = CordRepRing::Append(ring, CreateFlat("world"));
-// DoSomethingWithRing(ring);
-// CordRep::Unref(ring);
-// }
-//
-// Example of code Copying an existing ring buffer and modifying it:
-//
-// void MoreFunWithRings(CordRepRing* src) {
-// CordRepRing* ring = CordRep::Ref(src)->ring();
-// ring = CordRepRing::Append(ring, CreateFlat("Hello"));
-// ring = CordRepRing::Append(ring, CreateFlat(" "));
-// ring = CordRepRing::Append(ring, CreateFlat("world"));
-// DoSomethingWithRing(ring);
-// CordRep::Unref(ring);
-// }
-//
-class CordRepRing : public CordRep {
- public:
- // `pos_type` represents a 'logical position'. A CordRepRing instance has a
- // `begin_pos` (default 0), and each node inside the buffer will have an
- // `end_pos` which is the `end_pos` of the previous node (or `begin_pos`) plus
- // this node's length. The purpose is to allow for a binary search on this
- // position, while allowing O(1) prepend and append operations.
- using pos_type = size_t;
-
- // `index_type` is the type for the `head`, `tail` and `capacity` indexes.
- // Ring buffers are limited to having no more than four billion entries.
- using index_type = uint32_t;
-
- // `offset_type` is the type for the data offset inside a child rep's data.
- using offset_type = uint32_t;
-
- // Position holds the node index and relative offset into the node for
- // some physical offset in the contained data as returned by the Find()
- // and FindTail() methods.
- struct Position {
- index_type index;
- size_t offset;
- };
-
- // The maximum # of child nodes that can be hosted inside a CordRepRing.
- static constexpr size_t kMaxCapacity = (std::numeric_limits<uint32_t>::max)();
-
- // CordRepring can not be default constructed, moved, copied or assigned.
- CordRepRing() = delete;
- CordRepRing(const CordRepRing&) = delete;
- CordRepRing& operator=(const CordRepRing&) = delete;
-
- // Returns true if this instance is valid, false if some or all of the
- // invariants are broken. Intended for debug purposes only.
- // `output` receives an explanation of the broken invariants.
- bool IsValid(std::ostream& output) const;
-
- // Returns the size in bytes for a CordRepRing with `capacity' entries.
- static constexpr size_t AllocSize(size_t capacity);
-
- // Returns the distance in bytes from `pos` to `end_pos`.
- static constexpr size_t Distance(pos_type pos, pos_type end_pos);
-
- // Creates a new ring buffer from the provided `rep`. Adopts a reference
- // on `rep`. The returned ring buffer has a capacity of at least `extra + 1`
- static CordRepRing* Create(CordRep* child, size_t extra = 0);
-
- // `head`, `tail` and `capacity` indexes defining the ring buffer boundaries.
- index_type head() const { return head_; }
- index_type tail() const { return tail_; }
- index_type capacity() const { return capacity_; }
-
- // Returns the number of entries in this instance.
- index_type entries() const { return entries(head_, tail_); }
-
- // Returns the logical begin position of this instance.
- pos_type begin_pos() const { return begin_pos_; }
-
- // Returns the number of entries for a given head-tail range.
- // Requires `head` and `tail` values to be less than `capacity()`.
- index_type entries(index_type head, index_type tail) const {
- assert(head < capacity_ && tail < capacity_);
- return tail - head + ((tail > head) ? 0 : capacity_);
- }
-
- // Returns the logical end position of entry `index`.
- pos_type const& entry_end_pos(index_type index) const {
- assert(IsValidIndex(index));
- return Layout::Partial().Pointer<0>(data_)[index];
- }
-
- // Returns the child pointer of entry `index`.
- CordRep* const& entry_child(index_type index) const {
- assert(IsValidIndex(index));
- return Layout::Partial(capacity()).Pointer<1>(data_)[index];
- }
-
- // Returns the data offset of entry `index`
- offset_type const& entry_data_offset(index_type index) const {
- assert(IsValidIndex(index));
- return Layout::Partial(capacity(), capacity()).Pointer<2>(data_)[index];
- }
-
- // Appends the provided child node to the `rep` instance.
- // Adopts a reference from `rep` and `child` which may not be null.
- // If the provided child is a FLAT or EXTERNAL node, or a SUBSTRING node
- // containing a FLAT or EXTERNAL node, then flat or external the node is added
- // 'as is', with an offset added for the SUBSTRING case.
- // If the provided child is a RING or CONCAT tree, or a SUBSTRING of a RING or
- // CONCAT tree, then all child nodes not excluded by any start offset or
- // length values are added recursively.
- static CordRepRing* Append(CordRepRing* rep, CordRep* child);
-
- // Appends the provided string data to the `rep` instance.
- // This function will attempt to utilize any remaining capacity in the last
- // node of the input if that node is not shared (directly or indirectly), and
- // of type FLAT. Remaining data will be added as one or more FLAT nodes.
- // Any last node added to the ring buffer will be allocated with up to
- // `extra` bytes of capacity for (anticipated) subsequent append actions.
- static CordRepRing* Append(CordRepRing* rep, string_view data,
- size_t extra = 0);
-
- // Prepends the provided child node to the `rep` instance.
- // Adopts a reference from `rep` and `child` which may not be null.
- // If the provided child is a FLAT or EXTERNAL node, or a SUBSTRING node
- // containing a FLAT or EXTERNAL node, then flat or external the node is
- // prepended 'as is', with an optional offset added for the SUBSTRING case.
- // If the provided child is a RING or CONCAT tree, or a SUBSTRING of a RING
- // or CONCAT tree, then all child nodes not excluded by any start offset or
- // length values are added recursively.
- static CordRepRing* Prepend(CordRepRing* rep, CordRep* child);
-
- // Prepends the provided string data to the `rep` instance.
- // This function will attempt to utilize any remaining capacity in the first
- // node of the input if that node is not shared (directly or indirectly), and
- // of type FLAT. Remaining data will be added as one or more FLAT nodes.
- // Any first node prepnded to the ring buffer will be allocated with up to
- // `extra` bytes of capacity for (anticipated) subsequent prepend actions.
- static CordRepRing* Prepend(CordRepRing* rep, string_view data,
- size_t extra = 0);
-
- // Returns a span referencing potentially unused capacity in the last node.
- // The returned span may be empty if no such capacity is available, or if the
- // current instance is shared. Else, a span of size `n <= size` is returned.
- // If non empty, the ring buffer is adjusted to the new length, with the newly
- // added capacity left uninitialized. Callers should assign a value to the
- // entire span before any other operations on this instance.
- Span<char> GetAppendBuffer(size_t size);
-
- // Returns a span referencing potentially unused capacity in the first node.
- // This function is identical to GetAppendBuffer except that it returns a span
- // referencing up to `size` capacity directly before the existing data.
- Span<char> GetPrependBuffer(size_t size);
-
- // Returns a cord ring buffer containing `len` bytes of data starting at
- // `offset`. If the input is not shared, this function will remove all head
- // and tail child nodes outside of the requested range, and adjust the new
- // head and tail nodes as required. If the input is shared, this function
- // returns a new instance sharing some or all of the nodes from the input.
- static CordRepRing* SubRing(CordRepRing* r, size_t offset, size_t len,
- size_t extra = 0);
-
- // Returns a cord ring buffer with the first `len` bytes removed.
- // If the input is not shared, this function will remove all head child nodes
- // fully inside the first `length` bytes, and adjust the new head as required.
- // If the input is shared, this function returns a new instance sharing some
- // or all of the nodes from the input.
- static CordRepRing* RemoveSuffix(CordRepRing* r, size_t len,
- size_t extra = 0);
-
- // Returns a cord ring buffer with the last `len` bytes removed.
- // If the input is not shared, this function will remove all head child nodes
- // fully inside the first `length` bytes, and adjust the new head as required.
- // If the input is shared, this function returns a new instance sharing some
- // or all of the nodes from the input.
- static CordRepRing* RemovePrefix(CordRepRing* r, size_t len,
- size_t extra = 0);
-
- // Returns the character at `offset`. Requires that `offset < length`.
- char GetCharacter(size_t offset) const;
-
- // Returns true if this instance manages a single contiguous buffer, in which
- // case the (optional) output parameter `fragment` is set. Otherwise, the
- // function returns false, and `fragment` is left unchanged.
- bool IsFlat(absl::string_view* fragment) const;
-
- // Returns true if the data starting at `offset` with length `len` is
- // managed by this instance inside a single contiguous buffer, in which case
- // the (optional) output parameter `fragment` is set to the contiguous memory
- // starting at offset `offset` with length `length`. Otherwise, the function
- // returns false, and `fragment` is left unchanged.
- bool IsFlat(size_t offset, size_t len, absl::string_view* fragment) const;
-
- // Testing only: set capacity to requested capacity.
- void SetCapacityForTesting(size_t capacity);
-
- // Returns the CordRep data pointer for the provided CordRep.
- // Requires that the provided `rep` is either a FLAT or EXTERNAL CordRep.
- static const char* GetLeafData(const CordRep* rep);
-
- // Returns the CordRep data pointer for the provided CordRep.
- // Requires that `rep` is either a FLAT, EXTERNAL, or SUBSTRING CordRep.
- static const char* GetRepData(const CordRep* rep);
-
- // Advances the provided position, wrapping around capacity as needed.
- // Requires `index` < capacity()
- inline index_type advance(index_type index) const;
-
- // Advances the provided position by 'n`, wrapping around capacity as needed.
- // Requires `index` < capacity() and `n` <= capacity.
- inline index_type advance(index_type index, index_type n) const;
-
- // Retreats the provided position, wrapping around 0 as needed.
- // Requires `index` < capacity()
- inline index_type retreat(index_type index) const;
-
- // Retreats the provided position by 'n', wrapping around 0 as needed.
- // Requires `index` < capacity()
- inline index_type retreat(index_type index, index_type n) const;
-
- // Returns the logical begin position of entry `index`
- pos_type const& entry_begin_pos(index_type index) const {
- return (index == head_) ? begin_pos_ : entry_end_pos(retreat(index));
- }
-
- // Returns the physical start offset of entry `index`
- size_t entry_start_offset(index_type index) const {
- return Distance(begin_pos_, entry_begin_pos(index));
- }
-
- // Returns the physical end offset of entry `index`
- size_t entry_end_offset(index_type index) const {
- return Distance(begin_pos_, entry_end_pos(index));
- }
-
- // Returns the data length for entry `index`
- size_t entry_length(index_type index) const {
- return Distance(entry_begin_pos(index), entry_end_pos(index));
- }
-
- // Returns the data for entry `index`
- absl::string_view entry_data(index_type index) const;
-
- // Returns the position for `offset` as {index, prefix}. `index` holds the
- // index of the entry at the specified offset and `prefix` holds the relative
- // offset inside that entry.
- // Requires `offset` < length.
- //
- // For example we can implement GetCharacter(offset) as:
- // char GetCharacter(size_t offset) {
- // Position pos = this->Find(offset);
- // return this->entry_data(pos.pos)[pos.offset];
- // }
- inline Position Find(size_t offset) const;
-
- // Find starting at `head`
- inline Position Find(index_type head, size_t offset) const;
-
- // Returns the tail position for `offset` as {tail index, suffix}.
- // `tail index` holds holds the index of the entry holding the offset directly
- // before 'offset` advanced by one. 'suffix` holds the relative offset from
- // that relative offset in the entry to the end of the entry.
- // For example, FindTail(length) will return {tail(), 0}, FindTail(length - 5)
- // will return {retreat(tail), 5)} provided the preceding entry contains at
- // least 5 bytes of data.
- // Requires offset >= 1 && offset <= length.
- //
- // This function is very useful in functions that need to clip the end of some
- // ring buffer such as 'RemovePrefix'.
- // For example, we could implement RemovePrefix for non shared instances as:
- // void RemoveSuffix(size_t n) {
- // Position pos = FindTail(length - n);
- // UnrefEntries(pos.pos, this->tail_);
- // this->tail_ = pos.pos;
- // entry(retreat(pos.pos)).end_pos -= pos.offset;
- // }
- inline Position FindTail(size_t offset) const;
-
- // Find tail starting at `head`
- inline Position FindTail(index_type head, size_t offset) const;
-
- // Invokes f(index_type index) for each entry inside the range [head, tail>
- template <typename F>
- void ForEach(index_type head, index_type tail, F&& f) const {
- index_type n1 = (tail > head) ? tail : capacity_;
- for (index_type i = head; i < n1; ++i) f(i);
- if (tail <= head) {
- for (index_type i = 0; i < tail; ++i) f(i);
- }
- }
-
- // Invokes f(index_type index) for each entry inside this instance.
- template <typename F>
- void ForEach(F&& f) const {
- ForEach(head_, tail_, std::forward<F>(f));
- }
-
- // Dump this instance's data tp stream `s` in human readable format, excluding
- // the actual data content itself. Intended for debug purposes only.
- friend std::ostream& operator<<(std::ostream& s, const CordRepRing& rep);
-
- private:
- enum class AddMode { kAppend, kPrepend };
-
- using Layout = container_internal::Layout<pos_type, CordRep*, offset_type>;
-
- class Filler;
- class Transaction;
- class CreateTransaction;
-
- static constexpr size_t kLayoutAlignment = Layout::Partial().Alignment();
-
- // Creates a new CordRepRing.
- explicit CordRepRing(index_type capacity) : capacity_(capacity) {}
-
- // Returns true if `index` is a valid index into this instance.
- bool IsValidIndex(index_type index) const;
-
- // Debug use only: validates the provided CordRepRing invariants.
- // Verification of all CordRepRing methods can be enabled by defining
- // EXTRA_CORD_RING_VALIDATION, i.e.: `--copts=-DEXTRA_CORD_RING_VALIDATION`
- // Verification is VERY expensive, so only do it for debugging purposes.
- static CordRepRing* Validate(CordRepRing* rep, const char* file = nullptr,
- int line = 0);
-
- // Allocates a CordRepRing large enough to hold `capacity + extra' entries.
- // The returned capacity may be larger if the allocated memory allows for it.
- // The maximum capacity of a CordRepRing is capped at kMaxCapacity.
- // Throws `std::length_error` if `capacity + extra' exceeds kMaxCapacity.
- static CordRepRing* New(size_t capacity, size_t extra);
-
- // Deallocates (but does not destroy) the provided ring buffer.
- static void Delete(CordRepRing* rep);
-
- // Destroys the provided ring buffer, decrementing the reference count of all
- // contained child CordReps. The provided 1\`rep` should have a ref count of
- // one (pre decrement destroy call observing `refcount.IsOne()`) or zero
- // (post decrement destroy call observing `!refcount.Decrement()`).
- static void Destroy(CordRepRing* rep);
-
- // Returns a mutable reference to the logical end position array.
- pos_type* entry_end_pos() {
- return Layout::Partial().Pointer<0>(data_);
- }
-
- // Returns a mutable reference to the child pointer array.
- CordRep** entry_child() {
- return Layout::Partial(capacity()).Pointer<1>(data_);
- }
-
- // Returns a mutable reference to the data offset array.
- offset_type* entry_data_offset() {
- return Layout::Partial(capacity(), capacity()).Pointer<2>(data_);
- }
-
- // Find implementations for the non fast path 0 / length cases.
- Position FindSlow(index_type head, size_t offset) const;
- Position FindTailSlow(index_type head, size_t offset) const;
-
- // Finds the index of the first node that is inside a reasonable distance
- // of the node at `offset` from which we can continue with a linear search.
- template <bool wrap>
- index_type FindBinary(index_type head, index_type tail, size_t offset) const;
-
- // Fills the current (initialized) instance from the provided source, copying
- // entries [head, tail). Adds a reference to copied entries if `ref` is true.
- template <bool ref>
- void Fill(const CordRepRing* src, index_type head, index_type tail);
-
- // Create a copy of 'rep', copying all entries [head, tail), allocating room
- // for `extra` entries. Adds a reference on all copied entries.
- static CordRepRing* Copy(CordRepRing* rep, index_type head, index_type tail,
- size_t extra = 0);
-
- // Returns a Mutable CordRepRing reference from `rep` with room for at least
- // `extra` additional nodes. Adopts a reference count from `rep`.
- // This function will return `rep` if, and only if:
- // - rep.entries + extra <= rep.capacity
- // - rep.refcount == 1
- // Otherwise, this function will create a new copy of `rep` with additional
- // capacity to satisfy `extra` extra nodes, and unref the old `rep` instance.
- //
- // If a new CordRepRing can not be allocated, or the new capacity would exceed
- // the maximum capacity, then the input is consumed only, and an exception is
- // thrown.
- static CordRepRing* Mutable(CordRepRing* rep, size_t extra);
-
- // Slow path for Append(CordRepRing* rep, CordRep* child). This function is
- // exercised if the provided `child` in Append() is not a leaf node, i.e., a
- // ring buffer or old (concat) cord tree.
- static CordRepRing* AppendSlow(CordRepRing* rep, CordRep* child);
-
- // Appends the provided leaf node. Requires `child` to be FLAT or EXTERNAL.
- static CordRepRing* AppendLeaf(CordRepRing* rep, CordRep* child,
- size_t offset, size_t length);
-
- // Prepends the provided leaf node. Requires `child` to be FLAT or EXTERNAL.
- static CordRepRing* PrependLeaf(CordRepRing* rep, CordRep* child,
- size_t offset, size_t length);
-
- // Slow path for Prepend(CordRepRing* rep, CordRep* child). This function is
- // exercised if the provided `child` in Prepend() is not a leaf node, i.e., a
- // ring buffer or old (concat) cord tree.
- static CordRepRing* PrependSlow(CordRepRing* rep, CordRep* child);
-
- // Slow path for Create(CordRep* child, size_t extra). This function is
- // exercised if the provided `child` in Prepend() is not a leaf node, i.e., a
- // ring buffer or old (concat) cord tree.
- static CordRepRing* CreateSlow(CordRep* child, size_t extra);
-
- // Creates a new ring buffer from the provided `child` leaf node. Requires
- // `child` to be FLAT or EXTERNAL. on `rep`.
- // The returned ring buffer has a capacity of at least `1 + extra`
- static CordRepRing* CreateFromLeaf(CordRep* child, size_t offset,
- size_t length, size_t extra);
-
- // Appends or prepends (depending on AddMode) the ring buffer in `ring' to
- // `rep` starting at `offset` with length `len`.
- template <AddMode mode>
- static CordRepRing* AddRing(CordRepRing* rep, CordRepRing* ring,
- size_t offset, size_t len);
-
- // Increases the data offset for entry `index` by `n`.
- void AddDataOffset(index_type index, size_t n);
-
- // Decreases the length for entry `index` by `n`.
- void SubLength(index_type index, size_t n);
-
- index_type head_;
- index_type tail_;
- index_type capacity_;
- pos_type begin_pos_;
-
- alignas(kLayoutAlignment) char data_[kLayoutAlignment];
-
- friend struct CordRep;
-};
-
-constexpr size_t CordRepRing::AllocSize(size_t capacity) {
- return sizeof(CordRepRing) - sizeof(data_) +
- Layout(capacity, capacity, capacity).AllocSize();
-}
-
-inline constexpr size_t CordRepRing::Distance(pos_type pos, pos_type end_pos) {
- return (end_pos - pos);
-}
-
-inline const char* CordRepRing::GetLeafData(const CordRep* rep) {
- return rep->tag != EXTERNAL ? rep->flat()->Data() : rep->external()->base;
-}
-
-inline const char* CordRepRing::GetRepData(const CordRep* rep) {
- if (rep->tag >= FLAT) return rep->flat()->Data();
- if (rep->tag == EXTERNAL) return rep->external()->base;
- return GetLeafData(rep->substring()->child) + rep->substring()->start;
-}
-
-inline CordRepRing::index_type CordRepRing::advance(index_type index) const {
- assert(index < capacity_);
- return ++index == capacity_ ? 0 : index;
-}
-
-inline CordRepRing::index_type CordRepRing::advance(index_type index,
- index_type n) const {
- assert(index < capacity_ && n <= capacity_);
- return (index += n) >= capacity_ ? index - capacity_ : index;
-}
-
-inline CordRepRing::index_type CordRepRing::retreat(index_type index) const {
- assert(index < capacity_);
- return (index > 0 ? index : capacity_) - 1;
-}
-
-inline CordRepRing::index_type CordRepRing::retreat(index_type index,
- index_type n) const {
- assert(index < capacity_ && n <= capacity_);
- return index >= n ? index - n : capacity_ - n + index;
-}
-
-inline absl::string_view CordRepRing::entry_data(index_type index) const {
- size_t data_offset = entry_data_offset(index);
- return {GetRepData(entry_child(index)) + data_offset, entry_length(index)};
-}
-
-inline bool CordRepRing::IsValidIndex(index_type index) const {
- if (index >= capacity_) return false;
- return (tail_ > head_) ? (index >= head_ && index < tail_)
- : (index >= head_ || index < tail_);
-}
-
-#ifndef EXTRA_CORD_RING_VALIDATION
-inline CordRepRing* CordRepRing::Validate(CordRepRing* rep,
- const char* /*file*/, int /*line*/) {
- return rep;
-}
-#endif
-
-inline CordRepRing::Position CordRepRing::Find(size_t offset) const {
- assert(offset < length);
- return (offset == 0) ? Position{head_, 0} : FindSlow(head_, offset);
-}
-
-inline CordRepRing::Position CordRepRing::Find(index_type head,
- size_t offset) const {
- assert(offset < length);
- assert(IsValidIndex(head) && offset >= entry_start_offset(head));
- return (offset == 0) ? Position{head_, 0} : FindSlow(head, offset);
-}
-
-inline CordRepRing::Position CordRepRing::FindTail(size_t offset) const {
- assert(offset > 0 && offset <= length);
- return (offset == length) ? Position{tail_, 0} : FindTailSlow(head_, offset);
-}
-
-inline CordRepRing::Position CordRepRing::FindTail(index_type head,
- size_t offset) const {
- assert(offset > 0 && offset <= length);
- assert(IsValidIndex(head) && offset >= entry_start_offset(head) + 1);
- return (offset == length) ? Position{tail_, 0} : FindTailSlow(head, offset);
-}
-
-// Now that CordRepRing is defined, we can define CordRep's helper casts:
-inline CordRepRing* CordRep::ring() {
- assert(IsRing());
- return static_cast<CordRepRing*>(this);
-}
-
-inline const CordRepRing* CordRep::ring() const {
- assert(IsRing());
- return static_cast<const CordRepRing*>(this);
-}
-
-inline bool CordRepRing::IsFlat(absl::string_view* fragment) const {
- if (entries() == 1) {
- if (fragment) *fragment = entry_data(head());
- return true;
- }
- return false;
-}
-
-inline bool CordRepRing::IsFlat(size_t offset, size_t len,
- absl::string_view* fragment) const {
- const Position pos = Find(offset);
- const absl::string_view data = entry_data(pos.index);
- if (data.length() >= len && data.length() - len >= pos.offset) {
- if (fragment) *fragment = data.substr(pos.offset, len);
- return true;
- }
- return false;
-}
-
-std::ostream& operator<<(std::ostream& s, const CordRepRing& rep);
-
-} // namespace cord_internal
-ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_STRINGS_INTERNAL_CORD_REP_RING_H_
diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info.cc
index 515dfafbb3..b24c3da712 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info.cc
@@ -21,7 +21,6 @@
#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_btree.h"
#include "absl/strings/internal/cord_rep_crc.h"
-#include "absl/strings/internal/cord_rep_ring.h"
#include "absl/strings/internal/cordz_handle.h"
#include "absl/strings/internal/cordz_statistics.h"
#include "absl/strings/internal/cordz_update_tracker.h"
@@ -33,8 +32,6 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {
-using ::absl::base_internal::SpinLockHolder;
-
#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
constexpr size_t CordzInfo::kMaxStackDepth;
#endif
@@ -79,6 +76,8 @@ class CordRepAnalyzer {
// adds the results to `statistics`. Note that node counts and memory sizes
// are not initialized, computed values are added to any existing values.
void AnalyzeCordRep(const CordRep* rep) {
+ ABSL_ASSERT(rep != nullptr);
+
// Process all linear nodes.
// As per the class comments, use refcout - 1 on the top level node, as the
// top level node is assumed to be referenced only for analysis purposes.
@@ -86,7 +85,7 @@ class CordRepAnalyzer {
RepRef repref{rep, (refcount > 1) ? refcount - 1 : 1};
// Process the top level CRC node, if present.
- if (repref.rep->tag == CRC) {
+ if (repref.tag() == CRC) {
statistics_.node_count++;
statistics_.node_counts.crc++;
memory_usage_.Add(sizeof(CordRepCrc), repref.refcount);
@@ -96,15 +95,14 @@ class CordRepAnalyzer {
// Process all top level linear nodes (substrings and flats).
repref = CountLinearReps(repref, memory_usage_);
- if (repref.rep != nullptr) {
- if (repref.rep->tag == RING) {
- AnalyzeRing(repref);
- } else if (repref.rep->tag == BTREE) {
+ switch (repref.tag()) {
+ case CordRepKind::BTREE:
AnalyzeBtree(repref);
- } else {
- // We should have either a concat, btree, or ring node if not null.
- assert(false);
- }
+ break;
+ default:
+ // We should have a btree node if not null.
+ ABSL_ASSERT(repref.tag() == CordRepKind::UNUSED_0);
+ break;
}
// Adds values to output
@@ -122,11 +120,19 @@ class CordRepAnalyzer {
const CordRep* rep;
size_t refcount;
- // Returns a 'child' RepRef which contains the cumulative reference count of
- // this instance multiplied by the child's reference count.
+ // Returns a 'child' RepRef which contains the cumulative reference count
+ // of this instance multiplied by the child's reference count. Returns a
+ // nullptr RepRef value with a refcount of 0 if `child` is nullptr.
RepRef Child(const CordRep* child) const {
+ if (child == nullptr) return RepRef{nullptr, 0};
return RepRef{child, refcount * child->refcount.Get()};
}
+
+ // Returns the tag of this rep, or UNUSED_0 if this instance is null
+ constexpr CordRepKind tag() const {
+ ABSL_ASSERT(rep == nullptr || rep->tag != CordRepKind::UNUSED_0);
+ return rep ? static_cast<CordRepKind>(rep->tag) : CordRepKind::UNUSED_0;
+ }
};
// Memory usage values
@@ -167,7 +173,7 @@ class CordRepAnalyzer {
// buffers where we count children unrounded.
RepRef CountLinearReps(RepRef rep, MemoryUsage& memory_usage) {
// Consume all substrings
- while (rep.rep->tag == SUBSTRING) {
+ while (rep.tag() == SUBSTRING) {
statistics_.node_count++;
statistics_.node_counts.substring++;
memory_usage.Add(sizeof(CordRepSubstring), rep.refcount);
@@ -175,7 +181,7 @@ class CordRepAnalyzer {
}
// Consume possible FLAT
- if (rep.rep->tag >= FLAT) {
+ if (rep.tag() >= FLAT) {
size_t size = rep.rep->flat()->AllocatedSize();
CountFlat(size);
memory_usage.Add(size, rep.refcount);
@@ -183,7 +189,7 @@ class CordRepAnalyzer {
}
// Consume possible external
- if (rep.rep->tag == EXTERNAL) {
+ if (rep.tag() == EXTERNAL) {
statistics_.node_count++;
statistics_.node_counts.external++;
size_t size = rep.rep->length + sizeof(CordRepExternalImpl<intptr_t>);
@@ -194,17 +200,6 @@ class CordRepAnalyzer {
return rep;
}
- // Analyzes the provided ring.
- void AnalyzeRing(RepRef rep) {
- statistics_.node_count++;
- statistics_.node_counts.ring++;
- const CordRepRing* ring = rep.rep->ring();
- memory_usage_.Add(CordRepRing::AllocSize(ring->capacity()), rep.refcount);
- ring->ForEach([&](CordRepRing::index_type pos) {
- CountLinearReps(rep.Child(ring->entry_child(pos)), memory_usage_);
- });
- }
-
// Analyzes the provided btree.
void AnalyzeBtree(RepRef rep) {
statistics_.node_count++;
diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/memutil.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/memutil.cc
index e2e7347c49..0bbd8aa1bd 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/internal/memutil.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/internal/memutil.cc
@@ -27,10 +27,18 @@ int memcasecmp(const char* s1, const char* s2, size_t len) {
const unsigned char* us2 = reinterpret_cast<const unsigned char*>(s2);
for (size_t i = 0; i < len; i++) {
- const int diff =
- int{static_cast<unsigned char>(absl::ascii_tolower(us1[i]))} -
- int{static_cast<unsigned char>(absl::ascii_tolower(us2[i]))};
- if (diff != 0) return diff;
+ unsigned char c1 = us1[i];
+ unsigned char c2 = us2[i];
+ // If bytes are the same, they will be the same when converted to lower.
+ // So we only need to convert if bytes are not equal.
+ // NOTE(b/308193381): We do not use `absl::ascii_tolower` here in order
+ // to avoid its lookup table and improve performance.
+ if (c1 != c2) {
+ c1 = c1 >= 'A' && c1 <= 'Z' ? c1 - 'A' + 'a' : c1;
+ c2 = c2 >= 'A' && c2 <= 'Z' ? c2 - 'A' + 'a' : c2;
+ const int diff = int{c1} - int{c2};
+ if (diff != 0) return diff;
+ }
}
return 0;
}
diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.cc
index c0a9a28ef9..eeb2108154 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.cc
@@ -18,15 +18,28 @@
//
#include "absl/strings/internal/str_format/arg.h"
+#include <algorithm>
#include <cassert>
-#include <cerrno>
+#include <cstddef>
+#include <cstdint>
#include <cstdlib>
+#include <cstring>
+#include <cwchar>
#include <string>
#include <type_traits>
-#include "absl/base/port.h"
+#include "absl/base/config.h"
+#include "absl/base/optimization.h"
+#include "absl/container/fixed_array.h"
+#include "absl/numeric/int128.h"
+#include "absl/strings/internal/str_format/extension.h"
#include "absl/strings/internal/str_format/float_conversion.h"
#include "absl/strings/numbers.h"
+#include "absl/strings/string_view.h"
+
+#if defined(ABSL_HAVE_STD_STRING_VIEW)
+#include <string_view>
+#endif
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -298,6 +311,83 @@ inline bool ConvertStringArg(string_view v, const FormatConversionSpecImpl conv,
conv.has_left_flag());
}
+struct ShiftState {
+ bool saw_high_surrogate = false;
+ uint8_t bits = 0;
+};
+
+// Converts `v` from UTF-16 or UTF-32 to UTF-8 and writes to `buf`. `buf` is
+// assumed to have enough space for the output. `s` is used to carry state
+// between successive calls with a UTF-16 surrogate pair. Returns the number of
+// chars written, or `static_cast<size_t>(-1)` on failure.
+//
+// This is basically std::wcrtomb(), but always outputting UTF-8 instead of
+// respecting the current locale.
+inline size_t WideToUtf8(wchar_t wc, char *buf, ShiftState &s) {
+ const auto v = static_cast<uint32_t>(wc);
+ if (v < 0x80) {
+ *buf = static_cast<char>(v);
+ return 1;
+ } else if (v < 0x800) {
+ *buf++ = static_cast<char>(0xc0 | (v >> 6));
+ *buf = static_cast<char>(0x80 | (v & 0x3f));
+ return 2;
+ } else if (v < 0xd800 || (v - 0xe000) < 0x2000) {
+ *buf++ = static_cast<char>(0xe0 | (v >> 12));
+ *buf++ = static_cast<char>(0x80 | ((v >> 6) & 0x3f));
+ *buf = static_cast<char>(0x80 | (v & 0x3f));
+ return 3;
+ } else if ((v - 0x10000) < 0x100000) {
+ *buf++ = static_cast<char>(0xf0 | (v >> 18));
+ *buf++ = static_cast<char>(0x80 | ((v >> 12) & 0x3f));
+ *buf++ = static_cast<char>(0x80 | ((v >> 6) & 0x3f));
+ *buf = static_cast<char>(0x80 | (v & 0x3f));
+ return 4;
+ } else if (v < 0xdc00) {
+ s.saw_high_surrogate = true;
+ s.bits = static_cast<uint8_t>(v & 0x3);
+ const uint8_t high_bits = ((v >> 6) & 0xf) + 1;
+ *buf++ = static_cast<char>(0xf0 | (high_bits >> 2));
+ *buf =
+ static_cast<char>(0x80 | static_cast<uint8_t>((high_bits & 0x3) << 4) |
+ static_cast<uint8_t>((v >> 2) & 0xf));
+ return 2;
+ } else if (v < 0xe000 && s.saw_high_surrogate) {
+ *buf++ = static_cast<char>(0x80 | static_cast<uint8_t>(s.bits << 4) |
+ static_cast<uint8_t>((v >> 6) & 0xf));
+ *buf = static_cast<char>(0x80 | (v & 0x3f));
+ s.saw_high_surrogate = false;
+ s.bits = 0;
+ return 2;
+ } else {
+ return static_cast<size_t>(-1);
+ }
+}
+
+inline bool ConvertStringArg(const wchar_t *v,
+ size_t len,
+ const FormatConversionSpecImpl conv,
+ FormatSinkImpl *sink) {
+ FixedArray<char> mb(len * 4);
+ ShiftState s;
+ size_t chars_written = 0;
+ for (size_t i = 0; i < len; ++i) {
+ const size_t chars = WideToUtf8(v[i], &mb[chars_written], s);
+ if (chars == static_cast<size_t>(-1)) { return false; }
+ chars_written += chars;
+ }
+ return ConvertStringArg(string_view(mb.data(), chars_written), conv, sink);
+}
+
+bool ConvertWCharTImpl(wchar_t v, const FormatConversionSpecImpl conv,
+ FormatSinkImpl *sink) {
+ char mb[4];
+ ShiftState s;
+ const size_t chars_written = WideToUtf8(v, mb, s);
+ return chars_written != static_cast<size_t>(-1) && !s.saw_high_surrogate &&
+ ConvertStringArg(string_view(mb, chars_written), conv, sink);
+}
+
} // namespace
bool ConvertBoolArg(bool v, FormatSinkImpl *sink) {
@@ -316,11 +406,14 @@ bool ConvertIntArg(T v, FormatConversionSpecImpl conv, FormatSinkImpl *sink) {
// This odd casting is due to a bug in -Wswitch behavior in gcc49 which causes
// it to complain about a switch/case type mismatch, even though both are
- // FormatConverionChar. Likely this is because at this point
+ // FormatConversionChar. Likely this is because at this point
// FormatConversionChar is declared, but not defined.
switch (static_cast<uint8_t>(conv.conversion_char())) {
case static_cast<uint8_t>(FormatConversionCharInternal::c):
- return ConvertCharImpl(static_cast<char>(v), conv, sink);
+ return (std::is_same<T, wchar_t>::value ||
+ (conv.length_mod() == LengthMod::l))
+ ? ConvertWCharTImpl(static_cast<wchar_t>(v), conv, sink)
+ : ConvertCharImpl(static_cast<char>(v), conv, sink);
case static_cast<uint8_t>(FormatConversionCharInternal::o):
as_digits.PrintAsOct(static_cast<U>(v));
@@ -372,6 +465,8 @@ template bool ConvertIntArg<signed char>(signed char v,
template bool ConvertIntArg<unsigned char>(unsigned char v,
FormatConversionSpecImpl conv,
FormatSinkImpl *sink);
+template bool ConvertIntArg<wchar_t>(wchar_t v, FormatConversionSpecImpl conv,
+ FormatSinkImpl *sink);
template bool ConvertIntArg<short>(short v, // NOLINT
FormatConversionSpecImpl conv,
FormatSinkImpl *sink);
@@ -403,16 +498,29 @@ StringConvertResult FormatConvertImpl(const std::string &v,
return {ConvertStringArg(v, conv, sink)};
}
+StringConvertResult FormatConvertImpl(const std::wstring &v,
+ const FormatConversionSpecImpl conv,
+ FormatSinkImpl *sink) {
+ return {ConvertStringArg(v.data(), v.size(), conv, sink)};
+}
+
StringConvertResult FormatConvertImpl(string_view v,
const FormatConversionSpecImpl conv,
FormatSinkImpl *sink) {
return {ConvertStringArg(v, conv, sink)};
}
-ArgConvertResult<FormatConversionCharSetUnion(
- FormatConversionCharSetInternal::s, FormatConversionCharSetInternal::p)>
-FormatConvertImpl(const char *v, const FormatConversionSpecImpl conv,
- FormatSinkImpl *sink) {
+#if defined(ABSL_HAVE_STD_STRING_VIEW)
+StringConvertResult FormatConvertImpl(std::wstring_view v,
+ const FormatConversionSpecImpl conv,
+ FormatSinkImpl* sink) {
+ return {ConvertStringArg(v.data(), v.size(), conv, sink)};
+}
+#endif
+
+StringPtrConvertResult FormatConvertImpl(const char* v,
+ const FormatConversionSpecImpl conv,
+ FormatSinkImpl* sink) {
if (conv.conversion_char() == FormatConversionCharInternal::p)
return {FormatConvertImpl(VoidPtr(v), conv, sink).value};
size_t len;
@@ -427,6 +535,30 @@ FormatConvertImpl(const char *v, const FormatConversionSpecImpl conv,
return {ConvertStringArg(string_view(v, len), conv, sink)};
}
+StringPtrConvertResult FormatConvertImpl(const wchar_t* v,
+ const FormatConversionSpecImpl conv,
+ FormatSinkImpl* sink) {
+ if (conv.conversion_char() == FormatConversionCharInternal::p) {
+ return {FormatConvertImpl(VoidPtr(v), conv, sink).value};
+ }
+ size_t len;
+ if (v == nullptr) {
+ len = 0;
+ } else if (conv.precision() < 0) {
+ len = std::wcslen(v);
+ } else {
+ // If precision is set, we look for the NUL-terminator on the valid range.
+ len = static_cast<size_t>(std::find(v, v + conv.precision(), L'\0') - v);
+ }
+ return {ConvertStringArg(v, len, conv, sink)};
+}
+
+StringPtrConvertResult FormatConvertImpl(std::nullptr_t,
+ const FormatConversionSpecImpl conv,
+ FormatSinkImpl* sink) {
+ return FormatConvertImpl(static_cast<const char*>(nullptr), conv, sink);
+}
+
// ==================== Raw pointers ====================
ArgConvertResult<FormatConversionCharSetInternal::p> FormatConvertImpl(
VoidPtr v, const FormatConversionSpecImpl conv, FormatSinkImpl *sink) {
@@ -461,6 +593,11 @@ CharConvertResult FormatConvertImpl(char v, const FormatConversionSpecImpl conv,
FormatSinkImpl *sink) {
return {ConvertIntArg(v, conv, sink)};
}
+CharConvertResult FormatConvertImpl(wchar_t v,
+ const FormatConversionSpecImpl conv,
+ FormatSinkImpl* sink) {
+ return {ConvertIntArg(v, conv, sink)};
+}
// ==================== Ints ====================
IntegralConvertResult FormatConvertImpl(signed char v,
diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.h b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.h
index 3ce30feb49..309161d591 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.h
@@ -19,8 +19,9 @@
#include <wchar.h>
#include <algorithm>
+#include <cstddef>
+#include <cstdint>
#include <cstdio>
-#include <iomanip>
#include <limits>
#include <memory>
#include <sstream>
@@ -28,13 +29,18 @@
#include <type_traits>
#include <utility>
-#include "absl/base/port.h"
+#include "absl/base/config.h"
+#include "absl/base/optimization.h"
#include "absl/meta/type_traits.h"
#include "absl/numeric/int128.h"
-#include "absl/strings/internal/has_absl_stringify.h"
+#include "absl/strings/has_absl_stringify.h"
#include "absl/strings/internal/str_format/extension.h"
#include "absl/strings/string_view.h"
+#if defined(ABSL_HAVE_STD_STRING_VIEW)
+#include <string_view>
+#endif
+
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -97,6 +103,9 @@ extern template bool ConvertIntArg<signed char>(signed char v,
extern template bool ConvertIntArg<unsigned char>(unsigned char v,
FormatConversionSpecImpl conv,
FormatSinkImpl* sink);
+extern template bool ConvertIntArg<wchar_t>(wchar_t v,
+ FormatConversionSpecImpl conv,
+ FormatSinkImpl* sink);
extern template bool ConvertIntArg<short>(short v, // NOLINT
FormatConversionSpecImpl conv,
FormatSinkImpl* sink);
@@ -158,6 +167,7 @@ template <typename T>
auto FormatConvertImpl(const T& v, FormatConversionSpecImpl,
FormatSinkImpl* sink)
-> std::enable_if_t<!std::is_enum<T>::value &&
+ !std::is_same<T, absl::Cord>::value &&
std::is_void<decltype(AbslStringify(
std::declval<FormatSink&>(), v))>::value,
ArgConvertResult<FormatConversionCharSetInternal::v>> {
@@ -202,30 +212,49 @@ constexpr FormatConversionCharSet ExtractCharSet(ArgConvertResult<C>) {
return C;
}
-using StringConvertResult = ArgConvertResult<FormatConversionCharSetUnion(
- FormatConversionCharSetInternal::s, FormatConversionCharSetInternal::v)>;
ArgConvertResult<FormatConversionCharSetInternal::p> FormatConvertImpl(
VoidPtr v, FormatConversionSpecImpl conv, FormatSinkImpl* sink);
// Strings.
+using StringConvertResult = ArgConvertResult<FormatConversionCharSetUnion(
+ FormatConversionCharSetInternal::s,
+ FormatConversionCharSetInternal::v)>;
StringConvertResult FormatConvertImpl(const std::string& v,
FormatConversionSpecImpl conv,
FormatSinkImpl* sink);
+StringConvertResult FormatConvertImpl(const std::wstring& v,
+ FormatConversionSpecImpl conv,
+ FormatSinkImpl* sink);
StringConvertResult FormatConvertImpl(string_view v,
FormatConversionSpecImpl conv,
FormatSinkImpl* sink);
-#if defined(ABSL_HAVE_STD_STRING_VIEW) && !defined(ABSL_USES_STD_STRING_VIEW)
+#if defined(ABSL_HAVE_STD_STRING_VIEW)
+StringConvertResult FormatConvertImpl(std::wstring_view v,
+ FormatConversionSpecImpl conv,
+ FormatSinkImpl* sink);
+#if !defined(ABSL_USES_STD_STRING_VIEW)
inline StringConvertResult FormatConvertImpl(std::string_view v,
FormatConversionSpecImpl conv,
FormatSinkImpl* sink) {
return FormatConvertImpl(absl::string_view(v.data(), v.size()), conv, sink);
}
-#endif // ABSL_HAVE_STD_STRING_VIEW && !ABSL_USES_STD_STRING_VIEW
-
-ArgConvertResult<FormatConversionCharSetUnion(
- FormatConversionCharSetInternal::s, FormatConversionCharSetInternal::p)>
-FormatConvertImpl(const char* v, const FormatConversionSpecImpl conv,
- FormatSinkImpl* sink);
+#endif // !ABSL_USES_STD_STRING_VIEW
+#endif // ABSL_HAVE_STD_STRING_VIEW
+
+using StringPtrConvertResult = ArgConvertResult<FormatConversionCharSetUnion(
+ FormatConversionCharSetInternal::s,
+ FormatConversionCharSetInternal::p)>;
+StringPtrConvertResult FormatConvertImpl(const char* v,
+ FormatConversionSpecImpl conv,
+ FormatSinkImpl* sink);
+StringPtrConvertResult FormatConvertImpl(const wchar_t* v,
+ FormatConversionSpecImpl conv,
+ FormatSinkImpl* sink);
+// This overload is needed to disambiguate, since `nullptr` could match either
+// of the other overloads equally well.
+StringPtrConvertResult FormatConvertImpl(std::nullptr_t,
+ FormatConversionSpecImpl conv,
+ FormatSinkImpl* sink);
template <class AbslCord, typename std::enable_if<std::is_same<
AbslCord, absl::Cord>::value>::type* = nullptr>
@@ -279,6 +308,9 @@ FloatingConvertResult FormatConvertImpl(long double v,
// Chars.
CharConvertResult FormatConvertImpl(char v, FormatConversionSpecImpl conv,
FormatSinkImpl* sink);
+CharConvertResult FormatConvertImpl(wchar_t v,
+ FormatConversionSpecImpl conv,
+ FormatSinkImpl* sink);
// Ints.
IntegralConvertResult FormatConvertImpl(signed char v,
@@ -333,7 +365,7 @@ IntegralConvertResult FormatConvertImpl(T v, FormatConversionSpecImpl conv,
template <typename T>
typename std::enable_if<std::is_enum<T>::value &&
!HasUserDefinedConvert<T>::value &&
- !strings_internal::HasAbslStringify<T>::value,
+ !HasAbslStringify<T>::value,
IntegralConvertResult>::type
FormatConvertImpl(T v, FormatConversionSpecImpl conv, FormatSinkImpl* sink);
@@ -440,6 +472,7 @@ class FormatArgImpl {
// Anything with a user-defined Convert will get its own vtable.
// For everything else:
// - Decay char* and char arrays into `const char*`
+ // - Decay wchar_t* and wchar_t arrays into `const wchar_t*`
// - Decay any other pointer to `const void*`
// - Decay all enums to the integral promotion of their underlying type.
// - Decay function pointers to void*.
@@ -447,20 +480,23 @@ class FormatArgImpl {
struct DecayType {
static constexpr bool kHasUserDefined =
str_format_internal::HasUserDefinedConvert<T>::value ||
- strings_internal::HasAbslStringify<T>::value;
+ HasAbslStringify<T>::value;
using type = typename std::conditional<
!kHasUserDefined && std::is_convertible<T, const char*>::value,
const char*,
- typename std::conditional<!kHasUserDefined &&
- std::is_convertible<T, VoidPtr>::value,
- VoidPtr, const T&>::type>::type;
+ typename std::conditional<
+ !kHasUserDefined && std::is_convertible<T, const wchar_t*>::value,
+ const wchar_t*,
+ typename std::conditional<
+ !kHasUserDefined && std::is_convertible<T, VoidPtr>::value,
+ VoidPtr,
+ const T&>::type>::type>::type;
};
template <typename T>
- struct DecayType<T,
- typename std::enable_if<
- !str_format_internal::HasUserDefinedConvert<T>::value &&
- !strings_internal::HasAbslStringify<T>::value &&
- std::is_enum<T>::value>::type> {
+ struct DecayType<
+ T, typename std::enable_if<
+ !str_format_internal::HasUserDefinedConvert<T>::value &&
+ !HasAbslStringify<T>::value && std::is_enum<T>::value>::type> {
using type = decltype(+typename std::underlying_type<T>::type());
};
@@ -585,7 +621,7 @@ class FormatArgImpl {
E template bool FormatArgImpl::Dispatch<T>(Data, FormatConversionSpecImpl, \
void*)
-#define ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_(...) \
+#define ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_NO_WSTRING_VIEW_(...) \
ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(str_format_internal::VoidPtr, \
__VA_ARGS__); \
ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(bool, __VA_ARGS__); \
@@ -611,7 +647,19 @@ class FormatArgImpl {
ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(long double, __VA_ARGS__); \
ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(const char*, __VA_ARGS__); \
ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(std::string, __VA_ARGS__); \
- ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(string_view, __VA_ARGS__)
+ ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(string_view, __VA_ARGS__); \
+ ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(const wchar_t*, __VA_ARGS__); \
+ ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(std::wstring, __VA_ARGS__)
+
+#if defined(ABSL_HAVE_STD_STRING_VIEW)
+#define ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_(...) \
+ ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_NO_WSTRING_VIEW_( \
+ __VA_ARGS__); \
+ ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(std::wstring_view, __VA_ARGS__)
+#else
+#define ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_(...) \
+ ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_NO_WSTRING_VIEW_(__VA_ARGS__)
+#endif
ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_(extern);
diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.cc
index 77a4222337..87e23b565c 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.cc
@@ -14,10 +14,24 @@
#include "absl/strings/internal/str_format/bind.h"
+#include <algorithm>
+#include <cassert>
#include <cerrno>
+#include <cstddef>
+#include <cstdio>
+#include <ios>
#include <limits>
+#include <ostream>
#include <sstream>
#include <string>
+#include "absl/base/config.h"
+#include "absl/base/optimization.h"
+#include "absl/strings/internal/str_format/arg.h"
+#include "absl/strings/internal/str_format/constexpr_parser.h"
+#include "absl/strings/internal/str_format/extension.h"
+#include "absl/strings/internal/str_format/output.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/span.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -90,6 +104,8 @@ inline bool ArgContext::Bind(const UnboundConversion* unbound,
} else {
FormatConversionSpecImplFriend::SetFlags(unbound->flags, bound);
}
+
+ FormatConversionSpecImplFriend::SetLengthMod(unbound->length_mod, bound);
} else {
FormatConversionSpecImplFriend::SetFlags(unbound->flags, bound);
FormatConversionSpecImplFriend::SetWidth(-1, bound);
@@ -215,7 +231,7 @@ std::string& AppendPack(std::string* out, const UntypedFormatSpecImpl format,
return *out;
}
-std::string FormatPack(const UntypedFormatSpecImpl format,
+std::string FormatPack(UntypedFormatSpecImpl format,
absl::Span<const FormatArgImpl> args) {
std::string out;
if (ABSL_PREDICT_FALSE(!FormatUntyped(&out, format, args))) {
diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.h b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.h
index 5e2a43d5c9..120bc355c7 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.h
@@ -15,16 +15,19 @@
#ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_BIND_H_
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_BIND_H_
-#include <array>
+#include <cassert>
#include <cstdio>
-#include <sstream>
+#include <ostream>
#include <string>
-#include "absl/base/port.h"
+#include "absl/base/config.h"
#include "absl/container/inlined_vector.h"
#include "absl/strings/internal/str_format/arg.h"
#include "absl/strings/internal/str_format/checker.h"
+#include "absl/strings/internal/str_format/constexpr_parser.h"
+#include "absl/strings/internal/str_format/extension.h"
#include "absl/strings/internal/str_format/parser.h"
+#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "absl/utility/utility.h"
@@ -203,7 +206,7 @@ bool FormatUntyped(FormatRawSinkImpl raw_sink, UntypedFormatSpecImpl format,
std::string& AppendPack(std::string* out, UntypedFormatSpecImpl format,
absl::Span<const FormatArgImpl> args);
-std::string FormatPack(const UntypedFormatSpecImpl format,
+std::string FormatPack(UntypedFormatSpecImpl format,
absl::Span<const FormatArgImpl> args);
int FprintF(std::FILE* output, UntypedFormatSpecImpl format,
diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/constexpr_parser.h b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/constexpr_parser.h
index b70a16e40c..8f59387047 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/constexpr_parser.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/constexpr_parser.h
@@ -17,17 +17,18 @@
#include <cassert>
#include <cstdint>
+#include <cstdio>
#include <limits>
+#include "absl/base/config.h"
#include "absl/base/const_init.h"
+#include "absl/base/optimization.h"
#include "absl/strings/internal/str_format/extension.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace str_format_internal {
-enum class LengthMod : std::uint8_t { h, hh, l, ll, L, j, z, t, q, none };
-
// The analyzed properties of a single specified conversion.
struct UnboundConversion {
// This is a user defined default constructor on purpose to skip the
@@ -306,7 +307,6 @@ constexpr const char* ConsumeConversion(const char* pos, const char* const end,
if (ABSL_PREDICT_FALSE(!tag.is_length())) return nullptr;
// It is a length modifier.
- using str_format_internal::LengthMod;
LengthMod length_mod = tag.as_length();
ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();
if (c == 'h' && length_mod == LengthMod::h) {
@@ -322,6 +322,11 @@ constexpr const char* ConsumeConversion(const char* pos, const char* const end,
if (ABSL_PREDICT_FALSE(c == 'v')) return nullptr;
if (ABSL_PREDICT_FALSE(!tag.is_conv())) return nullptr;
+
+ // `wchar_t` args are marked non-basic so `Bind()` will copy the length mod.
+ if (conv->length_mod == LengthMod::l && c == 'c') {
+ conv->flags = conv->flags | Flags::kNonBasic;
+ }
}
#undef ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR
diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/extension.h b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/extension.h
index 8de42d2cfc..173284c6c7 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/extension.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/extension.h
@@ -16,16 +16,14 @@
#ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_
-#include <limits.h>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <ostream>
+#include <string>
#include "absl/base/config.h"
-#include "absl/base/port.h"
-#include "absl/meta/type_traits.h"
#include "absl/strings/internal/str_format/output.h"
#include "absl/strings/string_view.h"
@@ -34,6 +32,7 @@ ABSL_NAMESPACE_BEGIN
enum class FormatConversionChar : uint8_t;
enum class FormatConversionCharSet : uint64_t;
+enum class LengthMod : std::uint8_t { h, hh, l, ll, L, j, z, t, q, none };
namespace str_format_internal {
@@ -139,7 +138,8 @@ enum class Flags : uint8_t {
kAlt = 1 << 3,
kZero = 1 << 4,
// This is not a real flag. It just exists to turn off kBasic when no other
- // flags are set. This is for when width/precision are specified.
+ // flags are set. This is for when width/precision are specified, or a length
+ // modifier affects the behavior ("%lc").
kNonBasic = 1 << 5,
};
@@ -285,6 +285,8 @@ class FormatConversionSpecImpl {
bool has_alt_flag() const { return FlagsContains(flags_, Flags::kAlt); }
bool has_zero_flag() const { return FlagsContains(flags_, Flags::kZero); }
+ LengthMod length_mod() const { return length_mod_; }
+
FormatConversionChar conversion_char() const {
// Keep this field first in the struct . It generates better code when
// accessing it when ConversionSpec is passed by value in registers.
@@ -310,6 +312,7 @@ class FormatConversionSpecImpl {
friend struct str_format_internal::FormatConversionSpecImplFriend;
FormatConversionChar conv_ = FormatConversionCharInternal::kNone;
Flags flags_;
+ LengthMod length_mod_ = LengthMod::none;
int width_;
int precision_;
};
@@ -318,6 +321,9 @@ struct FormatConversionSpecImplFriend final {
static void SetFlags(Flags f, FormatConversionSpecImpl* conv) {
conv->flags_ = f;
}
+ static void SetLengthMod(LengthMod l, FormatConversionSpecImpl* conv) {
+ conv->length_mod_ = l;
+ }
static void SetConversionChar(FormatConversionChar c,
FormatConversionSpecImpl* conv) {
conv->conv_ = c;
diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/parser.h b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/parser.h
index 35b6d49c14..b1d6d5fd0e 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/parser.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/parser.h
@@ -15,22 +15,23 @@
#ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_PARSER_H_
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_PARSER_H_
-#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
#include <cassert>
-#include <cstdint>
+#include <cstring>
#include <initializer_list>
-#include <iosfwd>
-#include <iterator>
#include <memory>
#include <string>
+#include <utility>
#include <vector>
+#include "absl/base/config.h"
+#include "absl/base/optimization.h"
#include "absl/strings/internal/str_format/checker.h"
#include "absl/strings/internal/str_format/constexpr_parser.h"
#include "absl/strings/internal/str_format/extension.h"
+#include "absl/strings/string_view.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/contrib/restricted/abseil-cpp/absl/strings/match.cc b/contrib/restricted/abseil-cpp/absl/strings/match.cc
index 3b81b2c052..72ae6a430a 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/match.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/match.cc
@@ -17,10 +17,13 @@
#include <algorithm>
#include <cstdint>
+#include "absl/base/config.h"
#include "absl/base/internal/endian.h"
+#include "absl/base/optimization.h"
#include "absl/numeric/bits.h"
#include "absl/strings/ascii.h"
#include "absl/strings/internal/memutil.h"
+#include "absl/strings/string_view.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/contrib/restricted/abseil-cpp/absl/strings/numbers.cc b/contrib/restricted/abseil-cpp/absl/strings/numbers.cc
index c43c6bcc19..882c3a8b85 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/numbers.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/numbers.cc
@@ -20,32 +20,36 @@
#include <algorithm>
#include <cassert>
#include <cfloat> // for DBL_DIG and FLT_DIG
+#include <climits>
#include <cmath> // for HUGE_VAL
+#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iterator>
#include <limits>
-#include <memory>
+#include <system_error> // NOLINT(build/c++11)
+#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/raw_logging.h"
+#include "absl/base/nullability.h"
#include "absl/base/optimization.h"
#include "absl/numeric/bits.h"
+#include "absl/numeric/int128.h"
#include "absl/strings/ascii.h"
#include "absl/strings/charconv.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/internal/memutil.h"
#include "absl/strings/match.h"
-#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
-bool SimpleAtof(absl::string_view str, float* out) {
+bool SimpleAtof(absl::string_view str, absl::Nonnull<float*> out) {
*out = 0.0;
str = StripAsciiWhitespace(str);
// std::from_chars doesn't accept an initial +, but SimpleAtof does, so if one
@@ -76,7 +80,7 @@ bool SimpleAtof(absl::string_view str, float* out) {
return true;
}
-bool SimpleAtod(absl::string_view str, double* out) {
+bool SimpleAtod(absl::string_view str, absl::Nonnull<double*> out) {
*out = 0.0;
str = StripAsciiWhitespace(str);
// std::from_chars doesn't accept an initial +, but SimpleAtod does, so if one
@@ -107,7 +111,7 @@ bool SimpleAtod(absl::string_view str, double* out) {
return true;
}
-bool SimpleAtob(absl::string_view str, bool* out) {
+bool SimpleAtob(absl::string_view str, absl::Nonnull<bool*> out) {
ABSL_RAW_CHECK(out != nullptr, "Output pointer must not be nullptr.");
if (EqualsIgnoreCase(str, "true") || EqualsIgnoreCase(str, "t") ||
EqualsIgnoreCase(str, "yes") || EqualsIgnoreCase(str, "y") ||
@@ -155,29 +159,71 @@ constexpr uint32_t kTwoZeroBytes = 0x0101 * '0';
constexpr uint64_t kFourZeroBytes = 0x01010101 * '0';
constexpr uint64_t kEightZeroBytes = 0x0101010101010101ull * '0';
-// * 103 / 1024 is a division by 10 for values from 0 to 99. It's also a
-// division of a structure [k takes 2 bytes][m takes 2 bytes], then * 103 / 1024
-// will be [k / 10][m / 10]. It allows parallel division.
-constexpr uint64_t kDivisionBy10Mul = 103u;
+template <typename T>
+constexpr T Pow(T base, uint32_t n) {
+ // Exponentiation by squaring
+ return static_cast<T>((n > 1 ? Pow(base * base, n >> 1) : static_cast<T>(1)) *
+ ((n & 1) ? base : static_cast<T>(1)));
+}
+
+// Given n, calculates C where the following holds for all 0 <= x < Pow(100, n):
+// x / Pow(10, n) == x * C / Pow(2, n * 10)
+// In other words, it allows us to divide by a power of 10 via a single
+// multiplication and bit shifts, assuming the input will be smaller than the
+// square of that power of 10.
+template <typename T>
+constexpr T ComputePowerOf100DivisionCoefficient(uint32_t n) {
+ if (n > 4) {
+ // This doesn't work for large powers of 100, due to overflow
+ abort();
+ }
+ T denom = 16 - 1;
+ T num = (denom + 1) - 10;
+ T gcd = 3; // Greatest common divisor of numerator and denominator
+ denom = Pow(denom / gcd, n);
+ num = Pow(num / gcd, 9 * n);
+ T quotient = num / denom;
+ if (num % denom >= denom / 2) {
+ // Round up, since the remainder is more than half the denominator
+ ++quotient;
+ }
+ return quotient;
+}
+
+// * kDivisionBy10Mul / kDivisionBy10Div is a division by 10 for values from 0
+// to 99. It's also a division of a structure [k takes 2 bytes][m takes 2
+// bytes], then * kDivisionBy10Mul / kDivisionBy10Div will be [k / 10][m / 10].
+// It allows parallel division.
+constexpr uint64_t kDivisionBy10Mul =
+ ComputePowerOf100DivisionCoefficient<uint64_t>(1);
+static_assert(kDivisionBy10Mul == 103,
+ "division coefficient for 10 is incorrect");
constexpr uint64_t kDivisionBy10Div = 1 << 10;
-// * 10486 / 1048576 is a division by 100 for values from 0 to 9999.
-constexpr uint64_t kDivisionBy100Mul = 10486u;
+// * kDivisionBy100Mul / kDivisionBy100Div is a division by 100 for values from
+// 0 to 9999.
+constexpr uint64_t kDivisionBy100Mul =
+ ComputePowerOf100DivisionCoefficient<uint64_t>(2);
+static_assert(kDivisionBy100Mul == 10486,
+ "division coefficient for 100 is incorrect");
constexpr uint64_t kDivisionBy100Div = 1 << 20;
-// Encode functions write the ASCII output of input `n` to `out_str`.
-inline char* EncodeHundred(uint32_t n, char* out_str) {
- int num_digits = static_cast<int>(n - 10) >> 8;
- uint32_t base = kTwoZeroBytes;
- uint32_t div10 = (n * kDivisionBy10Mul) / kDivisionBy10Div;
- uint32_t mod10 = n - 10u * div10;
- base += div10 + (mod10 << 8);
- base >>= num_digits & 8;
- little_endian::Store16(out_str, static_cast<uint16_t>(base));
- return out_str + 2 + num_digits;
+static_assert(ComputePowerOf100DivisionCoefficient<uint64_t>(3) == 1073742,
+ "division coefficient for 1000 is incorrect");
+
+// Same as `PrepareEightDigits`, but produces 2 digits for integers < 100.
+inline uint32_t PrepareTwoDigitsImpl(uint32_t i, bool reversed) {
+ assert(i < 100);
+ uint32_t div10 = (i * kDivisionBy10Mul) / kDivisionBy10Div;
+ uint32_t mod10 = i - 10u * div10;
+ return (div10 << (reversed ? 8 : 0)) + (mod10 << (reversed ? 0 : 8));
+}
+inline uint32_t PrepareTwoDigits(uint32_t i) {
+ return PrepareTwoDigitsImpl(i, false);
}
-inline char* EncodeTenThousand(uint32_t n, char* out_str) {
+// Same as `PrepareEightDigits`, but produces 4 digits for integers < 10000.
+inline uint32_t PrepareFourDigitsImpl(uint32_t n, bool reversed) {
// We split lower 2 digits and upper 2 digits of n into 2 byte consecutive
// blocks. 123 -> [\0\1][\0\23]. We divide by 10 both blocks
// (it's 1 division + zeroing upper bits), and compute modulo 10 as well "in
@@ -185,146 +231,335 @@ inline char* EncodeTenThousand(uint32_t n, char* out_str) {
// strip trailing zeros, add ASCII '0000' and return.
uint32_t div100 = (n * kDivisionBy100Mul) / kDivisionBy100Div;
uint32_t mod100 = n - 100ull * div100;
- uint32_t hundreds = (mod100 << 16) + div100;
+ uint32_t hundreds =
+ (mod100 << (reversed ? 0 : 16)) + (div100 << (reversed ? 16 : 0));
uint32_t tens = (hundreds * kDivisionBy10Mul) / kDivisionBy10Div;
tens &= (0xFull << 16) | 0xFull;
- tens += (hundreds - 10ull * tens) << 8;
- ABSL_ASSUME(tens != 0);
- // The result can contain trailing zero bits, we need to strip them to a first
- // significant byte in a final representation. For example, for n = 123, we
- // have tens to have representation \0\1\2\3. We do `& -8` to round
- // to a multiple to 8 to strip zero bytes, not all zero bits.
- // countr_zero to help.
- // 0 minus 8 to make MSVC happy.
- uint32_t zeroes = static_cast<uint32_t>(absl::countr_zero(tens)) & (0 - 8ull);
- tens += kFourZeroBytes;
- tens >>= zeroes;
- little_endian::Store32(out_str, tens);
- return out_str + sizeof(tens) - zeroes / 8;
+ tens = (tens << (reversed ? 8 : 0)) +
+ static_cast<uint32_t>((hundreds - 10ull * tens) << (reversed ? 0 : 8));
+ return tens;
+}
+inline uint32_t PrepareFourDigits(uint32_t n) {
+ return PrepareFourDigitsImpl(n, false);
+}
+inline uint32_t PrepareFourDigitsReversed(uint32_t n) {
+ return PrepareFourDigitsImpl(n, true);
}
-// Prepare functions return an integer that should be written to out_str
-// (but possibly include trailing zeros).
-// For hi < 10000, lo < 10000 returns uint64_t as encoded in ASCII with
-// possibly trailing zeroes of the number hi * 10000 + lo.
-inline uint64_t PrepareTenThousands(uint64_t hi, uint64_t lo) {
- uint64_t merged = hi | (lo << 32);
+// Helper function to produce an ASCII representation of `i`.
+//
+// Function returns an 8-byte integer which when summed with `kEightZeroBytes`,
+// can be treated as a printable buffer with ascii representation of `i`,
+// possibly with leading zeros.
+//
+// Example:
+//
+// uint64_t buffer = PrepareEightDigits(102030) + kEightZeroBytes;
+// char* ascii = reinterpret_cast<char*>(&buffer);
+// // Note two leading zeros:
+// EXPECT_EQ(absl::string_view(ascii, 8), "00102030");
+//
+// If `Reversed` is set to true, the result becomes reversed to "03020100".
+//
+// Pre-condition: `i` must be less than 100000000.
+inline uint64_t PrepareEightDigitsImpl(uint32_t i, bool reversed) {
+ ABSL_ASSUME(i < 10000'0000);
+ // Prepare 2 blocks of 4 digits "in parallel".
+ uint32_t hi = i / 10000;
+ uint32_t lo = i % 10000;
+ uint64_t merged = (uint64_t{hi} << (reversed ? 32 : 0)) |
+ (uint64_t{lo} << (reversed ? 0 : 32));
uint64_t div100 = ((merged * kDivisionBy100Mul) / kDivisionBy100Div) &
((0x7Full << 32) | 0x7Full);
uint64_t mod100 = merged - 100ull * div100;
- uint64_t hundreds = (mod100 << 16) + div100;
+ uint64_t hundreds =
+ (mod100 << (reversed ? 0 : 16)) + (div100 << (reversed ? 16 : 0));
uint64_t tens = (hundreds * kDivisionBy10Mul) / kDivisionBy10Div;
tens &= (0xFull << 48) | (0xFull << 32) | (0xFull << 16) | 0xFull;
- tens += (hundreds - 10ull * tens) << 8;
+ tens = (tens << (reversed ? 8 : 0)) +
+ ((hundreds - 10ull * tens) << (reversed ? 0 : 8));
return tens;
}
+inline uint64_t PrepareEightDigits(uint32_t i) {
+ return PrepareEightDigitsImpl(i, false);
+}
+inline uint64_t PrepareEightDigitsReversed(uint32_t i) {
+ return PrepareEightDigitsImpl(i, true);
+}
+
+template <typename T, typename BackwardIt>
+class FastUIntToStringConverter {
+ static_assert(
+ std::is_same<T, decltype(+std::declval<T>())>::value,
+ "to avoid code bloat, only instantiate this for int and larger types");
+ static_assert(std::is_unsigned<T>::value,
+ "this class is only for unsigned types");
+
+ public:
+ // Outputs the given number backward (like with std::copy_backward),
+ // starting from the end of the string.
+ // The number of digits in the number must have been already measured and
+ // passed *exactly*, otherwise the behavior is undefined.
+ // (This is an optimization, as calculating the number of digits again would
+ // slow down the hot path.)
+ // Returns an iterator to the start of the suffix that was appended.
+ static BackwardIt FastIntToBufferBackward(T v, BackwardIt end) {
+ // THIS IS A HOT FUNCTION with a very deliberate structure to exploit branch
+ // prediction and shorten the critical path for smaller numbers.
+ // Do not move around the if/else blocks or attempt to simplify it
+ // without benchmarking any changes.
+
+ if (v < 10) {
+ goto AT_LEAST_1 /* NOTE: mandatory for the 0 case */;
+ }
+ if (v < 1000) {
+ goto AT_LEAST_10;
+ }
+ if (v < 10000000) {
+ goto AT_LEAST_1000;
+ }
+
+ if (v >= 100000000 / 10) {
+ if (v >= 10000000000000000 / 10) {
+ DoFastIntToBufferBackward<8>(v, end);
+ }
+ DoFastIntToBufferBackward<8>(v, end);
+ }
+
+ if (v >= 10000 / 10) {
+ AT_LEAST_1000:
+ DoFastIntToBufferBackward<4>(v, end);
+ }
+
+ if (v >= 100 / 10) {
+ AT_LEAST_10:
+ DoFastIntToBufferBackward<2>(v, end);
+ }
-inline char* EncodeFullU32(uint32_t n, char* out_str) {
- if (n < 100'000'000) {
- uint64_t bottom = PrepareTenThousands(n / 10000, n % 10000);
- ABSL_ASSUME(bottom != 0);
- // 0 minus 8 to make MSVC happy.
- uint32_t zeroes = static_cast<uint32_t>(absl::countr_zero(bottom))
- & (0 - 8ull);
- uint64_t bottom_res = bottom + kEightZeroBytes;
- bottom_res >>= zeroes;
- little_endian::Store64(out_str, bottom_res);
- return out_str + sizeof(bottom) - zeroes / 8;
+ if (v >= 10 / 10) {
+ AT_LEAST_1:
+ end = DoFastIntToBufferBackward(v, end, std::integral_constant<int, 1>());
+ }
+ return end;
}
- uint32_t top = n / 100'000'000;
- n %= 100'000'000;
- uint64_t bottom = PrepareTenThousands(n / 10000, n % 10000);
- uint64_t bottom_res = bottom + kEightZeroBytes;
- out_str = EncodeHundred(top, out_str);
- little_endian::Store64(out_str, bottom_res);
- return out_str + sizeof(bottom);
-}
-} // namespace
+ private:
+ // Only assume pointers are contiguous for now. String and vector iterators
+ // could be special-cased as well, but there's no need for them here.
+ // With C++20 we can probably switch to std::contiguous_iterator_tag.
+ static constexpr bool kIsContiguousIterator =
+ std::is_pointer<BackwardIt>::value;
+
+ template <int Exponent>
+ static void DoFastIntToBufferBackward(T& v, BackwardIt& end) {
+ constexpr T kModulus = Pow<T>(10, Exponent);
+ T remainder = static_cast<T>(v % kModulus);
+ v = static_cast<T>(v / kModulus);
+ end = DoFastIntToBufferBackward(remainder, end,
+ std::integral_constant<int, Exponent>());
+ }
-void numbers_internal::PutTwoDigits(uint32_t i, char* buf) {
- assert(i < 100);
- uint32_t base = kTwoZeroBytes;
- uint32_t div10 = (i * kDivisionBy10Mul) / kDivisionBy10Div;
- uint32_t mod10 = i - 10u * div10;
- base += div10 + (mod10 << 8);
- little_endian::Store16(buf, static_cast<uint16_t>(base));
-}
+ static BackwardIt DoFastIntToBufferBackward(const T&, BackwardIt end,
+ std::integral_constant<int, 0>) {
+ return end;
+ }
-char* numbers_internal::FastIntToBuffer(uint32_t n, char* out_str) {
- if (n < 100) {
- out_str = EncodeHundred(n, out_str);
- goto set_last_zero;
+ static BackwardIt DoFastIntToBufferBackward(T v, BackwardIt end,
+ std::integral_constant<int, 1>) {
+ *--end = static_cast<char>('0' + v);
+ return DoFastIntToBufferBackward(v, end, std::integral_constant<int, 0>());
}
- if (n < 10000) {
- out_str = EncodeTenThousand(n, out_str);
- goto set_last_zero;
+
+ static BackwardIt DoFastIntToBufferBackward(T v, BackwardIt end,
+ std::integral_constant<int, 4>) {
+ if (kIsContiguousIterator) {
+ const uint32_t digits =
+ PrepareFourDigits(static_cast<uint32_t>(v)) + kFourZeroBytes;
+ end -= sizeof(digits);
+ little_endian::Store32(&*end, digits);
+ } else {
+ uint32_t digits =
+ PrepareFourDigitsReversed(static_cast<uint32_t>(v)) + kFourZeroBytes;
+ for (size_t i = 0; i < sizeof(digits); ++i) {
+ *--end = static_cast<char>(digits);
+ digits >>= CHAR_BIT;
+ }
+ }
+ return end;
}
- out_str = EncodeFullU32(n, out_str);
-set_last_zero:
- *out_str = '\0';
- return out_str;
-}
-char* numbers_internal::FastIntToBuffer(int32_t i, char* buffer) {
- uint32_t u = static_cast<uint32_t>(i);
- if (i < 0) {
- *buffer++ = '-';
- // We need to do the negation in modular (i.e., "unsigned")
- // arithmetic; MSVC++ apparently warns for plain "-u", so
- // we write the equivalent expression "0 - u" instead.
- u = 0 - u;
+ static BackwardIt DoFastIntToBufferBackward(T v, BackwardIt end,
+ std::integral_constant<int, 8>) {
+ if (kIsContiguousIterator) {
+ const uint64_t digits =
+ PrepareEightDigits(static_cast<uint32_t>(v)) + kEightZeroBytes;
+ end -= sizeof(digits);
+ little_endian::Store64(&*end, digits);
+ } else {
+ uint64_t digits = PrepareEightDigitsReversed(static_cast<uint32_t>(v)) +
+ kEightZeroBytes;
+ for (size_t i = 0; i < sizeof(digits); ++i) {
+ *--end = static_cast<char>(digits);
+ digits >>= CHAR_BIT;
+ }
+ }
+ return end;
}
- return numbers_internal::FastIntToBuffer(u, buffer);
-}
-char* numbers_internal::FastIntToBuffer(uint64_t i, char* buffer) {
- uint32_t u32 = static_cast<uint32_t>(i);
- if (u32 == i) return numbers_internal::FastIntToBuffer(u32, buffer);
-
- // 10**9 < 2**32 <= i < 10**10, we can do 2+8
- uint64_t div08 = i / 100'000'000ull;
- uint64_t mod08 = i % 100'000'000ull;
- uint64_t mod_result =
- PrepareTenThousands(mod08 / 10000, mod08 % 10000) + kEightZeroBytes;
- if (i < 10'000'000'000ull) {
- buffer = EncodeHundred(static_cast<uint32_t>(div08), buffer);
- little_endian::Store64(buffer, mod_result);
- buffer += 8;
- goto set_last_zero;
+ template <int Digits>
+ static BackwardIt DoFastIntToBufferBackward(
+ T v, BackwardIt end, std::integral_constant<int, Digits>) {
+ constexpr int kLogModulus = Digits - Digits / 2;
+ constexpr T kModulus = Pow(static_cast<T>(10), kLogModulus);
+ bool is_safe_to_use_division_trick = Digits <= 8;
+ T quotient, remainder;
+ if (is_safe_to_use_division_trick) {
+ constexpr uint64_t kCoefficient =
+ ComputePowerOf100DivisionCoefficient<uint64_t>(kLogModulus);
+ quotient = (v * kCoefficient) >> (10 * kLogModulus);
+ remainder = v - quotient * kModulus;
+ } else {
+ quotient = v / kModulus;
+ remainder = v % kModulus;
+ }
+ end = DoFastIntToBufferBackward(remainder, end,
+ std::integral_constant<int, kLogModulus>());
+ return DoFastIntToBufferBackward(
+ quotient, end, std::integral_constant<int, Digits - kLogModulus>());
}
+};
- // i < 10**16, in this case 8+8
- if (i < 10'000'000'000'000'000ull) {
- buffer = EncodeFullU32(static_cast<uint32_t>(div08), buffer);
- little_endian::Store64(buffer, mod_result);
- buffer += 8;
- goto set_last_zero;
- } else {
- // 4 + 8 + 8
- uint64_t div016 = i / 10'000'000'000'000'000ull;
- buffer = EncodeTenThousand(static_cast<uint32_t>(div016), buffer);
- uint64_t mid_result = div08 - div016 * 100'000'000ull;
- mid_result = PrepareTenThousands(mid_result / 10000, mid_result % 10000) +
- kEightZeroBytes;
- little_endian::Store64(buffer, mid_result);
- buffer += 8;
- little_endian::Store64(buffer, mod_result);
- buffer += 8;
- goto set_last_zero;
+// Returns an iterator to the start of the suffix that was appended
+template <typename T, typename BackwardIt>
+std::enable_if_t<std::is_unsigned<T>::value, BackwardIt>
+DoFastIntToBufferBackward(T v, BackwardIt end, uint32_t digits) {
+ using PromotedT = std::decay_t<decltype(+v)>;
+ using Converter = FastUIntToStringConverter<PromotedT, BackwardIt>;
+ (void)digits;
+ return Converter().FastIntToBufferBackward(v, end);
+}
+
+template <typename T, typename BackwardIt>
+std::enable_if_t<std::is_signed<T>::value, BackwardIt>
+DoFastIntToBufferBackward(T v, BackwardIt end, uint32_t digits) {
+ if (absl::numbers_internal::IsNegative(v)) {
+ // Store the minus sign *before* we produce the number itself, not after.
+ // This gets us a tail call.
+ end[-static_cast<ptrdiff_t>(digits) - 1] = '-';
}
-set_last_zero:
- *buffer = '\0';
+ return DoFastIntToBufferBackward(
+ absl::numbers_internal::UnsignedAbsoluteValue(v), end, digits);
+}
+
+template <class T>
+std::enable_if_t<std::is_integral<T>::value, int>
+GetNumDigitsOrNegativeIfNegativeImpl(T v) {
+ const auto /* either bool or std::false_type */ is_negative =
+ absl::numbers_internal::IsNegative(v);
+ const int digits = static_cast<int>(absl::numbers_internal::Base10Digits(
+ absl::numbers_internal::UnsignedAbsoluteValue(v)));
+ return is_negative ? ~digits : digits;
+}
+
+} // namespace
+
+void numbers_internal::PutTwoDigits(uint32_t i, absl::Nonnull<char*> buf) {
+ little_endian::Store16(
+ buf, static_cast<uint16_t>(PrepareTwoDigits(i) + kTwoZeroBytes));
+}
+
+absl::Nonnull<char*> numbers_internal::FastIntToBuffer(
+ uint32_t i, absl::Nonnull<char*> buffer) {
+ const uint32_t digits = absl::numbers_internal::Base10Digits(i);
+ buffer += digits;
+ *buffer = '\0'; // We're going backward, so store this first
+ FastIntToBufferBackward(i, buffer, digits);
return buffer;
}
-char* numbers_internal::FastIntToBuffer(int64_t i, char* buffer) {
- uint64_t u = static_cast<uint64_t>(i);
- if (i < 0) {
- *buffer++ = '-';
- u = 0 - u;
- }
- return numbers_internal::FastIntToBuffer(u, buffer);
+absl::Nonnull<char*> numbers_internal::FastIntToBuffer(
+ int32_t i, absl::Nonnull<char*> buffer) {
+ buffer += static_cast<int>(i < 0);
+ uint32_t digits = absl::numbers_internal::Base10Digits(
+ absl::numbers_internal::UnsignedAbsoluteValue(i));
+ buffer += digits;
+ *buffer = '\0'; // We're going backward, so store this first
+ FastIntToBufferBackward(i, buffer, digits);
+ return buffer;
+}
+
+absl::Nonnull<char*> numbers_internal::FastIntToBuffer(
+ uint64_t i, absl::Nonnull<char*> buffer) {
+ uint32_t digits = absl::numbers_internal::Base10Digits(i);
+ buffer += digits;
+ *buffer = '\0'; // We're going backward, so store this first
+ FastIntToBufferBackward(i, buffer, digits);
+ return buffer;
+}
+
+absl::Nonnull<char*> numbers_internal::FastIntToBuffer(
+ int64_t i, absl::Nonnull<char*> buffer) {
+ buffer += static_cast<int>(i < 0);
+ uint32_t digits = absl::numbers_internal::Base10Digits(
+ absl::numbers_internal::UnsignedAbsoluteValue(i));
+ buffer += digits;
+ *buffer = '\0'; // We're going backward, so store this first
+ FastIntToBufferBackward(i, buffer, digits);
+ return buffer;
+}
+
+absl::Nonnull<char*> numbers_internal::FastIntToBufferBackward(
+ uint32_t i, absl::Nonnull<char*> buffer_end, uint32_t exact_digit_count) {
+ return DoFastIntToBufferBackward(i, buffer_end, exact_digit_count);
+}
+
+absl::Nonnull<char*> numbers_internal::FastIntToBufferBackward(
+ int32_t i, absl::Nonnull<char*> buffer_end, uint32_t exact_digit_count) {
+ return DoFastIntToBufferBackward(i, buffer_end, exact_digit_count);
+}
+
+absl::Nonnull<char*> numbers_internal::FastIntToBufferBackward(
+ uint64_t i, absl::Nonnull<char*> buffer_end, uint32_t exact_digit_count) {
+ return DoFastIntToBufferBackward(i, buffer_end, exact_digit_count);
+}
+
+absl::Nonnull<char*> numbers_internal::FastIntToBufferBackward(
+ int64_t i, absl::Nonnull<char*> buffer_end, uint32_t exact_digit_count) {
+ return DoFastIntToBufferBackward(i, buffer_end, exact_digit_count);
+}
+
+int numbers_internal::GetNumDigitsOrNegativeIfNegative(signed char v) {
+ return GetNumDigitsOrNegativeIfNegativeImpl(v);
+}
+int numbers_internal::GetNumDigitsOrNegativeIfNegative(unsigned char v) {
+ return GetNumDigitsOrNegativeIfNegativeImpl(v);
+}
+int numbers_internal::GetNumDigitsOrNegativeIfNegative(short v) { // NOLINT
+ return GetNumDigitsOrNegativeIfNegativeImpl(v);
+}
+int numbers_internal::GetNumDigitsOrNegativeIfNegative(
+ unsigned short v) { // NOLINT
+ return GetNumDigitsOrNegativeIfNegativeImpl(v);
+}
+int numbers_internal::GetNumDigitsOrNegativeIfNegative(int v) {
+ return GetNumDigitsOrNegativeIfNegativeImpl(v);
+}
+int numbers_internal::GetNumDigitsOrNegativeIfNegative(unsigned int v) {
+ return GetNumDigitsOrNegativeIfNegativeImpl(v);
+}
+int numbers_internal::GetNumDigitsOrNegativeIfNegative(long v) { // NOLINT
+ return GetNumDigitsOrNegativeIfNegativeImpl(v);
+}
+int numbers_internal::GetNumDigitsOrNegativeIfNegative(
+ unsigned long v) { // NOLINT
+ return GetNumDigitsOrNegativeIfNegativeImpl(v);
+}
+int numbers_internal::GetNumDigitsOrNegativeIfNegative(long long v) { // NOLINT
+ return GetNumDigitsOrNegativeIfNegativeImpl(v);
+}
+int numbers_internal::GetNumDigitsOrNegativeIfNegative(
+ unsigned long long v) { // NOLINT
+ return GetNumDigitsOrNegativeIfNegativeImpl(v);
}
// Given a 128-bit number expressed as a pair of uint64_t, high half first,
@@ -534,7 +769,8 @@ static ExpDigits SplitToSix(const double value) {
// Helper function for fast formatting of floating-point.
// The result is the same as "%g", a.k.a. "%.6g".
-size_t numbers_internal::SixDigitsToBuffer(double d, char* const buffer) {
+size_t numbers_internal::SixDigitsToBuffer(double d,
+ absl::Nonnull<char*> const buffer) {
static_assert(std::numeric_limits<float>::is_iec559,
"IEEE-754/IEC-559 support only");
@@ -681,9 +917,10 @@ static const int8_t kAsciiToInt[256] = {
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36};
// Parse the sign and optional hex or oct prefix in text.
-inline bool safe_parse_sign_and_base(absl::string_view* text /*inout*/,
- int* base_ptr /*inout*/,
- bool* negative_ptr /*output*/) {
+inline bool safe_parse_sign_and_base(
+ absl::Nonnull<absl::string_view*> text /*inout*/,
+ absl::Nonnull<int*> base_ptr /*inout*/,
+ absl::Nonnull<bool*> negative_ptr /*output*/) {
if (text->data() == nullptr) {
return false;
}
@@ -968,7 +1205,7 @@ ABSL_CONST_INIT const IntType LookupTables<IntType>::kVminOverBase[] =
template <typename IntType>
inline bool safe_parse_positive_int(absl::string_view text, int base,
- IntType* value_p) {
+ absl::Nonnull<IntType*> value_p) {
IntType value = 0;
const IntType vmax = std::numeric_limits<IntType>::max();
assert(vmax > 0);
@@ -1005,7 +1242,7 @@ inline bool safe_parse_positive_int(absl::string_view text, int base,
template <typename IntType>
inline bool safe_parse_negative_int(absl::string_view text, int base,
- IntType* value_p) {
+ absl::Nonnull<IntType*> value_p) {
IntType value = 0;
const IntType vmin = std::numeric_limits<IntType>::min();
assert(vmin < 0);
@@ -1049,8 +1286,8 @@ inline bool safe_parse_negative_int(absl::string_view text, int base,
// Input format based on POSIX.1-2008 strtol
// http://pubs.opengroup.org/onlinepubs/9699919799/functions/strtol.html
template <typename IntType>
-inline bool safe_int_internal(absl::string_view text, IntType* value_p,
- int base) {
+inline bool safe_int_internal(absl::string_view text,
+ absl::Nonnull<IntType*> value_p, int base) {
*value_p = 0;
bool negative;
if (!safe_parse_sign_and_base(&text, &base, &negative)) {
@@ -1064,8 +1301,8 @@ inline bool safe_int_internal(absl::string_view text, IntType* value_p,
}
template <typename IntType>
-inline bool safe_uint_internal(absl::string_view text, IntType* value_p,
- int base) {
+inline bool safe_uint_internal(absl::string_view text,
+ absl::Nonnull<IntType*> value_p, int base) {
*value_p = 0;
bool negative;
if (!safe_parse_sign_and_base(&text, &base, &negative) || negative) {
@@ -1099,27 +1336,33 @@ ABSL_CONST_INIT ABSL_DLL const char kHexTable[513] =
"e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
-bool safe_strto32_base(absl::string_view text, int32_t* value, int base) {
+bool safe_strto32_base(absl::string_view text, absl::Nonnull<int32_t*> value,
+ int base) {
return safe_int_internal<int32_t>(text, value, base);
}
-bool safe_strto64_base(absl::string_view text, int64_t* value, int base) {
+bool safe_strto64_base(absl::string_view text, absl::Nonnull<int64_t*> value,
+ int base) {
return safe_int_internal<int64_t>(text, value, base);
}
-bool safe_strto128_base(absl::string_view text, int128* value, int base) {
+bool safe_strto128_base(absl::string_view text, absl::Nonnull<int128*> value,
+ int base) {
return safe_int_internal<absl::int128>(text, value, base);
}
-bool safe_strtou32_base(absl::string_view text, uint32_t* value, int base) {
+bool safe_strtou32_base(absl::string_view text, absl::Nonnull<uint32_t*> value,
+ int base) {
return safe_uint_internal<uint32_t>(text, value, base);
}
-bool safe_strtou64_base(absl::string_view text, uint64_t* value, int base) {
+bool safe_strtou64_base(absl::string_view text, absl::Nonnull<uint64_t*> value,
+ int base) {
return safe_uint_internal<uint64_t>(text, value, base);
}
-bool safe_strtou128_base(absl::string_view text, uint128* value, int base) {
+bool safe_strtou128_base(absl::string_view text, absl::Nonnull<uint128*> value,
+ int base) {
return safe_uint_internal<absl::uint128>(text, value, base);
}
diff --git a/contrib/restricted/abseil-cpp/absl/strings/numbers.h b/contrib/restricted/abseil-cpp/absl/strings/numbers.h
index d7630cef9c..ad4e66b634 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/numbers.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/numbers.h
@@ -32,6 +32,7 @@
#endif
#include <cstddef>
+#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <ctime>
@@ -39,9 +40,12 @@
#include <string>
#include <type_traits>
+#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/endian.h"
#include "absl/base/macros.h"
+#include "absl/base/nullability.h"
+#include "absl/base/optimization.h"
#include "absl/base/port.h"
#include "absl/numeric/bits.h"
#include "absl/numeric/int128.h"
@@ -59,7 +63,8 @@ ABSL_NAMESPACE_BEGIN
// encountered, this function returns `false`, leaving `out` in an unspecified
// state.
template <typename int_type>
-ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view str, int_type* out);
+ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view str,
+ absl::Nonnull<int_type*> out);
// SimpleAtof()
//
@@ -70,7 +75,8 @@ ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view str, int_type* out);
// allowed formats for `str`, except SimpleAtof() is locale-independent and will
// always use the "C" locale. If any errors are encountered, this function
// returns `false`, leaving `out` in an unspecified state.
-ABSL_MUST_USE_RESULT bool SimpleAtof(absl::string_view str, float* out);
+ABSL_MUST_USE_RESULT bool SimpleAtof(absl::string_view str,
+ absl::Nonnull<float*> out);
// SimpleAtod()
//
@@ -81,7 +87,8 @@ ABSL_MUST_USE_RESULT bool SimpleAtof(absl::string_view str, float* out);
// allowed formats for `str`, except SimpleAtod is locale-independent and will
// always use the "C" locale. If any errors are encountered, this function
// returns `false`, leaving `out` in an unspecified state.
-ABSL_MUST_USE_RESULT bool SimpleAtod(absl::string_view str, double* out);
+ABSL_MUST_USE_RESULT bool SimpleAtod(absl::string_view str,
+ absl::Nonnull<double*> out);
// SimpleAtob()
//
@@ -91,7 +98,8 @@ ABSL_MUST_USE_RESULT bool SimpleAtod(absl::string_view str, double* out);
// are interpreted as boolean `false`: "false", "f", "no", "n", "0". If any
// errors are encountered, this function returns `false`, leaving `out` in an
// unspecified state.
-ABSL_MUST_USE_RESULT bool SimpleAtob(absl::string_view str, bool* out);
+ABSL_MUST_USE_RESULT bool SimpleAtob(absl::string_view str,
+ absl::Nonnull<bool*> out);
// SimpleHexAtoi()
//
@@ -104,13 +112,14 @@ ABSL_MUST_USE_RESULT bool SimpleAtob(absl::string_view str, bool* out);
// by this function. If any errors are encountered, this function returns
// `false`, leaving `out` in an unspecified state.
template <typename int_type>
-ABSL_MUST_USE_RESULT bool SimpleHexAtoi(absl::string_view str, int_type* out);
+ABSL_MUST_USE_RESULT bool SimpleHexAtoi(absl::string_view str,
+ absl::Nonnull<int_type*> out);
// Overloads of SimpleHexAtoi() for 128 bit integers.
-ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(absl::string_view str,
- absl::int128* out);
-ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(absl::string_view str,
- absl::uint128* out);
+ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(
+ absl::string_view str, absl::Nonnull<absl::int128*> out);
+ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(
+ absl::string_view str, absl::Nonnull<absl::uint128*> out);
ABSL_NAMESPACE_END
} // namespace absl
@@ -132,42 +141,136 @@ ABSL_DLL extern const char
// PutTwoDigits(42, buf);
// // buf[0] == '4'
// // buf[1] == '2'
-void PutTwoDigits(uint32_t i, char* buf);
+void PutTwoDigits(uint32_t i, absl::Nonnull<char*> buf);
// safe_strto?() functions for implementing SimpleAtoi()
-bool safe_strto32_base(absl::string_view text, int32_t* value, int base);
-bool safe_strto64_base(absl::string_view text, int64_t* value, int base);
-bool safe_strto128_base(absl::string_view text, absl::int128* value,
- int base);
-bool safe_strtou32_base(absl::string_view text, uint32_t* value, int base);
-bool safe_strtou64_base(absl::string_view text, uint64_t* value, int base);
-bool safe_strtou128_base(absl::string_view text, absl::uint128* value,
- int base);
+bool safe_strto32_base(absl::string_view text, absl::Nonnull<int32_t*> value,
+ int base);
+bool safe_strto64_base(absl::string_view text, absl::Nonnull<int64_t*> value,
+ int base);
+bool safe_strto128_base(absl::string_view text,
+ absl::Nonnull<absl::int128*> value, int base);
+bool safe_strtou32_base(absl::string_view text, absl::Nonnull<uint32_t*> value,
+ int base);
+bool safe_strtou64_base(absl::string_view text, absl::Nonnull<uint64_t*> value,
+ int base);
+bool safe_strtou128_base(absl::string_view text,
+ absl::Nonnull<absl::uint128*> value, int base);
static const int kFastToBufferSize = 32;
static const int kSixDigitsToBufferSize = 16;
+template <class T>
+std::enable_if_t<!std::is_unsigned<T>::value, bool> IsNegative(const T& v) {
+ return v < T();
+}
+
+template <class T>
+std::enable_if_t<std::is_unsigned<T>::value, std::false_type> IsNegative(
+ const T&) {
+ // The integer is unsigned, so return a compile-time constant.
+ // This can help the optimizer avoid having to prove bool to be false later.
+ return std::false_type();
+}
+
+template <class T>
+std::enable_if_t<std::is_unsigned<std::decay_t<T>>::value, T&&>
+UnsignedAbsoluteValue(T&& v ABSL_ATTRIBUTE_LIFETIME_BOUND) {
+ // The value is unsigned; just return the original.
+ return std::forward<T>(v);
+}
+
+template <class T>
+ABSL_ATTRIBUTE_CONST_FUNCTION
+ std::enable_if_t<!std::is_unsigned<T>::value, std::make_unsigned_t<T>>
+ UnsignedAbsoluteValue(T v) {
+ using U = std::make_unsigned_t<T>;
+ return IsNegative(v) ? U() - static_cast<U>(v) : static_cast<U>(v);
+}
+
+// Returns the number of base-10 digits in the given number.
+// Note that this strictly counts digits. It does not count the sign.
+// The `initial_digits` parameter is the starting point, which is normally equal
+// to 1 because the number of digits in 0 is 1 (a special case).
+// However, callers may e.g. wish to change it to 2 to account for the sign.
+template <typename T>
+std::enable_if_t<std::is_unsigned<T>::value, uint32_t> Base10Digits(
+ T v, const uint32_t initial_digits = 1) {
+ uint32_t r = initial_digits;
+ // If code size becomes an issue, the 'if' stage can be removed for a minor
+ // performance loss.
+ for (;;) {
+ if (ABSL_PREDICT_TRUE(v < 10 * 10)) {
+ r += (v >= 10);
+ break;
+ }
+ if (ABSL_PREDICT_TRUE(v < 1000 * 10)) {
+ r += (v >= 1000) + 2;
+ break;
+ }
+ if (ABSL_PREDICT_TRUE(v < 100000 * 10)) {
+ r += (v >= 100000) + 4;
+ break;
+ }
+ r += 6;
+ v = static_cast<T>(v / 1000000);
+ }
+ return r;
+}
+
+template <typename T>
+std::enable_if_t<std::is_signed<T>::value, uint32_t> Base10Digits(
+ T v, uint32_t r = 1) {
+ // Branchlessly add 1 to account for a minus sign.
+ r += static_cast<uint32_t>(IsNegative(v));
+ return Base10Digits(UnsignedAbsoluteValue(v), r);
+}
+
+// These functions return the number of base-10 digits, but multiplied by -1 if
+// the input itself is negative. This is handy and efficient for later usage,
+// since the bitwise complement of the result becomes equal to the number of
+// characters required.
+ABSL_ATTRIBUTE_CONST_FUNCTION int GetNumDigitsOrNegativeIfNegative(
+ signed char v);
+ABSL_ATTRIBUTE_CONST_FUNCTION int GetNumDigitsOrNegativeIfNegative(
+ unsigned char v);
+ABSL_ATTRIBUTE_CONST_FUNCTION int GetNumDigitsOrNegativeIfNegative(
+ short v); // NOLINT
+ABSL_ATTRIBUTE_CONST_FUNCTION int GetNumDigitsOrNegativeIfNegative(
+ unsigned short v); // NOLINT
+ABSL_ATTRIBUTE_CONST_FUNCTION int GetNumDigitsOrNegativeIfNegative(int v);
+ABSL_ATTRIBUTE_CONST_FUNCTION int GetNumDigitsOrNegativeIfNegative(
+ unsigned int v);
+ABSL_ATTRIBUTE_CONST_FUNCTION int GetNumDigitsOrNegativeIfNegative(
+ long v); // NOLINT
+ABSL_ATTRIBUTE_CONST_FUNCTION int GetNumDigitsOrNegativeIfNegative(
+ unsigned long v); // NOLINT
+ABSL_ATTRIBUTE_CONST_FUNCTION int GetNumDigitsOrNegativeIfNegative(
+ long long v); // NOLINT
+ABSL_ATTRIBUTE_CONST_FUNCTION int GetNumDigitsOrNegativeIfNegative(
+ unsigned long long v); // NOLINT
+
// Helper function for fast formatting of floating-point values.
// The result is the same as printf's "%g", a.k.a. "%.6g"; that is, six
// significant digits are returned, trailing zeros are removed, and numbers
// outside the range 0.0001-999999 are output using scientific notation
// (1.23456e+06). This routine is heavily optimized.
// Required buffer size is `kSixDigitsToBufferSize`.
-size_t SixDigitsToBuffer(double d, char* buffer);
+size_t SixDigitsToBuffer(double d, absl::Nonnull<char*> buffer);
-// These functions are intended for speed. All functions take an output buffer
+// All of these functions take an output buffer
// as an argument and return a pointer to the last byte they wrote, which is the
// terminating '\0'. At most `kFastToBufferSize` bytes are written.
-char* FastIntToBuffer(int32_t, char*);
-char* FastIntToBuffer(uint32_t, char*);
-char* FastIntToBuffer(int64_t, char*);
-char* FastIntToBuffer(uint64_t, char*);
+absl::Nonnull<char*> FastIntToBuffer(int32_t i, absl::Nonnull<char*> buffer);
+absl::Nonnull<char*> FastIntToBuffer(uint32_t i, absl::Nonnull<char*> buffer);
+absl::Nonnull<char*> FastIntToBuffer(int64_t i, absl::Nonnull<char*> buffer);
+absl::Nonnull<char*> FastIntToBuffer(uint64_t i, absl::Nonnull<char*> buffer);
// For enums and integer types that are not an exact match for the types above,
// use templates to call the appropriate one of the four overloads above.
template <typename int_type>
-char* FastIntToBuffer(int_type i, char* buffer) {
+absl::Nonnull<char*> FastIntToBuffer(int_type i, absl::Nonnull<char*> buffer) {
static_assert(sizeof(i) <= 64 / 8,
"FastIntToBuffer works only with 64-bit-or-less integers.");
// TODO(jorg): This signed-ness check is used because it works correctly
@@ -191,10 +294,63 @@ char* FastIntToBuffer(int_type i, char* buffer) {
}
}
+// These functions do NOT add any null-terminator.
+// They return a pointer to the beginning of the written string.
+// The digit counts provided must *exactly* match the number of base-10 digits
+// in the number, or the behavior is undefined.
+// (i.e. do NOT count the minus sign, or over- or under-count the digits.)
+absl::Nonnull<char*> FastIntToBufferBackward(int32_t i,
+ absl::Nonnull<char*> buffer_end,
+ uint32_t exact_digit_count);
+absl::Nonnull<char*> FastIntToBufferBackward(uint32_t i,
+ absl::Nonnull<char*> buffer_end,
+ uint32_t exact_digit_count);
+absl::Nonnull<char*> FastIntToBufferBackward(int64_t i,
+ absl::Nonnull<char*> buffer_end,
+ uint32_t exact_digit_count);
+absl::Nonnull<char*> FastIntToBufferBackward(uint64_t i,
+ absl::Nonnull<char*> buffer_end,
+ uint32_t exact_digit_count);
+
+// For enums and integer types that are not an exact match for the types above,
+// use templates to call the appropriate one of the four overloads above.
+template <typename int_type>
+absl::Nonnull<char*> FastIntToBufferBackward(int_type i,
+ absl::Nonnull<char*> buffer_end,
+ uint32_t exact_digit_count) {
+ static_assert(
+ sizeof(i) <= 64 / 8,
+ "FastIntToBufferBackward works only with 64-bit-or-less integers.");
+ // This signed-ness check is used because it works correctly
+ // with enums, and it also serves to check that int_type is not a pointer.
+ // If one day something like std::is_signed<enum E> works, switch to it.
+ // These conditions are constexpr bools to suppress MSVC warning C4127.
+ constexpr bool kIsSigned = static_cast<int_type>(1) - 2 < 0;
+ constexpr bool kUse64Bit = sizeof(i) > 32 / 8;
+ if (kIsSigned) {
+ if (kUse64Bit) {
+ return FastIntToBufferBackward(static_cast<int64_t>(i), buffer_end,
+ exact_digit_count);
+ } else {
+ return FastIntToBufferBackward(static_cast<int32_t>(i), buffer_end,
+ exact_digit_count);
+ }
+ } else {
+ if (kUse64Bit) {
+ return FastIntToBufferBackward(static_cast<uint64_t>(i), buffer_end,
+ exact_digit_count);
+ } else {
+ return FastIntToBufferBackward(static_cast<uint32_t>(i), buffer_end,
+ exact_digit_count);
+ }
+ }
+}
+
// Implementation of SimpleAtoi, generalized to support arbitrary base (used
// with base different from 10 elsewhere in Abseil implementation).
template <typename int_type>
-ABSL_MUST_USE_RESULT bool safe_strtoi_base(absl::string_view s, int_type* out,
+ABSL_MUST_USE_RESULT bool safe_strtoi_base(absl::string_view s,
+ absl::Nonnull<int_type*> out,
int base) {
static_assert(sizeof(*out) == 4 || sizeof(*out) == 8,
"SimpleAtoi works only with 32-bit or 64-bit integers.");
@@ -237,7 +393,7 @@ ABSL_MUST_USE_RESULT bool safe_strtoi_base(absl::string_view s, int_type* out,
// without the terminating null character. Thus `out` must be of length >= 16.
// Returns the number of non-pad digits of the output (it can never be zero
// since 0 has one digit).
-inline size_t FastHexToBufferZeroPad16(uint64_t val, char* out) {
+inline size_t FastHexToBufferZeroPad16(uint64_t val, absl::Nonnull<char*> out) {
#ifdef ABSL_INTERNAL_HAVE_SSSE3
uint64_t be = absl::big_endian::FromHost64(val);
const auto kNibbleMask = _mm_set1_epi8(0xf);
@@ -263,32 +419,34 @@ inline size_t FastHexToBufferZeroPad16(uint64_t val, char* out) {
} // namespace numbers_internal
template <typename int_type>
-ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view str, int_type* out) {
+ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view str,
+ absl::Nonnull<int_type*> out) {
return numbers_internal::safe_strtoi_base(str, out, 10);
}
ABSL_MUST_USE_RESULT inline bool SimpleAtoi(absl::string_view str,
- absl::int128* out) {
+ absl::Nonnull<absl::int128*> out) {
return numbers_internal::safe_strto128_base(str, out, 10);
}
ABSL_MUST_USE_RESULT inline bool SimpleAtoi(absl::string_view str,
- absl::uint128* out) {
+ absl::Nonnull<absl::uint128*> out) {
return numbers_internal::safe_strtou128_base(str, out, 10);
}
template <typename int_type>
-ABSL_MUST_USE_RESULT bool SimpleHexAtoi(absl::string_view str, int_type* out) {
+ABSL_MUST_USE_RESULT bool SimpleHexAtoi(absl::string_view str,
+ absl::Nonnull<int_type*> out) {
return numbers_internal::safe_strtoi_base(str, out, 16);
}
-ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(absl::string_view str,
- absl::int128* out) {
+ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(
+ absl::string_view str, absl::Nonnull<absl::int128*> out) {
return numbers_internal::safe_strto128_base(str, out, 16);
}
-ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(absl::string_view str,
- absl::uint128* out) {
+ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(
+ absl::string_view str, absl::Nonnull<absl::uint128*> out) {
return numbers_internal::safe_strtou128_base(str, out, 16);
}
diff --git a/contrib/restricted/abseil-cpp/absl/strings/str_cat.cc b/contrib/restricted/abseil-cpp/absl/strings/str_cat.cc
index 2e49c31b68..098ab18388 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/str_cat.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/str_cat.cc
@@ -16,13 +16,15 @@
#include <assert.h>
-#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <cstring>
+#include <initializer_list>
#include <string>
+#include <type_traits>
-#include "absl/strings/ascii.h"
+#include "absl/base/config.h"
+#include "absl/base/nullability.h"
#include "absl/strings/internal/resize_uninitialized.h"
#include "absl/strings/numbers.h"
#include "absl/strings/string_view.h"
@@ -30,6 +32,7 @@
namespace absl {
ABSL_NAMESPACE_BEGIN
+
// ----------------------------------------------------------------------
// StrCat()
// This merges the given strings or integers, with no delimiter. This
@@ -37,9 +40,10 @@ ABSL_NAMESPACE_BEGIN
// of a mix of raw C strings, string_views, strings, and integer values.
// ----------------------------------------------------------------------
+namespace {
// Append is merely a version of memcpy that returns the address of the byte
// after the area just overwritten.
-static char* Append(char* out, const AlphaNum& x) {
+absl::Nonnull<char*> Append(absl::Nonnull<char*> out, const AlphaNum& x) {
// memcpy is allowed to overwrite arbitrary memory, so doing this after the
// call would force an extra fetch of x.size().
char* after = out + x.size();
@@ -49,6 +53,8 @@ static char* Append(char* out, const AlphaNum& x) {
return after;
}
+} // namespace
+
std::string StrCat(const AlphaNum& a, const AlphaNum& b) {
std::string result;
absl::strings_internal::STLStringResizeUninitialized(&result,
@@ -92,6 +98,130 @@ std::string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c,
namespace strings_internal {
// Do not call directly - these are not part of the public API.
+void STLStringAppendUninitializedAmortized(std::string* dest,
+ size_t to_append) {
+ strings_internal::AppendUninitializedTraits<std::string>::Append(dest,
+ to_append);
+}
+
+template <typename Integer>
+std::enable_if_t<std::is_integral<Integer>::value, std::string> IntegerToString(
+ Integer i) {
+ std::string str;
+ const auto /* either bool or std::false_type */ is_negative =
+ absl::numbers_internal::IsNegative(i);
+ const uint32_t digits = absl::numbers_internal::Base10Digits(
+ absl::numbers_internal::UnsignedAbsoluteValue(i));
+ absl::strings_internal::STLStringResizeUninitialized(
+ &str, digits + static_cast<uint32_t>(is_negative));
+ absl::numbers_internal::FastIntToBufferBackward(i, &str[str.size()], digits);
+ return str;
+}
+
+template <>
+std::string IntegerToString(long i) { // NOLINT
+ if (sizeof(i) <= sizeof(int)) {
+ return IntegerToString(static_cast<int>(i));
+ } else {
+ return IntegerToString(static_cast<long long>(i)); // NOLINT
+ }
+}
+
+template <>
+std::string IntegerToString(unsigned long i) { // NOLINT
+ if (sizeof(i) <= sizeof(unsigned int)) {
+ return IntegerToString(static_cast<unsigned int>(i));
+ } else {
+ return IntegerToString(static_cast<unsigned long long>(i)); // NOLINT
+ }
+}
+
+template <typename Float>
+std::enable_if_t<std::is_floating_point<Float>::value, std::string>
+FloatToString(Float f) {
+ std::string result;
+ strings_internal::STLStringResizeUninitialized(
+ &result, numbers_internal::kSixDigitsToBufferSize);
+ char* start = &result[0];
+ result.erase(numbers_internal::SixDigitsToBuffer(f, start));
+ return result;
+}
+
+std::string SingleArgStrCat(int x) { return IntegerToString(x); }
+std::string SingleArgStrCat(unsigned int x) { return IntegerToString(x); }
+// NOLINTNEXTLINE
+std::string SingleArgStrCat(long x) { return IntegerToString(x); }
+// NOLINTNEXTLINE
+std::string SingleArgStrCat(unsigned long x) { return IntegerToString(x); }
+// NOLINTNEXTLINE
+std::string SingleArgStrCat(long long x) { return IntegerToString(x); }
+// NOLINTNEXTLINE
+std::string SingleArgStrCat(unsigned long long x) { return IntegerToString(x); }
+std::string SingleArgStrCat(float x) { return FloatToString(x); }
+std::string SingleArgStrCat(double x) { return FloatToString(x); }
+
+template <class Integer>
+std::enable_if_t<std::is_integral<Integer>::value, void> AppendIntegerToString(
+ std::string& str, Integer i) {
+ const auto /* either bool or std::false_type */ is_negative =
+ absl::numbers_internal::IsNegative(i);
+ const uint32_t digits = absl::numbers_internal::Base10Digits(
+ absl::numbers_internal::UnsignedAbsoluteValue(i));
+ absl::strings_internal::STLStringAppendUninitializedAmortized(
+ &str, digits + static_cast<uint32_t>(is_negative));
+ absl::numbers_internal::FastIntToBufferBackward(i, &str[str.size()], digits);
+}
+
+template <>
+void AppendIntegerToString(std::string& str, long i) { // NOLINT
+ if (sizeof(i) <= sizeof(int)) {
+ return AppendIntegerToString(str, static_cast<int>(i));
+ } else {
+ return AppendIntegerToString(str, static_cast<long long>(i)); // NOLINT
+ }
+}
+
+template <>
+void AppendIntegerToString(std::string& str,
+ unsigned long i) { // NOLINT
+ if (sizeof(i) <= sizeof(unsigned int)) {
+ return AppendIntegerToString(str, static_cast<unsigned int>(i));
+ } else {
+ return AppendIntegerToString(str,
+ static_cast<unsigned long long>(i)); // NOLINT
+ }
+}
+
+// `SingleArgStrAppend` overloads are defined here for the same reasons as with
+// `SingleArgStrCat` above.
+void SingleArgStrAppend(std::string& str, int x) {
+ return AppendIntegerToString(str, x);
+}
+
+void SingleArgStrAppend(std::string& str, unsigned int x) {
+ return AppendIntegerToString(str, x);
+}
+
+// NOLINTNEXTLINE
+void SingleArgStrAppend(std::string& str, long x) {
+ return AppendIntegerToString(str, x);
+}
+
+// NOLINTNEXTLINE
+void SingleArgStrAppend(std::string& str, unsigned long x) {
+ return AppendIntegerToString(str, x);
+}
+
+// NOLINTNEXTLINE
+void SingleArgStrAppend(std::string& str, long long x) {
+ return AppendIntegerToString(str, x);
+}
+
+// NOLINTNEXTLINE
+void SingleArgStrAppend(std::string& str, unsigned long long x) {
+ return AppendIntegerToString(str, x);
+}
+
std::string CatPieces(std::initializer_list<absl::string_view> pieces) {
std::string result;
size_t total_size = 0;
@@ -120,15 +250,15 @@ std::string CatPieces(std::initializer_list<absl::string_view> pieces) {
assert(((src).size() == 0) || \
(uintptr_t((src).data() - (dest).data()) > uintptr_t((dest).size())))
-void AppendPieces(std::string* dest,
+void AppendPieces(absl::Nonnull<std::string*> dest,
std::initializer_list<absl::string_view> pieces) {
size_t old_size = dest->size();
- size_t total_size = old_size;
+ size_t to_append = 0;
for (absl::string_view piece : pieces) {
ASSERT_NO_OVERLAP(*dest, piece);
- total_size += piece.size();
+ to_append += piece.size();
}
- strings_internal::STLStringResizeUninitializedAmortized(dest, total_size);
+ strings_internal::STLStringAppendUninitializedAmortized(dest, to_append);
char* const begin = &(*dest)[0];
char* out = begin + old_size;
@@ -144,23 +274,23 @@ void AppendPieces(std::string* dest,
} // namespace strings_internal
-void StrAppend(std::string* dest, const AlphaNum& a) {
+void StrAppend(absl::Nonnull<std::string*> dest, const AlphaNum& a) {
ASSERT_NO_OVERLAP(*dest, a);
std::string::size_type old_size = dest->size();
- strings_internal::STLStringResizeUninitializedAmortized(dest,
- old_size + a.size());
+ strings_internal::STLStringAppendUninitializedAmortized(dest, a.size());
char* const begin = &(*dest)[0];
char* out = begin + old_size;
out = Append(out, a);
assert(out == begin + dest->size());
}
-void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b) {
+void StrAppend(absl::Nonnull<std::string*> dest, const AlphaNum& a,
+ const AlphaNum& b) {
ASSERT_NO_OVERLAP(*dest, a);
ASSERT_NO_OVERLAP(*dest, b);
std::string::size_type old_size = dest->size();
- strings_internal::STLStringResizeUninitializedAmortized(
- dest, old_size + a.size() + b.size());
+ strings_internal::STLStringAppendUninitializedAmortized(dest,
+ a.size() + b.size());
char* const begin = &(*dest)[0];
char* out = begin + old_size;
out = Append(out, a);
@@ -168,14 +298,14 @@ void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b) {
assert(out == begin + dest->size());
}
-void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b,
- const AlphaNum& c) {
+void StrAppend(absl::Nonnull<std::string*> dest, const AlphaNum& a,
+ const AlphaNum& b, const AlphaNum& c) {
ASSERT_NO_OVERLAP(*dest, a);
ASSERT_NO_OVERLAP(*dest, b);
ASSERT_NO_OVERLAP(*dest, c);
std::string::size_type old_size = dest->size();
- strings_internal::STLStringResizeUninitializedAmortized(
- dest, old_size + a.size() + b.size() + c.size());
+ strings_internal::STLStringAppendUninitializedAmortized(
+ dest, a.size() + b.size() + c.size());
char* const begin = &(*dest)[0];
char* out = begin + old_size;
out = Append(out, a);
@@ -184,15 +314,15 @@ void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b,
assert(out == begin + dest->size());
}
-void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b,
- const AlphaNum& c, const AlphaNum& d) {
+void StrAppend(absl::Nonnull<std::string*> dest, const AlphaNum& a,
+ const AlphaNum& b, const AlphaNum& c, const AlphaNum& d) {
ASSERT_NO_OVERLAP(*dest, a);
ASSERT_NO_OVERLAP(*dest, b);
ASSERT_NO_OVERLAP(*dest, c);
ASSERT_NO_OVERLAP(*dest, d);
std::string::size_type old_size = dest->size();
- strings_internal::STLStringResizeUninitializedAmortized(
- dest, old_size + a.size() + b.size() + c.size() + d.size());
+ strings_internal::STLStringAppendUninitializedAmortized(
+ dest, a.size() + b.size() + c.size() + d.size());
char* const begin = &(*dest)[0];
char* out = begin + old_size;
out = Append(out, a);
diff --git a/contrib/restricted/abseil-cpp/absl/strings/str_cat.h b/contrib/restricted/abseil-cpp/absl/strings/str_cat.h
index d5f71ff003..ea2c4dcad8 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/str_cat.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/str_cat.h
@@ -89,6 +89,8 @@
#include <algorithm>
#include <array>
+#include <cassert>
+#include <cstddef>
#include <cstdint>
#include <cstring>
#include <string>
@@ -97,8 +99,11 @@
#include <vector>
#include "absl/base/attributes.h"
+#include "absl/base/nullability.h"
#include "absl/base/port.h"
-#include "absl/strings/internal/has_absl_stringify.h"
+#include "absl/meta/type_traits.h"
+#include "absl/strings/has_absl_stringify.h"
+#include "absl/strings/internal/resize_uninitialized.h"
#include "absl/strings/internal/stringify_sink.h"
#include "absl/strings/numbers.h"
#include "absl/strings/string_view.h"
@@ -201,7 +206,7 @@ struct Hex {
!std::is_pointer<Int>::value>::type* = nullptr)
: Hex(spec, static_cast<uint64_t>(v)) {}
template <typename Pointee>
- explicit Hex(Pointee* v, PadSpec spec = absl::kNoPad)
+ explicit Hex(absl::Nullable<Pointee*> v, PadSpec spec = absl::kNoPad)
: Hex(spec, reinterpret_cast<uintptr_t>(v)) {}
template <typename S>
@@ -253,10 +258,9 @@ struct Dec {
typename std::enable_if<(sizeof(Int) <= 8)>::type* = nullptr)
: value(v >= 0 ? static_cast<uint64_t>(v)
: uint64_t{0} - static_cast<uint64_t>(v)),
- width(spec == absl::kNoPad
- ? 1
- : spec >= absl::kSpacePad2 ? spec - absl::kSpacePad2 + 2
- : spec - absl::kZeroPad2 + 2),
+ width(spec == absl::kNoPad ? 1
+ : spec >= absl::kSpacePad2 ? spec - absl::kSpacePad2 + 2
+ : spec - absl::kZeroPad2 + 2),
fill(spec >= absl::kSpacePad2 ? ' ' : '0'),
neg(v < 0) {}
@@ -344,7 +348,7 @@ class AlphaNum {
ABSL_ATTRIBUTE_LIFETIME_BOUND)
: piece_(&buf.data[0], buf.size) {}
- AlphaNum(const char* c_str // NOLINT(runtime/explicit)
+ AlphaNum(absl::Nullable<const char*> c_str // NOLINT(runtime/explicit)
ABSL_ATTRIBUTE_LIFETIME_BOUND)
: piece_(NullSafeStringView(c_str)) {}
AlphaNum(absl::string_view pc // NOLINT(runtime/explicit)
@@ -352,7 +356,7 @@ class AlphaNum {
: piece_(pc) {}
template <typename T, typename = typename std::enable_if<
- strings_internal::HasAbslStringify<T>::value>::type>
+ HasAbslStringify<T>::value>::type>
AlphaNum( // NOLINT(runtime/explicit)
const T& v ABSL_ATTRIBUTE_LIFETIME_BOUND,
strings_internal::StringifySink&& sink ABSL_ATTRIBUTE_LIFETIME_BOUND = {})
@@ -371,7 +375,7 @@ class AlphaNum {
AlphaNum& operator=(const AlphaNum&) = delete;
absl::string_view::size_type size() const { return piece_.size(); }
- const char* data() const { return piece_.data(); }
+ absl::Nullable<const char*> data() const { return piece_.data(); }
absl::string_view Piece() const { return piece_; }
// Match unscoped enums. Use integral promotion so that a `char`-backed
@@ -379,17 +383,17 @@ class AlphaNum {
template <typename T,
typename = typename std::enable_if<
std::is_enum<T>{} && std::is_convertible<T, int>{} &&
- !strings_internal::HasAbslStringify<T>::value>::type>
+ !HasAbslStringify<T>::value>::type>
AlphaNum(T e) // NOLINT(runtime/explicit)
: AlphaNum(+e) {}
// This overload matches scoped enums. We must explicitly cast to the
// underlying type, but use integral promotion for the same reason as above.
template <typename T,
- typename std::enable_if<
- std::is_enum<T>{} && !std::is_convertible<T, int>{} &&
- !strings_internal::HasAbslStringify<T>::value,
- char*>::type = nullptr>
+ typename std::enable_if<std::is_enum<T>{} &&
+ !std::is_convertible<T, int>{} &&
+ !HasAbslStringify<T>::value,
+ char*>::type = nullptr>
AlphaNum(T e) // NOLINT(runtime/explicit)
: AlphaNum(+static_cast<typename std::underlying_type<T>::type>(e)) {}
@@ -441,13 +445,48 @@ namespace strings_internal {
// Do not call directly - this is not part of the public API.
std::string CatPieces(std::initializer_list<absl::string_view> pieces);
-void AppendPieces(std::string* dest,
+void AppendPieces(absl::Nonnull<std::string*> dest,
std::initializer_list<absl::string_view> pieces);
+void STLStringAppendUninitializedAmortized(std::string* dest, size_t to_append);
+
+// `SingleArgStrCat` overloads take built-in `int`, `long` and `long long` types
+// (signed / unsigned) to avoid ambiguity on the call side. If we used int32_t
+// and int64_t, then at least one of the three (`int` / `long` / `long long`)
+// would have been ambiguous when passed to `SingleArgStrCat`.
+std::string SingleArgStrCat(int x);
+std::string SingleArgStrCat(unsigned int x);
+std::string SingleArgStrCat(long x); // NOLINT
+std::string SingleArgStrCat(unsigned long x); // NOLINT
+std::string SingleArgStrCat(long long x); // NOLINT
+std::string SingleArgStrCat(unsigned long long x); // NOLINT
+std::string SingleArgStrCat(float x);
+std::string SingleArgStrCat(double x);
+
+// `SingleArgStrAppend` overloads are defined here for the same reasons as with
+// `SingleArgStrCat` above.
+void SingleArgStrAppend(std::string& str, int x);
+void SingleArgStrAppend(std::string& str, unsigned int x);
+void SingleArgStrAppend(std::string& str, long x); // NOLINT
+void SingleArgStrAppend(std::string& str, unsigned long x); // NOLINT
+void SingleArgStrAppend(std::string& str, long long x); // NOLINT
+void SingleArgStrAppend(std::string& str, unsigned long long x); // NOLINT
+
+template <typename T,
+ typename = std::enable_if_t<std::is_arithmetic<T>::value &&
+ !std::is_same<T, char>::value &&
+ !std::is_same<T, bool>::value>>
+using EnableIfFastCase = T;
+
} // namespace strings_internal
ABSL_MUST_USE_RESULT inline std::string StrCat() { return std::string(); }
+template <typename T>
+ABSL_MUST_USE_RESULT inline std::string StrCat(
+ strings_internal::EnableIfFastCase<T> a) {
+ return strings_internal::SingleArgStrCat(a);
+}
ABSL_MUST_USE_RESULT inline std::string StrCat(const AlphaNum& a) {
return std::string(a.data(), a.size());
}
@@ -495,24 +534,87 @@ ABSL_MUST_USE_RESULT inline std::string StrCat(
// absl::string_view p = s;
// StrAppend(&s, p);
-inline void StrAppend(std::string*) {}
-void StrAppend(std::string* dest, const AlphaNum& a);
-void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b);
-void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b,
- const AlphaNum& c);
-void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b,
- const AlphaNum& c, const AlphaNum& d);
+inline void StrAppend(absl::Nonnull<std::string*>) {}
+void StrAppend(absl::Nonnull<std::string*> dest, const AlphaNum& a);
+void StrAppend(absl::Nonnull<std::string*> dest, const AlphaNum& a,
+ const AlphaNum& b);
+void StrAppend(absl::Nonnull<std::string*> dest, const AlphaNum& a,
+ const AlphaNum& b, const AlphaNum& c);
+void StrAppend(absl::Nonnull<std::string*> dest, const AlphaNum& a,
+ const AlphaNum& b, const AlphaNum& c, const AlphaNum& d);
// Support 5 or more arguments
template <typename... AV>
-inline void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b,
- const AlphaNum& c, const AlphaNum& d, const AlphaNum& e,
- const AV&... args) {
+inline void StrAppend(absl::Nonnull<std::string*> dest, const AlphaNum& a,
+ const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
+ const AlphaNum& e, const AV&... args) {
strings_internal::AppendPieces(
dest, {a.Piece(), b.Piece(), c.Piece(), d.Piece(), e.Piece(),
static_cast<const AlphaNum&>(args).Piece()...});
}
+template <class String, class T>
+std::enable_if_t<
+ std::is_integral<absl::strings_internal::EnableIfFastCase<T>>::value, void>
+StrAppend(absl::Nonnull<String*> result, T i) {
+ return absl::strings_internal::SingleArgStrAppend(*result, i);
+}
+
+// This overload is only selected if all the parameters are numbers that can be
+// handled quickly.
+// Later we can look into how we can extend this to more general argument
+// mixtures without bloating codegen too much, or copying unnecessarily.
+template <typename String, typename... T>
+std::enable_if_t<
+ (sizeof...(T) > 1),
+ std::common_type_t<std::conditional_t<
+ true, void, absl::strings_internal::EnableIfFastCase<T>>...>>
+StrAppend(absl::Nonnull<String*> str, T... args) {
+ // Do not add unnecessary variables, logic, or even "free" lambdas here.
+ // They can add overhead for the compiler and/or at run time.
+ // Furthermore, assume this function will be inlined.
+ // This function is carefully tailored to be able to be largely optimized away
+ // so that it becomes near-equivalent to the caller handling each argument
+ // individually while minimizing register pressure, so that the compiler
+ // can inline it with minimal overhead.
+
+ // First, calculate the total length, so we can perform just a single resize.
+ // Save all the lengths for later.
+ size_t total_length = 0;
+ const ptrdiff_t lengths[] = {
+ absl::numbers_internal::GetNumDigitsOrNegativeIfNegative(args)...};
+ for (const ptrdiff_t possibly_negative_length : lengths) {
+ // Lengths are negative for negative numbers. Keep them for later use, but
+ // take their absolute values for calculating total lengths;
+ total_length += possibly_negative_length < 0
+ ? static_cast<size_t>(-possibly_negative_length)
+ : static_cast<size_t>(possibly_negative_length);
+ }
+
+ // Now reserve space for all the arguments.
+ const size_t old_size = str->size();
+ absl::strings_internal::STLStringAppendUninitializedAmortized(str,
+ total_length);
+
+ // Finally, output each argument one-by-one, from left to right.
+ size_t i = 0; // The current argument we're processing
+ ptrdiff_t n; // The length of the current argument
+ typename String::pointer pos = &(*str)[old_size];
+ using SomeTrivialEmptyType = std::false_type;
+ // Ugly code due to the lack of C++14 fold expression makes us.
+ const SomeTrivialEmptyType dummy1;
+ for (const SomeTrivialEmptyType& dummy2 :
+ {(/* Comma expressions are poor man's C++17 fold expression for C++14 */
+ (void)(n = lengths[i]),
+ (void)(n < 0 ? (void)(*pos++ = '-'), (n = ~n) : 0),
+ (void)absl::numbers_internal::FastIntToBufferBackward(
+ absl::numbers_internal::UnsignedAbsoluteValue(std::move(args)),
+ pos += n, static_cast<uint32_t>(n)),
+ (void)++i, dummy1)...}) {
+ (void)dummy2; // Remove & migrate to fold expressions in C++17
+ }
+}
+
// Helper function for the future StrCat default floating-point format, %.6g
// This is fast.
inline strings_internal::AlphaNumBuffer<
diff --git a/contrib/restricted/abseil-cpp/absl/strings/str_format.h b/contrib/restricted/abseil-cpp/absl/strings/str_format.h
index 023e4350d3..66b6af5854 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/str_format.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/str_format.h
@@ -72,14 +72,21 @@
#ifndef ABSL_STRINGS_STR_FORMAT_H_
#define ABSL_STRINGS_STR_FORMAT_H_
+#include <cstdint>
#include <cstdio>
#include <string>
+#include <type_traits>
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/base/nullability.h"
#include "absl/strings/internal/str_format/arg.h" // IWYU pragma: export
#include "absl/strings/internal/str_format/bind.h" // IWYU pragma: export
#include "absl/strings/internal/str_format/checker.h" // IWYU pragma: export
#include "absl/strings/internal/str_format/extension.h" // IWYU pragma: export
#include "absl/strings/internal/str_format/parser.h" // IWYU pragma: export
+#include "absl/strings/string_view.h"
+#include "absl/types/span.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -104,7 +111,8 @@ class UntypedFormatSpec {
explicit UntypedFormatSpec(string_view s) : spec_(s) {}
protected:
- explicit UntypedFormatSpec(const str_format_internal::ParsedFormatBase* pc)
+ explicit UntypedFormatSpec(
+ absl::Nonnull<const str_format_internal::ParsedFormatBase*> pc)
: spec_(pc) {}
private:
@@ -144,7 +152,7 @@ str_format_internal::StreamedWrapper<T> FormatStreamed(const T& v) {
// EXPECT_EQ(8, n);
class FormatCountCapture {
public:
- explicit FormatCountCapture(int* p) : p_(p) {}
+ explicit FormatCountCapture(absl::Nonnull<int*> p) : p_(p) {}
private:
// FormatCountCaptureHelper is used to define FormatConvertImpl() for this
@@ -153,8 +161,8 @@ class FormatCountCapture {
// Unused() is here because of the false positive from -Wunused-private-field
// p_ is used in the templated function of the friend FormatCountCaptureHelper
// class.
- int* Unused() { return p_; }
- int* p_;
+ absl::Nonnull<int*> Unused() { return p_; }
+ absl::Nonnull<int*> p_;
};
// FormatSpec
@@ -250,13 +258,13 @@ class FormatCountCapture {
// `v` uses `d` for signed integer values, `u` for unsigned integer values, `g`
// for floating point values, and formats boolean values as "true"/"false"
// (instead of 1 or 0 for booleans formatted using d). `const char*` is not
-// supported; please use `std:string` and `string_view`. `char` is also not
+// supported; please use `std::string` and `string_view`. `char` is also not
// supported due to ambiguity of the type. This specifier does not support
// modifiers.
//
// The `FormatSpec` intrinsically supports all of these fundamental C++ types:
//
-// * Characters: `char`, `signed char`, `unsigned char`
+// * Characters: `char`, `signed char`, `unsigned char`, `wchar_t`
// * Integers: `int`, `short`, `unsigned short`, `unsigned`, `long`,
// `unsigned long`, `long long`, `unsigned long long`
// * Enums: printed as their underlying integral value
@@ -264,9 +272,9 @@ class FormatCountCapture {
//
// However, in the `str_format` library, a format conversion specifies a broader
// C++ conceptual category instead of an exact type. For example, `%s` binds to
-// any string-like argument, so `std::string`, `absl::string_view`, and
-// `const char*` are all accepted. Likewise, `%d` accepts any integer-like
-// argument, etc.
+// any string-like argument, so `std::string`, `std::wstring`,
+// `absl::string_view`, `const char*`, and `const wchar_t*` are all accepted.
+// Likewise, `%d` accepts any integer-like argument, etc.
template <typename... Args>
using FormatSpec = str_format_internal::FormatSpecTemplate<
@@ -287,8 +295,8 @@ using FormatSpec = str_format_internal::FormatSpecTemplate<
// Example:
//
// // Verified at compile time.
-// absl::ParsedFormat<'s', 'd'> formatString("Welcome to %s, Number %d!");
-// absl::StrFormat(formatString, "TheVillage", 6);
+// absl::ParsedFormat<'s', 'd'> format_string("Welcome to %s, Number %d!");
+// absl::StrFormat(format_string, "TheVillage", 6);
//
// // Verified at runtime.
// auto format_runtime = absl::ParsedFormat<'d'>::New(format_string);
@@ -369,7 +377,7 @@ ABSL_MUST_USE_RESULT std::string StrFormat(const FormatSpec<Args...>& format,
// std::string orig("For example PI is approximately ");
// std::cout << StrAppendFormat(&orig, "%12.6f", 3.14);
template <typename... Args>
-std::string& StrAppendFormat(std::string* dst,
+std::string& StrAppendFormat(absl::Nonnull<std::string*> dst,
const FormatSpec<Args...>& format,
const Args&... args) {
return str_format_internal::AppendPack(
@@ -381,7 +389,7 @@ std::string& StrAppendFormat(std::string* dst,
//
// Writes to an output stream given a format string and zero or more arguments,
// generally in a manner that is more efficient than streaming the result of
-// `absl:: StrFormat()`. The returned object must be streamed before the full
+// `absl::StrFormat()`. The returned object must be streamed before the full
// expression ends.
//
// Example:
@@ -429,7 +437,7 @@ int PrintF(const FormatSpec<Args...>& format, const Args&... args) {
// Outputs: "The capital of Mongolia is Ulaanbaatar"
//
template <typename... Args>
-int FPrintF(std::FILE* output, const FormatSpec<Args...>& format,
+int FPrintF(absl::Nonnull<std::FILE*> output, const FormatSpec<Args...>& format,
const Args&... args) {
return str_format_internal::FprintF(
output, str_format_internal::UntypedFormatSpecImpl::Extract(format),
@@ -458,8 +466,8 @@ int FPrintF(std::FILE* output, const FormatSpec<Args...>& format,
// Post-condition: output == "The capital of Mongolia is Ulaanbaatar"
//
template <typename... Args>
-int SNPrintF(char* output, std::size_t size, const FormatSpec<Args...>& format,
- const Args&... args) {
+int SNPrintF(absl::Nonnull<char*> output, std::size_t size,
+ const FormatSpec<Args...>& format, const Args&... args) {
return str_format_internal::SnprintF(
output, size, str_format_internal::UntypedFormatSpecImpl::Extract(format),
{str_format_internal::FormatArgImpl(args)...});
@@ -492,7 +500,7 @@ class FormatRawSink {
template <typename T,
typename = typename std::enable_if<std::is_constructible<
str_format_internal::FormatRawSinkImpl, T*>::value>::type>
- FormatRawSink(T* raw) // NOLINT
+ FormatRawSink(absl::Nonnull<T*> raw) // NOLINT
: sink_(raw) {}
private:
@@ -849,14 +857,16 @@ class FormatSink {
}
// Support `absl::Format(&sink, format, args...)`.
- friend void AbslFormatFlush(FormatSink* sink, absl::string_view v) {
+ friend void AbslFormatFlush(absl::Nonnull<FormatSink*> sink,
+ absl::string_view v) {
sink->Append(v);
}
private:
friend str_format_internal::FormatSinkImpl;
- explicit FormatSink(str_format_internal::FormatSinkImpl* s) : sink_(s) {}
- str_format_internal::FormatSinkImpl* sink_;
+ explicit FormatSink(absl::Nonnull<str_format_internal::FormatSinkImpl*> s)
+ : sink_(s) {}
+ absl::Nonnull<str_format_internal::FormatSinkImpl*> sink_;
};
// FormatConvertResult
diff --git a/contrib/restricted/abseil-cpp/absl/strings/str_join.h b/contrib/restricted/abseil-cpp/absl/strings/str_join.h
index ee5ae7efdf..6a92c0f53a 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/str_join.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/str_join.h
@@ -80,7 +80,7 @@ ABSL_NAMESPACE_BEGIN
// absl::StrJoin(v, ", ", [](std::string* out, absl::Duration dur) {
// absl::StrAppend(out, absl::FormatDuration(dur));
// });
-// EXPECT_EQ("1s, 10ms", s);
+// EXPECT_EQ(s, "1s, 10ms");
//
// The following standard formatters are provided within this file:
//
@@ -164,21 +164,21 @@ DereferenceFormatter() {
// // of `absl::string_view` or even `const char*`.
// std::vector<std::string> v = {"foo", "bar", "baz"};
// std::string s = absl::StrJoin(v, "-");
-// EXPECT_EQ("foo-bar-baz", s);
+// EXPECT_EQ(s, "foo-bar-baz");
//
// Example 2:
// // Joins the values in the given `std::initializer_list<>` specified using
// // brace initialization. This pattern also works with an initializer_list
// // of ints or `absl::string_view` -- any `AlphaNum`-compatible type.
// std::string s = absl::StrJoin({"foo", "bar", "baz"}, "-");
-// EXPECT_EQ("foo-bar-baz", s);
+// EXPECT_EQs, "foo-bar-baz");
//
// Example 3:
// // Joins a collection of ints. This pattern also works with floats,
// // doubles, int64s -- any `StrCat()`-compatible type.
// std::vector<int> v = {1, 2, 3, -4};
// std::string s = absl::StrJoin(v, "-");
-// EXPECT_EQ("1-2-3--4", s);
+// EXPECT_EQ(s, "1-2-3--4");
//
// Example 4:
// // Joins a collection of pointer-to-int. By default, pointers are
@@ -189,7 +189,7 @@ DereferenceFormatter() {
// int x = 1, y = 2, z = 3;
// std::vector<int*> v = {&x, &y, &z};
// std::string s = absl::StrJoin(v, "-");
-// EXPECT_EQ("1-2-3", s);
+// EXPECT_EQ(s, "1-2-3");
//
// Example 5:
// // Dereferencing of `std::unique_ptr<>` is also supported:
@@ -198,42 +198,42 @@ DereferenceFormatter() {
// v.emplace_back(new int(2));
// v.emplace_back(new int(3));
// std::string s = absl::StrJoin(v, "-");
-// EXPECT_EQ("1-2-3", s);
+// EXPECT_EQ(s, "1-2-3");
//
// Example 6:
// // Joins a `std::map`, with each key-value pair separated by an equals
// // sign. This pattern would also work with, say, a
// // `std::vector<std::pair<>>`.
// std::map<std::string, int> m = {
-// std::make_pair("a", 1),
-// std::make_pair("b", 2),
-// std::make_pair("c", 3)};
+// {"a", 1},
+// {"b", 2},
+// {"c", 3}};
// std::string s = absl::StrJoin(m, ",", absl::PairFormatter("="));
-// EXPECT_EQ("a=1,b=2,c=3", s);
+// EXPECT_EQ(s, "a=1,b=2,c=3");
//
// Example 7:
// // These examples show how `absl::StrJoin()` handles a few common edge
// // cases:
// std::vector<std::string> v_empty;
-// EXPECT_EQ("", absl::StrJoin(v_empty, "-"));
+// EXPECT_EQ(absl::StrJoin(v_empty, "-"), "");
//
// std::vector<std::string> v_one_item = {"foo"};
-// EXPECT_EQ("foo", absl::StrJoin(v_one_item, "-"));
+// EXPECT_EQ(absl::StrJoin(v_one_item, "-"), "foo");
//
// std::vector<std::string> v_empty_string = {""};
-// EXPECT_EQ("", absl::StrJoin(v_empty_string, "-"));
+// EXPECT_EQ(absl::StrJoin(v_empty_string, "-"), "");
//
// std::vector<std::string> v_one_item_empty_string = {"a", ""};
-// EXPECT_EQ("a-", absl::StrJoin(v_one_item_empty_string, "-"));
+// EXPECT_EQ(absl::StrJoin(v_one_item_empty_string, "-"), "a-");
//
// std::vector<std::string> v_two_empty_string = {"", ""};
-// EXPECT_EQ("-", absl::StrJoin(v_two_empty_string, "-"));
+// EXPECT_EQ(absl::StrJoin(v_two_empty_string, "-"), "-");
//
// Example 8:
// // Joins a `std::tuple<T...>` of heterogeneous types, converting each to
// // a std::string using the `absl::AlphaNum` class.
// std::string s = absl::StrJoin(std::make_tuple(123, "abc", 0.456), "-");
-// EXPECT_EQ("123-abc-0.456", s);
+// EXPECT_EQ(s, "123-abc-0.456");
template <typename Iterator, typename Formatter>
std::string StrJoin(Iterator start, Iterator end, absl::string_view sep,
diff --git a/contrib/restricted/abseil-cpp/absl/strings/str_replace.cc b/contrib/restricted/abseil-cpp/absl/strings/str_replace.cc
index 2bd5fa9821..a7ab52fed5 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/str_replace.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/str_replace.cc
@@ -14,7 +14,16 @@
#include "absl/strings/str_replace.h"
+#include <cstddef>
+#include <initializer_list>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/base/config.h"
+#include "absl/base/nullability.h"
#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -28,8 +37,8 @@ using FixedMapping =
// occurred.
int ApplySubstitutions(
absl::string_view s,
- std::vector<strings_internal::ViableSubstitution>* subs_ptr,
- std::string* result_ptr) {
+ absl::Nonnull<std::vector<strings_internal::ViableSubstitution>*> subs_ptr,
+ absl::Nonnull<std::string*> result_ptr) {
auto& subs = *subs_ptr;
int substitutions = 0;
size_t pos = 0;
@@ -74,7 +83,7 @@ std::string StrReplaceAll(absl::string_view s,
}
int StrReplaceAll(strings_internal::FixedMapping replacements,
- std::string* target) {
+ absl::Nonnull<std::string*> target) {
return StrReplaceAll<strings_internal::FixedMapping>(replacements, target);
}
diff --git a/contrib/restricted/abseil-cpp/absl/strings/str_replace.h b/contrib/restricted/abseil-cpp/absl/strings/str_replace.h
index 273c707735..e77ced3e57 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/str_replace.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/str_replace.h
@@ -43,6 +43,7 @@
#include <vector>
#include "absl/base/attributes.h"
+#include "absl/base/nullability.h"
#include "absl/strings/string_view.h"
namespace absl {
@@ -113,7 +114,7 @@ std::string StrReplaceAll(absl::string_view s,
int StrReplaceAll(
std::initializer_list<std::pair<absl::string_view, absl::string_view>>
replacements,
- std::string* target);
+ absl::Nonnull<std::string*> target);
// Overload of `StrReplaceAll()` to replace patterns within a given output
// string *in place* with replacements provided within a container of key/value
@@ -128,7 +129,8 @@ int StrReplaceAll(
// EXPECT_EQ(count, 2);
// EXPECT_EQ("if (ptr &lt; &amp;foo)", s);
template <typename StrToStrMapping>
-int StrReplaceAll(const StrToStrMapping& replacements, std::string* target);
+int StrReplaceAll(const StrToStrMapping& replacements,
+ absl::Nonnull<std::string*> target);
// Implementation details only, past this point.
namespace strings_internal {
@@ -185,8 +187,8 @@ std::vector<ViableSubstitution> FindSubstitutions(
}
int ApplySubstitutions(absl::string_view s,
- std::vector<ViableSubstitution>* subs_ptr,
- std::string* result_ptr);
+ absl::Nonnull<std::vector<ViableSubstitution>*> subs_ptr,
+ absl::Nonnull<std::string*> result_ptr);
} // namespace strings_internal
@@ -201,7 +203,8 @@ std::string StrReplaceAll(absl::string_view s,
}
template <typename StrToStrMapping>
-int StrReplaceAll(const StrToStrMapping& replacements, std::string* target) {
+int StrReplaceAll(const StrToStrMapping& replacements,
+ absl::Nonnull<std::string*> target) {
auto subs = strings_internal::FindSubstitutions(*target, replacements);
if (subs.empty()) return 0;
diff --git a/contrib/restricted/abseil-cpp/absl/strings/str_split.cc b/contrib/restricted/abseil-cpp/absl/strings/str_split.cc
index 72ba7c02df..abe486b915 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/str_split.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/str_split.cc
@@ -15,16 +15,13 @@
#include "absl/strings/str_split.h"
#include <algorithm>
-#include <cassert>
-#include <cstdint>
+#include <cstddef>
#include <cstdlib>
#include <cstring>
-#include <iterator>
-#include <limits>
-#include <memory>
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
-#include "absl/strings/ascii.h"
+#include "absl/strings/string_view.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -99,6 +96,11 @@ absl::string_view ByString::Find(absl::string_view text, size_t pos) const {
return GenericFind(text, delimiter_, pos, LiteralPolicy());
}
+absl::string_view ByAsciiWhitespace::Find(absl::string_view text,
+ size_t pos) const {
+ return GenericFind(text, " \t\v\f\r\n", pos, AnyOfPolicy());
+}
+
//
// ByChar
//
diff --git a/contrib/restricted/abseil-cpp/absl/strings/str_split.h b/contrib/restricted/abseil-cpp/absl/strings/str_split.h
index 7bbb68a343..87540278ad 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/str_split.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/str_split.h
@@ -130,6 +130,24 @@ class ByString {
const std::string delimiter_;
};
+// ByAsciiWhitespace
+//
+// A sub-string delimiter that splits by ASCII whitespace
+// (space, tab, vertical tab, formfeed, linefeed, or carriage return).
+// Note: you probably want to use absl::SkipEmpty() as well!
+//
+// This class is equivalent to ByAnyChar with ASCII whitespace chars.
+//
+// Example:
+//
+// std::vector<std::string> v = absl::StrSplit(
+// "a b\tc\n d \n", absl::ByAsciiWhitespace(), absl::SkipEmpty());
+// // v[0] == "a", v[1] == "b", v[2] == "c", v[3] == "d"
+class ByAsciiWhitespace {
+ public:
+ absl::string_view Find(absl::string_view text, size_t pos) const;
+};
+
// ByChar
//
// A single character delimiter. `ByChar` is functionally equivalent to a
diff --git a/contrib/restricted/abseil-cpp/absl/strings/string_view.cc b/contrib/restricted/abseil-cpp/absl/strings/string_view.cc
index f20ff5306e..97025c32a5 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/string_view.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/string_view.cc
@@ -21,6 +21,8 @@
#include <cstring>
#include <ostream>
+#include "absl/base/nullability.h"
+
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -28,8 +30,10 @@ namespace {
// This is significantly faster for case-sensitive matches with very
// few possible matches.
-const char* memmatch(const char* phaystack, size_t haylen, const char* pneedle,
- size_t neelen) {
+absl::Nullable<const char*> memmatch(absl::Nullable<const char*> phaystack,
+ size_t haylen,
+ absl::Nullable<const char*> pneedle,
+ size_t neelen) {
if (0 == neelen) {
return phaystack; // even if haylen is 0
}
@@ -37,8 +41,8 @@ const char* memmatch(const char* phaystack, size_t haylen, const char* pneedle,
const char* match;
const char* hayend = phaystack + haylen - neelen + 1;
- // A static cast is used here to work around the fact that memchr returns
- // a void* on Posix-compliant systems and const void* on Windows.
+ // A static cast is used here as memchr returns a const void *, and pointer
+ // arithmetic is not allowed on pointers to void.
while (
(match = static_cast<const char*>(memchr(
phaystack, pneedle[0], static_cast<size_t>(hayend - phaystack))))) {
@@ -229,7 +233,6 @@ string_view::size_type string_view::find_last_not_of(
return npos;
}
-
#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
constexpr string_view::size_type string_view::npos;
constexpr string_view::size_type string_view::kMaxSize;
@@ -238,4 +241,22 @@ constexpr string_view::size_type string_view::kMaxSize;
ABSL_NAMESPACE_END
} // namespace absl
+#else
+
+// https://github.com/abseil/abseil-cpp/issues/1465
+// CMake builds on Apple platforms error when libraries are empty.
+// Our CMake configuration can avoid this error on header-only libraries,
+// but since this library is conditionally empty, including a single
+// variable is an easy workaround.
+#ifdef __APPLE__
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace strings_internal {
+extern const char kAvoidEmptyStringViewLibraryWarning;
+const char kAvoidEmptyStringViewLibraryWarning = 0;
+} // namespace strings_internal
+ABSL_NAMESPACE_END
+} // namespace absl
+#endif // __APPLE__
+
#endif // ABSL_USES_STD_STRING_VIEW
diff --git a/contrib/restricted/abseil-cpp/absl/strings/string_view.h b/contrib/restricted/abseil-cpp/absl/strings/string_view.h
index eae11b2ab6..04ca0a38ae 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/string_view.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/string_view.h
@@ -37,6 +37,7 @@
#include <string>
#include "absl/base/attributes.h"
+#include "absl/base/nullability.h"
#include "absl/base/config.h"
#include "absl/base/internal/throw_delegate.h"
#include "absl/base/macros.h"
@@ -162,11 +163,11 @@ class string_view {
public:
using traits_type = std::char_traits<char>;
using value_type = char;
- using pointer = char*;
- using const_pointer = const char*;
+ using pointer = absl::Nullable<char*>;
+ using const_pointer = absl::Nullable<const char*>;
using reference = char&;
using const_reference = const char&;
- using const_iterator = const char*;
+ using const_iterator = absl::Nullable<const char*>;
using iterator = const_iterator;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using reverse_iterator = const_reverse_iterator;
@@ -194,11 +195,12 @@ class string_view {
// accepting possibly null strings, use `absl::NullSafeStringView(str)`
// instead (see below).
// The length check is skipped since it is unnecessary and causes code bloat.
- constexpr string_view(const char* str) // NOLINT(runtime/explicit)
+ constexpr string_view( // NOLINT(runtime/explicit)
+ absl::Nonnull<const char*> str)
: ptr_(str), length_(str ? StrlenInternal(str) : 0) {}
// Implicit constructor of a `string_view` from a `const char*` and length.
- constexpr string_view(const char* data, size_type len)
+ constexpr string_view(absl::Nullable<const char*> data, size_type len)
: ptr_(data), length_(CheckLengthInternal(len)) {}
// NOTE: Harmlessly omitted to work around gdb bug.
@@ -427,18 +429,21 @@ class string_view {
// Overload of `string_view::compare()` for comparing a `string_view` and a
// a different C-style string `s`.
- constexpr int compare(const char* s) const { return compare(string_view(s)); }
+ constexpr int compare(absl::Nonnull<const char*> s) const {
+ return compare(string_view(s));
+ }
// Overload of `string_view::compare()` for comparing a substring of the
// `string_view` and a different string C-style string `s`.
- constexpr int compare(size_type pos1, size_type count1, const char* s) const {
+ constexpr int compare(size_type pos1, size_type count1,
+ absl::Nonnull<const char*> s) const {
return substr(pos1, count1).compare(string_view(s));
}
// Overload of `string_view::compare()` for comparing a substring of the
// `string_view` and a substring of a different C-style string `s`.
- constexpr int compare(size_type pos1, size_type count1, const char* s,
- size_type count2) const {
+ constexpr int compare(size_type pos1, size_type count1,
+ absl::Nonnull<const char*> s, size_type count2) const {
return substr(pos1, count1).compare(string_view(s, count2));
}
@@ -457,13 +462,14 @@ class string_view {
// Overload of `string_view::find()` for finding a substring of a different
// C-style string `s` within the `string_view`.
- size_type find(const char* s, size_type pos, size_type count) const {
+ size_type find(absl::Nonnull<const char*> s, size_type pos,
+ size_type count) const {
return find(string_view(s, count), pos);
}
// Overload of `string_view::find()` for finding a different C-style string
// `s` within the `string_view`.
- size_type find(const char* s, size_type pos = 0) const {
+ size_type find(absl::Nonnull<const char *> s, size_type pos = 0) const {
return find(string_view(s), pos);
}
@@ -480,13 +486,14 @@ class string_view {
// Overload of `string_view::rfind()` for finding a substring of a different
// C-style string `s` within the `string_view`.
- size_type rfind(const char* s, size_type pos, size_type count) const {
+ size_type rfind(absl::Nonnull<const char*> s, size_type pos,
+ size_type count) const {
return rfind(string_view(s, count), pos);
}
// Overload of `string_view::rfind()` for finding a different C-style string
// `s` within the `string_view`.
- size_type rfind(const char* s, size_type pos = npos) const {
+ size_type rfind(absl::Nonnull<const char*> s, size_type pos = npos) const {
return rfind(string_view(s), pos);
}
@@ -505,14 +512,15 @@ class string_view {
// Overload of `string_view::find_first_of()` for finding a substring of a
// different C-style string `s` within the `string_view`.
- size_type find_first_of(const char* s, size_type pos,
- size_type count) const {
+ size_type find_first_of(absl::Nonnull<const char*> s, size_type pos,
+ size_type count) const {
return find_first_of(string_view(s, count), pos);
}
// Overload of `string_view::find_first_of()` for finding a different C-style
// string `s` within the `string_view`.
- size_type find_first_of(const char* s, size_type pos = 0) const {
+ size_type find_first_of(absl::Nonnull<const char*> s,
+ size_type pos = 0) const {
return find_first_of(string_view(s), pos);
}
@@ -531,13 +539,15 @@ class string_view {
// Overload of `string_view::find_last_of()` for finding a substring of a
// different C-style string `s` within the `string_view`.
- size_type find_last_of(const char* s, size_type pos, size_type count) const {
+ size_type find_last_of(absl::Nonnull<const char*> s, size_type pos,
+ size_type count) const {
return find_last_of(string_view(s, count), pos);
}
// Overload of `string_view::find_last_of()` for finding a different C-style
// string `s` within the `string_view`.
- size_type find_last_of(const char* s, size_type pos = npos) const {
+ size_type find_last_of(absl::Nonnull<const char*> s,
+ size_type pos = npos) const {
return find_last_of(string_view(s), pos);
}
@@ -554,14 +564,15 @@ class string_view {
// Overload of `string_view::find_first_not_of()` for finding a substring of a
// different C-style string `s` within the `string_view`.
- size_type find_first_not_of(const char* s, size_type pos,
+ size_type find_first_not_of(absl::Nonnull<const char*> s, size_type pos,
size_type count) const {
return find_first_not_of(string_view(s, count), pos);
}
// Overload of `string_view::find_first_not_of()` for finding a different
// C-style string `s` within the `string_view`.
- size_type find_first_not_of(const char* s, size_type pos = 0) const {
+ size_type find_first_not_of(absl::Nonnull<const char*> s,
+ size_type pos = 0) const {
return find_first_not_of(string_view(s), pos);
}
@@ -579,22 +590,76 @@ class string_view {
// Overload of `string_view::find_last_not_of()` for finding a substring of a
// different C-style string `s` within the `string_view`.
- size_type find_last_not_of(const char* s, size_type pos,
+ size_type find_last_not_of(absl::Nonnull<const char*> s, size_type pos,
size_type count) const {
return find_last_not_of(string_view(s, count), pos);
}
// Overload of `string_view::find_last_not_of()` for finding a different
// C-style string `s` within the `string_view`.
- size_type find_last_not_of(const char* s, size_type pos = npos) const {
+ size_type find_last_not_of(absl::Nonnull<const char*> s,
+ size_type pos = npos) const {
return find_last_not_of(string_view(s), pos);
}
+#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+ // string_view::starts_with()
+ //
+ // Returns true if the `string_view` starts with the prefix `s`.
+ //
+ // This method only exists when targeting at least C++20.
+ // If support for C++ prior to C++20 is required, use `absl::StartsWith()`
+ // from `//absl/strings/match.h` for compatibility.
+ constexpr bool starts_with(string_view s) const noexcept {
+ return s.empty() ||
+ (size() >= s.size() &&
+ ABSL_INTERNAL_STRING_VIEW_MEMCMP(data(), s.data(), s.size()) == 0);
+ }
+
+ // Overload of `string_view::starts_with()` that returns true if `c` is the
+ // first character of the `string_view`.
+ constexpr bool starts_with(char c) const noexcept {
+ return !empty() && front() == c;
+ }
+
+ // Overload of `string_view::starts_with()` that returns true if the
+ // `string_view` starts with the C-style prefix `s`.
+ constexpr bool starts_with(const char* s) const {
+ return starts_with(string_view(s));
+ }
+
+ // string_view::ends_with()
+ //
+ // Returns true if the `string_view` ends with the suffix `s`.
+ //
+ // This method only exists when targeting at least C++20.
+ // If support for C++ prior to C++20 is required, use `absl::EndsWith()`
+ // from `//absl/strings/match.h` for compatibility.
+ constexpr bool ends_with(string_view s) const noexcept {
+ return s.empty() || (size() >= s.size() && ABSL_INTERNAL_STRING_VIEW_MEMCMP(
+ data() + (size() - s.size()),
+ s.data(), s.size()) == 0);
+ }
+
+ // Overload of `string_view::ends_with()` that returns true if `c` is the
+ // last character of the `string_view`.
+ constexpr bool ends_with(char c) const noexcept {
+ return !empty() && back() == c;
+ }
+
+ // Overload of `string_view::ends_with()` that returns true if the
+ // `string_view` ends with the C-style suffix `s`.
+ constexpr bool ends_with(const char* s) const {
+ return ends_with(string_view(s));
+ }
+#endif // ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+
private:
// The constructor from std::string delegates to this constructor.
// See the comment on that constructor for the rationale.
struct SkipCheckLengthTag {};
- string_view(const char* data, size_type len, SkipCheckLengthTag) noexcept
+ string_view(absl::Nullable<const char*> data, size_type len,
+ SkipCheckLengthTag) noexcept
: ptr_(data), length_(len) {}
static constexpr size_type kMaxSize =
@@ -604,7 +669,7 @@ class string_view {
return ABSL_HARDENING_ASSERT(len <= kMaxSize), len;
}
- static constexpr size_type StrlenInternal(const char* str) {
+ static constexpr size_type StrlenInternal(absl::Nonnull<const char*> str) {
#if defined(_MSC_VER) && _MSC_VER >= 1910 && !defined(__clang__)
// MSVC 2017+ can evaluate this at compile-time.
const char* begin = str;
@@ -633,7 +698,7 @@ class string_view {
: (compare_result < 0 ? -1 : 1);
}
- const char* ptr_;
+ absl::Nullable<const char*> ptr_;
size_type length_;
};
@@ -694,7 +759,7 @@ inline string_view ClippedSubstr(string_view s, size_t pos,
// Creates an `absl::string_view` from a pointer `p` even if it's null-valued.
// This function should be used where an `absl::string_view` can be created from
// a possibly-null pointer.
-constexpr string_view NullSafeStringView(const char* p) {
+constexpr string_view NullSafeStringView(absl::Nullable<const char*> p) {
return p ? string_view(p) : string_view();
}
diff --git a/contrib/restricted/abseil-cpp/absl/strings/strip.h b/contrib/restricted/abseil-cpp/absl/strings/strip.h
index 341e66fc92..e3cda5bac3 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/strip.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/strip.h
@@ -25,6 +25,7 @@
#include <string>
#include "absl/base/macros.h"
+#include "absl/base/nullability.h"
#include "absl/strings/ascii.h"
#include "absl/strings/match.h"
#include "absl/strings/string_view.h"
@@ -43,7 +44,8 @@ ABSL_NAMESPACE_BEGIN
// absl::string_view input("abc");
// EXPECT_TRUE(absl::ConsumePrefix(&input, "a"));
// EXPECT_EQ(input, "bc");
-inline bool ConsumePrefix(absl::string_view* str, absl::string_view expected) {
+inline 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;
@@ -59,7 +61,8 @@ inline bool ConsumePrefix(absl::string_view* str, absl::string_view expected) {
// absl::string_view input("abcdef");
// EXPECT_TRUE(absl::ConsumeSuffix(&input, "def"));
// EXPECT_EQ(input, "abc");
-inline bool ConsumeSuffix(absl::string_view* str, absl::string_view expected) {
+inline 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;
diff --git a/contrib/restricted/abseil-cpp/absl/strings/substitute.cc b/contrib/restricted/abseil-cpp/absl/strings/substitute.cc
index 33a39305db..dd32c75f69 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/substitute.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/substitute.cc
@@ -15,20 +15,28 @@
#include "absl/strings/substitute.h"
#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <string>
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
+#include "absl/base/nullability.h"
#include "absl/strings/ascii.h"
#include "absl/strings/escaping.h"
#include "absl/strings/internal/resize_uninitialized.h"
+#include "absl/strings/numbers.h"
+#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace substitute_internal {
-void SubstituteAndAppendArray(std::string* output, absl::string_view format,
- const absl::string_view* args_array,
- size_t num_args) {
+void SubstituteAndAppendArray(
+ absl::Nonnull<std::string*> output, absl::string_view format,
+ absl::Nullable<const absl::string_view*> args_array, size_t num_args) {
// Determine total size needed.
size_t size = 0;
for (size_t i = 0; i < format.size(); i++) {
@@ -97,7 +105,7 @@ void SubstituteAndAppendArray(std::string* output, absl::string_view format,
assert(target == output->data() + output->size());
}
-Arg::Arg(const void* value) {
+Arg::Arg(absl::Nullable<const void*> value) {
static_assert(sizeof(scratch_) >= sizeof(value) * 2 + 2,
"fix sizeof(scratch_)");
if (value == nullptr) {
diff --git a/contrib/restricted/abseil-cpp/absl/strings/substitute.h b/contrib/restricted/abseil-cpp/absl/strings/substitute.h
index d6a5a690d7..6c7cba4be5 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/substitute.h
+++ b/contrib/restricted/abseil-cpp/absl/strings/substitute.h
@@ -78,6 +78,7 @@
#include <vector>
#include "absl/base/macros.h"
+#include "absl/base/nullability.h"
#include "absl/base/port.h"
#include "absl/strings/ascii.h"
#include "absl/strings/escaping.h"
@@ -105,7 +106,7 @@ class Arg {
// Overloads for string-y things
//
// Explicitly overload `const char*` so the compiler doesn't cast to `bool`.
- Arg(const char* value) // NOLINT(google-explicit-constructor)
+ Arg(absl::Nullable<const char*> value) // NOLINT(google-explicit-constructor)
: piece_(absl::NullSafeStringView(value)) {}
template <typename Allocator>
Arg( // NOLINT
@@ -176,7 +177,7 @@ class Arg {
: piece_(value ? "true" : "false") {}
template <typename T, typename = typename std::enable_if<
- strings_internal::HasAbslStringify<T>::value>::type>
+ HasAbslStringify<T>::value>::type>
Arg( // NOLINT(google-explicit-constructor)
const T& v, strings_internal::StringifySink&& sink = {})
: piece_(strings_internal::ExtractStringification(sink, v)) {}
@@ -197,14 +198,15 @@ class Arg {
// `void*` values, with the exception of `char*`, are printed as
// "0x<hex value>". However, in the case of `nullptr`, "NULL" is printed.
- Arg(const void* value); // NOLINT(google-explicit-constructor)
+ Arg( // NOLINT(google-explicit-constructor)
+ absl::Nullable<const void*> value);
// Normal enums are already handled by the integer formatters.
// This overload matches only scoped enums.
template <typename T,
typename = typename std::enable_if<
std::is_enum<T>{} && !std::is_convertible<T, int>{} &&
- !strings_internal::HasAbslStringify<T>::value>::type>
+ !HasAbslStringify<T>::value>::type>
Arg(T value) // NOLINT(google-explicit-constructor)
: Arg(static_cast<typename std::underlying_type<T>::type>(value)) {}
@@ -220,12 +222,12 @@ class Arg {
// Internal helper function. Don't call this from outside this implementation.
// This interface may change without notice.
-void SubstituteAndAppendArray(std::string* output, absl::string_view format,
- const absl::string_view* args_array,
- size_t num_args);
+void SubstituteAndAppendArray(
+ absl::Nonnull<std::string*> output, absl::string_view format,
+ absl::Nullable<const absl::string_view*> args_array, size_t num_args);
#if defined(ABSL_BAD_CALL_IF)
-constexpr int CalculateOneBit(const char* format) {
+constexpr int CalculateOneBit(absl::Nonnull<const char*> format) {
// Returns:
// * 2^N for '$N' when N is in [0-9]
// * 0 for correct '$' escaping: '$$'.
@@ -234,11 +236,11 @@ constexpr int CalculateOneBit(const char* format) {
: (1 << (*format - '0'));
}
-constexpr const char* SkipNumber(const char* format) {
+constexpr const char* SkipNumber(absl::Nonnull<const char*> format) {
return !*format ? format : (format + 1);
}
-constexpr int PlaceholderBitmask(const char* format) {
+constexpr int PlaceholderBitmask(absl::Nonnull<const char*> format) {
return !*format
? 0
: *format != '$' ? PlaceholderBitmask(format + 1)
@@ -271,18 +273,21 @@ constexpr int PlaceholderBitmask(const char* format) {
// absl::SubstituteAndAppend(boilerplate, format, args...);
// }
//
-inline void SubstituteAndAppend(std::string* output, absl::string_view format) {
+inline void SubstituteAndAppend(absl::Nonnull<std::string*> output,
+ absl::string_view format) {
substitute_internal::SubstituteAndAppendArray(output, format, nullptr, 0);
}
-inline void SubstituteAndAppend(std::string* output, absl::string_view format,
+inline void SubstituteAndAppend(absl::Nonnull<std::string*> output,
+ absl::string_view format,
const substitute_internal::Arg& a0) {
const absl::string_view args[] = {a0.piece()};
substitute_internal::SubstituteAndAppendArray(output, format, args,
ABSL_ARRAYSIZE(args));
}
-inline void SubstituteAndAppend(std::string* output, absl::string_view format,
+inline void SubstituteAndAppend(absl::Nonnull<std::string*> output,
+ absl::string_view format,
const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1) {
const absl::string_view args[] = {a0.piece(), a1.piece()};
@@ -290,7 +295,8 @@ inline void SubstituteAndAppend(std::string* output, absl::string_view format,
ABSL_ARRAYSIZE(args));
}
-inline void SubstituteAndAppend(std::string* output, absl::string_view format,
+inline void SubstituteAndAppend(absl::Nonnull<std::string*> output,
+ absl::string_view format,
const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2) {
@@ -299,7 +305,8 @@ inline void SubstituteAndAppend(std::string* output, absl::string_view format,
ABSL_ARRAYSIZE(args));
}
-inline void SubstituteAndAppend(std::string* output, absl::string_view format,
+inline void SubstituteAndAppend(absl::Nonnull<std::string*> output,
+ absl::string_view format,
const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2,
@@ -310,7 +317,8 @@ inline void SubstituteAndAppend(std::string* output, absl::string_view format,
ABSL_ARRAYSIZE(args));
}
-inline void SubstituteAndAppend(std::string* output, absl::string_view format,
+inline void SubstituteAndAppend(absl::Nonnull<std::string*> output,
+ absl::string_view format,
const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2,
@@ -322,27 +330,23 @@ inline void SubstituteAndAppend(std::string* output, absl::string_view format,
ABSL_ARRAYSIZE(args));
}
-inline void SubstituteAndAppend(std::string* output, absl::string_view format,
- const substitute_internal::Arg& a0,
- const substitute_internal::Arg& a1,
- const substitute_internal::Arg& a2,
- const substitute_internal::Arg& a3,
- const substitute_internal::Arg& a4,
- const substitute_internal::Arg& a5) {
+inline void SubstituteAndAppend(
+ absl::Nonnull<std::string*> output, absl::string_view format,
+ const substitute_internal::Arg& a0, const substitute_internal::Arg& a1,
+ const substitute_internal::Arg& a2, const substitute_internal::Arg& a3,
+ const substitute_internal::Arg& a4, const substitute_internal::Arg& a5) {
const absl::string_view args[] = {a0.piece(), a1.piece(), a2.piece(),
a3.piece(), a4.piece(), a5.piece()};
substitute_internal::SubstituteAndAppendArray(output, format, args,
ABSL_ARRAYSIZE(args));
}
-inline void SubstituteAndAppend(std::string* output, absl::string_view format,
- const substitute_internal::Arg& a0,
- const substitute_internal::Arg& a1,
- const substitute_internal::Arg& a2,
- const substitute_internal::Arg& a3,
- const substitute_internal::Arg& a4,
- const substitute_internal::Arg& a5,
- const substitute_internal::Arg& a6) {
+inline void SubstituteAndAppend(
+ absl::Nonnull<std::string*> output, absl::string_view format,
+ const substitute_internal::Arg& a0, const substitute_internal::Arg& a1,
+ const substitute_internal::Arg& a2, const substitute_internal::Arg& a3,
+ const substitute_internal::Arg& a4, const substitute_internal::Arg& a5,
+ const substitute_internal::Arg& a6) {
const absl::string_view args[] = {a0.piece(), a1.piece(), a2.piece(),
a3.piece(), a4.piece(), a5.piece(),
a6.piece()};
@@ -351,7 +355,7 @@ inline void SubstituteAndAppend(std::string* output, absl::string_view format,
}
inline void SubstituteAndAppend(
- std::string* output, absl::string_view format,
+ absl::Nonnull<std::string*> output, absl::string_view format,
const substitute_internal::Arg& a0, const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2, const substitute_internal::Arg& a3,
const substitute_internal::Arg& a4, const substitute_internal::Arg& a5,
@@ -364,7 +368,7 @@ inline void SubstituteAndAppend(
}
inline void SubstituteAndAppend(
- std::string* output, absl::string_view format,
+ absl::Nonnull<std::string*> output, absl::string_view format,
const substitute_internal::Arg& a0, const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2, const substitute_internal::Arg& a3,
const substitute_internal::Arg& a4, const substitute_internal::Arg& a5,
@@ -378,7 +382,7 @@ inline void SubstituteAndAppend(
}
inline void SubstituteAndAppend(
- std::string* output, absl::string_view format,
+ absl::Nonnull<std::string*> output, absl::string_view format,
const substitute_internal::Arg& a0, const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2, const substitute_internal::Arg& a3,
const substitute_internal::Arg& a4, const substitute_internal::Arg& a5,
@@ -394,14 +398,16 @@ inline void SubstituteAndAppend(
#if defined(ABSL_BAD_CALL_IF)
// This body of functions catches cases where the number of placeholders
// doesn't match the number of data arguments.
-void SubstituteAndAppend(std::string* output, const char* format)
+void SubstituteAndAppend(absl::Nonnull<std::string*> output,
+ absl::Nonnull<const char*> format)
ABSL_BAD_CALL_IF(
substitute_internal::PlaceholderBitmask(format) != 0,
"There were no substitution arguments "
"but this format string either has a $[0-9] in it or contains "
"an unescaped $ character (use $$ instead)");
-void SubstituteAndAppend(std::string* output, const char* format,
+void SubstituteAndAppend(absl::Nonnull<std::string*> output,
+ absl::Nonnull<const char*> format,
const substitute_internal::Arg& a0)
ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 1,
"There was 1 substitution argument given, but "
@@ -409,7 +415,8 @@ void SubstituteAndAppend(std::string* output, const char* format,
"one of $1-$9, or contains an unescaped $ character (use "
"$$ instead)");
-void SubstituteAndAppend(std::string* output, const char* format,
+void SubstituteAndAppend(absl::Nonnull<std::string*> output,
+ absl::Nonnull<const char*> format,
const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1)
ABSL_BAD_CALL_IF(
@@ -418,7 +425,8 @@ void SubstituteAndAppend(std::string* output, const char* format,
"missing its $0/$1, contains one of $2-$9, or contains an "
"unescaped $ character (use $$ instead)");
-void SubstituteAndAppend(std::string* output, const char* format,
+void SubstituteAndAppend(absl::Nonnull<std::string*> output,
+ absl::Nonnull<const char*> format,
const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2)
@@ -428,7 +436,8 @@ void SubstituteAndAppend(std::string* output, const char* format,
"this format string is missing its $0/$1/$2, contains one of "
"$3-$9, or contains an unescaped $ character (use $$ instead)");
-void SubstituteAndAppend(std::string* output, const char* format,
+void SubstituteAndAppend(absl::Nonnull<std::string*> output,
+ absl::Nonnull<const char*> format,
const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2,
@@ -439,7 +448,8 @@ void SubstituteAndAppend(std::string* output, const char* format,
"this format string is missing its $0-$3, contains one of "
"$4-$9, or contains an unescaped $ character (use $$ instead)");
-void SubstituteAndAppend(std::string* output, const char* format,
+void SubstituteAndAppend(absl::Nonnull<std::string*> output,
+ absl::Nonnull<const char*> format,
const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2,
@@ -451,13 +461,11 @@ void SubstituteAndAppend(std::string* output, const char* format,
"this format string is missing its $0-$4, contains one of "
"$5-$9, or contains an unescaped $ character (use $$ instead)");
-void SubstituteAndAppend(std::string* output, const char* format,
- const substitute_internal::Arg& a0,
- const substitute_internal::Arg& a1,
- const substitute_internal::Arg& a2,
- const substitute_internal::Arg& a3,
- const substitute_internal::Arg& a4,
- const substitute_internal::Arg& a5)
+void SubstituteAndAppend(
+ absl::Nonnull<std::string*> output, absl::Nonnull<const char*> format,
+ const substitute_internal::Arg& a0, const substitute_internal::Arg& a1,
+ const substitute_internal::Arg& a2, const substitute_internal::Arg& a3,
+ const substitute_internal::Arg& a4, const substitute_internal::Arg& a5)
ABSL_BAD_CALL_IF(
substitute_internal::PlaceholderBitmask(format) != 63,
"There were 6 substitution arguments given, but "
@@ -465,10 +473,11 @@ void SubstituteAndAppend(std::string* output, const char* format,
"$6-$9, or contains an unescaped $ character (use $$ instead)");
void SubstituteAndAppend(
- std::string* output, const char* format, const substitute_internal::Arg& a0,
- const substitute_internal::Arg& a1, const substitute_internal::Arg& a2,
- const substitute_internal::Arg& a3, const substitute_internal::Arg& a4,
- const substitute_internal::Arg& a5, const substitute_internal::Arg& a6)
+ absl::Nonnull<std::string*> output, absl::Nonnull<const char*> format,
+ const substitute_internal::Arg& a0, const substitute_internal::Arg& a1,
+ const substitute_internal::Arg& a2, const substitute_internal::Arg& a3,
+ const substitute_internal::Arg& a4, const substitute_internal::Arg& a5,
+ const substitute_internal::Arg& a6)
ABSL_BAD_CALL_IF(
substitute_internal::PlaceholderBitmask(format) != 127,
"There were 7 substitution arguments given, but "
@@ -476,11 +485,11 @@ void SubstituteAndAppend(
"$7-$9, or contains an unescaped $ character (use $$ instead)");
void SubstituteAndAppend(
- std::string* output, const char* format, const substitute_internal::Arg& a0,
- const substitute_internal::Arg& a1, const substitute_internal::Arg& a2,
- const substitute_internal::Arg& a3, const substitute_internal::Arg& a4,
- const substitute_internal::Arg& a5, const substitute_internal::Arg& a6,
- const substitute_internal::Arg& a7)
+ absl::Nonnull<std::string*> output, absl::Nonnull<const char*> format,
+ const substitute_internal::Arg& a0, const substitute_internal::Arg& a1,
+ const substitute_internal::Arg& a2, const substitute_internal::Arg& a3,
+ const substitute_internal::Arg& a4, const substitute_internal::Arg& a5,
+ const substitute_internal::Arg& a6, const substitute_internal::Arg& a7)
ABSL_BAD_CALL_IF(
substitute_internal::PlaceholderBitmask(format) != 255,
"There were 8 substitution arguments given, but "
@@ -488,11 +497,12 @@ void SubstituteAndAppend(
"$8-$9, or contains an unescaped $ character (use $$ instead)");
void SubstituteAndAppend(
- std::string* output, const char* format, const substitute_internal::Arg& a0,
- const substitute_internal::Arg& a1, const substitute_internal::Arg& a2,
- const substitute_internal::Arg& a3, const substitute_internal::Arg& a4,
- const substitute_internal::Arg& a5, const substitute_internal::Arg& a6,
- const substitute_internal::Arg& a7, const substitute_internal::Arg& a8)
+ absl::Nonnull<std::string*> output, absl::Nonnull<const char*> format,
+ const substitute_internal::Arg& a0, const substitute_internal::Arg& a1,
+ const substitute_internal::Arg& a2, const substitute_internal::Arg& a3,
+ const substitute_internal::Arg& a4, const substitute_internal::Arg& a5,
+ const substitute_internal::Arg& a6, const substitute_internal::Arg& a7,
+ const substitute_internal::Arg& a8)
ABSL_BAD_CALL_IF(
substitute_internal::PlaceholderBitmask(format) != 511,
"There were 9 substitution arguments given, but "
@@ -500,12 +510,12 @@ void SubstituteAndAppend(
"contains an unescaped $ character (use $$ instead)");
void SubstituteAndAppend(
- std::string* output, const char* format, const substitute_internal::Arg& a0,
- const substitute_internal::Arg& a1, const substitute_internal::Arg& a2,
- const substitute_internal::Arg& a3, const substitute_internal::Arg& a4,
- const substitute_internal::Arg& a5, const substitute_internal::Arg& a6,
- const substitute_internal::Arg& a7, const substitute_internal::Arg& a8,
- const substitute_internal::Arg& a9)
+ absl::Nonnull<std::string*> output, absl::Nonnull<const char*> format,
+ const substitute_internal::Arg& a0, const substitute_internal::Arg& a1,
+ const substitute_internal::Arg& a2, const substitute_internal::Arg& a3,
+ const substitute_internal::Arg& a4, const substitute_internal::Arg& a5,
+ const substitute_internal::Arg& a6, const substitute_internal::Arg& a7,
+ const substitute_internal::Arg& a8, const substitute_internal::Arg& a9)
ABSL_BAD_CALL_IF(
substitute_internal::PlaceholderBitmask(format) != 1023,
"There were 10 substitution arguments given, but this "
@@ -633,20 +643,22 @@ ABSL_MUST_USE_RESULT inline std::string Substitute(
#if defined(ABSL_BAD_CALL_IF)
// This body of functions catches cases where the number of placeholders
// doesn't match the number of data arguments.
-std::string Substitute(const char* format)
+std::string Substitute(absl::Nonnull<const char*> format)
ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 0,
"There were no substitution arguments "
"but this format string either has a $[0-9] in it or "
"contains an unescaped $ character (use $$ instead)");
-std::string Substitute(const char* format, const substitute_internal::Arg& a0)
+std::string Substitute(absl::Nonnull<const char*> format,
+ const substitute_internal::Arg& a0)
ABSL_BAD_CALL_IF(
substitute_internal::PlaceholderBitmask(format) != 1,
"There was 1 substitution argument given, but "
"this format string is missing its $0, contains one of $1-$9, "
"or contains an unescaped $ character (use $$ instead)");
-std::string Substitute(const char* format, const substitute_internal::Arg& a0,
+std::string Substitute(absl::Nonnull<const char*> format,
+ const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1)
ABSL_BAD_CALL_IF(
substitute_internal::PlaceholderBitmask(format) != 3,
@@ -654,7 +666,8 @@ std::string Substitute(const char* format, const substitute_internal::Arg& a0,
"this format string is missing its $0/$1, contains one of "
"$2-$9, or contains an unescaped $ character (use $$ instead)");
-std::string Substitute(const char* format, const substitute_internal::Arg& a0,
+std::string Substitute(absl::Nonnull<const char*> format,
+ const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2)
ABSL_BAD_CALL_IF(
@@ -663,7 +676,8 @@ std::string Substitute(const char* format, const substitute_internal::Arg& a0,
"this format string is missing its $0/$1/$2, contains one of "
"$3-$9, or contains an unescaped $ character (use $$ instead)");
-std::string Substitute(const char* format, const substitute_internal::Arg& a0,
+std::string Substitute(absl::Nonnull<const char*> format,
+ const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2,
const substitute_internal::Arg& a3)
@@ -673,7 +687,8 @@ std::string Substitute(const char* format, const substitute_internal::Arg& a0,
"this format string is missing its $0-$3, contains one of "
"$4-$9, or contains an unescaped $ character (use $$ instead)");
-std::string Substitute(const char* format, const substitute_internal::Arg& a0,
+std::string Substitute(absl::Nonnull<const char*> format,
+ const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2,
const substitute_internal::Arg& a3,
@@ -684,7 +699,8 @@ std::string Substitute(const char* format, const substitute_internal::Arg& a0,
"this format string is missing its $0-$4, contains one of "
"$5-$9, or contains an unescaped $ character (use $$ instead)");
-std::string Substitute(const char* format, const substitute_internal::Arg& a0,
+std::string Substitute(absl::Nonnull<const char*> format,
+ const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2,
const substitute_internal::Arg& a3,
@@ -696,27 +712,23 @@ std::string Substitute(const char* format, const substitute_internal::Arg& a0,
"this format string is missing its $0-$5, contains one of "
"$6-$9, or contains an unescaped $ character (use $$ instead)");
-std::string Substitute(const char* format, const substitute_internal::Arg& a0,
- const substitute_internal::Arg& a1,
- const substitute_internal::Arg& a2,
- const substitute_internal::Arg& a3,
- const substitute_internal::Arg& a4,
- const substitute_internal::Arg& a5,
- const substitute_internal::Arg& a6)
+std::string Substitute(
+ absl::Nonnull<const char*> format, const substitute_internal::Arg& a0,
+ const substitute_internal::Arg& a1, const substitute_internal::Arg& a2,
+ const substitute_internal::Arg& a3, const substitute_internal::Arg& a4,
+ const substitute_internal::Arg& a5, const substitute_internal::Arg& a6)
ABSL_BAD_CALL_IF(
substitute_internal::PlaceholderBitmask(format) != 127,
"There were 7 substitution arguments given, but "
"this format string is missing its $0-$6, contains one of "
"$7-$9, or contains an unescaped $ character (use $$ instead)");
-std::string Substitute(const char* format, const substitute_internal::Arg& a0,
- const substitute_internal::Arg& a1,
- const substitute_internal::Arg& a2,
- const substitute_internal::Arg& a3,
- const substitute_internal::Arg& a4,
- const substitute_internal::Arg& a5,
- const substitute_internal::Arg& a6,
- const substitute_internal::Arg& a7)
+std::string Substitute(
+ absl::Nonnull<const char*> format, const substitute_internal::Arg& a0,
+ const substitute_internal::Arg& a1, const substitute_internal::Arg& a2,
+ const substitute_internal::Arg& a3, const substitute_internal::Arg& a4,
+ const substitute_internal::Arg& a5, const substitute_internal::Arg& a6,
+ const substitute_internal::Arg& a7)
ABSL_BAD_CALL_IF(
substitute_internal::PlaceholderBitmask(format) != 255,
"There were 8 substitution arguments given, but "
@@ -724,7 +736,7 @@ std::string Substitute(const char* format, const substitute_internal::Arg& a0,
"$8-$9, or contains an unescaped $ character (use $$ instead)");
std::string Substitute(
- const char* format, const substitute_internal::Arg& a0,
+ absl::Nonnull<const char*> format, const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1, const substitute_internal::Arg& a2,
const substitute_internal::Arg& a3, const substitute_internal::Arg& a4,
const substitute_internal::Arg& a5, const substitute_internal::Arg& a6,
@@ -736,7 +748,7 @@ std::string Substitute(
"contains an unescaped $ character (use $$ instead)");
std::string Substitute(
- const char* format, const substitute_internal::Arg& a0,
+ absl::Nonnull<const char*> format, const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1, const substitute_internal::Arg& a2,
const substitute_internal::Arg& a3, const substitute_internal::Arg& a4,
const substitute_internal::Arg& a5, const substitute_internal::Arg& a6,
diff --git a/contrib/restricted/abseil-cpp/absl/strings/ya.make b/contrib/restricted/abseil-cpp/absl/strings/ya.make
index 99b03d7bd6..dffec44d18 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/strings/ya.make
@@ -27,7 +27,7 @@ SRCS(
crc/internal/crc.cc
crc/internal/crc_cord_state.cc
crc/internal/crc_memcpy_fallback.cc
- crc/internal/crc_memcpy_x86_64.cc
+ crc/internal/crc_memcpy_x86_arm_combined.cc
crc/internal/crc_non_temporal_memcpy.cc
crc/internal/crc_x86_arm_combined.cc
status/statusor.cc
@@ -45,7 +45,6 @@ SRCS(
strings/internal/cord_rep_btree_reader.cc
strings/internal/cord_rep_consume.cc
strings/internal/cord_rep_crc.cc
- strings/internal/cord_rep_ring.cc
strings/internal/cordz_functions.cc
strings/internal/cordz_handle.cc
strings/internal/cordz_info.cc
diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/internal/pthread_waiter.h b/contrib/restricted/abseil-cpp/absl/synchronization/internal/pthread_waiter.h
index 206aefa47c..23db76ad44 100644
--- a/contrib/restricted/abseil-cpp/absl/synchronization/internal/pthread_waiter.h
+++ b/contrib/restricted/abseil-cpp/absl/synchronization/internal/pthread_waiter.h
@@ -16,7 +16,7 @@
#ifndef ABSL_SYNCHRONIZATION_INTERNAL_PTHREAD_WAITER_H_
#define ABSL_SYNCHRONIZATION_INTERNAL_PTHREAD_WAITER_H_
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__MINGW32__)
#include <pthread.h>
#include "absl/base/config.h"
@@ -55,6 +55,6 @@ class PthreadWaiter : public WaiterCrtp<PthreadWaiter> {
ABSL_NAMESPACE_END
} // namespace absl
-#endif // ndef _WIN32
+#endif // !defined(_WIN32) && !defined(__MINGW32__)
#endif // ABSL_SYNCHRONIZATION_INTERNAL_PTHREAD_WAITER_H_
diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/internal/win32_waiter.h b/contrib/restricted/abseil-cpp/absl/synchronization/internal/win32_waiter.h
index 87eb617cbd..fdab264e8c 100644
--- a/contrib/restricted/abseil-cpp/absl/synchronization/internal/win32_waiter.h
+++ b/contrib/restricted/abseil-cpp/absl/synchronization/internal/win32_waiter.h
@@ -20,7 +20,8 @@
#include <sdkddkver.h>
#endif
-#if defined(_WIN32) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+#if defined(_WIN32) && !defined(__MINGW32__) && \
+ _WIN32_WINNT >= _WIN32_WINNT_VISTA
#include "absl/base/config.h"
#include "absl/synchronization/internal/kernel_timeout.h"
@@ -65,6 +66,7 @@ class Win32Waiter : public WaiterCrtp<Win32Waiter> {
ABSL_NAMESPACE_END
} // namespace absl
-#endif // defined(_WIN32) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+#endif // defined(_WIN32) && !defined(__MINGW32__) &&
+ // _WIN32_WINNT >= _WIN32_WINNT_VISTA
#endif // ABSL_SYNCHRONIZATION_INTERNAL_WIN32_WAITER_H_
diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/mutex.cc b/contrib/restricted/abseil-cpp/absl/synchronization/mutex.cc
index 3aa5560a32..cb3c7e74ec 100644
--- a/contrib/restricted/abseil-cpp/absl/synchronization/mutex.cc
+++ b/contrib/restricted/abseil-cpp/absl/synchronization/mutex.cc
@@ -129,11 +129,15 @@ enum DelayMode { AGGRESSIVE, GENTLE };
struct ABSL_CACHELINE_ALIGNED MutexGlobals {
absl::once_flag once;
- int spinloop_iterations = 0;
+ // Note: this variable is initialized separately in Mutex::LockSlow,
+ // so that Mutex::Lock does not have a stack frame in optimized build.
+ std::atomic<int> spinloop_iterations{0};
int32_t mutex_sleep_spins[2] = {};
absl::Duration mutex_sleep_time;
};
+ABSL_CONST_INIT static MutexGlobals globals;
+
absl::Duration MeasureTimeToYield() {
absl::Time before = absl::Now();
ABSL_INTERNAL_C_SYMBOL(AbslInternalMutexYield)();
@@ -141,33 +145,30 @@ absl::Duration MeasureTimeToYield() {
}
const MutexGlobals& GetMutexGlobals() {
- ABSL_CONST_INIT static MutexGlobals data;
- absl::base_internal::LowLevelCallOnce(&data.once, [&]() {
+ absl::base_internal::LowLevelCallOnce(&globals.once, [&]() {
if (absl::base_internal::NumCPUs() > 1) {
- // If this is multiprocessor, allow spinning. If the mode is
- // aggressive then spin many times before yielding. If the mode is
- // gentle then spin only a few times before yielding. Aggressive spinning
- // is used to ensure that an Unlock() call, which must get the spin lock
- // for any thread to make progress gets it without undue delay.
- data.spinloop_iterations = 1500;
- data.mutex_sleep_spins[AGGRESSIVE] = 5000;
- data.mutex_sleep_spins[GENTLE] = 250;
- data.mutex_sleep_time = absl::Microseconds(10);
+ // If the mode is aggressive then spin many times before yielding.
+ // If the mode is gentle then spin only a few times before yielding.
+ // Aggressive spinning is used to ensure that an Unlock() call,
+ // which must get the spin lock for any thread to make progress gets it
+ // without undue delay.
+ globals.mutex_sleep_spins[AGGRESSIVE] = 5000;
+ globals.mutex_sleep_spins[GENTLE] = 250;
+ globals.mutex_sleep_time = absl::Microseconds(10);
} else {
// If this a uniprocessor, only yield/sleep. Real-time threads are often
// unable to yield, so the sleep time needs to be long enough to keep
// the calling thread asleep until scheduling happens.
- data.spinloop_iterations = 0;
- data.mutex_sleep_spins[AGGRESSIVE] = 0;
- data.mutex_sleep_spins[GENTLE] = 0;
- data.mutex_sleep_time = MeasureTimeToYield() * 5;
- data.mutex_sleep_time =
- std::min(data.mutex_sleep_time, absl::Milliseconds(1));
- data.mutex_sleep_time =
- std::max(data.mutex_sleep_time, absl::Microseconds(10));
+ globals.mutex_sleep_spins[AGGRESSIVE] = 0;
+ globals.mutex_sleep_spins[GENTLE] = 0;
+ globals.mutex_sleep_time = MeasureTimeToYield() * 5;
+ globals.mutex_sleep_time =
+ std::min(globals.mutex_sleep_time, absl::Milliseconds(1));
+ globals.mutex_sleep_time =
+ std::max(globals.mutex_sleep_time, absl::Microseconds(10));
}
});
- return data;
+ return globals;
}
} // namespace
@@ -202,31 +203,23 @@ int MutexDelay(int32_t c, int mode) {
// Ensure that "(*pv & bits) == bits" by doing an atomic update of "*pv" to
// "*pv | bits" if necessary. Wait until (*pv & wait_until_clear)==0
// before making any change.
+// Returns true if bits were previously unset and set by the call.
// This is used to set flags in mutex and condition variable words.
-static void AtomicSetBits(std::atomic<intptr_t>* pv, intptr_t bits,
+static bool AtomicSetBits(std::atomic<intptr_t>* pv, intptr_t bits,
intptr_t wait_until_clear) {
- intptr_t v;
- do {
- v = pv->load(std::memory_order_relaxed);
- } while ((v & bits) != bits &&
- ((v & wait_until_clear) != 0 ||
- !pv->compare_exchange_weak(v, v | bits, std::memory_order_release,
- std::memory_order_relaxed)));
-}
-
-// Ensure that "(*pv & bits) == 0" by doing an atomic update of "*pv" to
-// "*pv & ~bits" if necessary. Wait until (*pv & wait_until_clear)==0
-// before making any change.
-// This is used to unset flags in mutex and condition variable words.
-static void AtomicClearBits(std::atomic<intptr_t>* pv, intptr_t bits,
- intptr_t wait_until_clear) {
- intptr_t v;
- do {
- v = pv->load(std::memory_order_relaxed);
- } while ((v & bits) != 0 &&
- ((v & wait_until_clear) != 0 ||
- !pv->compare_exchange_weak(v, v & ~bits, std::memory_order_release,
- std::memory_order_relaxed)));
+ for (;;) {
+ intptr_t v = pv->load(std::memory_order_relaxed);
+ if ((v & bits) == bits) {
+ return false;
+ }
+ if ((v & wait_until_clear) != 0) {
+ continue;
+ }
+ if (pv->compare_exchange_weak(v, v | bits, std::memory_order_release,
+ std::memory_order_relaxed)) {
+ return true;
+ }
+ }
}
//------------------------------------------------------------------
@@ -337,12 +330,49 @@ static SynchEvent* EnsureSynchEvent(std::atomic<intptr_t>* addr,
const char* name, intptr_t bits,
intptr_t lockbit) {
uint32_t h = reinterpret_cast<uintptr_t>(addr) % kNSynchEvent;
- SynchEvent* e;
- // first look for existing SynchEvent struct..
synch_event_mu.Lock();
- for (e = synch_event[h];
- e != nullptr && e->masked_addr != base_internal::HidePtr(addr);
- e = e->next) {
+ // When a Mutex/CondVar is destroyed, we don't remove the associated
+ // SynchEvent to keep destructors empty in release builds for performance
+ // reasons. If the current call is the first to set bits (kMuEvent/kCVEvent),
+ // we don't look up the existing even because (if it exists, it must be for
+ // the previous Mutex/CondVar that existed at the same address).
+ // The leaking events must not be a problem for tests, which should create
+ // bounded amount of events. And debug logging is not supposed to be enabled
+ // in production. However, if it's accidentally enabled, or briefly enabled
+ // for some debugging, we don't want to crash the program. Instead we drop
+ // all events, if we accumulated too many of them. Size of a single event
+ // is ~48 bytes, so 100K events is ~5 MB.
+ // Additionally we could delete the old event for the same address,
+ // but it would require a better hashmap (if we accumulate too many events,
+ // linked lists will grow and traversing them will be very slow).
+ constexpr size_t kMaxSynchEventCount = 100 << 10;
+ // Total number of live synch events.
+ static size_t synch_event_count ABSL_GUARDED_BY(synch_event_mu);
+ if (++synch_event_count > kMaxSynchEventCount) {
+ synch_event_count = 0;
+ ABSL_RAW_LOG(ERROR,
+ "Accumulated %zu Mutex debug objects. If you see this"
+ " in production, it may mean that the production code"
+ " accidentally calls "
+ "Mutex/CondVar::EnableDebugLog/EnableInvariantDebugging.",
+ kMaxSynchEventCount);
+ for (auto*& head : synch_event) {
+ for (auto* e = head; e != nullptr;) {
+ SynchEvent* next = e->next;
+ if (--(e->refcount) == 0) {
+ base_internal::LowLevelAlloc::Free(e);
+ }
+ e = next;
+ }
+ head = nullptr;
+ }
+ }
+ SynchEvent* e = nullptr;
+ if (!AtomicSetBits(addr, bits, lockbit)) {
+ for (e = synch_event[h];
+ e != nullptr && e->masked_addr != base_internal::HidePtr(addr);
+ e = e->next) {
+ }
}
if (e == nullptr) { // no SynchEvent struct found; make one.
if (name == nullptr) {
@@ -358,7 +388,6 @@ static SynchEvent* EnsureSynchEvent(std::atomic<intptr_t>* addr,
e->log = false;
strcpy(e->name, name); // NOLINT(runtime/printf)
e->next = synch_event[h];
- AtomicSetBits(addr, bits, lockbit);
synch_event[h] = e;
} else {
e->refcount++; // for return value
@@ -367,11 +396,6 @@ static SynchEvent* EnsureSynchEvent(std::atomic<intptr_t>* addr,
return e;
}
-// Deallocate the SynchEvent *e, whose refcount has fallen to zero.
-static void DeleteSynchEvent(SynchEvent* e) {
- base_internal::LowLevelAlloc::Free(e);
-}
-
// Decrement the reference count of *e, or do nothing if e==null.
static void UnrefSynchEvent(SynchEvent* e) {
if (e != nullptr) {
@@ -379,36 +403,11 @@ static void UnrefSynchEvent(SynchEvent* e) {
bool del = (--(e->refcount) == 0);
synch_event_mu.Unlock();
if (del) {
- DeleteSynchEvent(e);
+ base_internal::LowLevelAlloc::Free(e);
}
}
}
-// Forget the mapping from the object (Mutex or CondVar) at address addr
-// to SynchEvent object, and clear "bits" in its word (waiting until lockbit
-// is clear before doing so).
-static void ForgetSynchEvent(std::atomic<intptr_t>* addr, intptr_t bits,
- intptr_t lockbit) {
- uint32_t h = reinterpret_cast<uintptr_t>(addr) % kNSynchEvent;
- SynchEvent** pe;
- SynchEvent* e;
- synch_event_mu.Lock();
- for (pe = &synch_event[h];
- (e = *pe) != nullptr && e->masked_addr != base_internal::HidePtr(addr);
- pe = &e->next) {
- }
- bool del = false;
- if (e != nullptr) {
- *pe = e->next;
- del = (--(e->refcount) == 0);
- }
- AtomicClearBits(addr, bits, lockbit);
- synch_event_mu.Unlock();
- if (del) {
- DeleteSynchEvent(e);
- }
-}
-
// Return a refcounted reference to the SynchEvent of the object at address
// "addr", if any. The pointer returned is valid until the UnrefSynchEvent() is
// called.
@@ -579,31 +578,25 @@ static SynchLocksHeld* Synch_GetAllLocks() {
// Post on "w"'s associated PerThreadSem.
void Mutex::IncrementSynchSem(Mutex* mu, PerThreadSynch* w) {
- if (mu) {
- ABSL_TSAN_MUTEX_PRE_DIVERT(mu, 0);
- // We miss synchronization around passing PerThreadSynch between threads
- // since it happens inside of the Mutex code, so we need to ignore all
- // accesses to the object.
- ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN();
- PerThreadSem::Post(w->thread_identity());
- ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END();
- ABSL_TSAN_MUTEX_POST_DIVERT(mu, 0);
- } else {
- PerThreadSem::Post(w->thread_identity());
- }
+ static_cast<void>(mu); // Prevent unused param warning in non-TSAN builds.
+ ABSL_TSAN_MUTEX_PRE_DIVERT(mu, 0);
+ // We miss synchronization around passing PerThreadSynch between threads
+ // since it happens inside of the Mutex code, so we need to ignore all
+ // accesses to the object.
+ ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN();
+ PerThreadSem::Post(w->thread_identity());
+ ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END();
+ ABSL_TSAN_MUTEX_POST_DIVERT(mu, 0);
}
// Wait on "w"'s associated PerThreadSem; returns false if timeout expired.
bool Mutex::DecrementSynchSem(Mutex* mu, PerThreadSynch* w, KernelTimeout t) {
- if (mu) {
- ABSL_TSAN_MUTEX_PRE_DIVERT(mu, 0);
- }
+ static_cast<void>(mu); // Prevent unused param warning in non-TSAN builds.
+ ABSL_TSAN_MUTEX_PRE_DIVERT(mu, 0);
assert(w == Synch_GetPerThread());
static_cast<void>(w);
bool res = PerThreadSem::Wait(t);
- if (mu) {
- ABSL_TSAN_MUTEX_POST_DIVERT(mu, 0);
- }
+ ABSL_TSAN_MUTEX_POST_DIVERT(mu, 0);
return res;
}
@@ -682,6 +675,7 @@ static const intptr_t kMuOne = 0x0100; // a count of one reader
// flags passed to Enqueue and LockSlow{,WithTimeout,Loop}
static const int kMuHasBlocked = 0x01; // already blocked (MUST == 1)
static const int kMuIsCond = 0x02; // conditional waiter (CV or Condition)
+static const int kMuIsFer = 0x04; // wait morphing from a CondVar
static_assert(PerThreadSynch::kAlignment > kMuLow,
"PerThreadSynch::kAlignment must be greater than kMuLow");
@@ -737,25 +731,43 @@ static unsigned TsanFlags(Mutex::MuHow how) {
}
#endif
-static bool DebugOnlyIsExiting() {
- return false;
-}
+#if defined(__APPLE__) || defined(ABSL_BUILD_DLL)
+// When building a dll symbol export lists may reference the destructor
+// and want it to be an exported symbol rather than an inline function.
+// Some apple builds also do dynamic library build but don't say it explicitly.
+Mutex::~Mutex() { Dtor(); }
+#endif
-Mutex::~Mutex() {
- intptr_t v = mu_.load(std::memory_order_relaxed);
- if ((v & kMuEvent) != 0 && !DebugOnlyIsExiting()) {
- ForgetSynchEvent(&this->mu_, kMuEvent, kMuSpin);
- }
+#if !defined(NDEBUG) || defined(ABSL_HAVE_THREAD_SANITIZER)
+void Mutex::Dtor() {
if (kDebugMode) {
this->ForgetDeadlockInfo();
}
ABSL_TSAN_MUTEX_DESTROY(this, __tsan_mutex_not_static);
}
+#endif
void Mutex::EnableDebugLog(const char* name) {
+ // Need to disable writes here and in EnableInvariantDebugging to prevent
+ // false race reports on SynchEvent objects. TSan ignores synchronization
+ // on synch_event_mu in Lock/Unlock/etc methods due to mutex annotations,
+ // but it sees few accesses to SynchEvent in EvalConditionAnnotated.
+ // If we don't ignore accesses here, it can result in false races
+ // between EvalConditionAnnotated and SynchEvent reuse in EnsureSynchEvent.
+ ABSL_ANNOTATE_IGNORE_WRITES_BEGIN();
SynchEvent* e = EnsureSynchEvent(&this->mu_, name, kMuEvent, kMuSpin);
e->log = true;
UnrefSynchEvent(e);
+ // This prevents "error: undefined symbol: absl::Mutex::~Mutex()"
+ // in a release build (NDEBUG defined) when a test does "#undef NDEBUG"
+ // to use assert macro. In such case, the test does not get the dtor
+ // definition because it's supposed to be outline when NDEBUG is not defined,
+ // and this source file does not define one either because NDEBUG is defined.
+ // Since it's not possible to take address of a destructor, we move the
+ // actual destructor code into the separate Dtor function and force the
+ // compiler to emit this function even if it's inline by taking its address.
+ ABSL_ATTRIBUTE_UNUSED volatile auto dtor = &Mutex::Dtor;
+ ABSL_ANNOTATE_IGNORE_WRITES_END();
}
void EnableMutexInvariantDebugging(bool enabled) {
@@ -763,6 +775,7 @@ void EnableMutexInvariantDebugging(bool enabled) {
}
void Mutex::EnableInvariantDebugging(void (*invariant)(void*), void* arg) {
+ ABSL_ANNOTATE_IGNORE_WRITES_BEGIN();
if (synch_check_invariants.load(std::memory_order_acquire) &&
invariant != nullptr) {
SynchEvent* e = EnsureSynchEvent(&this->mu_, nullptr, kMuEvent, kMuSpin);
@@ -770,6 +783,7 @@ void Mutex::EnableInvariantDebugging(void (*invariant)(void*), void* arg) {
e->arg = arg;
UnrefSynchEvent(e);
}
+ ABSL_ANNOTATE_IGNORE_WRITES_END();
}
void SetMutexDeadlockDetectionMode(OnDeadlockCycle mode) {
@@ -920,20 +934,23 @@ static PerThreadSynch* Enqueue(PerThreadSynch* head, SynchWaitParams* waitp,
s->wake = false; // not being woken
s->cond_waiter = ((flags & kMuIsCond) != 0);
#ifdef ABSL_HAVE_PTHREAD_GETSCHEDPARAM
- int64_t now_cycles = CycleClock::Now();
- if (s->next_priority_read_cycles < now_cycles) {
- // Every so often, update our idea of the thread's priority.
- // pthread_getschedparam() is 5% of the block/wakeup time;
- // CycleClock::Now() is 0.5%.
- int policy;
- struct sched_param param;
- const int err = pthread_getschedparam(pthread_self(), &policy, &param);
- if (err != 0) {
- ABSL_RAW_LOG(ERROR, "pthread_getschedparam failed: %d", err);
- } else {
- s->priority = param.sched_priority;
- s->next_priority_read_cycles =
- now_cycles + static_cast<int64_t>(CycleClock::Frequency());
+ if ((flags & kMuIsFer) == 0) {
+ assert(s == Synch_GetPerThread());
+ int64_t now_cycles = CycleClock::Now();
+ if (s->next_priority_read_cycles < now_cycles) {
+ // Every so often, update our idea of the thread's priority.
+ // pthread_getschedparam() is 5% of the block/wakeup time;
+ // CycleClock::Now() is 0.5%.
+ int policy;
+ struct sched_param param;
+ const int err = pthread_getschedparam(pthread_self(), &policy, &param);
+ if (err != 0) {
+ ABSL_RAW_LOG(ERROR, "pthread_getschedparam failed: %d", err);
+ } else {
+ s->priority = param.sched_priority;
+ s->next_priority_read_cycles =
+ now_cycles + static_cast<int64_t>(CycleClock::Frequency());
+ }
}
}
#endif
@@ -962,8 +979,7 @@ static PerThreadSynch* Enqueue(PerThreadSynch* head, SynchWaitParams* waitp,
} while (s->priority <= advance_to->priority);
// termination guaranteed because s->priority > head->priority
// and head is the end of a skip chain
- } else if (waitp->how == kExclusive &&
- Condition::GuaranteedEqual(waitp->cond, nullptr)) {
+ } else if (waitp->how == kExclusive && waitp->cond == nullptr) {
// An unlocker could be scanning the queue, but we know it will recheck
// the queue front for writers that have no condition, which is what s
// is, so an insert at front is safe.
@@ -994,6 +1010,24 @@ static PerThreadSynch* Enqueue(PerThreadSynch* head, SynchWaitParams* waitp,
if (MuEquivalentWaiter(s, s->next)) { // s->may_skip is known to be true
s->skip = s->next; // s may skip to its successor
}
+ } else if ((flags & kMuHasBlocked) &&
+ (s->priority >= head->next->priority) &&
+ (!head->maybe_unlocking ||
+ (waitp->how == kExclusive &&
+ Condition::GuaranteedEqual(waitp->cond, nullptr)))) {
+ // This thread has already waited, then was woken, then failed to acquire
+ // the mutex and now tries to requeue. Try to requeue it at head,
+ // otherwise it can suffer bad latency (wait whole queue several times).
+ // However, we need to be conservative. First, we need to ensure that we
+ // respect priorities. Then, we need to be careful to not break wait
+ // queue invariants: we require either that unlocker is not scanning
+ // the queue or that the current thread is a writer with no condition
+ // (unlocker will recheck the queue for such waiters).
+ s->next = head->next;
+ head->next = s;
+ if (MuEquivalentWaiter(s, s->next)) { // s->may_skip is known to be true
+ s->skip = s->next; // s may skip to its successor
+ }
} else { // enqueue not done any other way, so
// we're inserting s at the back
// s will become new head; copy data from head into it
@@ -1472,7 +1506,7 @@ void Mutex::AssertNotHeld() const {
// Attempt to acquire *mu, and return whether successful. The implementation
// may spin for a short while if the lock cannot be acquired immediately.
static bool TryAcquireWithSpinning(std::atomic<intptr_t>* mu) {
- int c = GetMutexGlobals().spinloop_iterations;
+ int c = globals.spinloop_iterations.load(std::memory_order_relaxed);
do { // do/while somewhat faster on AMD
intptr_t v = mu->load(std::memory_order_relaxed);
if ((v & (kMuReader | kMuEvent)) != 0) {
@@ -1492,11 +1526,12 @@ void Mutex::Lock() {
GraphId id = DebugOnlyDeadlockCheck(this);
intptr_t v = mu_.load(std::memory_order_relaxed);
// try fast acquire, then spin loop
- if ((v & (kMuWriter | kMuReader | kMuEvent)) != 0 ||
- !mu_.compare_exchange_strong(v, kMuWriter | v, std::memory_order_acquire,
- std::memory_order_relaxed)) {
+ if (ABSL_PREDICT_FALSE((v & (kMuWriter | kMuReader | kMuEvent)) != 0) ||
+ ABSL_PREDICT_FALSE(!mu_.compare_exchange_strong(
+ v, kMuWriter | v, std::memory_order_acquire,
+ std::memory_order_relaxed))) {
// try spin acquire, then slow loop
- if (!TryAcquireWithSpinning(&this->mu_)) {
+ if (ABSL_PREDICT_FALSE(!TryAcquireWithSpinning(&this->mu_))) {
this->LockSlow(kExclusive, nullptr, 0);
}
}
@@ -1508,159 +1543,95 @@ void Mutex::ReaderLock() {
ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_read_lock);
GraphId id = DebugOnlyDeadlockCheck(this);
intptr_t v = mu_.load(std::memory_order_relaxed);
- // try fast acquire, then slow loop
- if ((v & (kMuWriter | kMuWait | kMuEvent)) != 0 ||
- !mu_.compare_exchange_strong(v, (kMuReader | v) + kMuOne,
- std::memory_order_acquire,
- std::memory_order_relaxed)) {
- this->LockSlow(kShared, nullptr, 0);
+ for (;;) {
+ // If there are non-readers holding the lock, use the slow loop.
+ if (ABSL_PREDICT_FALSE(v & (kMuWriter | kMuWait | kMuEvent)) != 0) {
+ this->LockSlow(kShared, nullptr, 0);
+ break;
+ }
+ // We can avoid the loop and only use the CAS when the lock is free or
+ // only held by readers.
+ if (ABSL_PREDICT_TRUE(mu_.compare_exchange_weak(
+ v, (kMuReader | v) + kMuOne, std::memory_order_acquire,
+ std::memory_order_relaxed))) {
+ break;
+ }
}
DebugOnlyLockEnter(this, id);
ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_read_lock, 0);
}
-void Mutex::LockWhen(const Condition& cond) {
- ABSL_TSAN_MUTEX_PRE_LOCK(this, 0);
- GraphId id = DebugOnlyDeadlockCheck(this);
- this->LockSlow(kExclusive, &cond, 0);
- DebugOnlyLockEnter(this, id);
- ABSL_TSAN_MUTEX_POST_LOCK(this, 0, 0);
-}
-
-bool Mutex::LockWhenWithTimeout(const Condition& cond, absl::Duration timeout) {
- ABSL_TSAN_MUTEX_PRE_LOCK(this, 0);
- GraphId id = DebugOnlyDeadlockCheck(this);
- bool res = LockSlowWithDeadline(kExclusive, &cond, KernelTimeout(timeout), 0);
- DebugOnlyLockEnter(this, id);
- ABSL_TSAN_MUTEX_POST_LOCK(this, 0, 0);
- return res;
-}
-
-bool Mutex::LockWhenWithDeadline(const Condition& cond, absl::Time deadline) {
- ABSL_TSAN_MUTEX_PRE_LOCK(this, 0);
- GraphId id = DebugOnlyDeadlockCheck(this);
- bool res =
- LockSlowWithDeadline(kExclusive, &cond, KernelTimeout(deadline), 0);
- DebugOnlyLockEnter(this, id);
- ABSL_TSAN_MUTEX_POST_LOCK(this, 0, 0);
- return res;
-}
-
-void Mutex::ReaderLockWhen(const Condition& cond) {
- ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_read_lock);
- GraphId id = DebugOnlyDeadlockCheck(this);
- this->LockSlow(kShared, &cond, 0);
- DebugOnlyLockEnter(this, id);
- ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_read_lock, 0);
-}
-
-bool Mutex::ReaderLockWhenWithTimeout(const Condition& cond,
- absl::Duration timeout) {
- ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_read_lock);
- GraphId id = DebugOnlyDeadlockCheck(this);
- bool res = LockSlowWithDeadline(kShared, &cond, KernelTimeout(timeout), 0);
- DebugOnlyLockEnter(this, id);
- ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_read_lock, 0);
- return res;
-}
-
-bool Mutex::ReaderLockWhenWithDeadline(const Condition& cond,
- absl::Time deadline) {
- ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_read_lock);
+bool Mutex::LockWhenCommon(const Condition& cond,
+ synchronization_internal::KernelTimeout t,
+ bool write) {
+ MuHow how = write ? kExclusive : kShared;
+ ABSL_TSAN_MUTEX_PRE_LOCK(this, TsanFlags(how));
GraphId id = DebugOnlyDeadlockCheck(this);
- bool res = LockSlowWithDeadline(kShared, &cond, KernelTimeout(deadline), 0);
+ bool res = LockSlowWithDeadline(how, &cond, t, 0);
DebugOnlyLockEnter(this, id);
- ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_read_lock, 0);
+ ABSL_TSAN_MUTEX_POST_LOCK(this, TsanFlags(how), 0);
return res;
}
-void Mutex::Await(const Condition& cond) {
- if (cond.Eval()) { // condition already true; nothing to do
- if (kDebugMode) {
- this->AssertReaderHeld();
- }
- } else { // normal case
- ABSL_RAW_CHECK(this->AwaitCommon(cond, KernelTimeout::Never()),
- "condition untrue on return from Await");
- }
-}
-
-bool Mutex::AwaitWithTimeout(const Condition& cond, absl::Duration timeout) {
- if (cond.Eval()) { // condition already true; nothing to do
- if (kDebugMode) {
- this->AssertReaderHeld();
- }
- return true;
+bool Mutex::AwaitCommon(const Condition& cond, KernelTimeout t) {
+ if (kDebugMode) {
+ this->AssertReaderHeld();
}
-
- KernelTimeout t{timeout};
- bool res = this->AwaitCommon(cond, t);
- ABSL_RAW_CHECK(res || t.has_timeout(),
- "condition untrue on return from Await");
- return res;
-}
-
-bool Mutex::AwaitWithDeadline(const Condition& cond, absl::Time deadline) {
if (cond.Eval()) { // condition already true; nothing to do
- if (kDebugMode) {
- this->AssertReaderHeld();
- }
return true;
}
-
- KernelTimeout t{deadline};
- bool res = this->AwaitCommon(cond, t);
- ABSL_RAW_CHECK(res || t.has_timeout(),
- "condition untrue on return from Await");
- return res;
-}
-
-bool Mutex::AwaitCommon(const Condition& cond, KernelTimeout t) {
- this->AssertReaderHeld();
MuHow how =
(mu_.load(std::memory_order_relaxed) & kMuWriter) ? kExclusive : kShared;
ABSL_TSAN_MUTEX_PRE_UNLOCK(this, TsanFlags(how));
SynchWaitParams waitp(how, &cond, t, nullptr /*no cvmu*/,
Synch_GetPerThreadAnnotated(this),
nullptr /*no cv_word*/);
- int flags = kMuHasBlocked;
- if (!Condition::GuaranteedEqual(&cond, nullptr)) {
- flags |= kMuIsCond;
- }
this->UnlockSlow(&waitp);
this->Block(waitp.thread);
ABSL_TSAN_MUTEX_POST_UNLOCK(this, TsanFlags(how));
ABSL_TSAN_MUTEX_PRE_LOCK(this, TsanFlags(how));
- this->LockSlowLoop(&waitp, flags);
+ this->LockSlowLoop(&waitp, kMuHasBlocked | kMuIsCond);
bool res = waitp.cond != nullptr || // => cond known true from LockSlowLoop
EvalConditionAnnotated(&cond, this, true, false, how == kShared);
ABSL_TSAN_MUTEX_POST_LOCK(this, TsanFlags(how), 0);
+ ABSL_RAW_CHECK(res || t.has_timeout(),
+ "condition untrue on return from Await");
return res;
}
bool Mutex::TryLock() {
ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_try_lock);
intptr_t v = mu_.load(std::memory_order_relaxed);
- if ((v & (kMuWriter | kMuReader | kMuEvent)) == 0 && // try fast acquire
- mu_.compare_exchange_strong(v, kMuWriter | v, std::memory_order_acquire,
- std::memory_order_relaxed)) {
- DebugOnlyLockEnter(this);
- ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_try_lock, 0);
- return true;
- }
- if ((v & kMuEvent) != 0) { // we're recording events
- if ((v & kExclusive->slow_need_zero) == 0 && // try fast acquire
- mu_.compare_exchange_strong(
- v, (kExclusive->fast_or | v) + kExclusive->fast_add,
- std::memory_order_acquire, std::memory_order_relaxed)) {
+ // Try fast acquire.
+ if (ABSL_PREDICT_TRUE((v & (kMuWriter | kMuReader | kMuEvent)) == 0)) {
+ if (ABSL_PREDICT_TRUE(mu_.compare_exchange_strong(
+ v, kMuWriter | v, std::memory_order_acquire,
+ std::memory_order_relaxed))) {
DebugOnlyLockEnter(this);
- PostSynchEvent(this, SYNCH_EV_TRYLOCK_SUCCESS);
ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_try_lock, 0);
return true;
- } else {
- PostSynchEvent(this, SYNCH_EV_TRYLOCK_FAILED);
}
+ } else if (ABSL_PREDICT_FALSE((v & kMuEvent) != 0)) {
+ // We're recording events.
+ return TryLockSlow();
+ }
+ ABSL_TSAN_MUTEX_POST_LOCK(
+ this, __tsan_mutex_try_lock | __tsan_mutex_try_lock_failed, 0);
+ return false;
+}
+
+ABSL_ATTRIBUTE_NOINLINE bool Mutex::TryLockSlow() {
+ intptr_t v = mu_.load(std::memory_order_relaxed);
+ if ((v & kExclusive->slow_need_zero) == 0 && // try fast acquire
+ mu_.compare_exchange_strong(
+ v, (kExclusive->fast_or | v) + kExclusive->fast_add,
+ std::memory_order_acquire, std::memory_order_relaxed)) {
+ DebugOnlyLockEnter(this);
+ PostSynchEvent(this, SYNCH_EV_TRYLOCK_SUCCESS);
+ ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_try_lock, 0);
+ return true;
}
+ PostSynchEvent(this, SYNCH_EV_TRYLOCK_FAILED);
ABSL_TSAN_MUTEX_POST_LOCK(
this, __tsan_mutex_try_lock | __tsan_mutex_try_lock_failed, 0);
return false;
@@ -1670,41 +1641,57 @@ bool Mutex::ReaderTryLock() {
ABSL_TSAN_MUTEX_PRE_LOCK(this,
__tsan_mutex_read_lock | __tsan_mutex_try_lock);
intptr_t v = mu_.load(std::memory_order_relaxed);
+ // Clang tends to unroll the loop when compiling with optimization.
+ // But in this case it just unnecessary increases code size.
+ // If CAS is failing due to contention, the jump cost is negligible.
+#if defined(__clang__)
+#pragma nounroll
+#endif
// The while-loops (here and below) iterate only if the mutex word keeps
- // changing (typically because the reader count changes) under the CAS. We
- // limit the number of attempts to avoid having to think about livelock.
- int loop_limit = 5;
- while ((v & (kMuWriter | kMuWait | kMuEvent)) == 0 && loop_limit != 0) {
- if (mu_.compare_exchange_strong(v, (kMuReader | v) + kMuOne,
- std::memory_order_acquire,
- std::memory_order_relaxed)) {
+ // changing (typically because the reader count changes) under the CAS.
+ // We limit the number of attempts to avoid having to think about livelock.
+ for (int loop_limit = 5; loop_limit != 0; loop_limit--) {
+ if (ABSL_PREDICT_FALSE((v & (kMuWriter | kMuWait | kMuEvent)) != 0)) {
+ break;
+ }
+ if (ABSL_PREDICT_TRUE(mu_.compare_exchange_strong(
+ v, (kMuReader | v) + kMuOne, std::memory_order_acquire,
+ std::memory_order_relaxed))) {
DebugOnlyLockEnter(this);
ABSL_TSAN_MUTEX_POST_LOCK(
this, __tsan_mutex_read_lock | __tsan_mutex_try_lock, 0);
return true;
}
- loop_limit--;
- v = mu_.load(std::memory_order_relaxed);
}
- if ((v & kMuEvent) != 0) { // we're recording events
- loop_limit = 5;
- while ((v & kShared->slow_need_zero) == 0 && loop_limit != 0) {
- if (mu_.compare_exchange_strong(v, (kMuReader | v) + kMuOne,
- std::memory_order_acquire,
- std::memory_order_relaxed)) {
- DebugOnlyLockEnter(this);
- PostSynchEvent(this, SYNCH_EV_READERTRYLOCK_SUCCESS);
- ABSL_TSAN_MUTEX_POST_LOCK(
- this, __tsan_mutex_read_lock | __tsan_mutex_try_lock, 0);
- return true;
- }
- loop_limit--;
- v = mu_.load(std::memory_order_relaxed);
- }
- if ((v & kMuEvent) != 0) {
- PostSynchEvent(this, SYNCH_EV_READERTRYLOCK_FAILED);
+ if (ABSL_PREDICT_TRUE((v & kMuEvent) == 0)) {
+ ABSL_TSAN_MUTEX_POST_LOCK(this,
+ __tsan_mutex_read_lock | __tsan_mutex_try_lock |
+ __tsan_mutex_try_lock_failed,
+ 0);
+ return false;
+ }
+ // we're recording events
+ return ReaderTryLockSlow();
+}
+
+ABSL_ATTRIBUTE_NOINLINE bool Mutex::ReaderTryLockSlow() {
+ intptr_t v = mu_.load(std::memory_order_relaxed);
+#if defined(__clang__)
+#pragma nounroll
+#endif
+ for (int loop_limit = 5; loop_limit != 0; loop_limit--) {
+ if ((v & kShared->slow_need_zero) == 0 &&
+ mu_.compare_exchange_strong(v, (kMuReader | v) + kMuOne,
+ std::memory_order_acquire,
+ std::memory_order_relaxed)) {
+ DebugOnlyLockEnter(this);
+ PostSynchEvent(this, SYNCH_EV_READERTRYLOCK_SUCCESS);
+ ABSL_TSAN_MUTEX_POST_LOCK(
+ this, __tsan_mutex_read_lock | __tsan_mutex_try_lock, 0);
+ return true;
}
}
+ PostSynchEvent(this, SYNCH_EV_READERTRYLOCK_FAILED);
ABSL_TSAN_MUTEX_POST_LOCK(this,
__tsan_mutex_read_lock | __tsan_mutex_try_lock |
__tsan_mutex_try_lock_failed,
@@ -1768,16 +1755,20 @@ void Mutex::ReaderUnlock() {
DebugOnlyLockLeave(this);
intptr_t v = mu_.load(std::memory_order_relaxed);
assert((v & (kMuWriter | kMuReader)) == kMuReader);
- if ((v & (kMuReader | kMuWait | kMuEvent)) == kMuReader) {
+ for (;;) {
+ if (ABSL_PREDICT_FALSE((v & (kMuReader | kMuWait | kMuEvent)) !=
+ kMuReader)) {
+ this->UnlockSlow(nullptr /*no waitp*/); // take slow path
+ break;
+ }
// fast reader release (reader with no waiters)
intptr_t clear = ExactlyOneReader(v) ? kMuReader | kMuOne : kMuOne;
- if (mu_.compare_exchange_strong(v, v - clear, std::memory_order_release,
- std::memory_order_relaxed)) {
- ABSL_TSAN_MUTEX_POST_UNLOCK(this, __tsan_mutex_read_lock);
- return;
+ if (ABSL_PREDICT_TRUE(
+ mu_.compare_exchange_strong(v, v - clear, std::memory_order_release,
+ std::memory_order_relaxed))) {
+ break;
}
}
- this->UnlockSlow(nullptr /*no waitp*/); // take slow path
ABSL_TSAN_MUTEX_POST_UNLOCK(this, __tsan_mutex_read_lock);
}
@@ -1812,6 +1803,22 @@ static intptr_t IgnoreWaitingWritersMask(int flag) {
// Internal version of LockWhen(). See LockSlowWithDeadline()
ABSL_ATTRIBUTE_NOINLINE void Mutex::LockSlow(MuHow how, const Condition* cond,
int flags) {
+ // Note: we specifically initialize spinloop_iterations after the first use
+ // in TryAcquireWithSpinning so that Lock function does not have any non-tail
+ // calls and consequently a stack frame. It's fine to have spinloop_iterations
+ // uninitialized (meaning no spinning) in all initial uncontended Lock calls
+ // and in the first contended call. After that we will have
+ // spinloop_iterations properly initialized.
+ if (ABSL_PREDICT_FALSE(
+ globals.spinloop_iterations.load(std::memory_order_relaxed) == 0)) {
+ if (absl::base_internal::NumCPUs() > 1) {
+ // If this is multiprocessor, allow spinning.
+ globals.spinloop_iterations.store(1500, std::memory_order_relaxed);
+ } else {
+ // If this a uniprocessor, only yield/sleep.
+ globals.spinloop_iterations.store(-1, std::memory_order_relaxed);
+ }
+ }
ABSL_RAW_CHECK(
this->LockSlowWithDeadline(how, cond, KernelTimeout::Never(), flags),
"condition untrue on return from LockSlow");
@@ -1913,7 +1920,7 @@ bool Mutex::LockSlowWithDeadline(MuHow how, const Condition* cond,
SynchWaitParams waitp(how, cond, t, nullptr /*no cvmu*/,
Synch_GetPerThreadAnnotated(this),
nullptr /*no cv_word*/);
- if (!Condition::GuaranteedEqual(cond, nullptr)) {
+ if (cond != nullptr) {
flags |= kMuIsCond;
}
if (unlock) {
@@ -2103,7 +2110,6 @@ ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams* waitp) {
// head of the list searched previously, or zero
PerThreadSynch* old_h = nullptr;
// a condition that's known to be false.
- const Condition* known_false = nullptr;
PerThreadSynch* wake_list = kPerThreadSynchNull; // list of threads to wake
intptr_t wr_wait = 0; // set to kMuWrWait if we wake a reader and a
// later writer could have acquired the lock
@@ -2207,7 +2213,7 @@ ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams* waitp) {
}
}
if (h->next->waitp->how == kExclusive &&
- Condition::GuaranteedEqual(h->next->waitp->cond, nullptr)) {
+ h->next->waitp->cond == nullptr) {
// easy case: writer with no condition; no need to search
pw = h; // wake w, the successor of h (=pw)
w = h->next;
@@ -2290,10 +2296,8 @@ ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams* waitp) {
w_walk->wake = false;
if (w_walk->waitp->cond ==
nullptr || // no condition => vacuously true OR
- (w_walk->waitp->cond != known_false &&
- // this thread's condition is not known false, AND
- // is in fact true
- EvalConditionIgnored(this, w_walk->waitp->cond))) {
+ // this thread's condition is true
+ EvalConditionIgnored(this, w_walk->waitp->cond)) {
if (w == nullptr) {
w_walk->wake = true; // can wake this waiter
w = w_walk;
@@ -2307,8 +2311,6 @@ ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams* waitp) {
} else { // writer with true condition
wr_wait = kMuWrWait;
}
- } else { // can't wake; condition false
- known_false = w_walk->waitp->cond; // remember last false condition
}
if (w_walk->wake) { // we're waking reader w_walk
pw_walk = w_walk; // don't skip similar waiters
@@ -2414,10 +2416,10 @@ void Mutex::Fer(PerThreadSynch* w) {
int c = 0;
ABSL_RAW_CHECK(w->waitp->cond == nullptr,
"Mutex::Fer while waiting on Condition");
- ABSL_RAW_CHECK(!w->waitp->timeout.has_timeout(),
- "Mutex::Fer while in timed wait");
ABSL_RAW_CHECK(w->waitp->cv_word == nullptr,
"Mutex::Fer with pending CondVar queueing");
+ // The CondVar timeout is not relevant for the Mutex wait.
+ w->waitp->timeout = {};
for (;;) {
intptr_t v = mu_.load(std::memory_order_relaxed);
// Note: must not queue if the mutex is unlocked (nobody will wake it).
@@ -2436,7 +2438,8 @@ void Mutex::Fer(PerThreadSynch* w) {
} else {
if ((v & (kMuSpin | kMuWait)) == 0) { // no waiters
// This thread tries to become the one and only waiter.
- PerThreadSynch* new_h = Enqueue(nullptr, w->waitp, v, kMuIsCond);
+ PerThreadSynch* new_h =
+ Enqueue(nullptr, w->waitp, v, kMuIsCond | kMuIsFer);
ABSL_RAW_CHECK(new_h != nullptr,
"Enqueue failed"); // we must queue ourselves
if (mu_.compare_exchange_strong(
@@ -2447,7 +2450,7 @@ void Mutex::Fer(PerThreadSynch* w) {
} else if ((v & kMuSpin) == 0 &&
mu_.compare_exchange_strong(v, v | kMuSpin | kMuWait)) {
PerThreadSynch* h = GetPerThreadSynch(v);
- PerThreadSynch* new_h = Enqueue(h, w->waitp, v, kMuIsCond);
+ PerThreadSynch* new_h = Enqueue(h, w->waitp, v, kMuIsCond | kMuIsFer);
ABSL_RAW_CHECK(new_h != nullptr,
"Enqueue failed"); // we must queue ourselves
do {
@@ -2503,12 +2506,6 @@ void CondVar::EnableDebugLog(const char* name) {
UnrefSynchEvent(e);
}
-CondVar::~CondVar() {
- if ((cv_.load(std::memory_order_relaxed) & kCvEvent) != 0) {
- ForgetSynchEvent(&this->cv_, kCvEvent, kCvSpin);
- }
-}
-
// Remove thread s from the list of waiters on this condition variable.
void CondVar::Remove(PerThreadSynch* s) {
SchedulingGuard::ScopedDisable disable_rescheduling;
@@ -2659,33 +2656,6 @@ bool CondVar::WaitCommon(Mutex* mutex, KernelTimeout t) {
return rc;
}
-bool CondVar::WaitWithTimeout(Mutex* mu, absl::Duration timeout) {
- return WaitCommon(mu, KernelTimeout(timeout));
-}
-
-bool CondVar::WaitWithDeadline(Mutex* mu, absl::Time deadline) {
- return WaitCommon(mu, KernelTimeout(deadline));
-}
-
-void CondVar::Wait(Mutex* mu) { WaitCommon(mu, KernelTimeout::Never()); }
-
-// Wake thread w
-// If it was a timed wait, w will be waiting on w->cv
-// Otherwise, if it was not a Mutex mutex, w will be waiting on w->sem
-// Otherwise, w is transferred to the Mutex mutex via Mutex::Fer().
-void CondVar::Wakeup(PerThreadSynch* w) {
- if (w->waitp->timeout.has_timeout() || w->waitp->cvmu == nullptr) {
- // The waiting thread only needs to observe "w->state == kAvailable" to be
- // released, we must cache "cvmu" before clearing "next".
- Mutex* mu = w->waitp->cvmu;
- w->next = nullptr;
- w->state.store(PerThreadSynch::kAvailable, std::memory_order_release);
- Mutex::IncrementSynchSem(mu, w);
- } else {
- w->waitp->cvmu->Fer(w);
- }
-}
-
void CondVar::Signal() {
SchedulingGuard::ScopedDisable disable_rescheduling;
ABSL_TSAN_MUTEX_PRE_SIGNAL(nullptr, 0);
@@ -2710,7 +2680,7 @@ void CondVar::Signal() {
cv_.store((v & kCvEvent) | reinterpret_cast<intptr_t>(h),
std::memory_order_release);
if (w != nullptr) {
- CondVar::Wakeup(w); // wake waiter, if there was one
+ w->waitp->cvmu->Fer(w); // wake waiter, if there was one
cond_var_tracer("Signal wakeup", this);
}
if ((v & kCvEvent) != 0) {
@@ -2746,7 +2716,7 @@ void CondVar::SignalAll() {
do { // for every thread, wake it up
w = n;
n = n->next;
- CondVar::Wakeup(w);
+ w->waitp->cvmu->Fer(w);
} while (w != h);
cond_var_tracer("SignalAll wakeup", this);
}
@@ -2810,17 +2780,11 @@ Condition::Condition(const bool* cond)
StoreCallback(dereference);
}
-bool Condition::Eval() const {
- // eval_ == null for kTrue
- return (this->eval_ == nullptr) || (*this->eval_)(this);
-}
+bool Condition::Eval() const { return (*this->eval_)(this); }
bool Condition::GuaranteedEqual(const Condition* a, const Condition* b) {
- // kTrue logic.
- if (a == nullptr || a->eval_ == nullptr) {
- return b == nullptr || b->eval_ == nullptr;
- } else if (b == nullptr || b->eval_ == nullptr) {
- return false;
+ if (a == nullptr || b == nullptr) {
+ return a == b;
}
// Check equality of the representative fields.
return a->eval_ == b->eval_ && a->arg_ == b->arg_ &&
diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/mutex.h b/contrib/restricted/abseil-cpp/absl/synchronization/mutex.h
index 645c26d9c3..d53a22bbd9 100644
--- a/contrib/restricted/abseil-cpp/absl/synchronization/mutex.h
+++ b/contrib/restricted/abseil-cpp/absl/synchronization/mutex.h
@@ -64,6 +64,7 @@
#include <iterator>
#include <string>
+#include "absl/base/attributes.h"
#include "absl/base/const_init.h"
#include "absl/base/internal/identity.h"
#include "absl/base/internal/low_level_alloc.h"
@@ -324,7 +325,9 @@ class ABSL_LOCKABLE Mutex {
// `true`, `Await()` *may* skip the release/re-acquire step.
//
// `Await()` requires that this thread holds this `Mutex` in some mode.
- void Await(const Condition& cond);
+ void Await(const Condition& cond) {
+ AwaitCommon(cond, synchronization_internal::KernelTimeout::Never());
+ }
// Mutex::LockWhen()
// Mutex::ReaderLockWhen()
@@ -334,9 +337,15 @@ class ABSL_LOCKABLE Mutex {
// be acquired, then atomically acquires this `Mutex`. `LockWhen()` is
// logically equivalent to `*Lock(); Await();` though they may have different
// performance characteristics.
- void LockWhen(const Condition& cond) ABSL_EXCLUSIVE_LOCK_FUNCTION();
+ void LockWhen(const Condition& cond) ABSL_EXCLUSIVE_LOCK_FUNCTION() {
+ LockWhenCommon(cond, synchronization_internal::KernelTimeout::Never(),
+ true);
+ }
- void ReaderLockWhen(const Condition& cond) ABSL_SHARED_LOCK_FUNCTION();
+ void ReaderLockWhen(const Condition& cond) ABSL_SHARED_LOCK_FUNCTION() {
+ LockWhenCommon(cond, synchronization_internal::KernelTimeout::Never(),
+ false);
+ }
void WriterLockWhen(const Condition& cond) ABSL_EXCLUSIVE_LOCK_FUNCTION() {
this->LockWhen(cond);
@@ -363,9 +372,13 @@ class ABSL_LOCKABLE Mutex {
// Negative timeouts are equivalent to a zero timeout.
//
// This method requires that this thread holds this `Mutex` in some mode.
- bool AwaitWithTimeout(const Condition& cond, absl::Duration timeout);
+ bool AwaitWithTimeout(const Condition& cond, absl::Duration timeout) {
+ return AwaitCommon(cond, synchronization_internal::KernelTimeout{timeout});
+ }
- bool AwaitWithDeadline(const Condition& cond, absl::Time deadline);
+ bool AwaitWithDeadline(const Condition& cond, absl::Time deadline) {
+ return AwaitCommon(cond, synchronization_internal::KernelTimeout{deadline});
+ }
// Mutex::LockWhenWithTimeout()
// Mutex::ReaderLockWhenWithTimeout()
@@ -379,9 +392,15 @@ class ABSL_LOCKABLE Mutex {
//
// Negative timeouts are equivalent to a zero timeout.
bool LockWhenWithTimeout(const Condition& cond, absl::Duration timeout)
- ABSL_EXCLUSIVE_LOCK_FUNCTION();
+ ABSL_EXCLUSIVE_LOCK_FUNCTION() {
+ return LockWhenCommon(
+ cond, synchronization_internal::KernelTimeout{timeout}, true);
+ }
bool ReaderLockWhenWithTimeout(const Condition& cond, absl::Duration timeout)
- ABSL_SHARED_LOCK_FUNCTION();
+ ABSL_SHARED_LOCK_FUNCTION() {
+ return LockWhenCommon(
+ cond, synchronization_internal::KernelTimeout{timeout}, false);
+ }
bool WriterLockWhenWithTimeout(const Condition& cond, absl::Duration timeout)
ABSL_EXCLUSIVE_LOCK_FUNCTION() {
return this->LockWhenWithTimeout(cond, timeout);
@@ -399,9 +418,15 @@ class ABSL_LOCKABLE Mutex {
//
// Deadlines in the past are equivalent to an immediate deadline.
bool LockWhenWithDeadline(const Condition& cond, absl::Time deadline)
- ABSL_EXCLUSIVE_LOCK_FUNCTION();
+ ABSL_EXCLUSIVE_LOCK_FUNCTION() {
+ return LockWhenCommon(
+ cond, synchronization_internal::KernelTimeout{deadline}, true);
+ }
bool ReaderLockWhenWithDeadline(const Condition& cond, absl::Time deadline)
- ABSL_SHARED_LOCK_FUNCTION();
+ ABSL_SHARED_LOCK_FUNCTION() {
+ return LockWhenCommon(
+ cond, synchronization_internal::KernelTimeout{deadline}, false);
+ }
bool WriterLockWhenWithDeadline(const Condition& cond, absl::Time deadline)
ABSL_EXCLUSIVE_LOCK_FUNCTION() {
return this->LockWhenWithDeadline(cond, deadline);
@@ -497,15 +522,22 @@ class ABSL_LOCKABLE Mutex {
int flags) ABSL_ATTRIBUTE_COLD;
// slow path release
void UnlockSlow(SynchWaitParams* waitp) ABSL_ATTRIBUTE_COLD;
+ // TryLock slow path.
+ bool TryLockSlow();
+ // ReaderTryLock slow path.
+ bool ReaderTryLockSlow();
// Common code between Await() and AwaitWithTimeout/Deadline()
bool AwaitCommon(const Condition& cond,
synchronization_internal::KernelTimeout t);
+ bool LockWhenCommon(const Condition& cond,
+ synchronization_internal::KernelTimeout t, bool write);
// Attempt to remove thread s from queue.
void TryRemove(base_internal::PerThreadSynch* s);
// Block a thread on mutex.
void Block(base_internal::PerThreadSynch* s);
// Wake a thread; return successor.
base_internal::PerThreadSynch* Wakeup(base_internal::PerThreadSynch* w);
+ void Dtor();
friend class CondVar; // for access to Trans()/Fer().
void Trans(MuHow how); // used for CondVar->Mutex transfer
@@ -708,23 +740,25 @@ class Condition {
// a function template is passed as `func`. Also, the dummy `typename = void`
// template parameter exists just to work around a MSVC mangling bug.
template <typename T, typename = void>
- Condition(bool (*func)(T*), typename absl::internal::identity<T>::type* arg);
+ Condition(bool (*func)(T*),
+ typename absl::internal::type_identity<T>::type* arg);
// Templated version for invoking a method that returns a `bool`.
//
// `Condition(object, &Class::Method)` constructs a `Condition` that evaluates
// `object->Method()`.
//
- // Implementation Note: `absl::internal::identity` is used to allow methods to
- // come from base classes. A simpler signature like
+ // Implementation Note: `absl::internal::type_identity` is used to allow
+ // methods to come from base classes. A simpler signature like
// `Condition(T*, bool (T::*)())` does not suffice.
template <typename T>
- Condition(T* object, bool (absl::internal::identity<T>::type::*method)());
+ Condition(T* object,
+ bool (absl::internal::type_identity<T>::type::*method)());
// Same as above, for const members
template <typename T>
Condition(const T* object,
- bool (absl::internal::identity<T>::type::*method)() const);
+ bool (absl::internal::type_identity<T>::type::*method)() const);
// A Condition that returns the value of `*cond`
explicit Condition(const bool* cond);
@@ -816,7 +850,7 @@ class Condition {
static bool CallVoidPtrFunction(const Condition*);
template <typename T>
static bool CastAndCallFunction(const Condition* c);
- template <typename T>
+ template <typename T, typename ConditionMethodPtr>
static bool CastAndCallMethod(const Condition* c);
// Helper methods for storing, validating, and reading callback arguments.
@@ -833,8 +867,10 @@ class Condition {
std::memcpy(callback, callback_, sizeof(*callback));
}
+ static bool AlwaysTrue(const Condition*) { return true; }
+
// Used only to create kTrue.
- constexpr Condition() = default;
+ constexpr Condition() : eval_(AlwaysTrue), arg_(nullptr) {}
};
// -----------------------------------------------------------------------------
@@ -877,7 +913,6 @@ class CondVar {
// A `CondVar` allocated on the heap or on the stack can use the this
// constructor.
CondVar();
- ~CondVar();
// CondVar::Wait()
//
@@ -886,7 +921,9 @@ class CondVar {
// spurious wakeup), then reacquires the `Mutex` and returns.
//
// Requires and ensures that the current thread holds the `Mutex`.
- void Wait(Mutex* mu);
+ void Wait(Mutex* mu) {
+ WaitCommon(mu, synchronization_internal::KernelTimeout::Never());
+ }
// CondVar::WaitWithTimeout()
//
@@ -901,7 +938,9 @@ class CondVar {
// to return `true` or `false`.
//
// Requires and ensures that the current thread holds the `Mutex`.
- bool WaitWithTimeout(Mutex* mu, absl::Duration timeout);
+ bool WaitWithTimeout(Mutex* mu, absl::Duration timeout) {
+ return WaitCommon(mu, synchronization_internal::KernelTimeout(timeout));
+ }
// CondVar::WaitWithDeadline()
//
@@ -918,7 +957,9 @@ class CondVar {
// to return `true` or `false`.
//
// Requires and ensures that the current thread holds the `Mutex`.
- bool WaitWithDeadline(Mutex* mu, absl::Time deadline);
+ bool WaitWithDeadline(Mutex* mu, absl::Time deadline) {
+ return WaitCommon(mu, synchronization_internal::KernelTimeout(deadline));
+ }
// CondVar::Signal()
//
@@ -940,7 +981,6 @@ class CondVar {
private:
bool WaitCommon(Mutex* mutex, synchronization_internal::KernelTimeout t);
void Remove(base_internal::PerThreadSynch* s);
- void Wakeup(base_internal::PerThreadSynch* w);
std::atomic<intptr_t> cv_; // Condition variable state.
CondVar(const CondVar&) = delete;
CondVar& operator=(const CondVar&) = delete;
@@ -1024,15 +1064,30 @@ inline Mutex::Mutex() : mu_(0) {
inline constexpr Mutex::Mutex(absl::ConstInitType) : mu_(0) {}
+#if !defined(__APPLE__) && !defined(ABSL_BUILD_DLL)
+ABSL_ATTRIBUTE_ALWAYS_INLINE
+inline Mutex::~Mutex() { Dtor(); }
+#endif
+
+#if defined(NDEBUG) && !defined(ABSL_HAVE_THREAD_SANITIZER)
+// Use default (empty) destructor in release build for performance reasons.
+// We need to mark both Dtor and ~Mutex as always inline for inconsistent
+// builds that use both NDEBUG and !NDEBUG with dynamic libraries. In these
+// cases we want the empty functions to dissolve entirely rather than being
+// exported from dynamic libraries and potentially override the non-empty ones.
+ABSL_ATTRIBUTE_ALWAYS_INLINE
+inline void Mutex::Dtor() {}
+#endif
+
inline CondVar::CondVar() : cv_(0) {}
// static
-template <typename T>
+template <typename T, typename ConditionMethodPtr>
bool Condition::CastAndCallMethod(const Condition* c) {
T* object = static_cast<T*>(c->arg_);
- bool (T::*method_pointer)();
- c->ReadCallback(&method_pointer);
- return (object->*method_pointer)();
+ ConditionMethodPtr condition_method_pointer;
+ c->ReadCallback(&condition_method_pointer);
+ return (object->*condition_method_pointer)();
}
// static
@@ -1054,25 +1109,25 @@ inline Condition::Condition(bool (*func)(T*), T* arg)
}
template <typename T, typename>
-inline Condition::Condition(bool (*func)(T*),
- typename absl::internal::identity<T>::type* arg)
+inline Condition::Condition(
+ bool (*func)(T*), typename absl::internal::type_identity<T>::type* arg)
// Just delegate to the overload above.
: Condition(func, arg) {}
template <typename T>
-inline Condition::Condition(T* object,
- bool (absl::internal::identity<T>::type::*method)())
- : eval_(&CastAndCallMethod<T>), arg_(object) {
+inline Condition::Condition(
+ T* object, bool (absl::internal::type_identity<T>::type::*method)())
+ : eval_(&CastAndCallMethod<T, decltype(method)>), arg_(object) {
static_assert(sizeof(&method) <= sizeof(callback_),
"An overlarge method pointer was passed to Condition.");
StoreCallback(method);
}
template <typename T>
-inline Condition::Condition(const T* object,
- bool (absl::internal::identity<T>::type::*method)()
- const)
- : eval_(&CastAndCallMethod<T>),
+inline Condition::Condition(
+ const T* object,
+ bool (absl::internal::type_identity<T>::type::*method)() const)
+ : eval_(&CastAndCallMethod<const T, decltype(method)>),
arg_(reinterpret_cast<void*>(const_cast<T*>(object))) {
StoreCallback(method);
}
diff --git a/contrib/restricted/abseil-cpp/absl/time/civil_time.h b/contrib/restricted/abseil-cpp/absl/time/civil_time.h
index 5855bc73a1..3e904a113d 100644
--- a/contrib/restricted/abseil-cpp/absl/time/civil_time.h
+++ b/contrib/restricted/abseil-cpp/absl/time/civil_time.h
@@ -462,6 +462,32 @@ std::string FormatCivilTime(CivilDay c);
std::string FormatCivilTime(CivilMonth c);
std::string FormatCivilTime(CivilYear c);
+// Support for StrFormat(), StrCat(), etc
+template <typename Sink>
+void AbslStringify(Sink& sink, CivilSecond c) {
+ sink.Append(FormatCivilTime(c));
+}
+template <typename Sink>
+void AbslStringify(Sink& sink, CivilMinute c) {
+ sink.Append(FormatCivilTime(c));
+}
+template <typename Sink>
+void AbslStringify(Sink& sink, CivilHour c) {
+ sink.Append(FormatCivilTime(c));
+}
+template <typename Sink>
+void AbslStringify(Sink& sink, CivilDay c) {
+ sink.Append(FormatCivilTime(c));
+}
+template <typename Sink>
+void AbslStringify(Sink& sink, CivilMonth c) {
+ sink.Append(FormatCivilTime(c));
+}
+template <typename Sink>
+void AbslStringify(Sink& sink, CivilYear c) {
+ sink.Append(FormatCivilTime(c));
+}
+
// absl::ParseCivilTime()
//
// Parses a civil-time value from the specified `absl::string_view` into the
diff --git a/contrib/restricted/abseil-cpp/absl/time/clock.h b/contrib/restricted/abseil-cpp/absl/time/clock.h
index 5fe244d638..41d2cf2770 100644
--- a/contrib/restricted/abseil-cpp/absl/time/clock.h
+++ b/contrib/restricted/abseil-cpp/absl/time/clock.h
@@ -22,6 +22,9 @@
#ifndef ABSL_TIME_CLOCK_H_
#define ABSL_TIME_CLOCK_H_
+#include <cstdint>
+
+#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/time/time.h"
@@ -64,7 +67,8 @@ ABSL_NAMESPACE_END
// By changing our extension points to be extern "C", we dodge this
// check.
extern "C" {
-void ABSL_INTERNAL_C_SYMBOL(AbslInternalSleepFor)(absl::Duration duration);
+ABSL_DLL void ABSL_INTERNAL_C_SYMBOL(AbslInternalSleepFor)(
+ absl::Duration duration);
} // extern "C"
inline void absl::SleepFor(absl::Duration duration) {
diff --git a/contrib/restricted/abseil-cpp/absl/time/duration.cc b/contrib/restricted/abseil-cpp/absl/time/duration.cc
index 634e5d5845..bdb16e2109 100644
--- a/contrib/restricted/abseil-cpp/absl/time/duration.cc
+++ b/contrib/restricted/abseil-cpp/absl/time/duration.cc
@@ -55,8 +55,7 @@
#include <algorithm>
#include <cassert>
-#include <cctype>
-#include <cerrno>
+#include <chrono> // NOLINT(build/c++11)
#include <cmath>
#include <cstdint>
#include <cstdlib>
@@ -66,8 +65,9 @@
#include <limits>
#include <string>
+#include "absl/base/attributes.h"
#include "absl/base/casts.h"
-#include "absl/base/macros.h"
+#include "absl/base/config.h"
#include "absl/numeric/int128.h"
#include "absl/strings/string_view.h"
#include "absl/strings/strip.h"
diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h
index a5b084e6be..2b0aed56c3 100644
--- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h
+++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h
@@ -401,11 +401,11 @@ class civil_time {
: civil_time(ct.f_) {}
// Factories for the maximum/minimum representable civil_time.
- static CONSTEXPR_F civil_time(max)() {
+ static CONSTEXPR_F auto(max)() -> civil_time {
const auto max_year = (std::numeric_limits<std::int_least64_t>::max)();
return civil_time(max_year, 12, 31, 23, 59, 59);
}
- static CONSTEXPR_F civil_time(min)() {
+ static CONSTEXPR_F auto(min)() -> civil_time {
const auto min_year = (std::numeric_limits<std::int_least64_t>::min)();
return civil_time(min_year, 1, 1, 0, 0, 0);
}
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 9b91f61cf0..e7e30a2fb7 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
@@ -19,7 +19,7 @@
#endif
#if defined(HAS_STRPTIME) && HAS_STRPTIME
-#if !defined(_XOPEN_SOURCE) && !defined(__OpenBSD__)
+#if !defined(_XOPEN_SOURCE) && !defined(__FreeBSD__) && !defined(__OpenBSD__)
#define _XOPEN_SOURCE 500 // Exposes definitions for SUSv2 (UNIX 98).
#endif
#endif
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 f46198ffaa..b7178a6b67 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
@@ -474,7 +474,8 @@ std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open(
const std::size_t pos = (name.compare(0, 5, "file:") == 0) ? 5 : 0;
// See Android's libc/tzcode/bionic.cpp for additional information.
- for (const char* tzdata : {"/data/misc/zoneinfo/current/tzdata",
+ for (const char* tzdata : {"/apex/com.android.tzdata/etc/tz/tzdata",
+ "/data/misc/zoneinfo/current/tzdata",
"/system/usr/share/zoneinfo/tzdata"}) {
auto fp = FOpen(tzdata, "rb");
if (fp == nullptr) continue;
@@ -539,9 +540,16 @@ std::unique_ptr<ZoneInfoSource> FuchsiaZoneInfoSource::Open(
// Prefixes where a Fuchsia component might find zoneinfo files,
// in descending order of preference.
const auto kTzdataPrefixes = {
+ // The tzdata from `config-data`.
"/config/data/tzdata/",
+ // The tzdata bundled in the component's package.
"/pkg/data/tzdata/",
+ // General data storage.
"/data/tzdata/",
+ // The recommended path for routed-in tzdata files.
+ // See for details:
+ // https://fuchsia.dev/fuchsia-src/concepts/process/namespaces?hl=en#typical_directory_structure
+ "/config/tzdata/",
};
const auto kEmptyPrefix = {""};
const bool name_absolute = (pos != name.size() && name[pos] == '/');
@@ -744,19 +752,6 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) {
version_ = zip->Version();
}
- // Trim redundant transitions. zic may have added these to work around
- // differences between the glibc and reference implementations (see
- // zic.c:dontmerge) or to avoid bugs in old readers. For us, they just
- // get in the way when we do future_spec_ extension.
- while (hdr.timecnt > 1) {
- if (!EquivTransitions(transitions_[hdr.timecnt - 1].type_index,
- transitions_[hdr.timecnt - 2].type_index)) {
- break;
- }
- hdr.timecnt -= 1;
- }
- transitions_.resize(hdr.timecnt);
-
// Ensure that there is always a transition in the first half of the
// time line (the second half is handled below) so that the signed
// difference between a civil_second and the civil_second of its
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 9613055db7..114026d066 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
@@ -21,14 +21,6 @@
** Information about time zone files.
*/
-#ifndef TZDIR
-#define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */
-#endif /* !defined TZDIR */
-
-#ifndef TZDEFAULT
-#define TZDEFAULT "/etc/localtime"
-#endif /* !defined TZDEFAULT */
-
#ifndef TZDEFRULES
#define TZDEFRULES "posixrules"
#endif /* !defined TZDEFRULES */
diff --git a/contrib/restricted/abseil-cpp/absl/types/bad_any_cast.cc b/contrib/restricted/abseil-cpp/absl/types/bad_any_cast.cc
index b0592cc9bc..22558b48c2 100644
--- a/contrib/restricted/abseil-cpp/absl/types/bad_any_cast.cc
+++ b/contrib/restricted/abseil-cpp/absl/types/bad_any_cast.cc
@@ -43,4 +43,22 @@ void ThrowBadAnyCast() {
ABSL_NAMESPACE_END
} // namespace absl
+#else
+
+// https://github.com/abseil/abseil-cpp/issues/1465
+// CMake builds on Apple platforms error when libraries are empty.
+// Our CMake configuration can avoid this error on header-only libraries,
+// but since this library is conditionally empty, including a single
+// variable is an easy workaround.
+#ifdef __APPLE__
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace types_internal {
+extern const char kAvoidEmptyBadAnyCastLibraryWarning;
+const char kAvoidEmptyBadAnyCastLibraryWarning = 0;
+} // namespace types_internal
+ABSL_NAMESPACE_END
+} // namespace absl
+#endif // __APPLE__
+
#endif // ABSL_USES_STD_ANY
diff --git a/contrib/restricted/abseil-cpp/absl/types/bad_optional_access.cc b/contrib/restricted/abseil-cpp/absl/types/bad_optional_access.cc
index 26aca70d9c..2552cc853a 100644
--- a/contrib/restricted/abseil-cpp/absl/types/bad_optional_access.cc
+++ b/contrib/restricted/abseil-cpp/absl/types/bad_optional_access.cc
@@ -45,4 +45,22 @@ void throw_bad_optional_access() {
ABSL_NAMESPACE_END
} // namespace absl
+#else
+
+// https://github.com/abseil/abseil-cpp/issues/1465
+// CMake builds on Apple platforms error when libraries are empty.
+// Our CMake configuration can avoid this error on header-only libraries,
+// but since this library is conditionally empty, including a single
+// variable is an easy workaround.
+#ifdef __APPLE__
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace types_internal {
+extern const char kAvoidEmptyBadOptionalAccessLibraryWarning;
+const char kAvoidEmptyBadOptionalAccessLibraryWarning = 0;
+} // namespace types_internal
+ABSL_NAMESPACE_END
+} // namespace absl
+#endif // __APPLE__
+
#endif // ABSL_USES_STD_OPTIONAL
diff --git a/contrib/restricted/abseil-cpp/absl/types/bad_variant_access.cc b/contrib/restricted/abseil-cpp/absl/types/bad_variant_access.cc
index 3dc88cc09f..a76aa80dfa 100644
--- a/contrib/restricted/abseil-cpp/absl/types/bad_variant_access.cc
+++ b/contrib/restricted/abseil-cpp/absl/types/bad_variant_access.cc
@@ -61,4 +61,22 @@ void Rethrow() {
ABSL_NAMESPACE_END
} // namespace absl
+#else
+
+// https://github.com/abseil/abseil-cpp/issues/1465
+// CMake builds on Apple platforms error when libraries are empty.
+// Our CMake configuration can avoid this error on header-only libraries,
+// but since this library is conditionally empty, including a single
+// variable is an easy workaround.
+#ifdef __APPLE__
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace types_internal {
+extern const char kAvoidEmptyBadVariantAccessLibraryWarning;
+const char kAvoidEmptyBadVariantAccessLibraryWarning = 0;
+} // namespace types_internal
+ABSL_NAMESPACE_END
+} // namespace absl
+#endif // __APPLE__
+
#endif // ABSL_USES_STD_VARIANT
diff --git a/contrib/restricted/abseil-cpp/absl/types/internal/variant.h b/contrib/restricted/abseil-cpp/absl/types/internal/variant.h
index fc8829e5d8..263d7b0947 100644
--- a/contrib/restricted/abseil-cpp/absl/types/internal/variant.h
+++ b/contrib/restricted/abseil-cpp/absl/types/internal/variant.h
@@ -1047,11 +1047,11 @@ class VariantStateBase {
std::size_t index_;
};
-using absl::internal::identity;
+using absl::internal::type_identity;
// OverloadSet::Overload() is a unary function which is overloaded to
// take any of the element types of the variant, by reference-to-const.
-// The return type of the overload on T is identity<T>, so that you
+// The return type of the overload on T is type_identity<T>, so that you
// can statically determine which overload was called.
//
// Overload() is not defined, so it can only be called in unevaluated
@@ -1062,7 +1062,7 @@ struct OverloadSet;
template <typename T, typename... Ts>
struct OverloadSet<T, Ts...> : OverloadSet<Ts...> {
using Base = OverloadSet<Ts...>;
- static identity<T> Overload(const T&);
+ static type_identity<T> Overload(const T&);
using Base::Overload;
};
diff --git a/contrib/restricted/abseil-cpp/absl/types/optional.h b/contrib/restricted/abseil-cpp/absl/types/optional.h
index 0a8080dc1a..395fe62f29 100644
--- a/contrib/restricted/abseil-cpp/absl/types/optional.h
+++ b/contrib/restricted/abseil-cpp/absl/types/optional.h
@@ -61,6 +61,7 @@ ABSL_NAMESPACE_END
#include <utility>
#include "absl/base/attributes.h"
+#include "absl/base/nullability.h"
#include "absl/base/internal/inline_variable.h"
#include "absl/meta/type_traits.h"
#include "absl/types/bad_optional_access.h"
@@ -415,11 +416,11 @@ class optional : private optional_internal::optional_data<T>,
// `optional` is empty, behavior is undefined.
//
// If you need myOpt->foo in constexpr, use (*myOpt).foo instead.
- const T* operator->() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ absl::Nonnull<const T*> operator->() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
ABSL_HARDENING_ASSERT(this->engaged_);
return std::addressof(this->data_);
}
- T* operator->() ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ absl::Nonnull<T*> operator->() ABSL_ATTRIBUTE_LIFETIME_BOUND {
ABSL_HARDENING_ASSERT(this->engaged_);
return std::addressof(this->data_);
}
diff --git a/contrib/restricted/abseil-cpp/absl/types/span.h b/contrib/restricted/abseil-cpp/absl/types/span.h
index 70ed8eb6fa..88cd759540 100644
--- a/contrib/restricted/abseil-cpp/absl/types/span.h
+++ b/contrib/restricted/abseil-cpp/absl/types/span.h
@@ -63,6 +63,7 @@
#include "absl/base/attributes.h"
#include "absl/base/internal/throw_delegate.h"
#include "absl/base/macros.h"
+#include "absl/base/nullability.h"
#include "absl/base/optimization.h"
#include "absl/base/port.h" // TODO(strel): remove this include
#include "absl/meta/type_traits.h"
@@ -172,6 +173,8 @@ class Span {
public:
using element_type = T;
using value_type = absl::remove_cv_t<T>;
+ // TODO(b/316099902) - pointer should be Nullable<T*>, but this makes it hard
+ // to recognize foreach loops as safe.
using pointer = T*;
using const_pointer = const T*;
using reference = T&;
@@ -679,12 +682,12 @@ bool operator>=(Span<T> a, const U& b) {
// }
//
template <int&... ExplicitArgumentBarrier, typename T>
-constexpr Span<T> MakeSpan(T* ptr, size_t size) noexcept {
+constexpr Span<T> MakeSpan(absl::Nullable<T*> ptr, size_t size) noexcept {
return Span<T>(ptr, size);
}
template <int&... ExplicitArgumentBarrier, typename T>
-Span<T> MakeSpan(T* begin, T* end) noexcept {
+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));
}
@@ -725,12 +728,14 @@ constexpr Span<T> MakeSpan(T (&array)[N]) noexcept {
// ProcessInts(absl::MakeConstSpan(std::vector<int>{ 0, 0, 0 }));
//
template <int&... ExplicitArgumentBarrier, typename T>
-constexpr Span<const T> MakeConstSpan(T* ptr, size_t size) noexcept {
+constexpr Span<const T> MakeConstSpan(absl::Nullable<T*> ptr,
+ size_t size) noexcept {
return Span<const T>(ptr, size);
}
template <int&... ExplicitArgumentBarrier, typename T>
-Span<const T> MakeConstSpan(T* begin, T* end) noexcept {
+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);
}
diff --git a/contrib/restricted/abseil-cpp/absl/utility/utility.h b/contrib/restricted/abseil-cpp/absl/utility/utility.h
index bf9232209a..fc0d1f6551 100644
--- a/contrib/restricted/abseil-cpp/absl/utility/utility.h
+++ b/contrib/restricted/abseil-cpp/absl/utility/utility.h
@@ -12,17 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
-// This header file contains C++11 versions of standard <utility> header
-// abstractions available within C++14 and C++17, and are designed to be drop-in
+// This header file contains C++14 versions of standard <utility> header
+// abstractions available within C++17, and are designed to be drop-in
// replacement for code compliant with C++14 and C++17.
//
// The following abstractions are defined:
//
-// * integer_sequence<T, Ints...> == std::integer_sequence<T, Ints...>
-// * index_sequence<Ints...> == std::index_sequence<Ints...>
-// * make_integer_sequence<T, N> == std::make_integer_sequence<T, N>
-// * make_index_sequence<N> == std::make_index_sequence<N>
-// * index_sequence_for<Ts...> == std::index_sequence_for<Ts...>
// * apply<Functor, Tuple> == std::apply<Functor, Tuple>
// * exchange<T> == std::exchange<T>
// * make_from_tuple<T> == std::make_from_tuple<T>
@@ -33,7 +28,6 @@
//
// References:
//
-// https://en.cppreference.com/w/cpp/utility/integer_sequence
// https://en.cppreference.com/w/cpp/utility/apply
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3658.html
@@ -53,68 +47,18 @@
namespace absl {
ABSL_NAMESPACE_BEGIN
-// integer_sequence
-//
-// Class template representing a compile-time integer sequence. An instantiation
-// of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
-// type through its template arguments (which is a common need when
-// working with C++11 variadic templates). `absl::integer_sequence` is designed
-// to be a drop-in replacement for C++14's `std::integer_sequence`.
-//
-// Example:
-//
-// template< class T, T... Ints >
-// void user_function(integer_sequence<T, Ints...>);
-//
-// int main()
-// {
-// // user_function's `T` will be deduced to `int` and `Ints...`
-// // will be deduced to `0, 1, 2, 3, 4`.
-// user_function(make_integer_sequence<int, 5>());
-// }
-template <typename T, T... Ints>
-struct integer_sequence {
- using value_type = T;
- static constexpr size_t size() noexcept { return sizeof...(Ints); }
-};
-
-// index_sequence
-//
-// A helper template for an `integer_sequence` of `size_t`,
-// `absl::index_sequence` is designed to be a drop-in replacement for C++14's
-// `std::index_sequence`.
-template <size_t... Ints>
-using index_sequence = integer_sequence<size_t, Ints...>;
+// Historical note: Abseil once provided implementations of these
+// abstractions for platforms that had not yet provided them. Those
+// platforms are no longer supported. New code should simply use the
+// the ones from std directly.
+using std::index_sequence;
+using std::index_sequence_for;
+using std::integer_sequence;
+using std::make_index_sequence;
+using std::make_integer_sequence;
namespace utility_internal {
-template <typename Seq, size_t SeqSize, size_t Rem>
-struct Extend;
-
-// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
-template <typename T, T... Ints, size_t SeqSize>
-struct Extend<integer_sequence<T, Ints...>, SeqSize, 0> {
- using type = integer_sequence<T, Ints..., (Ints + SeqSize)...>;
-};
-
-template <typename T, T... Ints, size_t SeqSize>
-struct Extend<integer_sequence<T, Ints...>, SeqSize, 1> {
- using type = integer_sequence<T, Ints..., (Ints + SeqSize)..., 2 * SeqSize>;
-};
-
-// Recursion helper for 'make_integer_sequence<T, N>'.
-// 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
-template <typename T, size_t N>
-struct Gen {
- using type =
- typename Extend<typename Gen<T, N / 2>::type, N / 2, N % 2>::type;
-};
-
-template <typename T>
-struct Gen<T, 0> {
- using type = integer_sequence<T>;
-};
-
template <typename T>
struct InPlaceTypeTag {
explicit InPlaceTypeTag() = delete;
@@ -131,32 +75,6 @@ struct InPlaceIndexTag {
} // namespace utility_internal
-// Compile-time sequences of integers
-
-// make_integer_sequence
-//
-// This template alias is equivalent to
-// `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
-// replacement for C++14's `std::make_integer_sequence`.
-template <typename T, T N>
-using make_integer_sequence = typename utility_internal::Gen<T, N>::type;
-
-// make_index_sequence
-//
-// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
-// and is designed to be a drop-in replacement for C++14's
-// `std::make_index_sequence`.
-template <size_t N>
-using make_index_sequence = make_integer_sequence<size_t, N>;
-
-// index_sequence_for
-//
-// Converts a typename pack into an index sequence of the same length, and
-// is designed to be a drop-in replacement for C++14's
-// `std::index_sequence_for()`
-template <typename... Ts>
-using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
-
// Tag types
#ifdef ABSL_USES_STD_OPTIONAL
diff --git a/contrib/restricted/abseil-cpp/absl/utility/ya.make b/contrib/restricted/abseil-cpp/absl/utility/ya.make
index 3b66e3e400..3f9af85fe6 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(20230802.1)
+VERSION(20240116.0)
-ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20230802.1.tar.gz)
+ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20240116.0.tar.gz)
NO_RUNTIME()
diff --git a/contrib/restricted/abseil-cpp/ya.make b/contrib/restricted/abseil-cpp/ya.make
index c89fe4570a..36452ac10e 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(20230802.1)
+VERSION(20240116.0)
-ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20230802.1.tar.gz)
+ORIGINAL_SOURCE(https://github.com/abseil/abseil-cpp/archive/20240116.0.tar.gz)
PEERDIR(
contrib/restricted/abseil-cpp/absl/algorithm
diff --git a/contrib/restricted/boost/assert/include/boost/assert/source_location.hpp b/contrib/restricted/boost/assert/include/boost/assert/source_location.hpp
index 82e2d37854..2349ed8a2f 100644
--- a/contrib/restricted/boost/assert/include/boost/assert/source_location.hpp
+++ b/contrib/restricted/boost/assert/include/boost/assert/source_location.hpp
@@ -15,7 +15,7 @@
#include <cstring>
#if defined(__cpp_lib_source_location) && __cpp_lib_source_location >= 201907L
-# error #include <source_location>
+#include <source_location>
#endif
namespace boost
diff --git a/library/cpp/lcs/lcs_via_lis_ut.cpp b/library/cpp/lcs/lcs_via_lis_ut.cpp
index f6ad5152b6..0029a7c5b9 100644
--- a/library/cpp/lcs/lcs_via_lis_ut.cpp
+++ b/library/cpp/lcs/lcs_via_lis_ut.cpp
@@ -39,7 +39,7 @@ private:
void CheckLCSString(TStringBuf s1, TStringBuf s2, TStringBuf reflcs) {
TString lcs;
size_t len = NLCS::MakeLCS<char>(s1, s2, &lcs);
- const char* comment = Sprintf("%s & %s = %s", s1.data(), s2.data(), reflcs.data()).c_str();
+ const TString comment = Sprintf("%s & %s = %s", s1.data(), s2.data(), reflcs.data());
UNIT_ASSERT_VALUES_EQUAL_C(Length(s1, s2), len, comment);
UNIT_ASSERT_VALUES_EQUAL_C(lcs.size(), len, comment);
diff --git a/library/cpp/tld/tlds-alpha-by-domain.txt b/library/cpp/tld/tlds-alpha-by-domain.txt
index a85eba8c8b..76fbd16e7b 100644
--- a/library/cpp/tld/tlds-alpha-by-domain.txt
+++ b/library/cpp/tld/tlds-alpha-by-domain.txt
@@ -1,4 +1,4 @@
-# Version 2024012300, Last Updated Tue Jan 23 07:07:01 2024 UTC
+# Version 2024012400, Last Updated Wed Jan 24 07:07:01 2024 UTC
AAA
AARP
ABB
diff --git a/library/cpp/yt/misc/enum.h b/library/cpp/yt/misc/enum.h
index 1494ca7907..9da79b9fd3 100644
--- a/library/cpp/yt/misc/enum.h
+++ b/library/cpp/yt/misc/enum.h
@@ -185,6 +185,7 @@ struct TEnumTraits<T, true>
////////////////////////////////////////////////////////////////////////////////
+// TODO(babenko): drop in favor of TEnumIndexedArray
//! A statically sized vector with elements of type |T| indexed by
//! the items of enumeration type |E|.
/*!
diff --git a/library/cpp/yt/misc/enum_indexed_array-inl.h b/library/cpp/yt/misc/enum_indexed_array-inl.h
new file mode 100644
index 0000000000..edda891683
--- /dev/null
+++ b/library/cpp/yt/misc/enum_indexed_array-inl.h
@@ -0,0 +1,73 @@
+#pragma once
+#ifndef ENUM_INDEXED_ARRAY_INL_H_
+#error "Direct inclusion of this file is not allowed, include enum.h"
+// For the sake of sane code completion.
+#include "enum_indexed_array.h"
+#endif
+
+#include <library/cpp/yt/assert/assert.h>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class E, class T, E Min, E Max>
+TEnumIndexedArray<E, T, Min, Max>::TEnumIndexedArray(std::initializer_list<std::pair<E, T>> elements)
+{
+ for (const auto& [index, value] : elements) {
+ (*this)[index] = value;
+ }
+}
+
+template <class E, class T, E Min, E Max>
+T& TEnumIndexedArray<E, T, Min, Max>::operator[] (E index)
+{
+ YT_ASSERT(IsValidIndex(index));
+ return Items_[ToUnderlying(index) - ToUnderlying(Min)];
+}
+
+template <class E, class T, E Min, E Max>
+const T& TEnumIndexedArray<E, T, Min, Max>::operator[] (E index) const
+{
+ return const_cast<TEnumIndexedArray&>(*this)[index];
+}
+
+template <class E, class T, E Min, E Max>
+T* TEnumIndexedArray<E, T, Min, Max>::begin()
+{
+ return Items_.data();
+}
+
+template <class E, class T, E Min, E Max>
+const T* TEnumIndexedArray<E, T, Min, Max>::begin() const
+{
+ return Items_.data();
+}
+
+template <class E, class T, E Min, E Max>
+T* TEnumIndexedArray<E, T, Min, Max>::end()
+{
+ return begin() + Size;
+}
+
+template <class E, class T, E Min, E Max>
+const T* TEnumIndexedArray<E, T, Min, Max>::end() const
+{
+ return begin() + Size;
+}
+
+template <class E, class T, E Min, E Max>
+constexpr size_t TEnumIndexedArray<E, T, Min, Max>::size() const
+{
+ return Size;
+}
+
+template <class E, class T, E Min, E Max>
+bool TEnumIndexedArray<E, T, Min, Max>::IsValidIndex(E index)
+{
+ return index >= Min && index <= Max;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/misc/enum_indexed_array.h b/library/cpp/yt/misc/enum_indexed_array.h
new file mode 100644
index 0000000000..8992456277
--- /dev/null
+++ b/library/cpp/yt/misc/enum_indexed_array.h
@@ -0,0 +1,64 @@
+#pragma once
+
+#include "enum.h"
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+//! A statically sized vector with elements of type |T| indexed by
+//! the items of enumeration type |E|.
+/*!
+ * By default, valid indexes are in range from the minimum declared value of |E|
+ * to the maximum declared value of |E|.
+ *
+ * Items are value-initialized on construction.
+ */
+template <
+ class E,
+ class T,
+ E Min = TEnumTraits<E>::GetMinValue(),
+ E Max = TEnumTraits<E>::GetMaxValue()
+>
+class TEnumIndexedArray
+{
+public:
+ static_assert(Min <= Max);
+
+ using TIndex = E;
+ using TValue = T;
+
+ constexpr TEnumIndexedArray() = default;
+ TEnumIndexedArray(std::initializer_list<std::pair<E, T>> elements);
+
+ constexpr TEnumIndexedArray(const TEnumIndexedArray&) = default;
+ constexpr TEnumIndexedArray(TEnumIndexedArray&&) = default;
+
+ constexpr TEnumIndexedArray& operator=(const TEnumIndexedArray&) = default;
+ constexpr TEnumIndexedArray& operator=(TEnumIndexedArray&&) = default;
+
+ T& operator[] (E index);
+ const T& operator[] (E index) const;
+
+ // STL interop.
+ T* begin();
+ const T* begin() const;
+ T* end();
+ const T* end() const;
+
+ constexpr size_t size() const;
+
+ static bool IsValidIndex(E index);
+
+private:
+ static constexpr size_t Size = static_cast<size_t>(Max) - static_cast<size_t>(Min) + 1;
+ std::array<T, Size> Items_{};
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
+
+#define ENUM_INDEXED_ARRAY_INL_H_
+#include "enum_indexed_array-inl.h"
+#undef ENUM_INDEXED_ARRAY_INL_H_
diff --git a/library/cpp/yt/misc/unittests/enum_indexed_array_ut.cpp b/library/cpp/yt/misc/unittests/enum_indexed_array_ut.cpp
new file mode 100644
index 0000000000..4111c6f4fe
--- /dev/null
+++ b/library/cpp/yt/misc/unittests/enum_indexed_array_ut.cpp
@@ -0,0 +1,45 @@
+#include <library/cpp/testing/gtest/gtest.h>
+
+#include <library/cpp/yt/misc/enum_indexed_array.h>
+
+namespace NYT {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+
+DEFINE_ENUM(EColor,
+ ((Red) (10))
+ ((Green)(20))
+ ((Blue) (30))
+);
+
+TEST(TEnumIndexedArrayTest, Size)
+{
+ TEnumIndexedArray<EColor, int> arr;
+ EXPECT_EQ(std::ssize(arr), 21);
+}
+
+TEST(TEnumIndexedArrayTest, IsValidIndex)
+{
+ TEnumIndexedArray<EColor, int> arr;
+ EXPECT_TRUE(arr.IsValidIndex(EColor::Red));
+ EXPECT_TRUE(arr.IsValidIndex(EColor::Green));
+ EXPECT_TRUE(arr.IsValidIndex(EColor::Blue));
+ EXPECT_TRUE(arr.IsValidIndex(static_cast<EColor>(11)));
+ EXPECT_FALSE(arr.IsValidIndex(static_cast<EColor>(9)));
+}
+
+TEST(TEnumIndexedArrayTest, Simple)
+{
+ TEnumIndexedArray<EColor, int> arr;
+ EXPECT_EQ(arr[EColor::Red], 0);
+ arr[EColor::Red] = 1;
+ EXPECT_EQ(arr[EColor::Red], 1);
+ EXPECT_EQ(arr[EColor::Blue], 0);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace
+} // namespace NYT
+
diff --git a/library/cpp/yt/misc/unittests/ya.make b/library/cpp/yt/misc/unittests/ya.make
index 611edd7217..43e9f9b9ff 100644
--- a/library/cpp/yt/misc/unittests/ya.make
+++ b/library/cpp/yt/misc/unittests/ya.make
@@ -4,6 +4,7 @@ INCLUDE(${ARCADIA_ROOT}/library/cpp/yt/ya_cpp.make.inc)
SRCS(
enum_ut.cpp
+ enum_indexed_array_ut.cpp
guid_ut.cpp
preprocessor_ut.cpp
strong_typedef_ut.cpp
diff --git a/library/cpp/yt/string/format-inl.h b/library/cpp/yt/string/format-inl.h
index c379af712a..c198fdcd65 100644
--- a/library/cpp/yt/string/format-inl.h
+++ b/library/cpp/yt/string/format-inl.h
@@ -12,6 +12,7 @@
#include <library/cpp/yt/small_containers/compact_vector.h>
#include <library/cpp/yt/misc/enum.h>
+#include <library/cpp/yt/misc/enum_indexed_array.h>
#include <util/system/platform.h>
@@ -393,6 +394,27 @@ struct TValueFormatter<THashMultiMap<K, V>>
}
};
+// TEnumIndexedArray
+template <class E, class T>
+struct TValueFormatter<TEnumIndexedArray<E, T>>
+{
+ static void Do(TStringBuilderBase* builder, const TEnumIndexedArray<E, T>& collection, TStringBuf format)
+ {
+ builder->AppendChar('{');
+ bool firstItem = true;
+ for (const auto& index : TEnumTraits<E>::GetDomainValues()) {
+ if (!firstItem) {
+ builder->AppendString(DefaultJoinToStringDelimiter);
+ }
+ FormatValue(builder, index, format);
+ builder->AppendString(": ");
+ FormatValue(builder, collection[index], format);
+ firstItem = false;
+ }
+ builder->AppendChar('}');
+ }
+};
+
// TEnumIndexedVector
template <class E, class T>
struct TValueFormatter<TEnumIndexedVector<E, T>>
diff --git a/library/cpp/yt/string/unittests/enum_ut.cpp b/library/cpp/yt/string/unittests/enum_ut.cpp
index 4059b3d2e6..91a8b04500 100644
--- a/library/cpp/yt/string/unittests/enum_ut.cpp
+++ b/library/cpp/yt/string/unittests/enum_ut.cpp
@@ -13,6 +13,7 @@ namespace {
// Some compile-time sanity checks.
DEFINE_ENUM(ESample, (One)(Two));
static_assert(TFormatTraits<ESample>::HasCustomFormatValue);
+static_assert(TFormatTraits<TEnumIndexedArray<ESample, int>>::HasCustomFormatValue);
static_assert(TFormatTraits<TEnumIndexedVector<ESample, int>>::HasCustomFormatValue);
DEFINE_ENUM(EColor,
diff --git a/library/cpp/ytalloc/api/fallback.cpp b/library/cpp/ytalloc/api/fallback.cpp
index d094cf2e93..d7dca33f88 100644
--- a/library/cpp/ytalloc/api/fallback.cpp
+++ b/library/cpp/ytalloc/api/fallback.cpp
@@ -144,47 +144,47 @@ Y_WEAK void SetEnableMadvisePopulate(bool /*value*/)
////////////////////////////////////////////////////////////////////////////////
-Y_WEAK TEnumIndexedVector<ETotalCounter, ssize_t> GetTotalAllocationCounters()
+Y_WEAK TEnumIndexedArray<ETotalCounter, ssize_t> GetTotalAllocationCounters()
{
return {};
}
-Y_WEAK TEnumIndexedVector<ESmallCounter, ssize_t> GetSmallAllocationCounters()
+Y_WEAK TEnumIndexedArray<ESmallCounter, ssize_t> GetSmallAllocationCounters()
{
return {};
}
-Y_WEAK TEnumIndexedVector<ELargeCounter, ssize_t> GetLargeAllocationCounters()
+Y_WEAK TEnumIndexedArray<ELargeCounter, ssize_t> GetLargeAllocationCounters()
{
return {};
}
-Y_WEAK std::array<TEnumIndexedVector<ESmallArenaCounter, ssize_t>, SmallRankCount> GetSmallArenaAllocationCounters()
+Y_WEAK std::array<TEnumIndexedArray<ESmallArenaCounter, ssize_t>, SmallRankCount> GetSmallArenaAllocationCounters()
{
return {};
}
-Y_WEAK std::array<TEnumIndexedVector<ELargeArenaCounter, ssize_t>, LargeRankCount> GetLargeArenaAllocationCounters()
+Y_WEAK std::array<TEnumIndexedArray<ELargeArenaCounter, ssize_t>, LargeRankCount> GetLargeArenaAllocationCounters()
{
return {};
}
-Y_WEAK TEnumIndexedVector<EHugeCounter, ssize_t> GetHugeAllocationCounters()
+Y_WEAK TEnumIndexedArray<EHugeCounter, ssize_t> GetHugeAllocationCounters()
{
return {};
}
-Y_WEAK TEnumIndexedVector<ESystemCounter, ssize_t> GetSystemAllocationCounters()
+Y_WEAK TEnumIndexedArray<ESystemCounter, ssize_t> GetSystemAllocationCounters()
{
return {};
}
-Y_WEAK TEnumIndexedVector<EUndumpableCounter, ssize_t> GetUndumpableAllocationCounters()
+Y_WEAK TEnumIndexedArray<EUndumpableCounter, ssize_t> GetUndumpableAllocationCounters()
{
return {};
}
-Y_WEAK TEnumIndexedVector<ETimingEventType, TTimingEventCounters> GetTimingEventCounters()
+Y_WEAK TEnumIndexedArray<ETimingEventType, TTimingEventCounters> GetTimingEventCounters()
{
return {};
}
diff --git a/library/cpp/ytalloc/api/ytalloc.h b/library/cpp/ytalloc/api/ytalloc.h
index 219814def2..43ba48852d 100644
--- a/library/cpp/ytalloc/api/ytalloc.h
+++ b/library/cpp/ytalloc/api/ytalloc.h
@@ -3,6 +3,7 @@
#include <stddef.h>
#include <library/cpp/yt/misc/enum.h>
+#include <library/cpp/yt/misc/enum_indexed_array.h>
#include <util/system/types.h>
@@ -289,28 +290,28 @@ DEFINE_ENUM(ETotalCounter,
);
// Returns statistics for all user allocations.
-TEnumIndexedVector<ETotalCounter, ssize_t> GetTotalAllocationCounters();
+TEnumIndexedArray<ETotalCounter, ssize_t> GetTotalAllocationCounters();
// Returns statistics for small allocations; these are included into total statistics.
-TEnumIndexedVector<ESmallCounter, ssize_t> GetSmallAllocationCounters();
+TEnumIndexedArray<ESmallCounter, ssize_t> GetSmallAllocationCounters();
// Returns statistics for large allocations; these are included into total statistics.
-TEnumIndexedVector<ELargeCounter, ssize_t> GetLargeAllocationCounters();
+TEnumIndexedArray<ELargeCounter, ssize_t> GetLargeAllocationCounters();
// Returns per-arena statistics for small allocations; these are included into total statistics.
-std::array<TEnumIndexedVector<ESmallArenaCounter, ssize_t>, SmallRankCount> GetSmallArenaAllocationCounters();
+std::array<TEnumIndexedArray<ESmallArenaCounter, ssize_t>, SmallRankCount> GetSmallArenaAllocationCounters();
// Returns per-arena statistics for large allocations; these are included into total statistics.
-std::array<TEnumIndexedVector<ELargeArenaCounter, ssize_t>, LargeRankCount> GetLargeArenaAllocationCounters();
+std::array<TEnumIndexedArray<ELargeArenaCounter, ssize_t>, LargeRankCount> GetLargeArenaAllocationCounters();
// Returns statistics for huge allocations; these are included into total statistics.
-TEnumIndexedVector<EHugeCounter, ssize_t> GetHugeAllocationCounters();
+TEnumIndexedArray<EHugeCounter, ssize_t> GetHugeAllocationCounters();
// Returns statistics for all system allocations; these are not included into total statistics.
-TEnumIndexedVector<ESystemCounter, ssize_t> GetSystemAllocationCounters();
+TEnumIndexedArray<ESystemCounter, ssize_t> GetSystemAllocationCounters();
// Returns statistics for undumpable allocations.
-TEnumIndexedVector<EUndumpableCounter, ssize_t> GetUndumpableAllocationCounters();
+TEnumIndexedArray<EUndumpableCounter, ssize_t> GetUndumpableAllocationCounters();
DEFINE_ENUM(ETimingEventType,
(Mmap)
@@ -333,7 +334,7 @@ struct TTimingEventCounters
// Returns statistics for timing events happened since start.
// See SetTimingEventThreshold.
-TEnumIndexedVector<ETimingEventType, TTimingEventCounters> GetTimingEventCounters();
+TEnumIndexedArray<ETimingEventType, TTimingEventCounters> GetTimingEventCounters();
////////////////////////////////////////////////////////////////////////////////
@@ -349,7 +350,7 @@ struct TBacktrace
struct TProfiledAllocation
{
TBacktrace Backtrace;
- TEnumIndexedVector<EBasicCounter, ssize_t> Counters;
+ TEnumIndexedArray<EBasicCounter, ssize_t> Counters;
};
// Returns statistics for profiled allocations (available when allocation
diff --git a/library/cpp/ytalloc/impl/core-inl.h b/library/cpp/ytalloc/impl/core-inl.h
index 64e95188f4..ba5128bd8d 100644
--- a/library/cpp/ytalloc/impl/core-inl.h
+++ b/library/cpp/ytalloc/impl/core-inl.h
@@ -940,14 +940,14 @@ class TTimingManager
: public TEventLogManagerBase<TTimingEvent, TTimingManager>
{
public:
- TEnumIndexedVector<ETimingEventType, TTimingEventCounters> GetTimingEventCounters()
+ TEnumIndexedArray<ETimingEventType, TTimingEventCounters> GetTimingEventCounters()
{
auto guard = Guard(EventLock_);
return EventCounters_;
}
private:
- TEnumIndexedVector<ETimingEventType, TTimingEventCounters> EventCounters_;
+ TEnumIndexedArray<ETimingEventType, TTimingEventCounters> EventCounters_;
Y_POD_STATIC_THREAD(bool) DisabledForCurrentThread_;
@@ -1523,13 +1523,13 @@ static_assert(
"Wrong MaxMemoryTag");
template <class TCounter>
-using TUntaggedTotalCounters = TEnumIndexedVector<EBasicCounter, TCounter>;
+using TUntaggedTotalCounters = TEnumIndexedArray<EBasicCounter, TCounter>;
template <class TCounter>
struct TTaggedTotalCounterSet
: public TSystemAllocatable
{
- std::array<TEnumIndexedVector<EBasicCounter, TCounter>, TaggedCounterSetSize> Counters;
+ std::array<TEnumIndexedArray<EBasicCounter, TCounter>, TaggedCounterSetSize> Counters;
};
using TLocalTaggedBasicCounterSet = TTaggedTotalCounterSet<ssize_t>;
@@ -1577,20 +1577,20 @@ struct TTotalCounters
}
};
-using TLocalSystemCounters = TEnumIndexedVector<ESystemCounter, ssize_t>;
-using TGlobalSystemCounters = TEnumIndexedVector<ESystemCounter, std::atomic<ssize_t>>;
+using TLocalSystemCounters = TEnumIndexedArray<ESystemCounter, ssize_t>;
+using TGlobalSystemCounters = TEnumIndexedArray<ESystemCounter, std::atomic<ssize_t>>;
-using TLocalSmallCounters = TEnumIndexedVector<ESmallArenaCounter, ssize_t>;
-using TGlobalSmallCounters = TEnumIndexedVector<ESmallArenaCounter, std::atomic<ssize_t>>;
+using TLocalSmallCounters = TEnumIndexedArray<ESmallArenaCounter, ssize_t>;
+using TGlobalSmallCounters = TEnumIndexedArray<ESmallArenaCounter, std::atomic<ssize_t>>;
-using TLocalLargeCounters = TEnumIndexedVector<ELargeArenaCounter, ssize_t>;
-using TGlobalLargeCounters = TEnumIndexedVector<ELargeArenaCounter, std::atomic<ssize_t>>;
+using TLocalLargeCounters = TEnumIndexedArray<ELargeArenaCounter, ssize_t>;
+using TGlobalLargeCounters = TEnumIndexedArray<ELargeArenaCounter, std::atomic<ssize_t>>;
-using TLocalHugeCounters = TEnumIndexedVector<EHugeCounter, ssize_t>;
-using TGlobalHugeCounters = TEnumIndexedVector<EHugeCounter, std::atomic<ssize_t>>;
+using TLocalHugeCounters = TEnumIndexedArray<EHugeCounter, ssize_t>;
+using TGlobalHugeCounters = TEnumIndexedArray<EHugeCounter, std::atomic<ssize_t>>;
-using TLocalUndumpableCounters = TEnumIndexedVector<EUndumpableCounter, ssize_t>;
-using TGlobalUndumpableCounters = TEnumIndexedVector<EUndumpableCounter, std::atomic<ssize_t>>;
+using TLocalUndumpableCounters = TEnumIndexedArray<EUndumpableCounter, ssize_t>;
+using TGlobalUndumpableCounters = TEnumIndexedArray<EUndumpableCounter, std::atomic<ssize_t>>;
Y_FORCE_INLINE ssize_t LoadCounter(ssize_t counter)
{
@@ -1750,7 +1750,7 @@ struct TThreadState
std::array<bool, SmallRankCount> CachedChunkFull{};
#endif
};
- TEnumIndexedVector<EAllocationKind, TSmallBlobCache> SmallBlobCache;
+ TEnumIndexedArray<EAllocationKind, TSmallBlobCache> SmallBlobCache;
};
struct TThreadStateToRegistryNode
@@ -2227,7 +2227,7 @@ public:
}
// Computes memory usage for a list of tags by aggregating counters across threads.
- void GetTaggedMemoryCounters(const TMemoryTag* tags, size_t count, TEnumIndexedVector<EBasicCounter, ssize_t>* counters)
+ void GetTaggedMemoryCounters(const TMemoryTag* tags, size_t count, TEnumIndexedArray<EBasicCounter, ssize_t>* counters)
{
TMemoryTagGuard guard(NullMemoryTag);
@@ -2260,7 +2260,7 @@ public:
{
TMemoryTagGuard guard(NullMemoryTag);
- std::vector<TEnumIndexedVector<EBasicCounter, ssize_t>> counters;
+ std::vector<TEnumIndexedArray<EBasicCounter, ssize_t>> counters;
counters.resize(count);
GetTaggedMemoryCounters(tags, count, counters.data());
@@ -2269,9 +2269,9 @@ public:
}
}
- TEnumIndexedVector<ETotalCounter, ssize_t> GetTotalAllocationCounters()
+ TEnumIndexedArray<ETotalCounter, ssize_t> GetTotalAllocationCounters()
{
- TEnumIndexedVector<ETotalCounter, ssize_t> result;
+ TEnumIndexedArray<ETotalCounter, ssize_t> result;
auto accumulate = [&] (const auto& counters) {
result[ETotalCounter::BytesAllocated] += LoadCounter(counters[EBasicCounter::BytesAllocated]);
@@ -2312,9 +2312,9 @@ public:
return result;
}
- TEnumIndexedVector<ESmallCounter, ssize_t> GetSmallAllocationCounters()
+ TEnumIndexedArray<ESmallCounter, ssize_t> GetSmallAllocationCounters()
{
- TEnumIndexedVector<ESmallCounter, ssize_t> result;
+ TEnumIndexedArray<ESmallCounter, ssize_t> result;
auto totalCounters = GetTotalAllocationCounters();
result[ESmallCounter::BytesAllocated] = totalCounters[ETotalCounter::BytesAllocated];
@@ -2347,9 +2347,9 @@ public:
return result;
}
- TEnumIndexedVector<ELargeCounter, ssize_t> GetLargeAllocationCounters()
+ TEnumIndexedArray<ELargeCounter, ssize_t> GetLargeAllocationCounters()
{
- TEnumIndexedVector<ELargeCounter, ssize_t> result;
+ TEnumIndexedArray<ELargeCounter, ssize_t> result;
auto largeArenaCounters = GetLargeArenaAllocationCounters();
for (size_t rank = 0; rank < LargeRankCount; ++rank) {
result[ESmallCounter::BytesAllocated] += largeArenaCounters[rank][ELargeArenaCounter::BytesAllocated];
@@ -2826,7 +2826,7 @@ private:
}
};
-TExplicitlyConstructableSingleton<TEnumIndexedVector<EAllocationKind, std::array<TExplicitlyConstructableSingleton<TSmallArenaAllocator>, SmallRankCount>>> SmallArenaAllocators;
+TExplicitlyConstructableSingleton<TEnumIndexedArray<EAllocationKind, std::array<TExplicitlyConstructableSingleton<TSmallArenaAllocator>, SmallRankCount>>> SmallArenaAllocators;
////////////////////////////////////////////////////////////////////////////////
@@ -3023,7 +3023,7 @@ private:
std::array<TShardedFreeList<TChunkGroup>, SmallRankCount> RankToChunkGroups_;
};
-TExplicitlyConstructableSingleton<TEnumIndexedVector<EAllocationKind, TExplicitlyConstructableSingleton<TGlobalSmallChunkCache>>> GlobalSmallChunkCaches;
+TExplicitlyConstructableSingleton<TEnumIndexedArray<EAllocationKind, TExplicitlyConstructableSingleton<TGlobalSmallChunkCache>>> GlobalSmallChunkCaches;
////////////////////////////////////////////////////////////////////////////////
@@ -4750,49 +4750,49 @@ void SetEnableMadvisePopulate(bool value)
ConfigurationManager->SetEnableMadvisePopulate(value);
}
-TEnumIndexedVector<ETotalCounter, ssize_t> GetTotalAllocationCounters()
+TEnumIndexedArray<ETotalCounter, ssize_t> GetTotalAllocationCounters()
{
InitializeGlobals();
return StatisticsManager->GetTotalAllocationCounters();
}
-TEnumIndexedVector<ESystemCounter, ssize_t> GetSystemAllocationCounters()
+TEnumIndexedArray<ESystemCounter, ssize_t> GetSystemAllocationCounters()
{
InitializeGlobals();
return StatisticsManager->GetSystemAllocationCounters();
}
-TEnumIndexedVector<ESystemCounter, ssize_t> GetUndumpableAllocationCounters()
+TEnumIndexedArray<ESystemCounter, ssize_t> GetUndumpableAllocationCounters()
{
InitializeGlobals();
return StatisticsManager->GetUndumpableAllocationCounters();
}
-TEnumIndexedVector<ESmallCounter, ssize_t> GetSmallAllocationCounters()
+TEnumIndexedArray<ESmallCounter, ssize_t> GetSmallAllocationCounters()
{
InitializeGlobals();
return StatisticsManager->GetSmallAllocationCounters();
}
-TEnumIndexedVector<ESmallCounter, ssize_t> GetLargeAllocationCounters()
+TEnumIndexedArray<ESmallCounter, ssize_t> GetLargeAllocationCounters()
{
InitializeGlobals();
return StatisticsManager->GetLargeAllocationCounters();
}
-std::array<TEnumIndexedVector<ESmallArenaCounter, ssize_t>, SmallRankCount> GetSmallArenaAllocationCounters()
+std::array<TEnumIndexedArray<ESmallArenaCounter, ssize_t>, SmallRankCount> GetSmallArenaAllocationCounters()
{
InitializeGlobals();
return StatisticsManager->GetSmallArenaAllocationCounters();
}
-std::array<TEnumIndexedVector<ELargeArenaCounter, ssize_t>, LargeRankCount> GetLargeArenaAllocationCounters()
+std::array<TEnumIndexedArray<ELargeArenaCounter, ssize_t>, LargeRankCount> GetLargeArenaAllocationCounters()
{
InitializeGlobals();
return StatisticsManager->GetLargeArenaAllocationCounters();
}
-TEnumIndexedVector<EHugeCounter, ssize_t> GetHugeAllocationCounters()
+TEnumIndexedArray<EHugeCounter, ssize_t> GetHugeAllocationCounters()
{
InitializeGlobals();
return StatisticsManager->GetHugeAllocationCounters();
@@ -4816,7 +4816,7 @@ std::vector<TProfiledAllocation> GetProfiledAllocationStatistics()
}
tags.push_back(AllocationProfilingUnknownMemoryTag);
- std::vector<TEnumIndexedVector<EBasicCounter, ssize_t>> counters;
+ std::vector<TEnumIndexedArray<EBasicCounter, ssize_t>> counters;
counters.resize(tags.size());
StatisticsManager->GetTaggedMemoryCounters(tags.data(), tags.size(), counters.data());
@@ -4838,7 +4838,7 @@ std::vector<TProfiledAllocation> GetProfiledAllocationStatistics()
return statistics;
}
-TEnumIndexedVector<ETimingEventType, TTimingEventCounters> GetTimingEventCounters()
+TEnumIndexedArray<ETimingEventType, TTimingEventCounters> GetTimingEventCounters()
{
InitializeGlobals();
return TimingManager->GetTimingEventCounters();
diff --git a/library/rightlib_sha.txt b/library/rightlib_sha.txt
index d4f5181850..5bfd2b763b 100644
--- a/library/rightlib_sha.txt
+++ b/library/rightlib_sha.txt
@@ -1 +1 @@
-5987d9abc62382b1434059ccdf127fdafaf79578
+f6d7ec162ce757a854f4a619d6b0c7084ad48f3e
diff --git a/util/generic/yexception.cpp b/util/generic/yexception.cpp
index ac62a8f4d2..6b067e90bb 100644
--- a/util/generic/yexception.cpp
+++ b/util/generic/yexception.cpp
@@ -119,9 +119,11 @@ std::string CurrentExceptionTypeName() {
void TSystemError::Init() {
yexception& exc = *this;
- exc << TStringBuf("(");
- exc << TStringBuf(LastSystemErrorText(Status_));
- exc << TStringBuf(") ");
+ exc << "(Error "sv
+ << Status_
+ << ": "sv
+ << TStringBuf(LastSystemErrorText(Status_))
+ << ") "sv;
}
NPrivateException::yexception::yexception() {
diff --git a/ya b/ya
index a01e0fd9b7..a455229113 100755
--- a/ya
+++ b/ya
@@ -34,33 +34,33 @@ REGISTRY_ENDPOINT = os.environ.get("YA_REGISTRY_ENDPOINT", "https://devtools-reg
PLATFORM_MAP = {
"data": {
"darwin": {
- "md5": "aac10b71b364633a551e2aee7d74125c",
+ "md5": "35469cf30e4da49d46e77aafe344796c",
"urls": [
- f"{REGISTRY_ENDPOINT}/5707413774"
+ f"{REGISTRY_ENDPOINT}/5720350130"
]
},
"darwin-arm64": {
- "md5": "13edc8d010203aa1ca401c4adef46c8a",
+ "md5": "e1b24bcbf0c53e169ebab09b8a4ce96a",
"urls": [
- f"{REGISTRY_ENDPOINT}/5707412857"
+ f"{REGISTRY_ENDPOINT}/5720349611"
]
},
"linux-aarch64": {
- "md5": "968f03070c7c9759ba95c551e031a00d",
+ "md5": "e4eb5f2fc68e31109760933a99125430",
"urls": [
- f"{REGISTRY_ENDPOINT}/5707412269"
+ f"{REGISTRY_ENDPOINT}/5720349159"
]
},
"win32-clang-cl": {
- "md5": "c61932f2818c1fcb6d1586aed6beecf3",
+ "md5": "5e78baa59b32e4c66d1da363f37a05e1",
"urls": [
- f"{REGISTRY_ENDPOINT}/5707414392"
+ f"{REGISTRY_ENDPOINT}/5720350841"
]
},
"linux": {
- "md5": "3d86cc42b38043923c02680bc71fd39d",
+ "md5": "e8c956d24922f1b713533e311a050d3e",
"urls": [
- f"{REGISTRY_ENDPOINT}/5707415175"
+ f"{REGISTRY_ENDPOINT}/5720351345"
]
}
}
diff --git a/yt/cpp/mapreduce/client/file_writer.cpp b/yt/cpp/mapreduce/client/file_writer.cpp
index 5a9b9a1f58..d273731e1d 100644
--- a/yt/cpp/mapreduce/client/file_writer.cpp
+++ b/yt/cpp/mapreduce/client/file_writer.cpp
@@ -16,7 +16,8 @@ TFileWriter::TFileWriter(
const TClientContext& context,
const TTransactionId& transactionId,
const TFileWriterOptions& options)
- : RetryfulWriter_(
+ : AutoFinish_(options.AutoFinish_)
+ , RetryfulWriter_(
std::move(clientRetryPolicy),
std::move(transactionPinger),
context,
@@ -29,7 +30,7 @@ TFileWriter::TFileWriter(
TFileWriter::~TFileWriter()
{
- NDetail::FinishOrDie(this, "TFileWriter");
+ NDetail::FinishOrDie(this, AutoFinish_, "TFileWriter");
}
void TFileWriter::DoWrite(const void* buf, size_t len)
diff --git a/yt/cpp/mapreduce/client/file_writer.h b/yt/cpp/mapreduce/client/file_writer.h
index 259f778ea7..ae143a75be 100644
--- a/yt/cpp/mapreduce/client/file_writer.h
+++ b/yt/cpp/mapreduce/client/file_writer.h
@@ -30,6 +30,7 @@ protected:
size_t GetBufferMemoryUsage() const override;
private:
+ const bool AutoFinish_;
TRetryfulWriter RetryfulWriter_;
static const size_t BUFFER_SIZE = 64 << 20;
};
diff --git a/yt/cpp/mapreduce/client/retryful_writer.cpp b/yt/cpp/mapreduce/client/retryful_writer.cpp
index 057fb5e7f0..55165b17ff 100644
--- a/yt/cpp/mapreduce/client/retryful_writer.cpp
+++ b/yt/cpp/mapreduce/client/retryful_writer.cpp
@@ -17,7 +17,7 @@ namespace NYT {
TRetryfulWriter::~TRetryfulWriter()
{
- NDetail::FinishOrDie(this, "TRetryfulWriter");
+ NDetail::FinishOrDie(this, AutoFinish_, "TRetryfulWriter");
}
void TRetryfulWriter::CheckWriterState()
diff --git a/yt/cpp/mapreduce/client/retryful_writer.h b/yt/cpp/mapreduce/client/retryful_writer.h
index 0b345daabf..c2de332bff 100644
--- a/yt/cpp/mapreduce/client/retryful_writer.h
+++ b/yt/cpp/mapreduce/client/retryful_writer.h
@@ -39,6 +39,7 @@ public:
: ClientRetryPolicy_(std::move(clientRetryPolicy))
, TransactionPinger_(std::move(transactionPinger))
, Context_(context)
+ , AutoFinish_(options.AutoFinish_)
, Command_(command)
, Format_(format)
, BufferSize_(GetBufferSize(options.WriterOptions_))
@@ -91,6 +92,7 @@ private:
const IClientRetryPolicyPtr ClientRetryPolicy_;
const ITransactionPingerPtr TransactionPinger_;
const TClientContext Context_;
+ const bool AutoFinish_;
TString Command_;
TMaybe<TFormat> Format_;
const size_t BufferSize_;
diff --git a/yt/cpp/mapreduce/client/retryless_writer.cpp b/yt/cpp/mapreduce/client/retryless_writer.cpp
index e3cf7cba06..dcda69bce4 100644
--- a/yt/cpp/mapreduce/client/retryless_writer.cpp
+++ b/yt/cpp/mapreduce/client/retryless_writer.cpp
@@ -8,7 +8,7 @@ namespace NYT {
TRetrylessWriter::~TRetrylessWriter()
{
- NDetail::FinishOrDie(this, "TRetrylessWriter");
+ NDetail::FinishOrDie(this, AutoFinish_, "TRetrylessWriter");
}
void TRetrylessWriter::DoFinish()
diff --git a/yt/cpp/mapreduce/client/retryless_writer.h b/yt/cpp/mapreduce/client/retryless_writer.h
index 0a1b3865ee..6916cddbf6 100644
--- a/yt/cpp/mapreduce/client/retryless_writer.h
+++ b/yt/cpp/mapreduce/client/retryless_writer.h
@@ -1,7 +1,5 @@
#pragma once
-#include "transaction.h"
-
#include <yt/cpp/mapreduce/http/helpers.h>
#include <yt/cpp/mapreduce/http/http.h>
#include <yt/cpp/mapreduce/http/http_client.h>
@@ -36,6 +34,7 @@ public:
size_t bufferSize,
const TWriterOptions& options)
: BufferSize_(bufferSize)
+ , AutoFinish_(options.AutoFinish_)
{
THttpHeader header("PUT", command);
header.SetInputFormat(format);
@@ -72,6 +71,7 @@ protected:
private:
const size_t BufferSize_ = 0;
+ const bool AutoFinish_;
bool Running_ = true;
NHttpClient::IHttpRequestPtr Request_;
diff --git a/yt/cpp/mapreduce/client/ya.make b/yt/cpp/mapreduce/client/ya.make
index c159492808..3696a9ba8f 100644
--- a/yt/cpp/mapreduce/client/ya.make
+++ b/yt/cpp/mapreduce/client/ya.make
@@ -46,17 +46,10 @@ PEERDIR(
yt/cpp/mapreduce/raw_client
)
-IF (ARCH_X86_64 OR OS_DARWIN)
- PEERDIR(
- yt/yt/core
- yt/yt/core/http
- )
-ELSE()
- # Suppress yamaker's WBadIncl error on exotic platforms
- PEERDIR(
- yt/yt_proto/yt/core
- )
-ENDIF()
+PEERDIR(
+ yt/yt/core
+ yt/yt/core/http
+)
IF (BUILD_TYPE == "PROFILE")
PEERDIR(
diff --git a/yt/cpp/mapreduce/interface/client_method_options.h b/yt/cpp/mapreduce/interface/client_method_options.h
index b5f0f1e34e..24607de424 100644
--- a/yt/cpp/mapreduce/interface/client_method_options.h
+++ b/yt/cpp/mapreduce/interface/client_method_options.h
@@ -538,6 +538,16 @@ struct TFileWriterOptions
FLUENT_FIELD_OPTION(bool, ComputeMD5);
///
+ /// @brief Wheter to call Finish automatically in writer destructor.
+ ///
+ /// If set to true (default) Finish() is called automatically in the destructor of writer.
+ /// It is convenient for simple usecases but might be error-prone if writing exception safe code
+ /// (In case of exceptions it's common to abort writer and not commit partial data).
+ ///
+ /// If set to false Finish() has to be called explicitly.
+ FLUENT_FIELD_DEFAULT(bool, AutoFinish, true);
+
+ ///
/// @brief Options to control how YT server side writes data.
///
/// @see NYT::TWriterOptions
@@ -689,6 +699,16 @@ struct TTableWriterOptions
FLUENT_FIELD_OPTION(bool, InferSchema);
///
+ /// @brief Wheter to call Finish automatically in writer destructor.
+ ///
+ /// If set to true (default) Finish() is called automatically in the destructor of writer.
+ /// It is convenient for simple usecases but might be error-prone if writing exception safe code
+ /// (In case of exceptions it's common to abort writer and not commit partial data).
+ ///
+ /// If set to false Finish() has to be called explicitly.
+ FLUENT_FIELD_DEFAULT(bool, AutoFinish, true);
+
+ ///
/// @brief Options to control how YT server side writes data.
///
/// @see NYT::TWriterOptions
diff --git a/yt/cpp/mapreduce/interface/finish_or_die.h b/yt/cpp/mapreduce/interface/finish_or_die.h
index cb8d96c454..a6e190328f 100644
--- a/yt/cpp/mapreduce/interface/finish_or_die.h
+++ b/yt/cpp/mapreduce/interface/finish_or_die.h
@@ -10,8 +10,12 @@ namespace NYT::NDetail {
////////////////////////////////////////////////////////////////////////////////
template <typename T>
-void FinishOrDie(T* pThis, const char* className) noexcept
+void FinishOrDie(T* pThis, bool autoFinish, const char* className) noexcept
{
+ if (!autoFinish) {
+ return;
+ }
+
auto fail = [&] (const char* what) {
Y_ABORT(
"\n\n"
diff --git a/yt/cpp/mapreduce/interface/io-inl.h b/yt/cpp/mapreduce/interface/io-inl.h
index fee7ba20ff..7324eaca20 100644
--- a/yt/cpp/mapreduce/interface/io-inl.h
+++ b/yt/cpp/mapreduce/interface/io-inl.h
@@ -784,7 +784,7 @@ public:
~TTableWriterBase() override
{
if (Locks_.RefCount() == 1) {
- NDetail::FinishOrDie(this, "TTableWriterBase");
+ NDetail::FinishOrDie(this, /*autoFinish*/ true, "TTableWriterBase");
}
}
diff --git a/yt/cpp/mapreduce/interface/operation.h b/yt/cpp/mapreduce/interface/operation.h
index 31252c2737..69c873090d 100644
--- a/yt/cpp/mapreduce/interface/operation.h
+++ b/yt/cpp/mapreduce/interface/operation.h
@@ -1990,6 +1990,19 @@ public:
virtual void Load(IInputStream& stream) override { Load(&stream); } \
Y_PASS_VA_ARGS(Y_SAVELOAD_DEFINE(__VA_ARGS__))
+///
+/// @brief Same as the macro above, but also calls Base class's SaveLoad methods.
+#define Y_SAVELOAD_JOB_DERIVED(Base, ...) \
+ virtual void Save(IOutputStream& stream) const override { \
+ Base::Save(stream); \
+ Save(&stream); \
+ } \
+ virtual void Load(IInputStream& stream) override { \
+ Base::Load(stream); \
+ Load(&stream); \
+ } \
+ Y_PASS_VA_ARGS(Y_SAVELOAD_DEFINE(__VA_ARGS__))
+
////////////////////////////////////////////////////////////////////////////////
///
diff --git a/yt/yt/client/api/client_common.h b/yt/yt/client/api/client_common.h
index 8cbb77be07..3cc8fe461f 100644
--- a/yt/yt/client/api/client_common.h
+++ b/yt/yt/client/api/client_common.h
@@ -153,6 +153,8 @@ struct TSelectRowsOptionsBase
bool NewRangeInference = true;
//! Enables canonical SQL behaviour for relational operators, i.e. null </=/> value -> null.
bool UseCanonicalNullRelations = false;
+ //! Merge versioned rows from different stores when reading.
+ bool MergeVersionedRows = true;
};
struct TSelectRowsOptions
diff --git a/yt/yt/client/api/config.cpp b/yt/yt/client/api/config.cpp
index 404dd8ce95..525819bc07 100644
--- a/yt/yt/client/api/config.cpp
+++ b/yt/yt/client/api/config.cpp
@@ -1,6 +1,6 @@
#include "config.h"
-#include <yt/yt/core/misc/backoff_strategy_config.h>
+#include <yt/yt/core/misc/config.h>
namespace NYT::NApi {
diff --git a/yt/yt/client/api/operation_client.h b/yt/yt/client/api/operation_client.h
index 35d62da527..0d0ac82c0c 100644
--- a/yt/yt/client/api/operation_client.h
+++ b/yt/yt/client/api/operation_client.h
@@ -292,8 +292,8 @@ struct TListOperationsResult
std::optional<THashMap<TString, i64>> PoolTreeCounts;
std::optional<THashMap<TString, i64>> PoolCounts;
std::optional<THashMap<TString, i64>> UserCounts;
- std::optional<TEnumIndexedVector<NScheduler::EOperationState, i64>> StateCounts;
- std::optional<TEnumIndexedVector<NScheduler::EOperationType, i64>> TypeCounts;
+ std::optional<TEnumIndexedArray<NScheduler::EOperationState, i64>> StateCounts;
+ std::optional<TEnumIndexedArray<NScheduler::EOperationType, i64>> TypeCounts;
std::optional<i64> FailedJobsCount;
bool Incomplete = false;
};
@@ -338,8 +338,8 @@ void Serialize(const TJob& job, NYson::IYsonConsumer* consumer, TStringBuf idKey
struct TListJobsStatistics
{
- TEnumIndexedVector<NJobTrackerClient::EJobState, i64> StateCounts;
- TEnumIndexedVector<NJobTrackerClient::EJobType, i64> TypeCounts;
+ TEnumIndexedArray<NJobTrackerClient::EJobState, i64> StateCounts;
+ TEnumIndexedArray<NJobTrackerClient::EJobType, i64> TypeCounts;
};
struct TListJobsResult
diff --git a/yt/yt/client/api/public.h b/yt/yt/client/api/public.h
index 7e6c250481..55a72dd3c5 100644
--- a/yt/yt/client/api/public.h
+++ b/yt/yt/client/api/public.h
@@ -14,6 +14,8 @@
#include <yt/yt/core/rpc/public.h>
+#include <library/cpp/yt/misc/enum_indexed_array.h>
+
namespace NYT::NApi {
////////////////////////////////////////////////////////////////////////////////
@@ -217,7 +219,7 @@ DEFINE_ENUM(EMaintenanceComponent,
);
using TMaintenanceId = TGuid;
-using TMaintenanceCounts = TEnumIndexedVector<EMaintenanceType, int>;
+using TMaintenanceCounts = TEnumIndexedArray<EMaintenanceType, int>;
////////////////////////////////////////////////////////////////////////////////
diff --git a/yt/yt/client/api/rpc_proxy/client_base.cpp b/yt/yt/client/api/rpc_proxy/client_base.cpp
index 64fbb0de05..6f0961d58b 100644
--- a/yt/yt/client/api/rpc_proxy/client_base.cpp
+++ b/yt/yt/client/api/rpc_proxy/client_base.cpp
@@ -1003,6 +1003,7 @@ TFuture<TSelectRowsResult> TClientBase::SelectRows(
ToProto(req->mutable_suppressable_access_tracking_options(), options);
req->set_replica_consistency(static_cast<NProto::EReplicaConsistency>(options.ReplicaConsistency));
req->set_use_canonical_null_relations(options.UseCanonicalNullRelations);
+ req->set_merge_versioned_rows(options.MergeVersionedRows);
return req->Invoke().Apply(BIND([] (const TApiServiceProxy::TRspSelectRowsPtr& rsp) {
TSelectRowsResult result;
diff --git a/yt/yt/client/api/rpc_proxy/helpers.cpp b/yt/yt/client/api/rpc_proxy/helpers.cpp
index 9562053d10..819a478b41 100644
--- a/yt/yt/client/api/rpc_proxy/helpers.cpp
+++ b/yt/yt/client/api/rpc_proxy/helpers.cpp
@@ -349,7 +349,7 @@ void FromProto(
std::fill(result->StateCounts->begin(), result->StateCounts->end(), 0);
for (const auto& stateCount: proto.state_counts().entries()) {
auto state = ConvertOperationStateFromProto(stateCount.state());
- YT_VERIFY(result->StateCounts->IsDomainValue(state));
+ YT_VERIFY(result->StateCounts->IsValidIndex(state));
YT_VERIFY((*result->StateCounts)[state] == 0);
(*result->StateCounts)[state] = stateCount.count();
}
@@ -361,7 +361,7 @@ void FromProto(
std::fill(result->TypeCounts->begin(), result->TypeCounts->end(), 0);
for (const auto& typeCount: proto.type_counts().entries()) {
auto type = ConvertOperationTypeFromProto(typeCount.type());
- YT_VERIFY(result->TypeCounts->IsDomainValue(type));
+ YT_VERIFY(result->TypeCounts->IsValidIndex(type));
YT_VERIFY((*result->TypeCounts)[type] == 0);
(*result->TypeCounts)[type] = typeCount.count();
}
@@ -1113,7 +1113,7 @@ void FromProto(
std::fill(statistics->StateCounts.begin(), statistics->StateCounts.end(), 0);
for (const auto& stateCount: protoStatistics.state_counts().entries()) {
auto state = ConvertJobStateFromProto(stateCount.state());
- YT_VERIFY(statistics->StateCounts.IsDomainValue(state));
+ YT_VERIFY(statistics->StateCounts.IsValidIndex(state));
YT_VERIFY(statistics->StateCounts[state] == 0);
statistics->StateCounts[state] = stateCount.count();
}
@@ -1121,7 +1121,7 @@ void FromProto(
std::fill(statistics->TypeCounts.begin(), statistics->TypeCounts.end(), 0);
for (const auto& typeCount: protoStatistics.type_counts().entries()) {
auto type = ConvertJobTypeFromProto(typeCount.type());
- YT_VERIFY(statistics->TypeCounts.IsDomainValue(type));
+ YT_VERIFY(statistics->TypeCounts.IsValidIndex(type));
YT_VERIFY(statistics->TypeCounts[type] == 0);
statistics->TypeCounts[type] = typeCount.count();
}
diff --git a/yt/yt/client/api/security_client.h b/yt/yt/client/api/security_client.h
index 87ceab45f3..39e752799c 100644
--- a/yt/yt/client/api/security_client.h
+++ b/yt/yt/client/api/security_client.h
@@ -70,7 +70,9 @@ struct TCheckPermissionByAclResult
struct TSetUserPasswordOptions
: public TTimeoutOptions
-{ };
+{
+ bool PasswordIsTemporary = false;
+};
struct TIssueTokenOptions
: public TTimeoutOptions
diff --git a/yt/yt/client/driver/authentication_commands.cpp b/yt/yt/client/driver/authentication_commands.cpp
index 60546f842c..eeadbbbbc2 100644
--- a/yt/yt/client/driver/authentication_commands.cpp
+++ b/yt/yt/client/driver/authentication_commands.cpp
@@ -16,6 +16,12 @@ void TSetUserPasswordCommand::Register(TRegistrar registrar)
registrar.Parameter("current_password_sha256", &TThis::CurrentPasswordSha256_)
.Default();
registrar.Parameter("new_password_sha256", &TThis::NewPasswordSha256_);
+ registrar.ParameterWithUniversalAccessor<bool>(
+ "password_is_temporary",
+ [] (TThis* command) -> bool& {
+ return command->Options.PasswordIsTemporary;
+ })
+ .Default(false);
}
void TSetUserPasswordCommand::DoExecute(ICommandContextPtr context)
diff --git a/yt/yt/client/driver/command-inl.h b/yt/yt/client/driver/command-inl.h
index 6cd7d52810..d30876cacf 100644
--- a/yt/yt/client/driver/command-inl.h
+++ b/yt/yt/client/driver/command-inl.h
@@ -419,6 +419,13 @@ void TSelectRowsCommandBase<
return command->Options.UseCanonicalNullRelations;
})
.Optional(/*init*/ false);
+
+ registrar.template ParameterWithUniversalAccessor<bool>(
+ "merge_versioned_rows",
+ [] (TThis* command) -> auto& {
+ return command->Options.MergeVersionedRows;
+ })
+ .Optional(/*init*/ false);
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/yt/yt/client/driver/command.cpp b/yt/yt/client/driver/command.cpp
index 8a94593e8c..cd9cf53ad7 100644
--- a/yt/yt/client/driver/command.cpp
+++ b/yt/yt/client/driver/command.cpp
@@ -16,7 +16,6 @@ using namespace NConcurrency;
////////////////////////////////////////////////////////////////////////////////
-
void ProduceOutput(
ICommandContextPtr context,
const std::function<void(IYsonConsumer*)>& producer)
diff --git a/yt/yt/client/driver/driver.cpp b/yt/yt/client/driver/driver.cpp
index a9a8bd685e..b68aff58e7 100644
--- a/yt/yt/client/driver/driver.cpp
+++ b/yt/yt/client/driver/driver.cpp
@@ -362,9 +362,15 @@ public:
REGISTER_ALL(TGetBundleConfigCommand, "get_bundle_config", Null, Structured, false, false);
REGISTER_ALL(TSetBundleConfigCommand, "set_bundle_config", Structured, Null, false, false);
- REGISTER_ALL(TStartPipelineCommand, "start_pipeline", Null, Structured, false, false);
- REGISTER_ALL(TStopPipelineCommand, "stop_pipeline", Null, Structured, false, false);
- REGISTER_ALL(TPausePipelineCommand, "pause_pipeline", Null, Structured, false, false);
+ REGISTER (TGetPipelineSpecCommand, "get_pipeline_spec", Null, Structured, true, false, ApiVersion4);
+ REGISTER (TSetPipelineSpecCommand, "set_pipeline_spec", Structured, Null, true, false, ApiVersion4);
+ REGISTER (TRemovePipelineDynamicSpecCommand, "remove_pipeline_spec", Null, Null, true, false, ApiVersion4);
+ REGISTER (TGetPipelineDynamicSpecCommand, "get_pipeline_dynamic_spec", Null, Structured, true, false, ApiVersion4);
+ REGISTER (TSetPipelineDynamicSpecCommand, "set_pipeline_dynamic_spec", Structured, Null, true, false, ApiVersion4);
+ REGISTER (TRemovePipelineDynamicSpecCommand, "remove_pipeline_dynamic_spec", Null, Null, true, false, ApiVersion4);
+ REGISTER (TStartPipelineCommand, "start_pipeline", Null, Structured, false, false, ApiVersion4);
+ REGISTER (TStopPipelineCommand, "stop_pipeline", Null, Structured, false, false, ApiVersion4);
+ REGISTER (TPausePipelineCommand, "pause_pipeline", Null, Structured, false, false, ApiVersion4);
if (Config_->EnableInternalCommands) {
REGISTER_ALL(TReadHunksCommand, "read_hunks", Null, Structured, false, true );
diff --git a/yt/yt/client/driver/flow_commands.cpp b/yt/yt/client/driver/flow_commands.cpp
index c0543f4ad2..4b5d84bfd5 100644
--- a/yt/yt/client/driver/flow_commands.cpp
+++ b/yt/yt/client/driver/flow_commands.cpp
@@ -1,36 +1,286 @@
#include "flow_commands.h"
+#include <yt/yt/core/ytree/fluent.h>
+#include <yt/yt/core/ytree/ypath_client.h>
+
namespace NYT::NDriver {
using namespace NConcurrency;
+using namespace NYTree;
+using namespace NYPath;
+using namespace NYson;
+using namespace NApi;
////////////////////////////////////////////////////////////////////////////////
-void TStartPipelineCommand::Register(TRegistrar registrar)
+namespace {
+
+void ExecuteGetPipelineSpecCommand(
+ const ICommandContextPtr& context,
+ const TYPath& specPath,
+ const auto& specGetterOptions,
+ auto specGetter)
{
- registrar.Parameter("pipeline_path", &TThis::PipelinePath);
+ auto client = context->GetClient();
+ auto result = WaitFor(specGetter(client, specGetterOptions))
+ .ValueOrThrow();
+
+ auto spec = SyncYPathGet(ConvertToNode(result.Spec), specPath);
+
+ ProduceOutput(context, [&] (NYson::IYsonConsumer* consumer) {
+ BuildYsonFluently(consumer)
+ .BeginMap()
+ .Item("spec").Value(spec)
+ .Item("version").Value(result.Version)
+ .EndMap();
+ });
}
-void TStartPipelineCommand::DoExecute(ICommandContextPtr context)
+void ExecuteSetPipelineSpecCommand(
+ const ICommandContextPtr& context,
+ const TYPath& specPath,
+ const auto& specGetterOptions,
+ auto specGetter,
+ const auto& specSetterOptions,
+ auto specSetter)
{
auto client = context->GetClient();
- WaitFor(client->StartPipeline(PipelinePath))
- .ThrowOnError();
+ auto spec = context->ConsumeInputValue();
- ProduceEmptyOutput(context);
+ auto setResult = [&] {
+ if (specPath.empty()) {
+ return WaitFor(specSetter(client, spec, specSetterOptions))
+ .ValueOrThrow();
+ } else {
+ auto getResult = WaitFor(specGetter(client, specGetterOptions))
+ .ValueOrThrow();
+
+ if (specSetterOptions.ExpectedVersion && getResult.Version != *specSetterOptions.ExpectedVersion) {
+ THROW_ERROR_EXCEPTION(
+ NFlow::EErrorCode::SpecVersionMismatch,
+ "Spec version mismatch: expected %v, got %v",
+ *specSetterOptions.ExpectedVersion,
+ getResult.Version);
+ }
+
+ auto fullSpec = ConvertToNode(getResult.Spec);
+ SyncYPathSet(fullSpec, specPath, spec);
+
+ auto adjustedOptions = specSetterOptions;
+ adjustedOptions.ExpectedVersion = getResult.Version;
+ return WaitFor(specSetter(client, ConvertToYsonString(fullSpec), adjustedOptions))
+ .ValueOrThrow();
+ }
+ }();
+
+ ProduceOutput(context, [&] (NYson::IYsonConsumer* consumer) {
+ BuildYsonFluently(consumer)
+ .BeginMap()
+ .Item("version").Value(setResult.Version)
+ .EndMap();
+ });
+}
+
+void ExecuteRemovePipelineSpecCommand(
+ const ICommandContextPtr& context,
+ const TYPath& specPath,
+ const auto& specGetterOptions,
+ auto specGetter,
+ const auto& specSetterOptions,
+ auto specSetter)
+{
+ auto client = context->GetClient();
+ auto spec = context->ConsumeInputValue();
+
+ auto getResult = WaitFor(specGetter(client, specGetterOptions))
+ .ValueOrThrow();
+
+ if (specSetterOptions.ExpectedVersion && getResult.Version != *specSetterOptions.ExpectedVersion) {
+ THROW_ERROR_EXCEPTION(
+ NFlow::EErrorCode::SpecVersionMismatch,
+ "Spec version mismatch: expected %v, got %v",
+ *specSetterOptions.ExpectedVersion,
+ getResult.Version);
+ }
+
+ auto fullSpec = ConvertToNode(getResult.Spec);
+ SyncYPathRemove(fullSpec, specPath);
+
+ auto adjustedOptions = specSetterOptions;
+ adjustedOptions.ExpectedVersion = getResult.Version;
+ auto setResult = WaitFor(specSetter(client, ConvertToYsonString(fullSpec), adjustedOptions))
+ .ValueOrThrow();
+
+ ProduceOutput(context, [&] (NYson::IYsonConsumer* consumer) {
+ BuildYsonFluently(consumer)
+ .BeginMap()
+ .Item("version").Value(setResult.Version)
+ .EndMap();
+ });
}
+} // namespace
+
////////////////////////////////////////////////////////////////////////////////
-void TStopPipelineCommand::Register(TRegistrar registrar)
+void TPipelineCommandBase::Register(TRegistrar registrar)
{
registrar.Parameter("pipeline_path", &TThis::PipelinePath);
}
-void TStopPipelineCommand::DoExecute(ICommandContextPtr context)
+////////////////////////////////////////////////////////////////////////////////
+
+void TGetPipelineSpecCommand::Register(TRegistrar registrar)
+{
+ registrar.Parameter("spec_path", &TThis::SpecPath)
+ .Default();
+}
+
+void TGetPipelineSpecCommand::DoExecute(ICommandContextPtr context)
+{
+ ExecuteGetPipelineSpecCommand(
+ context,
+ SpecPath,
+ Options,
+ [&] (const auto& client, const auto& options) { return client->GetPipelineSpec(PipelinePath, options); });
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void TSetPipelineSpecCommand::Register(TRegistrar registrar)
+{
+ registrar.Parameter("spec_path", &TThis::SpecPath)
+ .Default();
+ registrar.ParameterWithUniversalAccessor<bool>(
+ "force",
+ [] (TThis* command) -> auto& {
+ return command->Options.Force;
+ })
+ .Optional(/*init*/ false);
+ registrar.ParameterWithUniversalAccessor<std::optional<NFlow::TVersion>>(
+ "expected_version",
+ [] (TThis* command) -> auto& {
+ return command->Options.ExpectedVersion;
+ })
+ .Optional(/*init*/ false);
+}
+
+void TSetPipelineSpecCommand::DoExecute(ICommandContextPtr context)
+{
+ ExecuteSetPipelineSpecCommand(
+ context,
+ SpecPath,
+ TGetPipelineSpecOptions(),
+ [&] (const auto& client, const auto& options) { return client->GetPipelineSpec(PipelinePath, options); },
+ Options,
+ [&] (const auto& client, const auto& spec, const auto& options) { return client->SetPipelineSpec(PipelinePath, spec, options); });
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void TRemovePipelineSpecCommand::Register(TRegistrar registrar)
+{
+ registrar.Parameter("spec_path", &TThis::SpecPath);
+ registrar.ParameterWithUniversalAccessor<bool>(
+ "force",
+ [] (TThis* command) -> auto& {
+ return command->Options.Force;
+ })
+ .Optional(/*init*/ false);
+ registrar.ParameterWithUniversalAccessor<std::optional<NFlow::TVersion>>(
+ "expected_version",
+ [] (TThis* command) -> auto& {
+ return command->Options.ExpectedVersion;
+ })
+ .Optional(/*init*/ false);
+}
+
+void TRemovePipelineSpecCommand::DoExecute(ICommandContextPtr context)
+{
+ ExecuteRemovePipelineSpecCommand(
+ context,
+ SpecPath,
+ TGetPipelineSpecOptions(),
+ [&] (const auto& client, const auto& options) { return client->GetPipelineSpec(PipelinePath, options); },
+ Options,
+ [&] (const auto& client, const auto& spec, const auto& options) { return client->SetPipelineSpec(PipelinePath, spec, options); });
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void TGetPipelineDynamicSpecCommand::Register(TRegistrar registrar)
+{
+ registrar.Parameter("spec_path", &TThis::SpecPath)
+ .Default();
+}
+
+void TGetPipelineDynamicSpecCommand::DoExecute(ICommandContextPtr context)
+{
+ ExecuteGetPipelineSpecCommand(
+ context,
+ SpecPath,
+ Options,
+ [&] (const auto& client, const auto& options) { return client->GetPipelineDynamicSpec(PipelinePath, options); });
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void TSetPipelineDynamicSpecCommand::Register(TRegistrar registrar)
+{
+ registrar.Parameter("spec_path", &TThis::SpecPath)
+ .Default();
+ registrar.ParameterWithUniversalAccessor<std::optional<NFlow::TVersion>>(
+ "expected_version",
+ [] (TThis* command) -> auto& {
+ return command->Options.ExpectedVersion;
+ })
+ .Optional(/*init*/ false);
+}
+
+void TSetPipelineDynamicSpecCommand::DoExecute(ICommandContextPtr context)
+{
+ ExecuteSetPipelineSpecCommand(
+ context,
+ SpecPath,
+ TGetPipelineDynamicSpecOptions(),
+ [&] (const auto& client, const auto& options) { return client->GetPipelineDynamicSpec(PipelinePath, options); },
+ Options,
+ [&] (const auto& client, const auto& spec, const auto& options) { return client->SetPipelineDynamicSpec(PipelinePath, spec, options); });
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void TRemovePipelineDynamicSpecCommand::Register(TRegistrar registrar)
+{
+ registrar.Parameter("spec_path", &TThis::SpecPath);
+ registrar.ParameterWithUniversalAccessor<std::optional<NFlow::TVersion>>(
+ "expected_version",
+ [] (TThis* command) -> auto& {
+ return command->Options.ExpectedVersion;
+ })
+ .Optional(/*init*/ false);
+}
+
+void TRemovePipelineDynamicSpecCommand::DoExecute(ICommandContextPtr context)
+{
+ ExecuteRemovePipelineSpecCommand(
+ context,
+ SpecPath,
+ TGetPipelineDynamicSpecOptions(),
+ [&] (const auto& client, const auto& options) { return client->GetPipelineDynamicSpec(PipelinePath, options); },
+ Options,
+ [&] (const auto& client, const auto& spec, const auto& options) { return client->SetPipelineDynamicSpec(PipelinePath, spec, options); });
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void TStartPipelineCommand::Register(TRegistrar /*registrar*/)
+{ }
+
+void TStartPipelineCommand::DoExecute(ICommandContextPtr context)
{
auto client = context->GetClient();
- WaitFor(client->StopPipeline(PipelinePath))
+ WaitFor(client->StartPipeline(PipelinePath, Options))
.ThrowOnError();
ProduceEmptyOutput(context);
@@ -38,15 +288,27 @@ void TStopPipelineCommand::DoExecute(ICommandContextPtr context)
////////////////////////////////////////////////////////////////////////////////
-void TPausePipelineCommand::Register(TRegistrar registrar)
+void TStopPipelineCommand::Register(TRegistrar /*registrar*/)
+{ }
+
+void TStopPipelineCommand::DoExecute(ICommandContextPtr context)
{
- registrar.Parameter("pipeline_path", &TThis::PipelinePath);
+ auto client = context->GetClient();
+ WaitFor(client->StopPipeline(PipelinePath, Options))
+ .ThrowOnError();
+
+ ProduceEmptyOutput(context);
}
+////////////////////////////////////////////////////////////////////////////////
+
+void TPausePipelineCommand::Register(TRegistrar /*registrar*/)
+{ }
+
void TPausePipelineCommand::DoExecute(ICommandContextPtr context)
{
auto client = context->GetClient();
- WaitFor(client->PausePipeline(PipelinePath))
+ WaitFor(client->PausePipeline(PipelinePath, Options))
.ThrowOnError();
ProduceEmptyOutput(context);
diff --git a/yt/yt/client/driver/flow_commands.h b/yt/yt/client/driver/flow_commands.h
index c6beb43dda..dd798adfcb 100644
--- a/yt/yt/client/driver/flow_commands.h
+++ b/yt/yt/client/driver/flow_commands.h
@@ -8,8 +8,125 @@ namespace NYT::NDriver {
////////////////////////////////////////////////////////////////////////////////
+class TPipelineCommandBase
+ : public virtual NYTree::TYsonStructLite
+{
+public:
+ REGISTER_YSON_STRUCT_LITE(TPipelineCommandBase);
+
+ static void Register(TRegistrar registrar);
+
+protected:
+ NYPath::TYPath PipelinePath;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class TGetPipelineSpecCommand
+ : public TTypedCommand<NApi::TGetPipelineSpecOptions>
+ , public TPipelineCommandBase
+{
+public:
+ REGISTER_YSON_STRUCT_LITE(TGetPipelineSpecCommand);
+
+ static void Register(TRegistrar registrar);
+
+private:
+ NYPath::TYPath SpecPath;
+
+ void DoExecute(ICommandContextPtr context) override;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class TSetPipelineSpecCommand
+ : public TTypedCommand<NApi::TSetPipelineSpecOptions>
+ , public TPipelineCommandBase
+{
+public:
+ REGISTER_YSON_STRUCT_LITE(TSetPipelineSpecCommand);
+
+ static void Register(TRegistrar registrar);
+
+private:
+ NYPath::TYPath SpecPath;
+
+ void DoExecute(ICommandContextPtr context) override;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class TRemovePipelineSpecCommand
+ : public TTypedCommand<NApi::TSetPipelineSpecOptions>
+ , public TPipelineCommandBase
+{
+public:
+ REGISTER_YSON_STRUCT_LITE(TRemovePipelineSpecCommand);
+
+ static void Register(TRegistrar registrar);
+
+private:
+ NYPath::TYPath SpecPath;
+
+ void DoExecute(ICommandContextPtr context) override;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class TGetPipelineDynamicSpecCommand
+ : public TTypedCommand<NApi::TGetPipelineDynamicSpecOptions>
+ , public TPipelineCommandBase
+{
+public:
+ REGISTER_YSON_STRUCT_LITE(TGetPipelineDynamicSpecCommand);
+
+ static void Register(TRegistrar registrar);
+
+private:
+ NYPath::TYPath SpecPath;
+
+ void DoExecute(ICommandContextPtr context) override;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class TSetPipelineDynamicSpecCommand
+ : public TTypedCommand<NApi::TSetPipelineDynamicSpecOptions>
+ , public TPipelineCommandBase
+{
+public:
+ REGISTER_YSON_STRUCT_LITE(TSetPipelineDynamicSpecCommand);
+
+ static void Register(TRegistrar registrar);
+
+private:
+ NYPath::TYPath SpecPath;
+
+ void DoExecute(ICommandContextPtr context) override;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class TRemovePipelineDynamicSpecCommand
+ : public TTypedCommand<NApi::TSetPipelineDynamicSpecOptions>
+ , public TPipelineCommandBase
+{
+public:
+ REGISTER_YSON_STRUCT_LITE(TRemovePipelineDynamicSpecCommand);
+
+ static void Register(TRegistrar registrar);
+
+private:
+ NYPath::TYPath SpecPath;
+
+ void DoExecute(ICommandContextPtr context) override;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
class TStartPipelineCommand
: public TTypedCommand<NApi::TStartPipelineOptions>
+ , public TPipelineCommandBase
{
public:
REGISTER_YSON_STRUCT_LITE(TStartPipelineCommand);
@@ -17,8 +134,6 @@ public:
static void Register(TRegistrar registrar);
private:
- NYPath::TYPath PipelinePath;
-
void DoExecute(ICommandContextPtr context) override;
};
@@ -26,6 +141,7 @@ private:
class TStopPipelineCommand
: public TTypedCommand<NApi::TStopPipelineOptions>
+ , public TPipelineCommandBase
{
public:
REGISTER_YSON_STRUCT_LITE(TStopPipelineCommand);
@@ -33,15 +149,14 @@ public:
static void Register(TRegistrar registrar);
private:
- NYPath::TYPath PipelinePath;
-
void DoExecute(ICommandContextPtr context) override;
};
////////////////////////////////////////////////////////////////////////////////
class TPausePipelineCommand
- : public TTypedCommand<NApi::TStopPipelineOptions>
+ : public TTypedCommand<NApi::TPausePipelineOptions>
+ , public TPipelineCommandBase
{
public:
REGISTER_YSON_STRUCT_LITE(TPausePipelineCommand);
@@ -49,8 +164,6 @@ public:
static void Register(TRegistrar registrar);
private:
- NYPath::TYPath PipelinePath;
-
void DoExecute(ICommandContextPtr context) override;
};
@@ -58,6 +171,7 @@ private:
class TGetPipelineStatusCommand
: public TTypedCommand<NApi::TGetPipelineStatusOptions>
+ , public TPipelineCommandBase
{
public:
REGISTER_YSON_STRUCT_LITE(TGetPipelineStatusCommand);
@@ -65,8 +179,6 @@ public:
static void Register(TRegistrar registrar);
private:
- NYPath::TYPath PipelinePath;
-
void DoExecute(ICommandContextPtr context) override;
};
diff --git a/yt/yt/client/federated/client.cpp b/yt/yt/client/federated/client.cpp
index cd3e0dd5c9..a90d324510 100644
--- a/yt/yt/client/federated/client.cpp
+++ b/yt/yt/client/federated/client.cpp
@@ -286,6 +286,8 @@ public:
TFuture<NYson::TYsonString> ListNode(const NYPath::TYPath&, const TListNodeOptions&) override;
TFuture<bool> NodeExists(const NYPath::TYPath&, const TNodeExistsOptions&) override;
+ TFuture<std::vector<TListQueueConsumerRegistrationsResult>> ListQueueConsumerRegistrations(const std::optional<NYPath::TRichYPath>&, const std::optional<NYPath::TRichYPath>&, const TListQueueConsumerRegistrationsOptions&) override;
+
const NTabletClient::ITableMountCachePtr& GetTableMountCache() override;
TFuture<std::vector<TTabletInfo>> GetTabletInfos(const NYPath::TYPath&, const std::vector<int>&, const TGetTabletInfosOptions&) override;
@@ -329,7 +331,6 @@ public:
// IClient unsupported methods.
UNIMPLEMENTED_METHOD(TFuture<void>, RegisterQueueConsumer, (const NYPath::TRichYPath&, const NYPath::TRichYPath&, bool, const TRegisterQueueConsumerOptions&));
UNIMPLEMENTED_METHOD(TFuture<void>, UnregisterQueueConsumer, (const NYPath::TRichYPath&, const NYPath::TRichYPath&, const TUnregisterQueueConsumerOptions&));
- UNIMPLEMENTED_METHOD(TFuture<std::vector<TListQueueConsumerRegistrationsResult>>, ListQueueConsumerRegistrations, (const std::optional<NYPath::TRichYPath>&, const std::optional<NYPath::TRichYPath>&, const TListQueueConsumerRegistrationsOptions&));
UNIMPLEMENTED_METHOD(const NChaosClient::IReplicationCardCachePtr&, GetReplicationCardCache, ());
UNIMPLEMENTED_METHOD(TFuture<void>, MountTable, (const NYPath::TYPath&, const TMountTableOptions&));
UNIMPLEMENTED_METHOD(TFuture<void>, UnmountTable, (const NYPath::TYPath&, const TUnmountTableOptions&));
@@ -667,6 +668,7 @@ CLIENT_METHOD_IMPL(NYson::TYsonString, ListNode, (const NYPath::TYPath&, const T
CLIENT_METHOD_IMPL(bool, NodeExists, (const NYPath::TYPath&, const TNodeExistsOptions&));
CLIENT_METHOD_IMPL(std::vector<TTabletInfo>, GetTabletInfos, (const NYPath::TYPath&, const std::vector<int>&, const TGetTabletInfosOptions&));
CLIENT_METHOD_IMPL(NChaosClient::TReplicationCardPtr, GetReplicationCard, (NChaosClient::TReplicationCardId, const TGetReplicationCardOptions&));
+CLIENT_METHOD_IMPL(std::vector<TListQueueConsumerRegistrationsResult>, ListQueueConsumerRegistrations, (const std::optional<NYPath::TRichYPath>&, const std::optional<NYPath::TRichYPath>&, const TListQueueConsumerRegistrationsOptions&));
const NTabletClient::ITableMountCachePtr& TClient::GetTableMountCache()
{
diff --git a/yt/yt/client/job_tracker_client/public.h b/yt/yt/client/job_tracker_client/public.h
index 5e1886f458..d67e273715 100644
--- a/yt/yt/client/job_tracker_client/public.h
+++ b/yt/yt/client/job_tracker_client/public.h
@@ -19,7 +19,7 @@ extern const TOperationId NullOperationId;
////////////////////////////////////////////////////////////////////////////////
// NB: Please keep the range of values small as this type
-// is used as a key of TEnumIndexedVector.
+// is used as a key of TEnumIndexedArray.
DEFINE_ENUM(EJobType,
// Scheduler jobs
((Map) ( 1))
@@ -58,7 +58,7 @@ constexpr auto FirstMasterJobType = EJobType::ReplicateChunk;
constexpr auto LastMasterJobType = EJobType::ReincarnateChunk;
// NB: Please keep the range of values small as this type
-// is used as a key of TEnumIndexedVector.
+// is used as a key of TEnumIndexedArray.
DEFINE_ENUM(EJobState,
((Waiting) (0))
((Running) (1))
diff --git a/yt/yt/client/table_client/blob_reader.cpp b/yt/yt/client/table_client/blob_reader.cpp
index f40e28f031..551878b805 100644
--- a/yt/yt/client/table_client/blob_reader.cpp
+++ b/yt/yt/client/table_client/blob_reader.cpp
@@ -100,7 +100,7 @@ private:
i64 Index_ = 0;
i64 NextPartIndex_;
- TEnumIndexedVector<EColumnType, std::optional<size_t>> ColumnIndex_;
+ TEnumIndexedArray<EColumnType, std::optional<size_t>> ColumnIndex_;
TSharedRef ProcessRow()
{
diff --git a/yt/yt/client/table_client/helpers.cpp b/yt/yt/client/table_client/helpers.cpp
index 9e33a43949..c19e217ad9 100644
--- a/yt/yt/client/table_client/helpers.cpp
+++ b/yt/yt/client/table_client/helpers.cpp
@@ -562,7 +562,7 @@ void ToUnversionedValue(
void FromUnversionedValue(NYson::TYsonStringBuf* value, TUnversionedValue unversionedValue)
{
- if (unversionedValue.Type != EValueType::Any) {
+ if (!IsAnyOrComposite(unversionedValue.Type)) {
THROW_ERROR_EXCEPTION("Cannot parse YSON string from %Qlv",
unversionedValue.Type);
}
diff --git a/yt/yt/client/tablet_client/table_mount_cache.h b/yt/yt/client/tablet_client/table_mount_cache.h
index bba0a1e0c0..773f641aae 100644
--- a/yt/yt/client/tablet_client/table_mount_cache.h
+++ b/yt/yt/client/tablet_client/table_mount_cache.h
@@ -96,7 +96,7 @@ struct TTableMountInfo
{
NYPath::TYPath Path;
NObjectClient::TObjectId TableId;
- TEnumIndexedVector<ETableSchemaKind, NTableClient::TTableSchemaPtr> Schemas;
+ TEnumIndexedArray<ETableSchemaKind, NTableClient::TTableSchemaPtr> Schemas;
// PhysicalPath points to a physical object, if current object is linked to some other object, then this field will point to the source.
// When this field is not supported on the server-side, this path will be equal to object path.
diff --git a/yt/yt/core/bus/tcp/config.h b/yt/yt/core/bus/tcp/config.h
index 54020c6b08..3695a42093 100644
--- a/yt/yt/core/bus/tcp/config.h
+++ b/yt/yt/core/bus/tcp/config.h
@@ -40,7 +40,7 @@ public:
THashMap<TString, std::vector<NNet::TIP6Network>> Networks;
- TEnumIndexedVector<EMultiplexingBand, TMultiplexingBandConfigPtr> MultiplexingBands;
+ TEnumIndexedArray<EMultiplexingBand, TMultiplexingBandConfigPtr> MultiplexingBands;
TTcpDispatcherConfigPtr ApplyDynamic(const TTcpDispatcherDynamicConfigPtr& dynamicConfig) const;
@@ -66,7 +66,7 @@ public:
std::optional<THashMap<TString, std::vector<NNet::TIP6Network>>> Networks;
- std::optional<TEnumIndexedVector<EMultiplexingBand, TMultiplexingBandConfigPtr>> MultiplexingBands;
+ std::optional<TEnumIndexedArray<EMultiplexingBand, TMultiplexingBandConfigPtr>> MultiplexingBands;
//! Used to store TLS/SSL certificate files.
std::optional<TString> BusCertsDirectoryPath;
diff --git a/yt/yt/core/bus/tcp/dispatcher.h b/yt/yt/core/bus/tcp/dispatcher.h
index b4a4a61580..8a64a6af1d 100644
--- a/yt/yt/core/bus/tcp/dispatcher.h
+++ b/yt/yt/core/bus/tcp/dispatcher.h
@@ -12,6 +12,8 @@
#include <yt/yt/core/ytree/public.h>
+#include <library/cpp/yt/misc/enum_indexed_array.h>
+
namespace NYT::NBus {
////////////////////////////////////////////////////////////////////////////////
@@ -27,7 +29,7 @@ struct TBusNetworkCounters final
{
static constexpr bool EnableHazard = true;
- TEnumIndexedVector<EMultiplexingBand, TBusNetworkBandCounters> PerBandCounters;
+ TEnumIndexedArray<EMultiplexingBand, TBusNetworkBandCounters> PerBandCounters;
TBusNetworkStatistics ToStatistics() const;
};
diff --git a/yt/yt/core/bus/tcp/dispatcher_impl.h b/yt/yt/core/bus/tcp/dispatcher_impl.h
index 80495eaa65..76b01356c7 100644
--- a/yt/yt/core/bus/tcp/dispatcher_impl.h
+++ b/yt/yt/core/bus/tcp/dispatcher_impl.h
@@ -101,7 +101,7 @@ private:
std::atomic<TTosLevel> TosLevel = DefaultTosLevel;
};
- TEnumIndexedVector<EMultiplexingBand, TBandDescriptor> BandToDescriptor_;
+ TEnumIndexedArray<EMultiplexingBand, TBandDescriptor> BandToDescriptor_;
};
////////////////////////////////////////////////////////////////////////////////
diff --git a/yt/yt/core/concurrency/config.cpp b/yt/yt/core/concurrency/config.cpp
index c54512e56e..acd8194e2f 100644
--- a/yt/yt/core/concurrency/config.cpp
+++ b/yt/yt/core/concurrency/config.cpp
@@ -32,10 +32,22 @@ void TPeriodicExecutorOptionsSerializer::Register(TRegistrar registrar)
void TRetryingPeriodicExecutorOptionsSerializer::Register(TRegistrar registrar)
{
- registrar.ExternalClassParameter("periodic", &TThat::Periodic)
- .Default();
- registrar.ExternalClassParameter("backoff_strategy", &TThat::BackoffStrategy)
- .Default();
+ //! NB(arkady-e1ppa): Defaults and preprocessors of derived class
+ //! override defaults and overrides of base class and base class fields
+ registrar.ExternalPreprocessor([] (TThat* options) {
+ *options = TRetryingPeriodicExecutorOptions{
+ {
+ .Period = TDuration::Seconds(5),
+ .Splay = TDuration::Seconds(1),
+ .Jitter = 0.0,
+ },
+ {
+ .MinBackoff = TDuration::Seconds(5),
+ .MaxBackoff = TDuration::Seconds(60),
+ .BackoffMultiplier = 2.0,
+ },
+ };
+ });
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/yt/yt/core/concurrency/config.h b/yt/yt/core/concurrency/config.h
index 24d5383e60..3777d7a8d4 100644
--- a/yt/yt/core/concurrency/config.h
+++ b/yt/yt/core/concurrency/config.h
@@ -2,8 +2,7 @@
#include "public.h"
-// TODO(arkady-e1ppa): Move backoff config+serialization into core/misc/config.h.
-#include <yt/yt/core/misc/backoff_strategy_config.h>
+#include <yt/yt/core/misc/config.h>
#include <yt/yt/core/ytree/yson_struct.h>
@@ -28,10 +27,9 @@ struct TPeriodicExecutorOptions
////////////////////////////////////////////////////////////////////////////////
struct TRetryingPeriodicExecutorOptions
-{
- TPeriodicExecutorOptions Periodic;
- TExponentialBackoffOptions BackoffStrategy;
-};
+ : public TPeriodicExecutorOptions
+ , public TExponentialBackoffOptions
+{ };
////////////////////////////////////////////////////////////////////////////////
@@ -40,7 +38,7 @@ namespace NDetail {
////////////////////////////////////////////////////////////////////////////////
class TPeriodicExecutorOptionsSerializer
- : public NYTree::TExternalizedYsonStruct
+ : public virtual NYTree::TExternalizedYsonStruct
{
public:
REGISTER_EXTERNALIZED_YSON_STRUCT(TPeriodicExecutorOptions, TPeriodicExecutorOptionsSerializer);
@@ -51,10 +49,15 @@ public:
////////////////////////////////////////////////////////////////////////////////
class TRetryingPeriodicExecutorOptionsSerializer
- : public NYTree::TExternalizedYsonStruct
+ : public TPeriodicExecutorOptionsSerializer
+ , public ::NYT::NDetail::TExponentialBackoffOptionsSerializer
{
public:
- REGISTER_EXTERNALIZED_YSON_STRUCT(TRetryingPeriodicExecutorOptions, TRetryingPeriodicExecutorOptionsSerializer);
+ REGISTER_DERIVED_EXTERNALIZED_YSON_STRUCT(
+ TRetryingPeriodicExecutorOptions,
+ TRetryingPeriodicExecutorOptionsSerializer,
+ (TPeriodicExecutorOptionsSerializer)
+ (::NYT::NDetail::TExponentialBackoffOptionsSerializer));
static void Register(TRegistrar registrar);
};
diff --git a/yt/yt/core/concurrency/retrying_periodic_executor.cpp b/yt/yt/core/concurrency/retrying_periodic_executor.cpp
index f8df164712..3be49c6001 100644
--- a/yt/yt/core/concurrency/retrying_periodic_executor.cpp
+++ b/yt/yt/core/concurrency/retrying_periodic_executor.cpp
@@ -21,8 +21,8 @@ namespace NDetail {
TRetryingInvocationTimePolicy::TRetryingInvocationTimePolicy(
const TOptions& options)
- : TDefaultInvocationTimePolicy(options.Periodic)
- , Backoff_(options.BackoffStrategy)
+ : TDefaultInvocationTimePolicy(options)
+ , Backoff_(options)
{ }
void TRetryingInvocationTimePolicy::ProcessResult(TError result)
@@ -40,7 +40,7 @@ void TRetryingInvocationTimePolicy::ProcessResult(TError result)
bool TRetryingInvocationTimePolicy::ShouldKickstart(const TOptions& newOptions)
{
- return ShouldKickstart(newOptions.Periodic, std::nullopt);
+ return ShouldKickstart(newOptions, std::nullopt);
}
bool TRetryingInvocationTimePolicy::ShouldKickstart(
@@ -54,7 +54,7 @@ bool TRetryingInvocationTimePolicy::ShouldKickstart(
void TRetryingInvocationTimePolicy::SetOptions(TOptions newOptions)
{
- SetOptions(newOptions.Periodic, newOptions.BackoffStrategy);
+ SetOptions(newOptions, newOptions);
}
void TRetryingInvocationTimePolicy::SetOptions(
@@ -69,6 +69,9 @@ void TRetryingInvocationTimePolicy::SetOptions(
CachedBackoffMultiplier_.store(
backoffOptions->BackoffMultiplier,
std::memory_order::relaxed);
+ CachedBackoffJitter_.store(
+ backoffOptions->BackoffJitter,
+ std::memory_order::relaxed);
Backoff_.UpdateOptions(*backoffOptions);
}
@@ -93,11 +96,15 @@ void TRetryingInvocationTimePolicy::Reset()
Backoff_.Restart();
}
-TDuration TRetryingInvocationTimePolicy::GetBackoffTimeEstimate() const
+std::tuple<TDuration, TDuration> TRetryingInvocationTimePolicy::GetBackoffInterval() const
{
- return
+ auto backoffMedian =
CachedBackoffDuration_.load(std::memory_order::relaxed) *
CachedBackoffMultiplier_.load(std::memory_order::relaxed);
+
+ auto backoffJitter = CachedBackoffJitter_.load(std::memory_order::relaxed);
+
+ return std::tuple(backoffMedian * (1 - backoffJitter), backoffMedian * (1 + backoffJitter));
}
bool TRetryingInvocationTimePolicy::IsInBackoffMode() const
@@ -149,9 +156,9 @@ TRetryingPeriodicExecutor::TRetryingPeriodicExecutor(
backoffOptions)
{ }
-TDuration TRetryingPeriodicExecutor::GetBackoffTimeEstimate() const
+std::tuple<TDuration, TDuration> TRetryingPeriodicExecutor::GetBackoffInterval() const
{
- return TBase::GetBackoffTimeEstimate();
+ return TBase::GetBackoffInterval();
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/yt/yt/core/concurrency/retrying_periodic_executor.h b/yt/yt/core/concurrency/retrying_periodic_executor.h
index 2bc1b2f3bf..6cb6d36a3e 100644
--- a/yt/yt/core/concurrency/retrying_periodic_executor.h
+++ b/yt/yt/core/concurrency/retrying_periodic_executor.h
@@ -6,7 +6,7 @@
#include <yt/yt/core/actions/callback.h>
#include <yt/yt/core/actions/future.h>
-#include <yt/yt/core/misc/backoff_strategy_config.h>
+#include <yt/yt/core/misc/config.h>
namespace NYT::NConcurrency {
@@ -47,12 +47,13 @@ public:
void Reset();
- TDuration GetBackoffTimeEstimate() const;
+ std::tuple<TDuration, TDuration> GetBackoffInterval() const;
private:
//! Used for backoff time estimation
std::atomic<TDuration> CachedBackoffDuration_;
std::atomic<double> CachedBackoffMultiplier_;
+ std::atomic<double> CachedBackoffJitter_;
TBackoffStrategy Backoff_;
@@ -86,7 +87,7 @@ public:
TExponentialBackoffOptions backoffOptions,
std::optional<TDuration> period = {});
- TDuration GetBackoffTimeEstimate() const;
+ std::tuple<TDuration, TDuration> GetBackoffInterval() const;
private:
using TBase = NDetail::TPeriodicExecutorBase<NDetail::TRetryingInvocationTimePolicy>;
diff --git a/yt/yt/core/misc/backoff_strategy.cpp b/yt/yt/core/misc/backoff_strategy.cpp
index 0bb28fdfa4..678a782a4b 100644
--- a/yt/yt/core/misc/backoff_strategy.cpp
+++ b/yt/yt/core/misc/backoff_strategy.cpp
@@ -20,19 +20,6 @@ double BackoffStrategyDefaultRandomGenerator()
////////////////////////////////////////////////////////////////////////////////
-TConstantBackoffOptions::operator TExponentialBackoffOptions() const
-{
- return TExponentialBackoffOptions{
- .InvocationCount = InvocationCount,
- .MinBackoff = Backoff,
- .MaxBackoff = Backoff,
- .BackoffMultiplier = 1.0,
- .BackoffJitter = BackoffJitter
- };
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
TBackoffStrategy::TBackoffStrategy(const TExponentialBackoffOptions& options)
: Options_(options)
{
diff --git a/yt/yt/core/misc/backoff_strategy.h b/yt/yt/core/misc/backoff_strategy.h
index 3a05d09354..d8549de65c 100644
--- a/yt/yt/core/misc/backoff_strategy.h
+++ b/yt/yt/core/misc/backoff_strategy.h
@@ -1,44 +1,12 @@
#pragma once
-#include "jitter.h"
+#include "config.h"
#include "public.h"
namespace NYT {
////////////////////////////////////////////////////////////////////////////////
-struct TExponentialBackoffOptions
-{
- static constexpr int DefaultInvocationCount = 10;
- static constexpr auto DefaultMinBackoff = TDuration::Seconds(1);
- static constexpr auto DefaultMaxBackoff = TDuration::Seconds(5);
- static constexpr double DefaultBackoffMultiplier = 1.5;
- static constexpr double DefaultBackoffJitter = 0.1;
-
- int InvocationCount = DefaultInvocationCount;
- TDuration MinBackoff = DefaultMinBackoff;
- TDuration MaxBackoff = DefaultMaxBackoff;
- double BackoffMultiplier = DefaultBackoffMultiplier;
- double BackoffJitter = DefaultBackoffJitter;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct TConstantBackoffOptions
-{
- static constexpr int DefaultInvocationCount = 10;
- static constexpr auto DefaultBackoff = TDuration::Seconds(3);
- static constexpr double DefaultBackoffJitter = 0.1;
-
- int InvocationCount = DefaultInvocationCount;
- TDuration Backoff = DefaultBackoff;
- double BackoffJitter = DefaultBackoffJitter;
-
- operator TExponentialBackoffOptions() const;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
//! Implements exponential backoffs with jitter.
//! Expected use after restart is Next() -> GetBackoff() (not the other way around).
class TBackoffStrategy
diff --git a/yt/yt/core/misc/backoff_strategy_config.cpp b/yt/yt/core/misc/backoff_strategy_config.cpp
deleted file mode 100644
index 7f02bb9f62..0000000000
--- a/yt/yt/core/misc/backoff_strategy_config.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-#include "backoff_strategy_config.h"
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-void TExponentialBackoffOptionsSerializer::Register(TRegistrar registrar)
-{
- registrar.ExternalClassParameter("invocation_count", &TThat::InvocationCount)
- .Alias("retry_count")
- .Default(TThat::DefaultInvocationCount);
-
- registrar.ExternalClassParameter("min_backoff", &TThat::MinBackoff)
- .Default(TThat::DefaultMinBackoff);
-
- registrar.ExternalClassParameter("max_backoff", &TThat::MaxBackoff)
- .Default(TThat::DefaultMaxBackoff);
-
- registrar.ExternalClassParameter("backoff_multiplier", &TThat::BackoffMultiplier)
- .Default(TThat::DefaultBackoffMultiplier)
- .GreaterThanOrEqual(1.0);
-
- registrar.ExternalClassParameter("backoff_jitter", &TThat::BackoffJitter)
- .Default(TThat::DefaultBackoffJitter);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-void TConstantBackoffOptionsSerializer::Register(TRegistrar registrar)
-{
- registrar.ExternalClassParameter("invocation_count", &TThat::InvocationCount)
- .Alias("retry_count")
- .Default(TThat::DefaultInvocationCount);
-
- registrar.ExternalClassParameter("backoff", &TThat::Backoff)
- .Default(TThat::DefaultBackoff);
-
- registrar.ExternalClassParameter("backoff_jitter", &TThat::BackoffJitter)
- .Default(TThat::DefaultBackoffJitter);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
diff --git a/yt/yt/core/misc/backoff_strategy_config.h b/yt/yt/core/misc/backoff_strategy_config.h
deleted file mode 100644
index 47038589ff..0000000000
--- a/yt/yt/core/misc/backoff_strategy_config.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-
-#include "backoff_strategy.h"
-
-#include <yt/yt/core/ytree/yson_struct.h>
-
-namespace NYT {
-
-////////////////////////////////////////////////////////////////////////////////
-
-class TExponentialBackoffOptionsSerializer
- : public NYTree::TExternalizedYsonStruct
-{
-public:
- REGISTER_EXTERNALIZED_YSON_STRUCT(TExponentialBackoffOptions, TExponentialBackoffOptionsSerializer);
-
- static void Register(TRegistrar registrar);
-};
-
-ASSIGN_EXTERNAL_YSON_SERIALIZER(TExponentialBackoffOptions, TExponentialBackoffOptionsSerializer);
-
-////////////////////////////////////////////////////////////////////////////////
-
-class TConstantBackoffOptionsSerializer
- : public NYTree::TExternalizedYsonStruct
-{
-public:
- REGISTER_EXTERNALIZED_YSON_STRUCT(TConstantBackoffOptions, TConstantBackoffOptionsSerializer);
-
- static void Register(TRegistrar registrar);
-};
-
-ASSIGN_EXTERNAL_YSON_SERIALIZER(TConstantBackoffOptions, TConstantBackoffOptionsSerializer);
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT
diff --git a/yt/yt/core/misc/config.cpp b/yt/yt/core/misc/config.cpp
index a33279b9b0..c888012afe 100644
--- a/yt/yt/core/misc/config.cpp
+++ b/yt/yt/core/misc/config.cpp
@@ -4,6 +4,19 @@ namespace NYT {
////////////////////////////////////////////////////////////////////////////////
+TConstantBackoffOptions::operator TExponentialBackoffOptions() const
+{
+ return TExponentialBackoffOptions{
+ .InvocationCount = InvocationCount,
+ .MinBackoff = Backoff,
+ .MaxBackoff = Backoff,
+ .BackoffMultiplier = 1.0,
+ .BackoffJitter = BackoffJitter
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
void TLogDigestConfig::Register(TRegistrar registrar)
{
registrar.Parameter("relative_precision", &TThis::RelativePrecision)
@@ -128,4 +141,45 @@ void TAdaptiveHedgingManagerConfig::Register(TRegistrar registrar)
////////////////////////////////////////////////////////////////////////////////
+namespace NDetail {
+
+void TExponentialBackoffOptionsSerializer::Register(TRegistrar registrar)
+{
+ registrar.ExternalClassParameter("invocation_count", &TThat::InvocationCount)
+ .Alias("retry_count")
+ .Default(TThat::DefaultInvocationCount);
+
+ registrar.ExternalClassParameter("min_backoff", &TThat::MinBackoff)
+ .Default(TThat::DefaultMinBackoff);
+
+ registrar.ExternalClassParameter("max_backoff", &TThat::MaxBackoff)
+ .Default(TThat::DefaultMaxBackoff);
+
+ registrar.ExternalClassParameter("backoff_multiplier", &TThat::BackoffMultiplier)
+ .Default(TThat::DefaultBackoffMultiplier)
+ .GreaterThanOrEqual(1.0);
+
+ registrar.ExternalClassParameter("backoff_jitter", &TThat::BackoffJitter)
+ .Default(TThat::DefaultBackoffJitter);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void TConstantBackoffOptionsSerializer::Register(TRegistrar registrar)
+{
+ registrar.ExternalClassParameter("invocation_count", &TThat::InvocationCount)
+ .Alias("retry_count")
+ .Default(TThat::DefaultInvocationCount);
+
+ registrar.ExternalClassParameter("backoff", &TThat::Backoff)
+ .Default(TThat::DefaultBackoff);
+
+ registrar.ExternalClassParameter("backoff_jitter", &TThat::BackoffJitter)
+ .Default(TThat::DefaultBackoffJitter);
+}
+
+} // namespace NDetail
+
+////////////////////////////////////////////////////////////////////////////////
+
} // namespace NYT
diff --git a/yt/yt/core/misc/config.h b/yt/yt/core/misc/config.h
index bf10114bf0..7b928e2151 100644
--- a/yt/yt/core/misc/config.h
+++ b/yt/yt/core/misc/config.h
@@ -10,6 +10,38 @@ namespace NYT {
////////////////////////////////////////////////////////////////////////////////
+struct TExponentialBackoffOptions
+{
+ static constexpr int DefaultInvocationCount = 10;
+ static constexpr auto DefaultMinBackoff = TDuration::Seconds(1);
+ static constexpr auto DefaultMaxBackoff = TDuration::Seconds(5);
+ static constexpr double DefaultBackoffMultiplier = 1.5;
+ static constexpr double DefaultBackoffJitter = 0.1;
+
+ int InvocationCount = DefaultInvocationCount;
+ TDuration MinBackoff = DefaultMinBackoff;
+ TDuration MaxBackoff = DefaultMaxBackoff;
+ double BackoffMultiplier = DefaultBackoffMultiplier;
+ double BackoffJitter = DefaultBackoffJitter;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct TConstantBackoffOptions
+{
+ static constexpr int DefaultInvocationCount = 10;
+ static constexpr auto DefaultBackoff = TDuration::Seconds(3);
+ static constexpr double DefaultBackoffJitter = 0.1;
+
+ int InvocationCount = DefaultInvocationCount;
+ TDuration Backoff = DefaultBackoff;
+ double BackoffJitter = DefaultBackoffJitter;
+
+ operator TExponentialBackoffOptions() const;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
class TLogDigestConfig
: public NYTree::TYsonStruct
{
@@ -114,4 +146,36 @@ DEFINE_REFCOUNTED_TYPE(TAdaptiveHedgingManagerConfig)
////////////////////////////////////////////////////////////////////////////////
+namespace NDetail {
+
+class TExponentialBackoffOptionsSerializer
+ : public virtual NYTree::TExternalizedYsonStruct
+{
+public:
+ REGISTER_EXTERNALIZED_YSON_STRUCT(TExponentialBackoffOptions, TExponentialBackoffOptionsSerializer);
+
+ static void Register(TRegistrar registrar);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+class TConstantBackoffOptionsSerializer
+ : public NYTree::TExternalizedYsonStruct
+{
+public:
+ REGISTER_EXTERNALIZED_YSON_STRUCT(TConstantBackoffOptions, TConstantBackoffOptionsSerializer);
+
+ static void Register(TRegistrar registrar);
+};
+
+
+
+} // namespace NDetail
+
+////////////////////////////////////////////////////////////////////////////////
+
} // namespace NYT
+
+ASSIGN_EXTERNAL_YSON_SERIALIZER(NYT::TExponentialBackoffOptions, NYT::NDetail::TExponentialBackoffOptionsSerializer);
+ASSIGN_EXTERNAL_YSON_SERIALIZER(NYT::TConstantBackoffOptions, NYT::NDetail::TConstantBackoffOptionsSerializer);
diff --git a/yt/yt/core/misc/protobuf_helpers-inl.h b/yt/yt/core/misc/protobuf_helpers-inl.h
index e8d74b6c6f..887d11974a 100644
--- a/yt/yt/core/misc/protobuf_helpers-inl.h
+++ b/yt/yt/core/misc/protobuf_helpers-inl.h
@@ -337,11 +337,11 @@ typename std::enable_if_t<std::is_trivial_v<TValue>> SetPairValueImpl(TProtoPair
template <class TSerializedArray, class T, class E, E Min, E Max>
void ToProtoArrayImpl(
TSerializedArray* serializedArray,
- const TEnumIndexedVector<E, T, Min, Max>& originalArray)
+ const TEnumIndexedArray<E, T, Min, Max>& originalArray)
{
serializedArray->Clear();
for (auto key : TEnumTraits<E>::GetDomainValues()) {
- if (originalArray.IsDomainValue(key)) {
+ if (originalArray.IsValidIndex(key)) {
const auto& value = originalArray[key];
auto* pair = serializedArray->Add();
pair->set_key(static_cast<i32>(key));
@@ -352,17 +352,17 @@ void ToProtoArrayImpl(
template <class T, class E, E Min, E Max, class TSerializedArray>
void FromProtoArrayImpl(
- TEnumIndexedVector<E, T, Min, Max>* originalArray,
+ TEnumIndexedArray<E, T, Min, Max>* originalArray,
const TSerializedArray& serializedArray)
{
for (auto key : TEnumTraits<E>::GetDomainValues()) {
- if (originalArray->IsDomainValue(key)) {
+ if (originalArray->IsValidIndex(key)) {
(*originalArray)[key] = T{};
}
}
for (const auto& pair : serializedArray) {
const auto& key = static_cast<E>(pair.key());
- if (originalArray->IsDomainValue(key)) {
+ if (originalArray->IsValidIndex(key)) {
FromProto(&(*originalArray)[key], pair.value());
}
}
diff --git a/yt/yt/core/misc/public.h b/yt/yt/core/misc/public.h
index 1577de2203..fa66b2ffef 100644
--- a/yt/yt/core/misc/public.h
+++ b/yt/yt/core/misc/public.h
@@ -191,10 +191,18 @@ struct TIsInvocable;
template <class T, class TRet, bool NoExcept, class... TArgs>
struct TIsInvocable<T, TRet(TArgs...) noexcept(NoExcept)>
{
+private:
+ static constexpr bool IsInvocable_ = requires (T&& t, TArgs&&... args) {
+ { std::forward<T>(t)(std::forward<TArgs>(args)...) } -> std::same_as<TRet>;
+ };
+
+ static constexpr bool IsNoThrowInvocable_ = requires (T&& t, TArgs&&... args) {
+ { std::forward<T>(t)(std::forward<TArgs>(args)...) } noexcept;
+ };
+public:
static constexpr bool Value =
- NoExcept ?
- std::is_nothrow_invocable_r_v<TRet, T, TArgs...> :
- std::is_invocable_r_v<TRet, T, TArgs...>;
+ IsInvocable_ &&
+ (!NoExcept || IsNoThrowInvocable_);
};
template <class T, class Sig>
diff --git a/yt/yt/core/misc/serialize-inl.h b/yt/yt/core/misc/serialize-inl.h
index 5269014db1..6a0948e051 100644
--- a/yt/yt/core/misc/serialize-inl.h
+++ b/yt/yt/core/misc/serialize-inl.h
@@ -10,6 +10,8 @@
#include <library/cpp/yt/small_containers/compact_flat_map.h>
#include <library/cpp/yt/small_containers/compact_set.h>
+#include <library/cpp/yt/misc/enum_indexed_array.h>
+
#include <optional>
#include <variant>
@@ -1356,17 +1358,17 @@ struct TOptionalListSerializer
};
template <class TItemSerializer = TDefaultSerializer>
-struct TEnumIndexedVectorSerializer
+struct TEnumIndexedArraySerializer
{
template <class E, class T, class C, E Min, E Max>
- static void Save(C& context, const TEnumIndexedVector<E, T, Min, Max>& vector)
+ static void Save(C& context, const TEnumIndexedArray<E, T, Min, Max>& vector)
{
using NYT::Save;
auto keys = TEnumTraits<E>::GetDomainValues();
size_t count = 0;
for (auto key : keys) {
- if (!vector.IsDomainValue(key)) {
+ if (!vector.IsValidIndex(key)) {
continue;
}
++count;
@@ -1375,7 +1377,7 @@ struct TEnumIndexedVectorSerializer
TSizeSerializer::Save(context, count);
for (auto key : keys) {
- if (!vector.IsDomainValue(key)) {
+ if (!vector.IsValidIndex(key)) {
continue;
}
Save(context, key);
@@ -1384,7 +1386,7 @@ struct TEnumIndexedVectorSerializer
}
template <class E, class T, class C, E Min, E Max>
- static void Load(C& context, TEnumIndexedVector<E, T, Min, Max>& vector)
+ static void Load(C& context, TEnumIndexedArray<E, T, Min, Max>& vector)
{
if constexpr (std::is_copy_assignable_v<T>) {
std::fill(vector.begin(), vector.end(), T());
@@ -1403,7 +1405,7 @@ struct TEnumIndexedVectorSerializer
auto key = LoadSuspended<E>(context);
SERIALIZATION_DUMP_WRITE(context, "%v =>", key);
SERIALIZATION_DUMP_INDENT(context) {
- if (!vector.IsDomainValue(key)) {
+ if (!vector.IsValidIndex(key)) {
T dummy;
TItemSerializer::Load(context, dummy);
} else {
@@ -1967,9 +1969,9 @@ struct TSerializerTraits<THashMultiMap<K, V>, C, void>
};
template <class E, class T, class C, E Min, E Max>
-struct TSerializerTraits<TEnumIndexedVector<E, T, Min, Max>, C, void>
+struct TSerializerTraits<TEnumIndexedArray<E, T, Min, Max>, C, void>
{
- using TSerializer = TEnumIndexedVectorSerializer<>;
+ using TSerializer = TEnumIndexedArraySerializer<>;
};
template <class F, class S, class C>
diff --git a/yt/yt/core/rpc/bus/channel.cpp b/yt/yt/core/rpc/bus/channel.cpp
index 513fa531c1..e5d04ea83a 100644
--- a/yt/yt/core/rpc/bus/channel.cpp
+++ b/yt/yt/core/rpc/bus/channel.cpp
@@ -162,7 +162,7 @@ private:
bool Terminated = false;
};
- TEnumIndexedVector<EMultiplexingBand, TBandBucket> Buckets_;
+ TEnumIndexedArray<EMultiplexingBand, TBandBucket> Buckets_;
std::atomic<bool> TerminationFlag_ = false;
TAtomicObject<TError> TerminationError_;
diff --git a/yt/yt/core/ya.make b/yt/yt/core/ya.make
index fe08f07e71..5bd8822192 100644
--- a/yt/yt/core/ya.make
+++ b/yt/yt/core/ya.make
@@ -107,7 +107,6 @@ SRCS(
misc/arithmetic_formula.cpp
GLOBAL misc/assert.cpp
misc/backoff_strategy.cpp
- misc/backoff_strategy_config.cpp
misc/bitmap.cpp
misc/bit_packed_unsigned_vector.cpp
misc/bit_packing.cpp
diff --git a/yt/yt/core/yson/pull_parser_deserialize-inl.h b/yt/yt/core/yson/pull_parser_deserialize-inl.h
index c5e39e7df8..9d45eec2a7 100644
--- a/yt/yt/core/yson/pull_parser_deserialize-inl.h
+++ b/yt/yt/core/yson/pull_parser_deserialize-inl.h
@@ -281,7 +281,7 @@ void Deserialize(
template <class E, class T, E Min, E Max>
void Deserialize(
- TEnumIndexedVector<E, T, Min, Max>& vector,
+ TEnumIndexedArray<E, T, Min, Max>& vector,
TYsonPullParserCursor* cursor,
std::enable_if_t<ArePullParserDeserializable<T>(), void*>)
{
@@ -289,7 +289,7 @@ void Deserialize(
auto itemVisitor = [&] (TYsonPullParserCursor* cursor) {
auto key = ExtractTo<E>(cursor);
- if (!vector.IsDomainValue(key)) {
+ if (!vector.IsValidIndex(key)) {
THROW_ERROR_EXCEPTION("Enum value %Qlv is out of supported range",
key);
}
diff --git a/yt/yt/core/yson/pull_parser_deserialize.h b/yt/yt/core/yson/pull_parser_deserialize.h
index 0a03fc775e..20cd57b68a 100644
--- a/yt/yt/core/yson/pull_parser_deserialize.h
+++ b/yt/yt/core/yson/pull_parser_deserialize.h
@@ -4,12 +4,14 @@
#include "pull_parser.h"
+#include <library/cpp/yt/misc/enum_indexed_array.h>
+
namespace NYT::NYson {
////////////////////////////////////////////////////////////////////////////////
-inline void SkipAttributes(TYsonPullParserCursor* cursor);
-inline void MaybeSkipAttributes(TYsonPullParserCursor* cursor);
+void SkipAttributes(TYsonPullParserCursor* cursor);
+void MaybeSkipAttributes(TYsonPullParserCursor* cursor);
////////////////////////////////////////////////////////////////////////////////
@@ -17,12 +19,12 @@ namespace NDetail {
template <typename T, typename = void>
struct TIsPullParserDeserializable
- : std::false_type
+ : public std::false_type
{ };
template <typename T>
struct TIsPullParserDeserializable<T, std::void_t<decltype(Deserialize(std::declval<T&>(), (NYson::TYsonPullParserCursor*)(nullptr)))>>
- : std::true_type
+ : public std::true_type
{ };
template <typename T>
@@ -145,7 +147,7 @@ void Deserialize(
template <class E, class T, E Min, E Max>
void Deserialize(
- TEnumIndexedVector<E, T, Min, Max>& vector,
+ TEnumIndexedArray<E, T, Min, Max>& vector,
TYsonPullParserCursor* cursor,
std::enable_if_t<ArePullParserDeserializable<T>(), void*> = nullptr);
diff --git a/yt/yt/core/ytalloc/bindings.cpp b/yt/yt/core/ytalloc/bindings.cpp
index 33eb077a5b..72b866114d 100644
--- a/yt/yt/core/ytalloc/bindings.cpp
+++ b/yt/yt/core/ytalloc/bindings.cpp
@@ -127,7 +127,7 @@ private:
void PushSmallArenaStatistics(
NProfiling::ISensorWriter* writer,
size_t rank,
- const TEnumIndexedVector<ESmallArenaCounter, ssize_t>& counters)
+ const TEnumIndexedArray<ESmallArenaCounter, ssize_t>& counters)
{
NProfiling::TWithTagGuard withTagGuard(writer, "rank", ToString(rank));
PushAllocationCounterStatistics(writer, "/small_arena", counters);
@@ -147,7 +147,7 @@ private:
void PushLargeArenaStatistics(
NProfiling::ISensorWriter* writer,
size_t rank,
- const TEnumIndexedVector<ELargeArenaCounter, ssize_t>& counters)
+ const TEnumIndexedArray<ELargeArenaCounter, ssize_t>& counters)
{
NProfiling::TWithTagGuard withTagGuard(writer, "rank", ToString(rank));
diff --git a/yt/yt/core/ytree/serialize-inl.h b/yt/yt/core/ytree/serialize-inl.h
index 74a1ad9c4d..eea8f121b4 100644
--- a/yt/yt/core/ytree/serialize-inl.h
+++ b/yt/yt/core/ytree/serialize-inl.h
@@ -426,11 +426,11 @@ void Serialize(const C<T...>& value, NYson::IYsonConsumer* consumer)
}
template <class E, class T, E Min, E Max>
-void Serialize(const TEnumIndexedVector<E, T, Min, Max>& vector, NYson::IYsonConsumer* consumer)
+void Serialize(const TEnumIndexedArray<E, T, Min, Max>& vector, NYson::IYsonConsumer* consumer)
{
consumer->OnBeginMap();
for (auto key : TEnumTraits<E>::GetDomainValues()) {
- if (!vector.IsDomainValue(key)) {
+ if (!vector.IsValidIndex(key)) {
continue;
}
const auto& value = vector[key];
@@ -614,13 +614,13 @@ void Deserialize(C<T...>& value, INodePtr node)
}
template <class E, class T, E Min, E Max>
-void Deserialize(TEnumIndexedVector<E, T, Min, Max>& vector, INodePtr node)
+void Deserialize(TEnumIndexedArray<E, T, Min, Max>& vector, INodePtr node)
{
vector = {};
auto mapNode = node->AsMap();
for (const auto& [stringKey, child] : mapNode->GetChildren()) {
auto key = ParseEnum<E>(stringKey);
- if (!vector.IsDomainValue(key)) {
+ if (!vector.IsValidIndex(key)) {
THROW_ERROR_EXCEPTION("Enum value %Qlv is out of supported range",
key);
}
diff --git a/yt/yt/core/ytree/serialize.h b/yt/yt/core/ytree/serialize.h
index 046f5f3e18..ed58a6f934 100644
--- a/yt/yt/core/ytree/serialize.h
+++ b/yt/yt/core/ytree/serialize.h
@@ -12,6 +12,8 @@
#include <library/cpp/yt/small_containers/compact_vector.h>
+#include <library/cpp/yt/misc/enum_indexed_array.h>
+
#include <optional>
namespace NYT::NYTree {
@@ -138,9 +140,9 @@ void Serialize(const std::tuple<T...>& value, NYson::IYsonConsumer* consumer);
template <template<typename...> class C, class... T, class K = typename C<T...>::key_type>
void Serialize(const C<T...>& value, NYson::IYsonConsumer* consumer);
-// TEnumIndexedVector
+// TEnumIndexedArray
template <class E, class T, E Min, E Max>
-void Serialize(const TEnumIndexedVector<E, T, Min, Max>& value, NYson::IYsonConsumer* consumer);
+void Serialize(const TEnumIndexedArray<E, T, Min, Max>& value, NYson::IYsonConsumer* consumer);
// Subtypes of google::protobuf::Message
template <class T>
@@ -241,9 +243,9 @@ void Deserialize(std::tuple<T...>& value, INodePtr node);
template <template<typename...> class C, class... T, class K = typename C<T...>::key_type>
void Deserialize(C<T...>& value, INodePtr node);
-// TEnumIndexedVector
+// TEnumIndexedArray
template <class E, class T, E Min, E Max>
-void Deserialize(TEnumIndexedVector<E, T, Min, Max>& vector, INodePtr node);
+void Deserialize(TEnumIndexedArray<E, T, Min, Max>& vector, INodePtr node);
// Subtypes of google::protobuf::Message
template <class T>
diff --git a/yt/yt/core/ytree/ypath_detail.cpp b/yt/yt/core/ytree/ypath_detail.cpp
index bb8aed4797..1cc159b24f 100644
--- a/yt/yt/core/ytree/ypath_detail.cpp
+++ b/yt/yt/core/ytree/ypath_detail.cpp
@@ -1077,7 +1077,7 @@ void TSupportsAttributes::DoRemoveAttribute(const TYPath& path, bool force)
}
if (!descriptor->Writable) {
- ThrowCannotSetBuiltinAttribute(key);
+ ThrowCannotRemoveAttribute(key);
}
permissionValidator.Validate(descriptor->ModifyPermission);
diff --git a/yt/yt/flow/lib/client/public.h b/yt/yt/flow/lib/client/public.h
index c813f0d5f6..e1812eaa08 100644
--- a/yt/yt/flow/lib/client/public.h
+++ b/yt/yt/flow/lib/client/public.h
@@ -27,6 +27,10 @@ DEFINE_ENUM(EPipelineState,
((Completed) (6))
);
+YT_DEFINE_ERROR_ENUM(
+ ((SpecVersionMismatch) (3300))
+);
+
YT_DEFINE_STRONG_TYPEDEF(TVersion, i64);
////////////////////////////////////////////////////////////////////////////////
diff --git a/yt/yt/library/column_converters/column_converter.cpp b/yt/yt/library/column_converters/column_converter.cpp
index 40d7a13733..b177657daa 100644
--- a/yt/yt/library/column_converters/column_converter.cpp
+++ b/yt/yt/library/column_converters/column_converter.cpp
@@ -107,7 +107,7 @@ TConvertedColumnRange TColumnConverters::ConvertRowsToColumns(
YT_VERIFY(iterSchema != columnSchema.end());
auto converter = CreateColumnConvert(iterSchema->second, ColumnIds_[offset], offset);
auto columns = converter->Convert(rowsValues);
- convertedColumnsRange.emplace_back(std::move(columns));
+ convertedColumnsRange.push_back(std::move(columns));
}
return convertedColumnsRange;
}
diff --git a/yt/yt/library/column_converters/string_column_converter.cpp b/yt/yt/library/column_converters/string_column_converter.cpp
index 68e1732386..f943d02e1c 100644
--- a/yt/yt/library/column_converters/string_column_converter.cpp
+++ b/yt/yt/library/column_converters/string_column_converter.cpp
@@ -274,9 +274,9 @@ private:
}
}
- TEnumIndexedVector<EUnversionedStringSegmentType, ui64> GetEncodingMethodsCosts() const
+ TEnumIndexedArray<EUnversionedStringSegmentType, ui64> GetEncodingMethodsCosts() const
{
- TEnumIndexedVector<EUnversionedStringSegmentType, ui64> costs;
+ TEnumIndexedArray<EUnversionedStringSegmentType, ui64> costs;
for (auto type : TEnumTraits<EUnversionedStringSegmentType>::GetDomainValues()) {
costs[type] = GetSpecificEncodingMethodCosts(type);
}
diff --git a/yt/yt/library/formats/web_json_writer.cpp b/yt/yt/library/formats/web_json_writer.cpp
index 582b2291a0..fdab73f878 100644
--- a/yt/yt/library/formats/web_json_writer.cpp
+++ b/yt/yt/library/formats/web_json_writer.cpp
@@ -343,7 +343,7 @@ private:
std::vector<TLogicalTypePtr> Types_;
std::vector<std::vector<int>> TableIndexToColumnIdToTypeIndex_;
THashMap<std::pair<int, TString>, int> TableIndexAndColumnNameToTypeIndex_;
- TEnumIndexedVector<EValueType, int> ValueTypeToTypeIndex_;
+ TEnumIndexedArray<EValueType, int> ValueTypeToTypeIndex_;
private:
int GetTypeIndex(int tableIndex, ui16 columnId, TStringBuf columnName, EValueType valueType)
diff --git a/yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto b/yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto
index 12fa0acd9a..9cab02e727 100644
--- a/yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto
+++ b/yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto
@@ -589,6 +589,7 @@ message TReqSelectRows
optional bytes placeholder_values = 18; // YSON
optional bool new_range_inference = 19;
optional bool use_canonical_null_relations = 20;
+ optional bool merge_versioned_rows = 21;
optional TSuppressableAccessTrackingOptions suppressable_access_tracking_options = 104;
}