
out2x
8build/make/tools/ide_query/prober_scripts/cpp/general.cc8build/make/tools/ide_query/prober_scripts/cpp/general.cc:½õ
8build/make/tools/ide_query/prober_scripts/cpp/general.cc8build/make/tools/ide_query/prober_scripts/cpp/general.cc"8prebuilts/clang/host/linux-x86/clang-r563880/bin/clang++"-nostdlibinc"-mthumb"-Os"-fomit-frame-pointer"-mllvm"-enable-shrink-wrap=false"-O2"-Wall"-Wextra"-Wpointer-arith"-Wunguarded-availability"-Werror=bool-operation"-Werror=date-time"-Werror=int-conversion"-Werror=multichar"-Werror=pragma-pack"&-Werror=pragma-pack-suspicious-include"-Werror=sizeof-array-div" -Werror=sizeof-pointer-memaccess"-Werror=string-plus-int"'-Werror=unreachable-code-loop-increment""-Wno-error=deprecated-declarations"-Wno-c23-extensions"-Wno-c99-designator"-Wno-gnu-folding-constant""-Wno-inconsistent-missing-override"-Wno-error=reorder-init-list"-Wno-reorder-init-list"-Wno-sign-compare"-Wno-unused"	-DANDROID"-DNDEBUG"-UDEBUG"(-D__compiler_offsetof=__builtin_offsetof"*-D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__"	-faddrsig"-fdebug-default-version=5"-fcolor-diagnostics"-ffp-contract=off"-fno-exceptions"-fno-strict-aliasing"-fmessage-length=0"-gsimple-template-names"-gz=zstd"-no-canonical-prefixes""-fdebug-prefix-map=/proc/self/cwd="-ftrivial-auto-var-init=zero"-g"-ffunction-sections"-fdata-sections"-fno-short-enums"-funwind-tables"-fstack-protector-strong"-Wa,--noexecstack"-D_FORTIFY_SOURCE=3"-Werror=non-virtual-dtor"-Werror=address"-Werror=sequence-point"-Werror=format-security"-msoft-float"-march=armv7-a"-mfloat-abi=softfp"
-mfpu=neon"/-Ibuild/make/tools/ide_query/prober_scripts/cpp"³-Iout/soong/.intermediates/build/make/tools/ide_query/prober_scripts/cpp/ide_query_proberscript_cc/android_arm_armv7-a-neon/gen/proto/build/make/tools/ide_query/prober_scripts/cpp"…-Iout/soong/.intermediates/build/make/tools/ide_query/prober_scripts/cpp/ide_query_proberscript_cc/android_arm_armv7-a-neon/gen/proto"-D__LIBC_API__=10000"-D__LIBM_API__=10000"-D__LIBDL_API__=10000"-Iexternal/protobuf/src"k-Iout/soong/.intermediates/external/abseil-cpp/absl_base_config_hdrs/gen/external/abseil-cpp/my_include_dir"W-Iout/soong/.intermediates/external/abseil-cpp/absl_base_config_hdrs/gen/my_include_dir"q-Iout/soong/.intermediates/external/abseil-cpp/absl_base_core_headers_hdrs/gen/external/abseil-cpp/my_include_dir"]-Iout/soong/.intermediates/external/abseil-cpp/absl_base_core_headers_hdrs/gen/my_include_dir"x-Iout/soong/.intermediates/external/abseil-cpp/absl_base_dynamic_annotations_hdrs/gen/external/abseil-cpp/my_include_dir"d-Iout/soong/.intermediates/external/abseil-cpp/absl_base_dynamic_annotations_hdrs/gen/my_include_dir"p-Iout/soong/.intermediates/external/abseil-cpp/absl_meta_type_traits_hdrs/gen/external/abseil-cpp/my_include_dir"\-Iout/soong/.intermediates/external/abseil-cpp/absl_meta_type_traits_hdrs/gen/my_include_dir"g-Iout/soong/.intermediates/external/abseil-cpp/absl_utility_hdrs/gen/external/abseil-cpp/my_include_dir"S-Iout/soong/.intermediates/external/abseil-cpp/absl_utility_hdrs/gen/my_include_dir"n-Iout/soong/.intermediates/external/abseil-cpp/absl_types_optional_hdrs/gen/external/abseil-cpp/my_include_dir"Z-Iout/soong/.intermediates/external/abseil-cpp/absl_types_optional_hdrs/gen/my_include_dir"p-Iout/soong/.intermediates/external/abseil-cpp/absl_container_common_hdrs/gen/external/abseil-cpp/my_include_dir"\-Iout/soong/.intermediates/external/abseil-cpp/absl_container_common_hdrs/gen/my_include_dir"~-Iout/soong/.intermediates/external/abseil-cpp/absl_container_common_policy_traits_hdrs/gen/external/abseil-cpp/my_include_dir"j-Iout/soong/.intermediates/external/abseil-cpp/absl_container_common_policy_traits_hdrs/gen/my_include_dir"z-Iout/soong/.intermediates/external/abseil-cpp/absl_container_compressed_tuple_hdrs/gen/external/abseil-cpp/my_include_dir"f-Iout/soong/.intermediates/external/abseil-cpp/absl_container_compressed_tuple_hdrs/gen/my_include_dir"f-Iout/soong/.intermediates/external/abseil-cpp/absl_memory_hdrs/gen/external/abseil-cpp/my_include_dir"R-Iout/soong/.intermediates/external/abseil-cpp/absl_memory_hdrs/gen/my_include_dir"z-Iout/soong/.intermediates/external/abseil-cpp/absl_container_container_memory_hdrs/gen/external/abseil-cpp/my_include_dir"f-Iout/soong/.intermediates/external/abseil-cpp/absl_container_container_memory_hdrs/gen/my_include_dir"p-Iout/soong/.intermediates/external/abseil-cpp/absl_base_atomic_hook_hdrs/gen/external/abseil-cpp/my_include_dir"\-Iout/soong/.intermediates/external/abseil-cpp/absl_base_atomic_hook_hdrs/gen/my_include_dir"r-Iout/soong/.intermediates/external/abseil-cpp/absl_base_base_internal_hdrs/gen/external/abseil-cpp/my_include_dir"^-Iout/soong/.intermediates/external/abseil-cpp/absl_base_base_internal_hdrs/gen/my_include_dir"x-Iout/soong/.intermediates/external/abseil-cpp/absl_base_cycleclock_internal_hdrs/gen/external/abseil-cpp/my_include_dir"d-Iout/soong/.intermediates/external/abseil-cpp/absl_base_cycleclock_internal_hdrs/gen/my_include_dir"q-Iout/soong/.intermediates/external/abseil-cpp/absl_base_log_severity_hdrs/gen/external/abseil-cpp/my_include_dir"]-Iout/soong/.intermediates/external/abseil-cpp/absl_base_log_severity_hdrs/gen/my_include_dir"p-Iout/soong/.intermediates/external/abseil-cpp/absl_base_nullability_hdrs/gen/external/abseil-cpp/my_include_dir"\-Iout/soong/.intermediates/external/abseil-cpp/absl_base_nullability_hdrs/gen/my_include_dir"p-Iout/soong/.intermediates/external/abseil-cpp/absl_base_errno_saver_hdrs/gen/external/abseil-cpp/my_include_dir"\-Iout/soong/.intermediates/external/abseil-cpp/absl_base_errno_saver_hdrs/gen/my_include_dir"y-Iout/soong/.intermediates/external/abseil-cpp/absl_base_raw_logging_internal_hdrs/gen/external/abseil-cpp/my_include_dir"e-Iout/soong/.intermediates/external/abseil-cpp/absl_base_raw_logging_internal_hdrs/gen/my_include_dir"r-Iout/soong/.intermediates/external/abseil-cpp/absl_base_spinlock_wait_hdrs/gen/external/abseil-cpp/my_include_dir"^-Iout/soong/.intermediates/external/abseil-cpp/absl_base_spinlock_wait_hdrs/gen/my_include_dir"d-Iout/soong/.intermediates/external/abseil-cpp/absl_base_hdrs/gen/external/abseil-cpp/my_include_dir"P-Iout/soong/.intermediates/external/abseil-cpp/absl_base_hdrs/gen/my_include_dir"k-Iout/soong/.intermediates/external/abseil-cpp/absl_base_endian_hdrs/gen/external/abseil-cpp/my_include_dir"W-Iout/soong/.intermediates/external/abseil-cpp/absl_base_endian_hdrs/gen/my_include_dir"l-Iout/soong/.intermediates/external/abseil-cpp/absl_numeric_bits_hdrs/gen/external/abseil-cpp/my_include_dir"X-Iout/soong/.intermediates/external/abseil-cpp/absl_numeric_bits_hdrs/gen/my_include_dir"†-Iout/soong/.intermediates/external/abseil-cpp/absl_debugging_bounded_utf8_length_sequence_hdrs/gen/external/abseil-cpp/my_include_dir"r-Iout/soong/.intermediates/external/abseil-cpp/absl_debugging_bounded_utf8_length_sequence_hdrs/gen/my_include_dir"}-Iout/soong/.intermediates/external/abseil-cpp/absl_debugging_utf8_for_code_point_hdrs/gen/external/abseil-cpp/my_include_dir"i-Iout/soong/.intermediates/external/abseil-cpp/absl_debugging_utf8_for_code_point_hdrs/gen/my_include_dir"~-Iout/soong/.intermediates/external/abseil-cpp/absl_debugging_decode_rust_punycode_hdrs/gen/external/abseil-cpp/my_include_dir"j-Iout/soong/.intermediates/external/abseil-cpp/absl_debugging_decode_rust_punycode_hdrs/gen/my_include_dir"w-Iout/soong/.intermediates/external/abseil-cpp/absl_debugging_demangle_rust_hdrs/gen/external/abseil-cpp/my_include_dir"c-Iout/soong/.intermediates/external/abseil-cpp/absl_debugging_demangle_rust_hdrs/gen/my_include_dir"{-Iout/soong/.intermediates/external/abseil-cpp/absl_debugging_demangle_internal_hdrs/gen/external/abseil-cpp/my_include_dir"g-Iout/soong/.intermediates/external/abseil-cpp/absl_debugging_demangle_internal_hdrs/gen/my_include_dir"s-Iout/soong/.intermediates/external/abseil-cpp/absl_base_throw_delegate_hdrs/gen/external/abseil-cpp/my_include_dir"_-Iout/soong/.intermediates/external/abseil-cpp/absl_base_throw_delegate_hdrs/gen/my_include_dir"s-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_string_view_hdrs/gen/external/abseil-cpp/my_include_dir"_-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_string_view_hdrs/gen/my_include_dir"o-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_charset_hdrs/gen/external/abseil-cpp/my_include_dir"[-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_charset_hdrs/gen/my_include_dir"p-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_internal_hdrs/gen/external/abseil-cpp/my_include_dir"\-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_internal_hdrs/gen/my_include_dir"}-Iout/soong/.intermediates/external/abseil-cpp/absl_base_iterator_traits_internal_hdrs/gen/external/abseil-cpp/my_include_dir"i-Iout/soong/.intermediates/external/abseil-cpp/absl_base_iterator_traits_internal_hdrs/gen/my_include_dir"m-Iout/soong/.intermediates/external/abseil-cpp/absl_types_compare_hdrs/gen/external/abseil-cpp/my_include_dir"Y-Iout/soong/.intermediates/external/abseil-cpp/absl_types_compare_hdrs/gen/my_include_dir"n-Iout/soong/.intermediates/external/abseil-cpp/absl_numeric_int128_hdrs/gen/external/abseil-cpp/my_include_dir"Z-Iout/soong/.intermediates/external/abseil-cpp/absl_numeric_int128_hdrs/gen/my_include_dir"g-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_hdrs/gen/external/abseil-cpp/my_include_dir"S-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_hdrs/gen/my_include_dir"i-Iout/soong/.intermediates/external/abseil-cpp/absl_algorithm_hdrs/gen/external/abseil-cpp/my_include_dir"U-Iout/soong/.intermediates/external/abseil-cpp/absl_algorithm_hdrs/gen/my_include_dir"y-Iout/soong/.intermediates/external/abseil-cpp/absl_hash_weakly_mixed_integer_hdrs/gen/external/abseil-cpp/my_include_dir"e-Iout/soong/.intermediates/external/abseil-cpp/absl_hash_weakly_mixed_integer_hdrs/gen/my_include_dir"j-Iout/soong/.intermediates/external/abseil-cpp/absl_types_span_hdrs/gen/external/abseil-cpp/my_include_dir"V-Iout/soong/.intermediates/external/abseil-cpp/absl_types_span_hdrs/gen/my_include_dir"p-Iout/soong/.intermediates/external/abseil-cpp/absl_container_layout_hdrs/gen/external/abseil-cpp/my_include_dir"\-Iout/soong/.intermediates/external/abseil-cpp/absl_container_layout_hdrs/gen/my_include_dir"�-Iout/soong/.intermediates/external/abseil-cpp/absl_container_inlined_vector_internal_hdrs/gen/external/abseil-cpp/my_include_dir"m-Iout/soong/.intermediates/external/abseil-cpp/absl_container_inlined_vector_internal_hdrs/gen/my_include_dir"x-Iout/soong/.intermediates/external/abseil-cpp/absl_container_inlined_vector_hdrs/gen/external/abseil-cpp/my_include_dir"d-Iout/soong/.intermediates/external/abseil-cpp/absl_container_inlined_vector_hdrs/gen/my_include_dir"n-Iout/soong/.intermediates/external/abseil-cpp/absl_crc_cpu_detect_hdrs/gen/external/abseil-cpp/my_include_dir"Z-Iout/soong/.intermediates/external/abseil-cpp/absl_crc_cpu_detect_hdrs/gen/my_include_dir"m-Iout/soong/.intermediates/external/abseil-cpp/absl_base_prefetch_hdrs/gen/external/abseil-cpp/my_include_dir"Y-Iout/soong/.intermediates/external/abseil-cpp/absl_base_prefetch_hdrs/gen/my_include_dir"p-Iout/soong/.intermediates/external/abseil-cpp/absl_crc_crc_internal_hdrs/gen/external/abseil-cpp/my_include_dir"\-Iout/soong/.intermediates/external/abseil-cpp/absl_crc_crc_internal_hdrs/gen/my_include_dir"-Iout/soong/.intermediates/external/abseil-cpp/absl_crc_non_temporal_arm_intrinsics_hdrs/gen/external/abseil-cpp/my_include_dir"k-Iout/soong/.intermediates/external/abseil-cpp/absl_crc_non_temporal_arm_intrinsics_hdrs/gen/my_include_dir"w-Iout/soong/.intermediates/external/abseil-cpp/absl_crc_non_temporal_memcpy_hdrs/gen/external/abseil-cpp/my_include_dir"c-Iout/soong/.intermediates/external/abseil-cpp/absl_crc_non_temporal_memcpy_hdrs/gen/my_include_dir"u-Iout/soong/.intermediates/external/abseil-cpp/absl_container_fixed_array_hdrs/gen/external/abseil-cpp/my_include_dir"a-Iout/soong/.intermediates/external/abseil-cpp/absl_container_fixed_array_hdrs/gen/my_include_dir"x-Iout/soong/.intermediates/external/abseil-cpp/absl_functional_any_invocable_hdrs/gen/external/abseil-cpp/my_include_dir"d-Iout/soong/.intermediates/external/abseil-cpp/absl_functional_any_invocable_hdrs/gen/my_include_dir"w-Iout/soong/.intermediates/external/abseil-cpp/absl_functional_function_ref_hdrs/gen/external/abseil-cpp/my_include_dir"c-Iout/soong/.intermediates/external/abseil-cpp/absl_functional_function_ref_hdrs/gen/my_include_dir"v-Iout/soong/.intermediates/external/abseil-cpp/absl_numeric_representation_hdrs/gen/external/abseil-cpp/my_include_dir"b-Iout/soong/.intermediates/external/abseil-cpp/absl_numeric_representation_hdrs/gen/my_include_dir"{-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_str_format_internal_hdrs/gen/external/abseil-cpp/my_include_dir"g-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_str_format_internal_hdrs/gen/my_include_dir"r-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_str_format_hdrs/gen/external/abseil-cpp/my_include_dir"^-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_str_format_hdrs/gen/my_include_dir"j-Iout/soong/.intermediates/external/abseil-cpp/absl_crc_crc32c_hdrs/gen/external/abseil-cpp/my_include_dir"V-Iout/soong/.intermediates/external/abseil-cpp/absl_crc_crc32c_hdrs/gen/my_include_dir"r-Iout/soong/.intermediates/external/abseil-cpp/absl_base_no_destructor_hdrs/gen/external/abseil-cpp/my_include_dir"^-Iout/soong/.intermediates/external/abseil-cpp/absl_base_no_destructor_hdrs/gen/my_include_dir"r-Iout/soong/.intermediates/external/abseil-cpp/absl_crc_crc_cord_state_hdrs/gen/external/abseil-cpp/my_include_dir"^-Iout/soong/.intermediates/external/abseil-cpp/absl_crc_crc_cord_state_hdrs/gen/my_include_dir"u-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_cord_internal_hdrs/gen/external/abseil-cpp/my_include_dir"a-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_cord_internal_hdrs/gen/my_include_dir"|-Iout/soong/.intermediates/external/abseil-cpp/absl_profiling_exponential_biased_hdrs/gen/external/abseil-cpp/my_include_dir"h-Iout/soong/.intermediates/external/abseil-cpp/absl_profiling_exponential_biased_hdrs/gen/my_include_dir"w-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_cordz_functions_hdrs/gen/external/abseil-cpp/my_include_dir"c-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_cordz_functions_hdrs/gen/my_include_dir"t-Iout/soong/.intermediates/external/abseil-cpp/absl_base_malloc_internal_hdrs/gen/external/abseil-cpp/my_include_dir"`-Iout/soong/.intermediates/external/abseil-cpp/absl_base_malloc_internal_hdrs/gen/my_include_dir"„-Iout/soong/.intermediates/external/abseil-cpp/absl_synchronization_graphcycles_internal_hdrs/gen/external/abseil-cpp/my_include_dir"p-Iout/soong/.intermediates/external/abseil-cpp/absl_synchronization_graphcycles_internal_hdrs/gen/my_include_dir"}-Iout/soong/.intermediates/external/abseil-cpp/absl_time_internal_cctz_civil_time_hdrs/gen/external/abseil-cpp/my_include_dir"i-Iout/soong/.intermediates/external/abseil-cpp/absl_time_internal_cctz_civil_time_hdrs/gen/my_include_dir"|-Iout/soong/.intermediates/external/abseil-cpp/absl_time_internal_cctz_time_zone_hdrs/gen/external/abseil-cpp/my_include_dir"h-Iout/soong/.intermediates/external/abseil-cpp/absl_time_internal_cctz_time_zone_hdrs/gen/my_include_dir"d-Iout/soong/.intermediates/external/abseil-cpp/absl_time_hdrs/gen/external/abseil-cpp/my_include_dir"P-Iout/soong/.intermediates/external/abseil-cpp/absl_time_hdrs/gen/my_include_dir"‡-Iout/soong/.intermediates/external/abseil-cpp/absl_synchronization_kernel_timeout_internal_hdrs/gen/external/abseil-cpp/my_include_dir"s-Iout/soong/.intermediates/external/abseil-cpp/absl_synchronization_kernel_timeout_internal_hdrs/gen/my_include_dir"u-Iout/soong/.intermediates/external/abseil-cpp/absl_base_tracing_internal_hdrs/gen/external/abseil-cpp/my_include_dir"a-Iout/soong/.intermediates/external/abseil-cpp/absl_base_tracing_internal_hdrs/gen/my_include_dir"|-Iout/soong/.intermediates/external/abseil-cpp/absl_debugging_debugging_internal_hdrs/gen/external/abseil-cpp/my_include_dir"h-Iout/soong/.intermediates/external/abseil-cpp/absl_debugging_debugging_internal_hdrs/gen/my_include_dir"t-Iout/soong/.intermediates/external/abseil-cpp/absl_debugging_stacktrace_hdrs/gen/external/abseil-cpp/my_include_dir"`-Iout/soong/.intermediates/external/abseil-cpp/absl_debugging_stacktrace_hdrs/gen/my_include_dir"s-Iout/soong/.intermediates/external/abseil-cpp/absl_debugging_symbolize_hdrs/gen/external/abseil-cpp/my_include_dir"_-Iout/soong/.intermediates/external/abseil-cpp/absl_debugging_symbolize_hdrs/gen/my_include_dir"o-Iout/soong/.intermediates/external/abseil-cpp/absl_synchronization_hdrs/gen/external/abseil-cpp/my_include_dir"[-Iout/soong/.intermediates/external/abseil-cpp/absl_synchronization_hdrs/gen/my_include_dir"t-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_cordz_handle_hdrs/gen/external/abseil-cpp/my_include_dir"`-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_cordz_handle_hdrs/gen/my_include_dir"|-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_cordz_update_tracker_hdrs/gen/external/abseil-cpp/my_include_dir"h-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_cordz_update_tracker_hdrs/gen/my_include_dir"x-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_cordz_statistics_hdrs/gen/external/abseil-cpp/my_include_dir"d-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_cordz_statistics_hdrs/gen/my_include_dir"r-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_cordz_info_hdrs/gen/external/abseil-cpp/my_include_dir"^-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_cordz_info_hdrs/gen/my_include_dir"z-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_cordz_update_scope_hdrs/gen/external/abseil-cpp/my_include_dir"f-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_cordz_update_scope_hdrs/gen/my_include_dir"l-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_cord_hdrs/gen/external/abseil-cpp/my_include_dir"X-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_cord_hdrs/gen/my_include_dir"o-Iout/soong/.intermediates/external/abseil-cpp/absl_container_btree_hdrs/gen/external/abseil-cpp/my_include_dir"[-Iout/soong/.intermediates/external/abseil-cpp/absl_container_btree_hdrs/gen/my_include_dir"i-Iout/soong/.intermediates/external/abseil-cpp/absl_hash_city_hdrs/gen/external/abseil-cpp/my_include_dir"U-Iout/soong/.intermediates/external/abseil-cpp/absl_hash_city_hdrs/gen/my_include_dir"s-Iout/soong/.intermediates/external/abseil-cpp/absl_hash_low_level_hash_hdrs/gen/external/abseil-cpp/my_include_dir"_-Iout/soong/.intermediates/external/abseil-cpp/absl_hash_low_level_hash_hdrs/gen/my_include_dir"m-Iout/soong/.intermediates/external/abseil-cpp/absl_types_variant_hdrs/gen/external/abseil-cpp/my_include_dir"Y-Iout/soong/.intermediates/external/abseil-cpp/absl_types_variant_hdrs/gen/my_include_dir"d-Iout/soong/.intermediates/external/abseil-cpp/absl_hash_hdrs/gen/external/abseil-cpp/my_include_dir"P-Iout/soong/.intermediates/external/abseil-cpp/absl_hash_hdrs/gen/my_include_dir"€-Iout/soong/.intermediates/external/abseil-cpp/absl_container_hash_function_defaults_hdrs/gen/external/abseil-cpp/my_include_dir"l-Iout/soong/.intermediates/external/abseil-cpp/absl_container_hash_function_defaults_hdrs/gen/my_include_dir"�-Iout/soong/.intermediates/external/abseil-cpp/absl_container_hash_container_defaults_hdrs/gen/external/abseil-cpp/my_include_dir"m-Iout/soong/.intermediates/external/abseil-cpp/absl_container_hash_container_defaults_hdrs/gen/my_include_dir"|-Iout/soong/.intermediates/external/abseil-cpp/absl_container_hash_policy_traits_hdrs/gen/external/abseil-cpp/my_include_dir"h-Iout/soong/.intermediates/external/abseil-cpp/absl_container_hash_policy_traits_hdrs/gen/my_include_dir"�-Iout/soong/.intermediates/external/abseil-cpp/absl_container_hashtable_control_bytes_hdrs/gen/external/abseil-cpp/my_include_dir"m-Iout/soong/.intermediates/external/abseil-cpp/absl_container_hashtable_control_bytes_hdrs/gen/my_include_dir"-Iout/soong/.intermediates/external/abseil-cpp/absl_container_hashtable_debug_hooks_hdrs/gen/external/abseil-cpp/my_include_dir"k-Iout/soong/.intermediates/external/abseil-cpp/absl_container_hashtable_debug_hooks_hdrs/gen/my_include_dir"y-Iout/soong/.intermediates/external/abseil-cpp/absl_profiling_sample_recorder_hdrs/gen/external/abseil-cpp/my_include_dir"e-Iout/soong/.intermediates/external/abseil-cpp/absl_profiling_sample_recorder_hdrs/gen/my_include_dir"|-Iout/soong/.intermediates/external/abseil-cpp/absl_container_hashtablez_sampler_hdrs/gen/external/abseil-cpp/my_include_dir"h-Iout/soong/.intermediates/external/abseil-cpp/absl_container_hashtablez_sampler_hdrs/gen/my_include_dir"‚-Iout/soong/.intermediates/external/abseil-cpp/absl_container_raw_hash_set_resize_impl_hdrs/gen/external/abseil-cpp/my_include_dir"n-Iout/soong/.intermediates/external/abseil-cpp/absl_container_raw_hash_set_resize_impl_hdrs/gen/my_include_dir"v-Iout/soong/.intermediates/external/abseil-cpp/absl_container_raw_hash_set_hdrs/gen/external/abseil-cpp/my_include_dir"b-Iout/soong/.intermediates/external/abseil-cpp/absl_container_raw_hash_set_hdrs/gen/my_include_dir"v-Iout/soong/.intermediates/external/abseil-cpp/absl_container_raw_hash_map_hdrs/gen/external/abseil-cpp/my_include_dir"b-Iout/soong/.intermediates/external/abseil-cpp/absl_container_raw_hash_map_hdrs/gen/my_include_dir"s-Iout/soong/.intermediates/external/abseil-cpp/absl_algorithm_container_hdrs/gen/external/abseil-cpp/my_include_dir"_-Iout/soong/.intermediates/external/abseil-cpp/absl_algorithm_container_hdrs/gen/my_include_dir"w-Iout/soong/.intermediates/external/abseil-cpp/absl_container_flat_hash_map_hdrs/gen/external/abseil-cpp/my_include_dir"c-Iout/soong/.intermediates/external/abseil-cpp/absl_container_flat_hash_map_hdrs/gen/my_include_dir"w-Iout/soong/.intermediates/external/abseil-cpp/absl_container_flat_hash_set_hdrs/gen/external/abseil-cpp/my_include_dir"c-Iout/soong/.intermediates/external/abseil-cpp/absl_container_flat_hash_set_hdrs/gen/my_include_dir"v-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_nullguard_hdrs/gen/external/abseil-cpp/my_include_dir"b-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_nullguard_hdrs/gen/my_include_dir"w-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_nullstream_hdrs/gen/external/abseil-cpp/my_include_dir"c-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_nullstream_hdrs/gen/my_include_dir"}-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_append_truncated_hdrs/gen/external/abseil-cpp/my_include_dir"i-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_append_truncated_hdrs/gen/my_include_dir"s-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_config_hdrs/gen/external/abseil-cpp/my_include_dir"_-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_config_hdrs/gen/my_include_dir"t-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_globals_hdrs/gen/external/abseil-cpp/my_include_dir"`-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_globals_hdrs/gen/my_include_dir"s-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_format_hdrs/gen/external/abseil-cpp/my_include_dir"_-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_format_hdrs/gen/my_include_dir"x-Iout/soong/.intermediates/external/abseil-cpp/absl_cleanup_cleanup_internal_hdrs/gen/external/abseil-cpp/my_include_dir"d-Iout/soong/.intermediates/external/abseil-cpp/absl_cleanup_cleanup_internal_hdrs/gen/my_include_dir"g-Iout/soong/.intermediates/external/abseil-cpp/absl_cleanup_hdrs/gen/external/abseil-cpp/my_include_dir"S-Iout/soong/.intermediates/external/abseil-cpp/absl_cleanup_hdrs/gen/my_include_dir"t-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_fnmatch_hdrs/gen/external/abseil-cpp/my_include_dir"`-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_fnmatch_hdrs/gen/my_include_dir"x-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_vlog_config_hdrs/gen/external/abseil-cpp/my_include_dir"d-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_vlog_config_hdrs/gen/my_include_dir"k-Iout/soong/.intermediates/external/abseil-cpp/absl_log_globals_hdrs/gen/external/abseil-cpp/my_include_dir"W-Iout/soong/.intermediates/external/abseil-cpp/absl_log_globals_hdrs/gen/my_include_dir"m-Iout/soong/.intermediates/external/abseil-cpp/absl_log_log_entry_hdrs/gen/external/abseil-cpp/my_include_dir"Y-Iout/soong/.intermediates/external/abseil-cpp/absl_log_log_entry_hdrs/gen/my_include_dir"l-Iout/soong/.intermediates/external/abseil-cpp/absl_log_log_sink_hdrs/gen/external/abseil-cpp/my_include_dir"X-Iout/soong/.intermediates/external/abseil-cpp/absl_log_log_sink_hdrs/gen/my_include_dir"y-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_log_sink_set_hdrs/gen/external/abseil-cpp/my_include_dir"e-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_log_sink_set_hdrs/gen/my_include_dir"r-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_proto_hdrs/gen/external/abseil-cpp/my_include_dir"^-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_proto_hdrs/gen/my_include_dir"}-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_structured_proto_hdrs/gen/external/abseil-cpp/my_include_dir"i-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_structured_proto_hdrs/gen/my_include_dir"m-Iout/soong/.intermediates/external/abseil-cpp/absl_base_strerror_hdrs/gen/external/abseil-cpp/my_include_dir"Y-Iout/soong/.intermediates/external/abseil-cpp/absl_base_strerror_hdrs/gen/my_include_dir"w-Iout/soong/.intermediates/external/abseil-cpp/absl_debugging_examine_stack_hdrs/gen/external/abseil-cpp/my_include_dir"c-Iout/soong/.intermediates/external/abseil-cpp/absl_debugging_examine_stack_hdrs/gen/my_include_dir"u-Iout/soong/.intermediates/external/abseil-cpp/absl_log_log_sink_registry_hdrs/gen/external/abseil-cpp/my_include_dir"a-Iout/soong/.intermediates/external/abseil-cpp/absl_log_log_sink_registry_hdrs/gen/my_include_dir"x-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_log_message_hdrs/gen/external/abseil-cpp/my_include_dir"d-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_log_message_hdrs/gen/my_include_dir"r-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_strip_hdrs/gen/external/abseil-cpp/my_include_dir"^-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_strip_hdrs/gen/my_include_dir"t-Iout/soong/.intermediates/external/abseil-cpp/absl_debugging_leak_check_hdrs/gen/external/abseil-cpp/my_include_dir"`-Iout/soong/.intermediates/external/abseil-cpp/absl_debugging_leak_check_hdrs/gen/my_include_dir"u-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_check_op_hdrs/gen/external/abseil-cpp/my_include_dir"a-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_check_op_hdrs/gen/my_include_dir"t-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_voidify_hdrs/gen/external/abseil-cpp/my_include_dir"`-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_voidify_hdrs/gen/my_include_dir"w-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_conditions_hdrs/gen/external/abseil-cpp/my_include_dir"c-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_conditions_hdrs/gen/my_include_dir"w-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_check_impl_hdrs/gen/external/abseil-cpp/my_include_dir"c-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_check_impl_hdrs/gen/my_include_dir"n-Iout/soong/.intermediates/external/abseil-cpp/absl_log_absl_check_hdrs/gen/external/abseil-cpp/my_include_dir"Z-Iout/soong/.intermediates/external/abseil-cpp/absl_log_absl_check_hdrs/gen/my_include_dir"s-Iout/soong/.intermediates/external/abseil-cpp/absl_log_absl_vlog_is_on_hdrs/gen/external/abseil-cpp/my_include_dir"_-Iout/soong/.intermediates/external/abseil-cpp/absl_log_absl_vlog_is_on_hdrs/gen/my_include_dir"u-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_log_impl_hdrs/gen/external/abseil-cpp/my_include_dir"a-Iout/soong/.intermediates/external/abseil-cpp/absl_log_internal_log_impl_hdrs/gen/my_include_dir"l-Iout/soong/.intermediates/external/abseil-cpp/absl_log_absl_log_hdrs/gen/external/abseil-cpp/my_include_dir"X-Iout/soong/.intermediates/external/abseil-cpp/absl_log_absl_log_hdrs/gen/my_include_dir"f-Iout/soong/.intermediates/external/abseil-cpp/absl_status_hdrs/gen/external/abseil-cpp/my_include_dir"R-Iout/soong/.intermediates/external/abseil-cpp/absl_status_hdrs/gen/my_include_dir"|-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_has_ostream_operator_hdrs/gen/external/abseil-cpp/my_include_dir"h-Iout/soong/.intermediates/external/abseil-cpp/absl_strings_has_ostream_operator_hdrs/gen/my_include_dir"o-Iout/soong/.intermediates/external/abseil-cpp/absl_status_statusor_hdrs/gen/external/abseil-cpp/my_include_dir"[-Iout/soong/.intermediates/external/abseil-cpp/absl_status_statusor_hdrs/gen/my_include_dir"Y-Iprebuilts/clang/host/linux-x86/clang-r563880/android_libc++/platform/arm/include/c++/v1"=-Iprebuilts/clang/host/linux-x86/clang-r563880/include/c++/v1" -Ibionic/libc/async_safe/include"-Isystem/logging/liblog/include"'-Ibionic/libc/system_properties/include"<-Isystem/core/property_service/libpropertyinfoparser/include"-isystem"bionic/libc/include"-isystem"bionic/libc/kernel/uapi/asm-arm"-isystem"bionic/libc/kernel/uapi"-isystem"bionic/libc/kernel/android/scsi"-isystem"bionic/libc/kernel/android/uapi"-target"armv7a-linux-androideabi10000"-DANDROID_STRICT"-fPIE"-Werror"-Wno-unused-parameter"-DGOOGLE_PROTOBUF_NO_RTTI"-Wimplicit-fallthrough"*-D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS"-Wno-gnu-include-next"-fvisibility-inlines-hidden"-mllvm"-enable-shrink-wrap=false"-std=gnu++20"	-fno-rtti"-Isystem/core/include"-Isystem/logging/liblog/include"-Isystem/media/audio/include"-Ihardware/libhardware/include"%-Ihardware/libhardware_legacy/include"-Ihardware/ril/include"-Iframeworks/native/include""-Iframeworks/native/opengl/include"-Iframeworks/av/include"-Werror=address-of-temporary"-Werror=dangling" -Werror=format-insufficient-args"-Werror=fortify-source"+-Werror=incompatible-function-pointer-types"-Werror=int-in-bool-context"-Werror=int-to-pointer-cast"-Werror=null-dereference"-Werror=return-type"-Werror=xor-used-as-pow"-Wno-pointer-to-int-cast"-Wno-error=unused-variable"-Wno-missing-field-initializers"-Wno-packed-non-pod"(-Wno-error=tautological-constant-compare""-Wno-implicit-int-float-conversion"!-Wno-tautological-overlap-compare"-Wno-deprecated-copy"-Wno-range-loop-construct""-Wno-zero-as-null-pointer-constant")-Wno-deprecated-anon-enum-enum-conversion"$-Wno-deprecated-enum-enum-conversion"-Wno-error=pessimizing-move"-Wno-non-c-typedef-for-linkage"-Wno-align-mismatch"#-Wno-error=unused-but-set-parameter"-Wno-error=deprecated"-Wno-error=invalid-offsetof"-Wno-nontrivial-memcall"-Wno-invalid-specialization"-Wno-vla-cxx-extension" -Wno-cast-function-type-mismatch"8build/make/tools/ide_query/prober_scripts/cpp/general.cc2Egenfiles_for_build/make/tools/ide_query/prober_scripts/cpp/general.cc:ãöf
Egenfiles_for_build/make/tools/ide_query/prober_scripts/cpp/general.cc*ã¢
soong/.intermediates/external/abseil-cpp/absl_container_btree_hdrs/gen/my_include_dir/absl/container/internal/btree_container.hÞ¡// Copyright 2018 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_CONTAINER_INTERNAL_BTREE_CONTAINER_H_
#define ABSL_CONTAINER_INTERNAL_BTREE_CONTAINER_H_

#include <algorithm>
#include <initializer_list>
#include <iterator>
#include <type_traits>
#include <utility>

#include "absl/base/attributes.h"
#include "absl/base/internal/throw_delegate.h"
#include "absl/container/internal/btree.h"  // IWYU pragma: export
#include "absl/container/internal/common.h"
#include "absl/hash/internal/weakly_mixed_integer.h"
#include "absl/memory/memory.h"
#include "absl/meta/type_traits.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace container_internal {

// A common base class for btree_set, btree_map, btree_multiset, and
// btree_multimap.
template <typename Tree>
class btree_container {
  using params_type = typename Tree::params_type;

 protected:
  // Alias used for heterogeneous lookup functions.
  // `key_arg<K>` evaluates to `K` when the functors are transparent and to
  // `key_type` otherwise. It permits template argument deduction on `K` for the
  // transparent case.
  template <class K>
  using key_arg =
      typename KeyArg<params_type::kIsKeyCompareTransparent>::template type<
          K, typename Tree::key_type>;

 public:
  using key_type = typename Tree::key_type;
  using value_type = typename Tree::value_type;
  using size_type = typename Tree::size_type;
  using difference_type = typename Tree::difference_type;
  using key_compare = typename Tree::original_key_compare;
  using value_compare = typename Tree::value_compare;
  using allocator_type = typename Tree::allocator_type;
  using reference = typename Tree::reference;
  using const_reference = typename Tree::const_reference;
  using pointer = typename Tree::pointer;
  using const_pointer = typename Tree::const_pointer;
  using iterator = typename Tree::iterator;
  using const_iterator = typename Tree::const_iterator;
  using reverse_iterator = typename Tree::reverse_iterator;
  using const_reverse_iterator = typename Tree::const_reverse_iterator;
  using node_type = typename Tree::node_handle_type;

  struct extract_and_get_next_return_type {
    node_type node;
    iterator next;
  };

  // Constructors/assignments.
  btree_container() : tree_(key_compare(), allocator_type()) {}
  explicit btree_container(const key_compare &comp,
                           const allocator_type &alloc = allocator_type())
      : tree_(comp, alloc) {}
  explicit btree_container(const allocator_type &alloc)
      : tree_(key_compare(), alloc) {}

  btree_container(const btree_container &other)
      : btree_container(other, absl::allocator_traits<allocator_type>::
                                   select_on_container_copy_construction(
                                       other.get_allocator())) {}
  btree_container(const btree_container &other, const allocator_type &alloc)
      : tree_(other.tree_, alloc) {}

  btree_container(btree_container &&other) noexcept(
      std::is_nothrow_move_constructible<Tree>::value) = default;
  btree_container(btree_container &&other, const allocator_type &alloc)
      : tree_(std::move(other.tree_), alloc) {}

  btree_container &operator=(const btree_container &other) = default;
  btree_container &operator=(btree_container &&other) noexcept(
      std::is_nothrow_move_assignable<Tree>::value) = default;

  // Iterator routines.
  iterator begin() ABSL_ATTRIBUTE_LIFETIME_BOUND { return tree_.begin(); }
  const_iterator begin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return tree_.begin();
  }
  const_iterator cbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return tree_.begin();
  }
  iterator end() ABSL_ATTRIBUTE_LIFETIME_BOUND { return tree_.end(); }
  const_iterator end() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return tree_.end();
  }
  const_iterator cend() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return tree_.end();
  }
  reverse_iterator rbegin() ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return tree_.rbegin();
  }
  const_reverse_iterator rbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return tree_.rbegin();
  }
  const_reverse_iterator crbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return tree_.rbegin();
  }
  reverse_iterator rend() ABSL_ATTRIBUTE_LIFETIME_BOUND { return tree_.rend(); }
  const_reverse_iterator rend() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return tree_.rend();
  }
  const_reverse_iterator crend() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return tree_.rend();
  }

  // Lookup routines.
  template <typename K = key_type>
  size_type count(const key_arg<K> &key) const {
    auto equal_range = this->equal_range(key);
    return equal_range.second - equal_range.first;
  }
  template <typename K = key_type>
  iterator find(const key_arg<K> &key) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return tree_.find(key);
  }
  template <typename K = key_type>
  const_iterator find(const key_arg<K> &key) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return tree_.find(key);
  }
  template <typename K = key_type>
  bool contains(const key_arg<K> &key) const {
    return find(key) != end();
  }
  template <typename K = key_type>
  iterator lower_bound(const key_arg<K> &key) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return tree_.lower_bound(key);
  }
  template <typename K = key_type>
  const_iterator lower_bound(const key_arg<K> &key) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return tree_.lower_bound(key);
  }
  template <typename K = key_type>
  iterator upper_bound(const key_arg<K> &key) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return tree_.upper_bound(key);
  }
  template <typename K = key_type>
  const_iterator upper_bound(const key_arg<K> &key) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return tree_.upper_bound(key);
  }
  template <typename K = key_type>
  std::pair<iterator, iterator> equal_range(const key_arg<K> &key)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return tree_.equal_range(key);
  }
  template <typename K = key_type>
  std::pair<const_iterator, const_iterator> equal_range(
      const key_arg<K> &key) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return tree_.equal_range(key);
  }

  // Deletion routines. Note that there is also a deletion routine that is
  // specific to btree_set_container/btree_multiset_container.

  // Erase the specified iterator from the btree. The iterator must be valid
  // (i.e. not equal to end()).  Return an iterator pointing to the node after
  // the one that was erased (or end() if none exists).
  iterator erase(const_iterator iter) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return tree_.erase(iterator(iter));
  }
  iterator erase(iterator iter) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return tree_.erase(iter);
  }
  iterator erase(const_iterator first,
                 const_iterator last) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return tree_.erase_range(iterator(first), iterator(last)).second;
  }
  template <typename K = key_type>
  size_type erase(const key_arg<K> &key) {
    auto equal_range = this->equal_range(key);
    return tree_.erase_range(equal_range.first, equal_range.second).first;
  }

  // Extract routines.
  extract_and_get_next_return_type extract_and_get_next(const_iterator position)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    // Use Construct instead of Transfer because the rebalancing code will
    // destroy the slot later.
    // Note: we rely on erase() taking place after Construct().
    return {CommonAccess::Construct<node_type>(get_allocator(),
                                               iterator(position).slot()),
            erase(position)};
  }
  node_type extract(iterator position) {
    // Use Construct instead of Transfer because the rebalancing code will
    // destroy the slot later.
    auto node =
        CommonAccess::Construct<node_type>(get_allocator(), position.slot());
    erase(position);
    return node;
  }
  node_type extract(const_iterator position) {
    return extract(iterator(position));
  }

  // Utility routines.
  ABSL_ATTRIBUTE_REINITIALIZES void clear() { tree_.clear(); }
  void swap(btree_container &other) { tree_.swap(other.tree_); }
  void verify() const { tree_.verify(); }

  // Size routines.
  size_type size() const { return tree_.size(); }
  size_type max_size() const { return tree_.max_size(); }
  bool empty() const { return tree_.empty(); }

  friend bool operator==(const btree_container &x, const btree_container &y) {
    if (x.size() != y.size()) return false;
    return std::equal(x.begin(), x.end(), y.begin());
  }

  friend bool operator!=(const btree_container &x, const btree_container &y) {
    return !(x == y);
  }

  friend bool operator<(const btree_container &x, const btree_container &y) {
    return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
  }

  friend bool operator>(const btree_container &x, const btree_container &y) {
    return y < x;
  }

  friend bool operator<=(const btree_container &x, const btree_container &y) {
    return !(y < x);
  }

  friend bool operator>=(const btree_container &x, const btree_container &y) {
    return !(x < y);
  }

  // The allocator used by the btree.
  allocator_type get_allocator() const { return tree_.get_allocator(); }

  // The key comparator used by the btree.
  key_compare key_comp() const { return key_compare(tree_.key_comp()); }
  value_compare value_comp() const { return tree_.value_comp(); }

  // Support absl::Hash.
  template <typename State>
  friend State AbslHashValue(State h, const btree_container &b) {
    for (const auto &v : b) {
      h = State::combine(std::move(h), v);
    }
    return State::combine(std::move(h),
                          hash_internal::WeaklyMixedInteger{b.size()});
  }

 protected:
  friend struct btree_access;
  Tree tree_;
};

// A common base class for btree_set and btree_map.
template <typename Tree>
class btree_set_container : public btree_container<Tree> {
  using super_type = btree_container<Tree>;
  using params_type = typename Tree::params_type;
  using init_type = typename params_type::init_type;
  using is_key_compare_to = typename params_type::is_key_compare_to;
  friend class BtreeNodePeer;

 protected:
  template <class K>
  using key_arg = typename super_type::template key_arg<K>;

 public:
  using key_type = typename Tree::key_type;
  using value_type = typename Tree::value_type;
  using size_type = typename Tree::size_type;
  using key_compare = typename Tree::original_key_compare;
  using allocator_type = typename Tree::allocator_type;
  using iterator = typename Tree::iterator;
  using const_iterator = typename Tree::const_iterator;
  using node_type = typename super_type::node_type;
  using insert_return_type = InsertReturnType<iterator, node_type>;

  // Inherit constructors.
  using super_type::super_type;
  btree_set_container() {}

  // Range constructors.
  template <class InputIterator>
  btree_set_container(InputIterator b, InputIterator e,
                      const key_compare &comp = key_compare(),
                      const allocator_type &alloc = allocator_type())
      : super_type(comp, alloc) {
    insert(b, e);
  }
  template <class InputIterator>
  btree_set_container(InputIterator b, InputIterator e,
                      const allocator_type &alloc)
      : btree_set_container(b, e, key_compare(), alloc) {}

  // Initializer list constructors.
  btree_set_container(std::initializer_list<init_type> init,
                      const key_compare &comp = key_compare(),
                      const allocator_type &alloc = allocator_type())
      : btree_set_container(init.begin(), init.end(), comp, alloc) {}
  btree_set_container(std::initializer_list<init_type> init,
                      const allocator_type &alloc)
      : btree_set_container(init.begin(), init.end(), alloc) {}

  // Insertion routines.
  std::pair<iterator, bool> insert(const value_type &v)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return this->tree_.insert_unique(params_type::key(v), v);
  }
  std::pair<iterator, bool> insert(value_type &&v)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return this->tree_.insert_unique(params_type::key(v), std::move(v));
  }
  template <typename... Args>
  std::pair<iterator, bool> emplace(Args &&...args)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    // Use a node handle to manage a temp slot.
    auto node = CommonAccess::Construct<node_type>(this->get_allocator(),
                                                   std::forward<Args>(args)...);
    auto *slot = CommonAccess::GetSlot(node);
    return this->tree_.insert_unique(params_type::key(slot), slot);
  }
  iterator insert(const_iterator hint,
                  const value_type &v) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return this->tree_
        .insert_hint_unique(iterator(hint), params_type::key(v), v)
        .first;
  }
  iterator insert(const_iterator hint,
                  value_type &&v) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return this->tree_
        .insert_hint_unique(iterator(hint), params_type::key(v), std::move(v))
        .first;
  }
  template <typename... Args>
  iterator emplace_hint(const_iterator hint,
                        Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    // Use a node handle to manage a temp slot.
    auto node = CommonAccess::Construct<node_type>(this->get_allocator(),
                                                   std::forward<Args>(args)...);
    auto *slot = CommonAccess::GetSlot(node);
    return this->tree_
        .insert_hint_unique(iterator(hint), params_type::key(slot), slot)
        .first;
  }
  template <typename InputIterator>
  void insert(InputIterator b, InputIterator e) {
    this->tree_.insert_iterator_unique(b, e, 0);
  }
  void insert(std::initializer_list<init_type> init) {
    this->tree_.insert_iterator_unique(init.begin(), init.end(), 0);
  }
  insert_return_type insert(node_type &&node) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    if (!node) return {this->end(), false, node_type()};
    std::pair<iterator, bool> res =
        this->tree_.insert_unique(params_type::key(CommonAccess::GetSlot(node)),
                                  CommonAccess::GetSlot(node));
    if (res.second) {
      CommonAccess::Destroy(&node);
      return {res.first, true, node_type()};
    } else {
      return {res.first, false, std::move(node)};
    }
  }
  iterator insert(const_iterator hint,
                  node_type &&node) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    if (!node) return this->end();
    std::pair<iterator, bool> res = this->tree_.insert_hint_unique(
        iterator(hint), params_type::key(CommonAccess::GetSlot(node)),
        CommonAccess::GetSlot(node));
    if (res.second) CommonAccess::Destroy(&node);
    return res.first;
  }

  // Node extraction routines.
  template <typename K = key_type>
  node_type extract(const key_arg<K> &key) {
    const std::pair<iterator, bool> lower_and_equal =
        this->tree_.lower_bound_equal(key);
    return lower_and_equal.second ? extract(lower_and_equal.first)
                                  : node_type();
  }
  using super_type::extract;

  // Merge routines.
  // Moves elements from `src` into `this`. If the element already exists in
  // `this`, it is left unmodified in `src`.
  template <
      typename T,
      typename absl::enable_if_t<
          absl::conjunction<
              std::is_same<value_type, typename T::value_type>,
              std::is_same<allocator_type, typename T::allocator_type>,
              std::is_same<typename params_type::is_map_container,
                           typename T::params_type::is_map_container>>::value,
          int> = 0>
  void merge(btree_container<T> &src) {  // NOLINT
    for (auto src_it = src.begin(); src_it != src.end();) {
      if (insert(std::move(params_type::element(src_it.slot()))).second) {
        src_it = src.erase(src_it);
      } else {
        ++src_it;
      }
    }
  }

  template <
      typename T,
      typename absl::enable_if_t<
          absl::conjunction<
              std::is_same<value_type, typename T::value_type>,
              std::is_same<allocator_type, typename T::allocator_type>,
              std::is_same<typename params_type::is_map_container,
                           typename T::params_type::is_map_container>>::value,
          int> = 0>
  void merge(btree_container<T> &&src) {
    merge(src);
  }
};

// Base class for btree_map.
template <typename Tree>
class btree_map_container : public btree_set_container<Tree> {
  using super_type = btree_set_container<Tree>;
  using params_type = typename Tree::params_type;
  friend class BtreeNodePeer;

 private:
  template <class K>
  using key_arg = typename super_type::template key_arg<K>;

  // NOTE: The mess here is to shorten the code for the (very repetitive)
  // function overloads, and to allow the lifetime-bound overloads to dispatch
  // to the non-lifetime-bound overloads, to ensure there is a single source of
  // truth for each overload set.
  //
  // Enabled if an assignment from the given type would require the
  // source object to remain alive for the life of the element.
  //
  // TODO(b/402804213): Remove these traits and simplify the overloads whenever
  // we have a better mechanism available to handle lifetime analysis.
  template <class K, bool Value, typename = void>
  using LifetimeBoundK =
      HasValue<Value, type_traits_internal::IsLifetimeBoundAssignment<
                          typename Tree::key_type, K>>;
  template <class M, bool Value, typename = void>
  using LifetimeBoundV =
      HasValue<Value, type_traits_internal::IsLifetimeBoundAssignment<
                          typename Tree::params_type::mapped_type, M>>;
  template <class K, bool KValue, class M, bool MValue, typename... Dummy>
  using LifetimeBoundKV =
      absl::conjunction<LifetimeBoundK<K, KValue, absl::void_t<Dummy...>>,
                        LifetimeBoundV<M, MValue>>;

 public:
  using key_type = typename Tree::key_type;
  using mapped_type = typename params_type::mapped_type;
  using value_type = typename Tree::value_type;
  using key_compare = typename Tree::original_key_compare;
  using allocator_type = typename Tree::allocator_type;
  using iterator = typename Tree::iterator;
  using const_iterator = typename Tree::const_iterator;

  // Inherit constructors.
  using super_type::super_type;
  btree_map_container() {}

  // TODO(b/402804213): Remove these macros whenever we have a better mechanism
  // available to handle lifetime analysis.
#define ABSL_INTERNAL_X(Func, Callee, KQual, MQual, KValue, MValue, ...)     \
  template <                                                                 \
      typename K = key_type, class M,                                        \
      ABSL_INTERNAL_IF_##KValue##_NOR_##MValue(                              \
          int = (EnableIf<LifetimeBoundKV<K, KValue, M, MValue,              \
                                          IfRRef<int KQual>::AddPtr<K>,      \
                                          IfRRef<int MQual>::AddPtr<M>>>()), \
          ABSL_INTERNAL_SINGLE_ARG(                                          \
              int &...,                                                      \
              decltype(EnableIf<LifetimeBoundKV<K, KValue, M, MValue>>()) =  \
                  0))>                                                       \
  decltype(auto) Func(                                                       \
      __VA_ARGS__ key_arg<K> KQual k ABSL_INTERNAL_IF_##KValue(              \
          ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this)),                        \
      M MQual obj ABSL_INTERNAL_IF_##MValue(                                 \
          ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this)))                        \
      ABSL_ATTRIBUTE_LIFETIME_BOUND {                                        \
    return ABSL_INTERNAL_IF_##KValue##_OR_##MValue(                          \
        (this->template Func<K, M, 0>), Callee)(                             \
        __VA_ARGS__ std::forward<decltype(k)>(k),                            \
        std::forward<decltype(obj)>(obj));                                   \
  }                                                                          \
  friend struct std::enable_if<false> /* just to force a semicolon */
  // Insertion routines.
  // Note: the nullptr template arguments and extra `const M&` overloads allow
  // for supporting bitfield arguments.
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, const &,
                  false, false);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, const &,
                  false, true);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, const &,
                  true, false);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, const &,
                  true, true);

  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, &&, false,
                  false);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, &&, false,
                  true);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, &&, true,
                  false);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, const &, &&, true,
                  true);

  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, const &, false,
                  false);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, const &, false,
                  true);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, const &, true,
                  false);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, const &, true,
                  true);

  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, &&, false,
                  false);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, &&, false, true);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, &&, true, false);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_impl, &&, &&, true, true);

  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, const &,
                  const &, false, false,
                  const_iterator(hint) ABSL_INTERNAL_COMMA);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, const &,
                  const &, false, true,
                  const_iterator(hint) ABSL_INTERNAL_COMMA);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, const &,
                  const &, true, false,
                  const_iterator(hint) ABSL_INTERNAL_COMMA);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, const &,
                  const &, true, true,
                  const_iterator(hint) ABSL_INTERNAL_COMMA);

  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, const &, &&,
                  false, false, const_iterator(hint) ABSL_INTERNAL_COMMA);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, const &, &&,
                  false, true, const_iterator(hint) ABSL_INTERNAL_COMMA);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, const &, &&,
                  true, false, const_iterator(hint) ABSL_INTERNAL_COMMA);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, const &, &&,
                  true, true, const_iterator(hint) ABSL_INTERNAL_COMMA);

  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, &&, const &,
                  false, false, const_iterator(hint) ABSL_INTERNAL_COMMA);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, &&, const &,
                  false, true, const_iterator(hint) ABSL_INTERNAL_COMMA);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, &&, const &,
                  true, false, const_iterator(hint) ABSL_INTERNAL_COMMA);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, &&, const &,
                  true, true, const_iterator(hint) ABSL_INTERNAL_COMMA);

  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, &&, &&, false,
                  false, const_iterator(hint) ABSL_INTERNAL_COMMA);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, &&, &&, false,
                  true, const_iterator(hint) ABSL_INTERNAL_COMMA);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, &&, &&, true,
                  false, const_iterator(hint) ABSL_INTERNAL_COMMA);
  ABSL_INTERNAL_X(insert_or_assign, insert_or_assign_hint_impl, &&, &&, true,
                  true, const_iterator(hint) ABSL_INTERNAL_COMMA);
#undef ABSL_INTERNAL_X

#define ABSL_INTERNAL_X(Func, Callee, KQual, KValue, ...)                      \
  template <                                                                   \
      class K = key_type,                                                      \
      ABSL_INTERNAL_IF_##KValue(                                               \
          class... Args,                                                       \
          int = (EnableIf<                                                     \
                 LifetimeBoundK<K, KValue, IfRRef<int KQual>::AddPtr<K>>>())), \
      ABSL_INTERNAL_IF_##KValue(                                               \
          decltype(EnableIf<LifetimeBoundK<                                    \
                       K, KValue, IfRRef<int KQual>::AddPtr<K>>>()) = 0,       \
          class... Args),                                                      \
      std::enable_if_t<!std::is_convertible<K, const_iterator>::value, int> =  \
          0>                                                                   \
  decltype(auto) Func(                                                         \
      __VA_ARGS__ key_arg<K> KQual k ABSL_INTERNAL_IF_##KValue(                \
          ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this)),                          \
      Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND {                          \
    return ABSL_INTERNAL_IF_##KValue((this->template Func<K, 0>), Callee)(     \
        __VA_ARGS__ std::forward<decltype(k)>(k),                              \
        std::forward<decltype(args)>(args)...);                                \
  }                                                                            \
  friend struct std::enable_if<false> /* just to force a semicolon */
  ABSL_INTERNAL_X(try_emplace, try_emplace_impl, const &, false);
  ABSL_INTERNAL_X(try_emplace, try_emplace_impl, const &, true);
  ABSL_INTERNAL_X(try_emplace, try_emplace_impl, &&, false);
  ABSL_INTERNAL_X(try_emplace, try_emplace_impl, &&, true);
  ABSL_INTERNAL_X(try_emplace, try_emplace_hint_impl, const &, false,
                  const_iterator(hint) ABSL_INTERNAL_COMMA);
  ABSL_INTERNAL_X(try_emplace, try_emplace_hint_impl, const &, true,
                  const_iterator(hint) ABSL_INTERNAL_COMMA);
  ABSL_INTERNAL_X(try_emplace, try_emplace_hint_impl, &&, false,
                  const_iterator(hint) ABSL_INTERNAL_COMMA);
  ABSL_INTERNAL_X(try_emplace, try_emplace_hint_impl, &&, true,
                  const_iterator(hint) ABSL_INTERNAL_COMMA);
#undef ABSL_INTERNAL_X

  template <class K = key_type, int = EnableIf<LifetimeBoundK<K, false>>()>
  mapped_type &operator[](const key_arg<K> &k) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return try_emplace(k).first->second;
  }
  template <class K = key_type, int &..., EnableIf<LifetimeBoundK<K, true>> = 0>
  mapped_type &operator[](
      const key_arg<K> &k ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this))
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return this->template operator[]<K, 0>(k);
  }
  template <class K = key_type, int = EnableIf<LifetimeBoundK<K, false>>()>
  mapped_type &operator[](key_arg<K> &&k) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return try_emplace(std::forward<K>(k)).first->second;
  }
  template <class K = key_type, int &..., EnableIf<LifetimeBoundK<K, true>> = 0>
  mapped_type &operator[](key_arg<K> &&k ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(
      this)) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return this->template operator[]<K, 0>(std::forward<K>(k));
  }

  template <typename K = key_type>
  mapped_type &at(const key_arg<K> &key) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    auto it = this->find(key);
    if (it == this->end())
      base_internal::ThrowStdOutOfRange("absl::btree_map::at");
    return it->second;
  }
  template <typename K = key_type>
  const mapped_type &at(const key_arg<K> &key) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    auto it = this->find(key);
    if (it == this->end())
      base_internal::ThrowStdOutOfRange("absl::btree_map::at");
    return it->second;
  }

 private:
  // Note: when we call `std::forward<M>(obj)` twice, it's safe because
  // insert_unique/insert_hint_unique are guaranteed to not consume `obj` when
  // `ret.second` is false.
  template <class K, class M>
  std::pair<iterator, bool> insert_or_assign_impl(K &&k, M &&obj) {
    const std::pair<iterator, bool> ret =
        this->tree_.insert_unique(k, std::forward<K>(k), std::forward<M>(obj));
    if (!ret.second) ret.first->second = std::forward<M>(obj);
    return ret;
  }
  template <class K, class M>
  iterator insert_or_assign_hint_impl(const_iterator hint, K &&k, M &&obj) {
    const std::pair<iterator, bool> ret = this->tree_.insert_hint_unique(
        iterator(hint), k, std::forward<K>(k), std::forward<M>(obj));
    if (!ret.second) ret.first->second = std::forward<M>(obj);
    return ret.first;
  }

  template <class K, class... Args>
  std::pair<iterator, bool> try_emplace_impl(K &&k, Args &&... args) {
    return this->tree_.insert_unique(
        k, std::piecewise_construct, std::forward_as_tuple(std::forward<K>(k)),
        std::forward_as_tuple(std::forward<Args>(args)...));
  }
  template <class K, class... Args>
  iterator try_emplace_hint_impl(const_iterator hint, K &&k, Args &&... args) {
    return this->tree_
        .insert_hint_unique(iterator(hint), k, std::piecewise_construct,
                            std::forward_as_tuple(std::forward<K>(k)),
                            std::forward_as_tuple(std::forward<Args>(args)...))
        .first;
  }
};

// A common base class for btree_multiset and btree_multimap.
template <typename Tree>
class btree_multiset_container : public btree_container<Tree> {
  using super_type = btree_container<Tree>;
  using params_type = typename Tree::params_type;
  using init_type = typename params_type::init_type;
  using is_key_compare_to = typename params_type::is_key_compare_to;
  friend class BtreeNodePeer;

  template <class K>
  using key_arg = typename super_type::template key_arg<K>;

 public:
  using key_type = typename Tree::key_type;
  using value_type = typename Tree::value_type;
  using size_type = typename Tree::size_type;
  using key_compare = typename Tree::original_key_compare;
  using allocator_type = typename Tree::allocator_type;
  using iterator = typename Tree::iterator;
  using const_iterator = typename Tree::const_iterator;
  using node_type = typename super_type::node_type;

  // Inherit constructors.
  using super_type::super_type;
  btree_multiset_container() {}

  // Range constructors.
  template <class InputIterator>
  btree_multiset_container(InputIterator b, InputIterator e,
                           const key_compare &comp = key_compare(),
                           const allocator_type &alloc = allocator_type())
      : super_type(comp, alloc) {
    insert(b, e);
  }
  template <class InputIterator>
  btree_multiset_container(InputIterator b, InputIterator e,
                           const allocator_type &alloc)
      : btree_multiset_container(b, e, key_compare(), alloc) {}

  // Initializer list constructors.
  btree_multiset_container(std::initializer_list<init_type> init,
                           const key_compare &comp = key_compare(),
                           const allocator_type &alloc = allocator_type())
      : btree_multiset_container(init.begin(), init.end(), comp, alloc) {}
  btree_multiset_container(std::initializer_list<init_type> init,
                           const allocator_type &alloc)
      : btree_multiset_container(init.begin(), init.end(), alloc) {}

  // Insertion routines.
  iterator insert(const value_type &v) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return this->tree_.insert_multi(v);
  }
  iterator insert(value_type &&v) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return this->tree_.insert_multi(std::move(v));
  }
  iterator insert(const_iterator hint,
                  const value_type &v) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return this->tree_.insert_hint_multi(iterator(hint), v);
  }
  iterator insert(const_iterator hint,
                  value_type &&v) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return this->tree_.insert_hint_multi(iterator(hint), std::move(v));
  }
  template <typename InputIterator>
  void insert(InputIterator b, InputIterator e) {
    this->tree_.insert_iterator_multi(b, e);
  }
  void insert(std::initializer_list<init_type> init) {
    this->tree_.insert_iterator_multi(init.begin(), init.end());
  }
  template <typename... Args>
  iterator emplace(Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    // Use a node handle to manage a temp slot.
    auto node = CommonAccess::Construct<node_type>(this->get_allocator(),
                                                   std::forward<Args>(args)...);
    return this->tree_.insert_multi(CommonAccess::GetSlot(node));
  }
  template <typename... Args>
  iterator emplace_hint(const_iterator hint,
                        Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    // Use a node handle to manage a temp slot.
    auto node = CommonAccess::Construct<node_type>(this->get_allocator(),
                                                   std::forward<Args>(args)...);
    return this->tree_.insert_hint_multi(iterator(hint),
                                         CommonAccess::GetSlot(node));
  }
  iterator insert(node_type &&node) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    if (!node) return this->end();
    iterator res =
        this->tree_.insert_multi(params_type::key(CommonAccess::GetSlot(node)),
                                 CommonAccess::GetSlot(node));
    CommonAccess::Destroy(&node);
    return res;
  }
  iterator insert(const_iterator hint,
                  node_type &&node) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    if (!node) return this->end();
    iterator res = this->tree_.insert_hint_multi(
        iterator(hint),
        std::move(params_type::element(CommonAccess::GetSlot(node))));
    CommonAccess::Destroy(&node);
    return res;
  }

  // Node extraction routines.
  template <typename K = key_type>
  node_type extract(const key_arg<K> &key) {
    const std::pair<iterator, bool> lower_and_equal =
        this->tree_.lower_bound_equal(key);
    return lower_and_equal.second ? extract(lower_and_equal.first)
                                  : node_type();
  }
  using super_type::extract;

  // Merge routines.
  // Moves all elements from `src` into `this`.
  template <
      typename T,
      typename absl::enable_if_t<
          absl::conjunction<
              std::is_same<value_type, typename T::value_type>,
              std::is_same<allocator_type, typename T::allocator_type>,
              std::is_same<typename params_type::is_map_container,
                           typename T::params_type::is_map_container>>::value,
          int> = 0>
  void merge(btree_container<T> &src) {  // NOLINT
    for (auto src_it = src.begin(), end = src.end(); src_it != end; ++src_it) {
      insert(std::move(params_type::element(src_it.slot())));
    }
    src.clear();
  }

  template <
      typename T,
      typename absl::enable_if_t<
          absl::conjunction<
              std::is_same<value_type, typename T::value_type>,
              std::is_same<allocator_type, typename T::allocator_type>,
              std::is_same<typename params_type::is_map_container,
                           typename T::params_type::is_map_container>>::value,
          int> = 0>
  void merge(btree_container<T> &&src) {
    merge(src);
  }
};

// A base class for btree_multimap.
template <typename Tree>
class btree_multimap_container : public btree_multiset_container<Tree> {
  using super_type = btree_multiset_container<Tree>;
  using params_type = typename Tree::params_type;
  friend class BtreeNodePeer;

 public:
  using mapped_type = typename params_type::mapped_type;

  // Inherit constructors.
  using super_type::super_type;
  btree_multimap_container() {}
};

}  // namespace container_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_CONTAINER_INTERNAL_BTREE_CONTAINER_H_
*ï
tsoong/.intermediates/external/abseil-cpp/absl_strings_hdrs/gen/my_include_dir/absl/strings/internal/stringify_sink.hö// 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.

#ifndef ABSL_STRINGS_INTERNAL_STRINGIFY_SINK_H_
#define ABSL_STRINGS_INTERNAL_STRINGIFY_SINK_H_

#include <string>
#include <type_traits>
#include <utility>

#include "absl/strings/string_view.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

namespace strings_internal {
class StringifySink {
 public:
  void Append(size_t count, char ch);

  void Append(string_view v);

  // Support `absl::Format(&sink, format, args...)`.
  friend void AbslFormatFlush(StringifySink* sink, absl::string_view v) {
    sink->Append(v);
  }

 private:
  template <typename T>
  friend string_view ExtractStringification(StringifySink& sink, const T& v);

  std::string buffer_;
};

template <typename T>
string_view ExtractStringification(StringifySink& sink, const T& v) {
  AbslStringify(sink, v);
  return sink.buffer_;
}

}  // namespace strings_internal

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_STRINGIFY_SINK_H_
*Ó#
ƒsoong/.intermediates/external/abseil-cpp/absl_strings_internal_hdrs/gen/my_include_dir/absl/strings/internal/resize_uninitialized.hÊ"//
// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#ifndef ABSL_STRINGS_INTERNAL_RESIZE_UNINITIALIZED_H_
#define ABSL_STRINGS_INTERNAL_RESIZE_UNINITIALIZED_H_

#include <algorithm>
#include <string>
#include <type_traits>
#include <utility>

#include "absl/base/port.h"
#include "absl/meta/type_traits.h"  //  for void_t

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace strings_internal {

// In this type trait, we look for a __resize_default_init member function, and
// we use it if available, otherwise, we use resize. We provide HasMember to
// indicate whether __resize_default_init is present.
template <typename string_type, typename = void>
struct ResizeUninitializedTraits {
  using HasMember = std::false_type;
  static void Resize(string_type* s, size_t new_size) { s->resize(new_size); }
};

// __resize_default_init is provided by libc++ >= 8.0
template <typename string_type>
struct ResizeUninitializedTraits<
    string_type, absl::void_t<decltype(std::declval<string_type&>()
                                           .__resize_default_init(237))> > {
  using HasMember = std::true_type;
  static void Resize(string_type* s, size_t new_size) {
    s->__resize_default_init(new_size);
  }
};

// Returns true if the std::string implementation supports a resize where
// the new characters added to the std::string are left untouched.
//
// (A better name might be "STLStringSupportsUninitializedResize", alluding to
// the previous function.)
template <typename string_type>
inline constexpr bool STLStringSupportsNontrashingResize(string_type*) {
  return ResizeUninitializedTraits<string_type>::HasMember::value;
}

// Like str->resize(new_size), except any new characters added to "*str" as a
// result of resizing may be left uninitialized, rather than being filled with
// '0' bytes. Typically used when code is then going to overwrite the backing
// store of the std::string with known data.
template <typename string_type, typename = void>
inline void STLStringResizeUninitialized(string_type* s, size_t new_size) {
  ResizeUninitializedTraits<string_type>::Resize(s, new_size);
}

// Used to ensure exponential growth so that the amortized complexity of
// increasing the string size by a small amount is O(1), in contrast to
// O(str->size()) in the case of precise growth.
template <typename string_type>
void STLStringReserveAmortized(string_type* s, size_t new_size) {
  const size_t cap = s->capacity();
  if (new_size > cap) {
    // Make sure to always grow by at least a factor of 2x.
    s->reserve((std::max)(new_size, 2 * cap));
  }
}

// In this type trait, we look for an __append_default_init member function, and
// we use it if available, otherwise, we use append.
template <typename string_type, typename = void>
struct AppendUninitializedTraits {
  static void Append(string_type* s, size_t n) {
    s->append(n, typename string_type::value_type());
  }
};

template <typename string_type>
struct AppendUninitializedTraits<
    string_type, absl::void_t<decltype(std::declval<string_type&>()
                                           .__append_default_init(237))> > {
  static void Append(string_type* s, size_t n) {
    s->__append_default_init(n);
  }
};

// Like STLStringResizeUninitialized(str, new_size), except guaranteed to use
// exponential growth so that the amortized complexity of increasing the string
// size by a small amount is O(1), in contrast to O(str->size()) in the case of
// precise growth.
template <typename string_type>
void STLStringResizeUninitializedAmortized(string_type* s, size_t new_size) {
  const size_t size = s->size();
  if (new_size > size) {
    AppendUninitializedTraits<string_type>::Append(s, new_size - size);
  } else {
    s->erase(new_size);
  }
}

}  // namespace strings_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_RESIZE_UNINITIALIZED_H_
*Ã
„soong/.intermediates/external/abseil-cpp/absl_debugging_demangle_internal_hdrs/gen/my_include_dir/absl/debugging/internal/demangle.h¹// Copyright 2018 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#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.
//
// 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
// types of template arguments.  It just skips them.  However, it's
// still very useful to extract basic information such as class,
// function, constructor, destructor, and operator names.
//
// See the implementation note in demangle.cc if you are interested.
//
// Example:
//
// | 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.
//
// Demangle also recognizes Rust mangled names by delegating the parsing of
// anything that starts with _R to DemangleRustSymbolEncoding (demangle_rust.h).
//
// Note: we might want to write demanglers for ABIs other than Itanium
// C++ ABI in the future.
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

#endif  // ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_
*ëø
wsoong/.intermediates/external/abseil-cpp/absl_container_layout_hdrs/gen/my_include_dir/absl/container/internal/layout.hî÷// Copyright 2018 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//                           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[0] 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 attempts to
// generate optimal code. To help the compiler do that in more cases, you can
// specify the fixed sizes using `WithStaticSizes`. This ensures that all
// computations that can be performed at compile time are indeed performed at
// compile time. Note that sometimes the `template` keyword is needed. E.g.:
//
//   using SL = L::template WithStaticSizes<1, 1>;
//
//   void Use(unsigned char* p) {
//     // First, extract N and M.
//     // Using `prefix` we can access the first three arrays but not more.
//     //
//     // More details: The first element always has offset 0. `SL`
//     // has offsets for the second and third array based on sizes of
//     // the first and second array, specified via `WithStaticSizes`.
//     constexpr auto prefix = SL::Partial();
//     size_t n = *prefix.Pointer<0>(p);
//     size_t m = *prefix.Pointer<1>(p);
//
//     // Now we can get a pointer to the final payload.
//     const SL layout(n, m);
//     double* a = layout.Pointer<double>(p);
//     int* b = layout.Pointer<int>(p);
//   }
//
// 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(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)).
//       return L::Partial().Pointer<char>(p_.get());
//     }
//
//    private:
//     // Our heap allocation contains a single size_t followed by an array of
//     // chars.
//     using L = Layout<size_t, char>::WithStaticSizes<1>;
//     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 classes `internal_layout::LayoutWithStaticSizes<>`
//   and `internal_layout::LayoutImpl<>`. Those classes aren't intended to be
//   used directly, and their name and template parameter list are internal
//   implementation details, but the classes themselves provide most of the
//   functionality in this file. See comments on their 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 <array>
#include <string>
#include <tuple>
#include <type_traits>
#include <typeinfo>
#include <utility>

#include "absl/base/config.h"
#include "absl/debugging/internal/demangle.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

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 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;
#ifdef ABSL_INTERNAL_HAS_RTTI
  absl::StrAppend(&out, "<",
                  absl::debugging_internal::DemangleString(typeid(T).name()),
                  ">");
#endif
  return out;
}

}  // namespace adl_barrier

// 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 StaticSizeSeq, class RuntimeSizeSeq,
          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.
//
// `StaticSizeSeq...` is an index_sequence containing the sizes specified at
// compile-time.
//
// `RuntimeSizeSeq...` is `[0, NumRuntimeSizes)`, where `NumRuntimeSizes` is the
// number of arguments passed to `Layout::Partial()` or `Layout::Layout()`.
//
// `SizeSeq...` is `[0, NumSizes)` where `NumSizes` is `NumRuntimeSizes` plus
// the number of sizes in `StaticSizeSeq`.
//
// `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... StaticSizeSeq, size_t... RuntimeSizeSeq,
          size_t... SizeSeq, size_t... OffsetSeq>
class LayoutImpl<
    std::tuple<Elements...>, absl::index_sequence<StaticSizeSeq...>,
    absl::index_sequence<RuntimeSizeSeq...>, 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)");
  static_assert(sizeof...(StaticSizeSeq) <= sizeof...(Elements),
                "Too many static sizes specified");

  enum {
    NumTypes = sizeof...(Elements),
    NumStaticSizes = sizeof...(StaticSizeSeq),
    NumRuntimeSizes = sizeof...(RuntimeSizeSeq),
    NumSizes = sizeof...(SizeSeq),
    NumOffsets = sizeof...(OffsetSeq),
  };

  // These are guaranteed by `Layout`.
  static_assert(NumStaticSizes + NumRuntimeSizes == NumSizes, "Internal error");
  static_assert(NumSizes <= NumTypes, "Internal error");
  static_assert(NumOffsets == adl_barrier::Min(NumTypes, NumSizes + 1),
                "Internal error");
  static_assert(NumTypes > 0, "Internal error");

  static constexpr std::array<size_t, sizeof...(StaticSizeSeq)> kStaticSizes = {
      StaticSizeSeq...};

  // 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<RuntimeSizeSeq>... 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>
  constexpr size_t Offset() const {
    if constexpr (N == 0) {
      return 0;
    } else {
      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 (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 {
    if constexpr (N < NumStaticSizes) {
      return kStaticSizes[N];
    } else {
      static_assert(N < NumSizes, "Index out of bounds");
      return size_[N - NumStaticSizes];
    }
  }

  // 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()`.
  template <class Char>
  auto 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 mark the parameter as maybe_unused because GCC detects it is not
  // used when `SizeSeq` is empty [-Werror=unused-but-set-parameter].
  template <class Char>
  auto Slices([[maybe_unused]] Char* p) const {
    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>
  void PoisonPadding(const Char* p) const {
    if constexpr (N == 0) {
      Pointer<0>(p);  // verify the requirements on `Char` and `p`
    } else {
      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, "[", DebugSize(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, "[", DebugSize(static_cast<size_t>(last)), "]");
    }
    return res;
  }

 private:
  size_t DebugSize(size_t n) const {
    if (n < NumStaticSizes) {
      return kStaticSizes[n];
    } else {
      return size_[n - NumStaticSizes];
    }
  }

  // Arguments of `Layout::Partial()` or `Layout::Layout()`.
  size_t size_[NumRuntimeSizes > 0 ? NumRuntimeSizes : 1];
};

template <class StaticSizeSeq, size_t NumRuntimeSizes, class... Ts>
using LayoutType = LayoutImpl<
    std::tuple<Ts...>, StaticSizeSeq,
    absl::make_index_sequence<NumRuntimeSizes>,
    absl::make_index_sequence<NumRuntimeSizes + StaticSizeSeq::size()>,
    absl::make_index_sequence<adl_barrier::Min(
        sizeof...(Ts), NumRuntimeSizes + StaticSizeSeq::size() + 1)>>;

template <class StaticSizeSeq, class... Ts>
class LayoutWithStaticSizes
    : public LayoutType<StaticSizeSeq,
                        sizeof...(Ts) - adl_barrier::Min(sizeof...(Ts),
                                                         StaticSizeSeq::size()),
                        Ts...> {
 private:
  using Super =
      LayoutType<StaticSizeSeq,
                 sizeof...(Ts) -
                     adl_barrier::Min(sizeof...(Ts), StaticSizeSeq::size()),
                 Ts...>;

 public:
  // The result type of `Partial()` with `NumSizes` arguments.
  template <size_t NumSizes>
  using PartialType =
      internal_layout::LayoutType<StaticSizeSeq, 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) + NumStaticSizes <= 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) + StaticSizeSeq::size() <= sizeof...(Ts),
                  "");
    return PartialType<sizeof...(Sizes)>(
        static_cast<size_t>(std::forward<Sizes>(sizes))...);
  }

  // Inherit LayoutType's constructor.
  //
  // 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.
  //
  // Implementation note: we do this via a `using` declaration instead of
  // defining our own explicit constructor because the signature of LayoutType's
  // constructor depends on RuntimeSizeSeq, which we don't have access to here.
  // If we defined our own constructor here, it would have to use a parameter
  // pack and then cast the arguments to size_t when calling the superclass
  // constructor, similar to what Partial() does. But that would suffer from the
  // same problem that Partial() has, which is that the parameter types are
  // inferred from the arguments, which may be signed types, which must then be
  // cast to size_t. This can lead to negative values being silently (i.e. with
  // no compiler warnings) cast to an unsigned type. Having a constructor with
  // size_t parameters helps the compiler generate better warnings about
  // potential bad casts, while avoiding false warnings when positive literal
  // arguments are used. If an argument is a positive literal integer (e.g.
  // `1`), the compiler will understand that it can be safely converted to
  // size_t, and hence not generate a warning. But if a negative literal (e.g.
  // `-1`) or a variable with signed type is used, then it can generate a
  // warning about a potentially unsafe implicit cast. It would be great if we
  // could do this for Partial() too, but unfortunately as of C++23 there seems
  // to be no way to define a function with a variable number of parameters of a
  // certain type, a.k.a. homogeneous function parameter packs. So we're forced
  // to choose between explicitly casting the arguments to size_t, which
  // suppresses all warnings, even potentially valid ones, or implicitly casting
  // them to size_t, which generates bogus warnings whenever literal arguments
  // are used, even if they're positive.
  using Super::Super;
};

}  // 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::LayoutWithStaticSizes and
// internal_layout::LayoutImpl above. Those types are internal to the library
// but their methods are public, and they are inherited by `Layout`.
template <class... Ts>
class Layout : public internal_layout::LayoutWithStaticSizes<
                   absl::make_index_sequence<0>, Ts...> {
 private:
  using Super =
      internal_layout::LayoutWithStaticSizes<absl::make_index_sequence<0>,
                                             Ts...>;

 public:
  // If you know the sizes of some or all of the arrays at compile time, you can
  // use `WithStaticSizes` or `WithStaticSizeSequence` to create a `Layout` type
  // with those sizes baked in. This can help the compiler generate optimal code
  // for calculating array offsets and AllocSize().
  //
  // Like `Partial()`, the N sizes you specify are for the first N arrays, and
  // they specify the number of elements in each array, not the number of bytes.
  template <class StaticSizeSeq>
  using WithStaticSizeSequence =
      internal_layout::LayoutWithStaticSizes<StaticSizeSeq, Ts...>;

  template <size_t... StaticSizes>
  using WithStaticSizes =
      WithStaticSizeSequence<std::index_sequence<StaticSizes...>>;

  // Inherit LayoutWithStaticSizes's constructor, which requires you to specify
  // all the array sizes.
  using Super::Super;
};

}  // namespace container_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_CONTAINER_INTERNAL_LAYOUT_H_
*«,
“soong/.intermediates/external/abseil-cpp/absl_container_common_policy_traits_hdrs/gen/my_include_dir/absl/container/internal/common_policy_traits.h’+// 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.

#ifndef ABSL_CONTAINER_INTERNAL_COMMON_POLICY_TRAITS_H_
#define ABSL_CONTAINER_INTERNAL_COMMON_POLICY_TRAITS_H_

#include <cstddef>
#include <cstring>
#include <memory>
#include <new>
#include <type_traits>
#include <utility>

#include "absl/meta/type_traits.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace container_internal {

template <class Policy, class = void>
struct policy_trait_element_is_owner : std::false_type {};

template <class Policy>
struct policy_trait_element_is_owner<
    Policy,
    std::enable_if_t<!std::is_void<typename Policy::element_is_owner>::value>>
    : Policy::element_is_owner {};

// Defines how slots are initialized/destroyed/moved.
template <class Policy, class = void>
struct common_policy_traits {
  // The actual object stored in the container.
  using slot_type = typename Policy::slot_type;
  using reference = decltype(Policy::element(std::declval<slot_type*>()));
  using value_type = typename std::remove_reference<reference>::type;

  // PRECONDITION: `slot` is UNINITIALIZED
  // POSTCONDITION: `slot` is INITIALIZED
  template <class Alloc, class... Args>
  static void construct(Alloc* alloc, slot_type* slot, Args&&... args) {
    Policy::construct(alloc, slot, std::forward<Args>(args)...);
  }

  // PRECONDITION: `slot` is INITIALIZED
  // POSTCONDITION: `slot` is UNINITIALIZED
  // Returns std::true_type in case destroy is trivial.
  template <class Alloc>
  static auto destroy(Alloc* alloc, slot_type* slot) {
    return Policy::destroy(alloc, slot);
  }

  // Transfers the `old_slot` to `new_slot`. Any memory allocated by the
  // allocator inside `old_slot` to `new_slot` can be transferred.
  //
  // OPTIONAL: defaults to:
  //
  //     clone(new_slot, std::move(*old_slot));
  //     destroy(old_slot);
  //
  // PRECONDITION: `new_slot` is UNINITIALIZED and `old_slot` is INITIALIZED
  // POSTCONDITION: `new_slot` is INITIALIZED and `old_slot` is
  //                UNINITIALIZED
  template <class Alloc>
  static void transfer(Alloc* alloc, slot_type* new_slot, slot_type* old_slot) {
    transfer_impl(alloc, new_slot, old_slot, Rank2{});
  }

  // PRECONDITION: `slot` is INITIALIZED
  // POSTCONDITION: `slot` is INITIALIZED
  // Note: we use remove_const_t so that the two overloads have different args
  // in the case of sets with explicitly const value_types.
  template <class P = Policy>
  static auto element(absl::remove_const_t<slot_type>* slot)
      -> decltype(P::element(slot)) {
    return P::element(slot);
  }
  template <class P = Policy>
  static auto element(const slot_type* slot) -> decltype(P::element(slot)) {
    return P::element(slot);
  }

  static constexpr bool transfer_uses_memcpy() {
    return std::is_same<decltype(transfer_impl<std::allocator<char>>(
                            nullptr, nullptr, nullptr, Rank2{})),
                        std::true_type>::value;
  }

  // Returns true if destroy is trivial and can be omitted.
  template <class Alloc>
  static constexpr bool destroy_is_trivial() {
    return std::is_same<decltype(destroy<Alloc>(nullptr, nullptr)),
                        std::true_type>::value;
  }

 private:
  // Use go/ranked-overloads for dispatching.
  struct Rank0 {};
  struct Rank1 : Rank0 {};
  struct Rank2 : 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,
                            Rank2) -> decltype(P::transfer(alloc, new_slot,
                                                           old_slot)) {
    return P::transfer(alloc, new_slot, old_slot);
  }

  // This overload returns true_type for the trait below.
  // The conditional_t is to make the enabler type dependent.
  template <class Alloc,
            typename = std::enable_if_t<absl::is_trivially_relocatable<
                std::conditional_t<false, Alloc, value_type>>::value>>
  static std::true_type transfer_impl(Alloc*, slot_type* new_slot,
                                      slot_type* old_slot, Rank1) {
    // TODO(b/247130232): remove casts after fixing warnings.
    // TODO(b/251814870): remove casts after fixing warnings.
    std::memcpy(
        static_cast<void*>(std::launder(
            const_cast<std::remove_const_t<value_type>*>(&element(new_slot)))),
        static_cast<const void*>(&element(old_slot)), sizeof(value_type));
    return {};
  }

  template <class Alloc>
  static void transfer_impl(Alloc* alloc, slot_type* new_slot,
                            slot_type* old_slot, Rank0) {
    construct(alloc, new_slot, std::move(element(old_slot)));
    destroy(alloc, old_slot);
  }
};

}  // namespace container_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_CONTAINER_INTERNAL_COMMON_POLICY_TRAITS_H_
*§„
psoong/.intermediates/external/abseil-cpp/absl_container_btree_hdrs/gen/my_include_dir/absl/container/btree_map.h±ƒ// Copyright 2018 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// File: btree_map.h
// -----------------------------------------------------------------------------
//
// This header file defines B-tree maps: sorted associative containers mapping
// keys to values.
//
//     * `absl::btree_map<>`
//     * `absl::btree_multimap<>`
//
// These B-tree types are similar to the corresponding types in the STL
// (`std::map` and `std::multimap`) and generally conform to the STL interfaces
// of those types. However, because they are implemented using B-trees, they
// are more efficient in most situations.
//
// Unlike `std::map` and `std::multimap`, which are commonly implemented using
// red-black tree nodes, B-tree maps use more generic B-tree nodes able to hold
// multiple values per node. Holding multiple values per node often makes
// B-tree maps perform better than their `std::map` counterparts, because
// multiple entries can be checked within the same cache hit.
//
// However, these types should not be considered drop-in replacements for
// `std::map` and `std::multimap` as there are some API differences, which are
// noted in this header file. The most consequential differences with respect to
// migrating to b-tree from the STL types are listed in the next paragraph.
// Other API differences are minor.
//
// Importantly, insertions and deletions may invalidate outstanding iterators,
// pointers, and references to elements. Such invalidations are typically only
// an issue if insertion and deletion operations are interleaved with the use of
// more than one iterator, pointer, or reference simultaneously.  For this
// reason, `insert()`, `erase()`, and `extract_and_get_next()` return a valid
// iterator at the current position. Another important difference is that
// key-types must be copy-constructible.
//
// There are other API differences: first, btree iterators can be subtracted,
// and this is faster than using `std::distance`. Additionally, btree
// iterators can be advanced via `operator+=` and `operator-=`, which is faster
// than using `std::advance`.
//
// B-tree maps are not exception-safe.

#ifndef ABSL_CONTAINER_BTREE_MAP_H_
#define ABSL_CONTAINER_BTREE_MAP_H_

#include "absl/base/attributes.h"
#include "absl/container/internal/btree.h"  // IWYU pragma: export
#include "absl/container/internal/btree_container.h"  // IWYU pragma: export

namespace absl {
ABSL_NAMESPACE_BEGIN

namespace container_internal {

template <typename Key, typename Data, typename Compare, typename Alloc,
          int TargetNodeSize, bool IsMulti>
struct map_params;

}  // namespace container_internal

// absl::btree_map<>
//
// An `absl::btree_map<K, V>` is an ordered associative container of
// unique keys and associated values designed to be a more efficient replacement
// for `std::map` (in most cases).
//
// Keys are sorted using an (optional) comparison function, which defaults to
// `std::less<K>`.
//
// An `absl::btree_map<K, V>` uses a default allocator of
// `std::allocator<std::pair<const K, V>>` to allocate (and deallocate)
// nodes, and construct and destruct values within those nodes. You may
// instead specify a custom allocator `A` (which in turn requires specifying a
// custom comparator `C`) as in `absl::btree_map<K, V, C, A>`.
//
template <typename Key, typename Value, typename Compare = std::less<Key>,
          typename Alloc = std::allocator<std::pair<const Key, Value>>>
class ABSL_ATTRIBUTE_OWNER btree_map
    : public container_internal::btree_map_container<
          container_internal::btree<container_internal::map_params<
              Key, Value, Compare, Alloc, /*TargetNodeSize=*/256,
              /*IsMulti=*/false>>> {
  using Base = typename btree_map::btree_map_container;

 public:
  // Constructors and Assignment Operators
  //
  // A `btree_map` supports the same overload set as `std::map`
  // for construction and assignment:
  //
  // * Default constructor
  //
  //   absl::btree_map<int, std::string> map1;
  //
  // * Initializer List constructor
  //
  //   absl::btree_map<int, std::string> map2 =
  //       {{1, "huey"}, {2, "dewey"}, {3, "louie"},};
  //
  // * Copy constructor
  //
  //   absl::btree_map<int, std::string> map3(map2);
  //
  // * Copy assignment operator
  //
  //  absl::btree_map<int, std::string> map4;
  //  map4 = map3;
  //
  // * Move constructor
  //
  //   // Move is guaranteed efficient
  //   absl::btree_map<int, std::string> map5(std::move(map4));
  //
  // * Move assignment operator
  //
  //   // May be efficient if allocators are compatible
  //   absl::btree_map<int, std::string> map6;
  //   map6 = std::move(map5);
  //
  // * Range constructor
  //
  //   std::vector<std::pair<int, std::string>> v = {{1, "a"}, {2, "b"}};
  //   absl::btree_map<int, std::string> map7(v.begin(), v.end());
  btree_map() {}
  using Base::Base;

  // btree_map::begin()
  //
  // Returns an iterator to the beginning of the `btree_map`.
  using Base::begin;

  // btree_map::cbegin()
  //
  // Returns a const iterator to the beginning of the `btree_map`.
  using Base::cbegin;

  // btree_map::end()
  //
  // Returns an iterator to the end of the `btree_map`.
  using Base::end;

  // btree_map::cend()
  //
  // Returns a const iterator to the end of the `btree_map`.
  using Base::cend;

  // btree_map::empty()
  //
  // Returns whether or not the `btree_map` is empty.
  using Base::empty;

  // btree_map::max_size()
  //
  // Returns the largest theoretical possible number of elements within a
  // `btree_map` under current memory constraints. This value can be thought
  // of as the largest value of `std::distance(begin(), end())` for a
  // `btree_map<Key, T>`.
  using Base::max_size;

  // btree_map::size()
  //
  // Returns the number of elements currently within the `btree_map`.
  using Base::size;

  // btree_map::clear()
  //
  // Removes all elements from the `btree_map`. Invalidates any references,
  // pointers, or iterators referring to contained elements.
  using Base::clear;

  // btree_map::erase()
  //
  // Erases elements within the `btree_map`. If an erase occurs, any references,
  // pointers, or iterators are invalidated.
  // Overloads are listed below.
  //
  // iterator erase(iterator position):
  // iterator erase(const_iterator position):
  //
  //   Erases the element at `position` of the `btree_map`, returning
  //   the iterator pointing to the element after the one that was erased
  //   (or end() if none exists).
  //
  // iterator erase(const_iterator first, const_iterator last):
  //
  //   Erases the elements in the open interval [`first`, `last`), returning
  //   the iterator pointing to the element after the interval that was erased
  //   (or end() if none exists).
  //
  // template <typename K> size_type erase(const K& key):
  //
  //   Erases the element with the matching key, if it exists, returning the
  //   number of elements erased (0 or 1).
  using Base::erase;

  // btree_map::insert()
  //
  // Inserts an element of the specified value into the `btree_map`,
  // returning an iterator pointing to the newly inserted element, provided that
  // an element with the given key does not already exist. If an insertion
  // occurs, any references, pointers, or iterators are invalidated.
  // Overloads are listed below.
  //
  // std::pair<iterator,bool> insert(const value_type& value):
  //
  //   Inserts a value into the `btree_map`. Returns a pair consisting of an
  //   iterator to the inserted element (or to the element that prevented the
  //   insertion) and a bool denoting whether the insertion took place.
  //
  // std::pair<iterator,bool> insert(value_type&& value):
  //
  //   Inserts a moveable value into the `btree_map`. Returns a pair
  //   consisting of an iterator to the inserted element (or to the element that
  //   prevented the insertion) and a bool denoting whether the insertion took
  //   place.
  //
  // iterator insert(const_iterator hint, const value_type& value):
  // iterator insert(const_iterator hint, value_type&& value):
  //
  //   Inserts a value, using the position of `hint` as a non-binding suggestion
  //   for where to begin the insertion search. Returns an iterator to the
  //   inserted element, or to the existing element that prevented the
  //   insertion.
  //
  // void insert(InputIterator first, InputIterator last):
  //
  //   Inserts a range of values [`first`, `last`).
  //
  // void insert(std::initializer_list<init_type> ilist):
  //
  //   Inserts the elements within the initializer list `ilist`.
  using Base::insert;

  // btree_map::insert_or_assign()
  //
  // Inserts an element of the specified value into the `btree_map` provided
  // that a value with the given key does not already exist, or replaces the
  // corresponding mapped type with the forwarded `obj` argument if a key for
  // that value already exists, returning an iterator pointing to the newly
  // inserted element. Overloads are listed below.
  //
  // pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj):
  // pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj):
  //
  //   Inserts/Assigns (or moves) the element of the specified key into the
  //   `btree_map`. If the returned bool is true, insertion took place, and if
  //   it's false, assignment took place.
  //
  // iterator insert_or_assign(const_iterator hint,
  //                           const key_type& k, M&& obj):
  // iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj):
  //
  //   Inserts/Assigns (or moves) the element of the specified key into the
  //   `btree_map` using the position of `hint` as a non-binding suggestion
  //   for where to begin the insertion search.
  using Base::insert_or_assign;

  // btree_map::emplace()
  //
  // Inserts an element of the specified value by constructing it in-place
  // within the `btree_map`, provided that no element with the given key
  // already exists.
  //
  // The element may be constructed even if there already is an element with the
  // key in the container, in which case the newly constructed element will be
  // destroyed immediately. Prefer `try_emplace()` unless your key is not
  // copyable or moveable.
  //
  // If an insertion occurs, any references, pointers, or iterators are
  // invalidated.
  using Base::emplace;

  // btree_map::emplace_hint()
  //
  // Inserts an element of the specified value by constructing it in-place
  // within the `btree_map`, using the position of `hint` as a non-binding
  // suggestion for where to begin the insertion search, and only inserts
  // provided that no element with the given key already exists.
  //
  // The element may be constructed even if there already is an element with the
  // key in the container, in which case the newly constructed element will be
  // destroyed immediately. Prefer `try_emplace()` unless your key is not
  // copyable or moveable.
  //
  // If an insertion occurs, any references, pointers, or iterators are
  // invalidated.
  using Base::emplace_hint;

  // btree_map::try_emplace()
  //
  // Inserts an element of the specified value by constructing it in-place
  // within the `btree_map`, provided that no element with the given key
  // already exists. Unlike `emplace()`, if an element with the given key
  // already exists, we guarantee that no element is constructed.
  //
  // If an insertion occurs, any references, pointers, or iterators are
  // invalidated.
  //
  // Overloads are listed below.
  //
  //   std::pair<iterator, bool> try_emplace(const key_type& k, Args&&... args):
  //   std::pair<iterator, bool> try_emplace(key_type&& k, Args&&... args):
  //
  // Inserts (via copy or move) the element of the specified key into the
  // `btree_map`.
  //
  //   iterator try_emplace(const_iterator hint,
  //                        const key_type& k, Args&&... args):
  //   iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args):
  //
  // Inserts (via copy or move) the element of the specified key into the
  // `btree_map` using the position of `hint` as a non-binding suggestion
  // for where to begin the insertion search.
  using Base::try_emplace;

  // btree_map::extract()
  //
  // Extracts the indicated element, erasing it in the process, and returns it
  // as a C++17-compatible node handle. Any references, pointers, or iterators
  // are invalidated. Overloads are listed below.
  //
  // node_type extract(const_iterator position):
  //
  //   Extracts the element at the indicated position and returns a node handle
  //   owning that extracted data.
  //
  // template <typename K> node_type extract(const K& k):
  //
  //   Extracts the element with the key matching the passed key value and
  //   returns a node handle owning that extracted data. If the `btree_map`
  //   does not contain an element with a matching key, this function returns an
  //   empty node handle.
  //
  // NOTE: when compiled in an earlier version of C++ than C++17,
  // `node_type::key()` returns a const reference to the key instead of a
  // mutable reference. We cannot safely return a mutable reference without
  // std::launder (which is not available before C++17).
  //
  // NOTE: In this context, `node_type` refers to the C++17 concept of a
  // move-only type that owns and provides access to the elements in associative
  // containers (https://en.cppreference.com/w/cpp/container/node_handle).
  // It does NOT refer to the data layout of the underlying btree.
  using Base::extract;

  // btree_map::extract_and_get_next()
  //
  // Extracts the indicated element, erasing it in the process, and returns it
  // as a C++17-compatible node handle along with an iterator to the next
  // element.
  //
  // extract_and_get_next_return_type extract_and_get_next(
  //     const_iterator position):
  //
  //   Extracts the element at the indicated position, returns a struct
  //   containing a member named `node`: a node handle owning that extracted
  //   data and a member named `next`: an iterator pointing to the next element
  //   in the btree.
  using Base::extract_and_get_next;

  // btree_map::merge()
  //
  // Extracts elements from a given `source` btree_map into this
  // `btree_map`. If the destination `btree_map` already contains an
  // element with an equivalent key, that element is not extracted.
  using Base::merge;

  // btree_map::swap(btree_map& other)
  //
  // Exchanges the contents of this `btree_map` with those of the `other`
  // btree_map, avoiding invocation of any move, copy, or swap operations on
  // individual elements.
  //
  // All iterators and references on the `btree_map` remain valid, excepting
  // for the past-the-end iterator, which is invalidated.
  using Base::swap;

  // btree_map::at()
  //
  // Returns a reference to the mapped value of the element with key equivalent
  // to the passed key.
  using Base::at;

  // btree_map::contains()
  //
  // template <typename K> bool contains(const K& key) const:
  //
  // Determines whether an element comparing equal to the given `key` exists
  // within the `btree_map`, returning `true` if so or `false` otherwise.
  //
  // Supports heterogeneous lookup, provided that the map has a compatible
  // heterogeneous comparator.
  using Base::contains;

  // btree_map::count()
  //
  // template <typename K> size_type count(const K& key) const:
  //
  // Returns the number of elements comparing equal to the given `key` within
  // the `btree_map`. Note that this function will return either `1` or `0`
  // since duplicate elements are not allowed within a `btree_map`.
  //
  // Supports heterogeneous lookup, provided that the map has a compatible
  // heterogeneous comparator.
  using Base::count;

  // btree_map::equal_range()
  //
  // Returns a half-open range [first, last), defined by a `std::pair` of two
  // iterators, containing all elements with the passed key in the `btree_map`.
  using Base::equal_range;

  // btree_map::find()
  //
  // template <typename K> iterator find(const K& key):
  // template <typename K> const_iterator find(const K& key) const:
  //
  // Finds an element with the passed `key` within the `btree_map`.
  //
  // Supports heterogeneous lookup, provided that the map has a compatible
  // heterogeneous comparator.
  using Base::find;

  // btree_map::lower_bound()
  //
  // template <typename K> iterator lower_bound(const K& key):
  // template <typename K> const_iterator lower_bound(const K& key) const:
  //
  // Finds the first element with a key that is not less than `key` within the
  // `btree_map`.
  //
  // Supports heterogeneous lookup, provided that the map has a compatible
  // heterogeneous comparator.
  using Base::lower_bound;

  // btree_map::upper_bound()
  //
  // template <typename K> iterator upper_bound(const K& key):
  // template <typename K> const_iterator upper_bound(const K& key) const:
  //
  // Finds the first element with a key that is greater than `key` within the
  // `btree_map`.
  //
  // Supports heterogeneous lookup, provided that the map has a compatible
  // heterogeneous comparator.
  using Base::upper_bound;

  // btree_map::operator[]()
  //
  // Returns a reference to the value mapped to the passed key within the
  // `btree_map`, performing an `insert()` if the key does not already
  // exist.
  //
  // If an insertion occurs, any references, pointers, or iterators are
  // invalidated. Otherwise iterators are not affected and references are not
  // invalidated. Overloads are listed below.
  //
  // T& operator[](key_type&& key):
  // T& operator[](const key_type& key):
  //
  //   Inserts a value_type object constructed in-place if the element with the
  //   given key does not exist.
  using Base::operator[];

  // btree_map::get_allocator()
  //
  // Returns the allocator function associated with this `btree_map`.
  using Base::get_allocator;

  // btree_map::key_comp();
  //
  // Returns the key comparator associated with this `btree_map`.
  using Base::key_comp;

  // btree_map::value_comp();
  //
  // Returns the value comparator associated with this `btree_map`.
  using Base::value_comp;
};

// absl::swap(absl::btree_map<>, absl::btree_map<>)
//
// Swaps the contents of two `absl::btree_map` containers.
template <typename K, typename V, typename C, typename A>
void swap(btree_map<K, V, C, A> &x, btree_map<K, V, C, A> &y) {
  return x.swap(y);
}

// absl::erase_if(absl::btree_map<>, Pred)
//
// Erases all elements that satisfy the predicate pred from the container.
// Returns the number of erased elements.
template <typename K, typename V, typename C, typename A, typename Pred>
typename btree_map<K, V, C, A>::size_type erase_if(
    btree_map<K, V, C, A> &map, Pred pred) {
  return container_internal::btree_access::erase_if(map, std::move(pred));
}

// absl::btree_multimap
//
// An `absl::btree_multimap<K, V>` is an ordered associative container of
// keys and associated values designed to be a more efficient replacement for
// `std::multimap` (in most cases). Unlike `absl::btree_map`, a B-tree multimap
// allows multiple elements with equivalent keys.
//
// Keys are sorted using an (optional) comparison function, which defaults to
// `std::less<K>`.
//
// An `absl::btree_multimap<K, V>` uses a default allocator of
// `std::allocator<std::pair<const K, V>>` to allocate (and deallocate)
// nodes, and construct and destruct values within those nodes. You may
// instead specify a custom allocator `A` (which in turn requires specifying a
// custom comparator `C`) as in `absl::btree_multimap<K, V, C, A>`.
//
template <typename Key, typename Value, typename Compare = std::less<Key>,
          typename Alloc = std::allocator<std::pair<const Key, Value>>>
class ABSL_ATTRIBUTE_OWNER btree_multimap
    : public container_internal::btree_multimap_container<
          container_internal::btree<container_internal::map_params<
              Key, Value, Compare, Alloc, /*TargetNodeSize=*/256,
              /*IsMulti=*/true>>> {
  using Base = typename btree_multimap::btree_multimap_container;

 public:
  // Constructors and Assignment Operators
  //
  // A `btree_multimap` supports the same overload set as `std::multimap`
  // for construction and assignment:
  //
  // * Default constructor
  //
  //   absl::btree_multimap<int, std::string> map1;
  //
  // * Initializer List constructor
  //
  //   absl::btree_multimap<int, std::string> map2 =
  //       {{1, "huey"}, {2, "dewey"}, {3, "louie"},};
  //
  // * Copy constructor
  //
  //   absl::btree_multimap<int, std::string> map3(map2);
  //
  // * Copy assignment operator
  //
  //  absl::btree_multimap<int, std::string> map4;
  //  map4 = map3;
  //
  // * Move constructor
  //
  //   // Move is guaranteed efficient
  //   absl::btree_multimap<int, std::string> map5(std::move(map4));
  //
  // * Move assignment operator
  //
  //   // May be efficient if allocators are compatible
  //   absl::btree_multimap<int, std::string> map6;
  //   map6 = std::move(map5);
  //
  // * Range constructor
  //
  //   std::vector<std::pair<int, std::string>> v = {{1, "a"}, {2, "b"}};
  //   absl::btree_multimap<int, std::string> map7(v.begin(), v.end());
  btree_multimap() {}
  using Base::Base;

  // btree_multimap::begin()
  //
  // Returns an iterator to the beginning of the `btree_multimap`.
  using Base::begin;

  // btree_multimap::cbegin()
  //
  // Returns a const iterator to the beginning of the `btree_multimap`.
  using Base::cbegin;

  // btree_multimap::end()
  //
  // Returns an iterator to the end of the `btree_multimap`.
  using Base::end;

  // btree_multimap::cend()
  //
  // Returns a const iterator to the end of the `btree_multimap`.
  using Base::cend;

  // btree_multimap::empty()
  //
  // Returns whether or not the `btree_multimap` is empty.
  using Base::empty;

  // btree_multimap::max_size()
  //
  // Returns the largest theoretical possible number of elements within a
  // `btree_multimap` under current memory constraints. This value can be
  // thought of as the largest value of `std::distance(begin(), end())` for a
  // `btree_multimap<Key, T>`.
  using Base::max_size;

  // btree_multimap::size()
  //
  // Returns the number of elements currently within the `btree_multimap`.
  using Base::size;

  // btree_multimap::clear()
  //
  // Removes all elements from the `btree_multimap`. Invalidates any references,
  // pointers, or iterators referring to contained elements.
  using Base::clear;

  // btree_multimap::erase()
  //
  // Erases elements within the `btree_multimap`. If an erase occurs, any
  // references, pointers, or iterators are invalidated.
  // Overloads are listed below.
  //
  // iterator erase(iterator position):
  // iterator erase(const_iterator position):
  //
  //   Erases the element at `position` of the `btree_multimap`, returning
  //   the iterator pointing to the element after the one that was erased
  //   (or end() if none exists).
  //
  // iterator erase(const_iterator first, const_iterator last):
  //
  //   Erases the elements in the open interval [`first`, `last`), returning
  //   the iterator pointing to the element after the interval that was erased
  //   (or end() if none exists).
  //
  // template <typename K> size_type erase(const K& key):
  //
  //   Erases the elements matching the key, if any exist, returning the
  //   number of elements erased.
  using Base::erase;

  // btree_multimap::insert()
  //
  // Inserts an element of the specified value into the `btree_multimap`,
  // returning an iterator pointing to the newly inserted element.
  // Any references, pointers, or iterators are invalidated.  Overloads are
  // listed below.
  //
  // iterator insert(const value_type& value):
  //
  //   Inserts a value into the `btree_multimap`, returning an iterator to the
  //   inserted element.
  //
  // iterator insert(value_type&& value):
  //
  //   Inserts a moveable value into the `btree_multimap`, returning an iterator
  //   to the inserted element.
  //
  // iterator insert(const_iterator hint, const value_type& value):
  // iterator insert(const_iterator hint, value_type&& value):
  //
  //   Inserts a value, using the position of `hint` as a non-binding suggestion
  //   for where to begin the insertion search. Returns an iterator to the
  //   inserted element.
  //
  // void insert(InputIterator first, InputIterator last):
  //
  //   Inserts a range of values [`first`, `last`).
  //
  // void insert(std::initializer_list<init_type> ilist):
  //
  //   Inserts the elements within the initializer list `ilist`.
  using Base::insert;

  // btree_multimap::emplace()
  //
  // Inserts an element of the specified value by constructing it in-place
  // within the `btree_multimap`. Any references, pointers, or iterators are
  // invalidated.
  using Base::emplace;

  // btree_multimap::emplace_hint()
  //
  // Inserts an element of the specified value by constructing it in-place
  // within the `btree_multimap`, using the position of `hint` as a non-binding
  // suggestion for where to begin the insertion search.
  //
  // Any references, pointers, or iterators are invalidated.
  using Base::emplace_hint;

  // btree_multimap::extract()
  //
  // Extracts the indicated element, erasing it in the process, and returns it
  // as a C++17-compatible node handle. Overloads are listed below.
  //
  // node_type extract(const_iterator position):
  //
  //   Extracts the element at the indicated position and returns a node handle
  //   owning that extracted data.
  //
  // template <typename K> node_type extract(const K& k):
  //
  //   Extracts the element with the key matching the passed key value and
  //   returns a node handle owning that extracted data. If the `btree_multimap`
  //   does not contain an element with a matching key, this function returns an
  //   empty node handle.
  //
  // NOTE: when compiled in an earlier version of C++ than C++17,
  // `node_type::key()` returns a const reference to the key instead of a
  // mutable reference. We cannot safely return a mutable reference without
  // std::launder (which is not available before C++17).
  //
  // NOTE: In this context, `node_type` refers to the C++17 concept of a
  // move-only type that owns and provides access to the elements in associative
  // containers (https://en.cppreference.com/w/cpp/container/node_handle).
  // It does NOT refer to the data layout of the underlying btree.
  using Base::extract;

  // btree_multimap::extract_and_get_next()
  //
  // Extracts the indicated element, erasing it in the process, and returns it
  // as a C++17-compatible node handle along with an iterator to the next
  // element.
  //
  // extract_and_get_next_return_type extract_and_get_next(
  //     const_iterator position):
  //
  //   Extracts the element at the indicated position, returns a struct
  //   containing a member named `node`: a node handle owning that extracted
  //   data and a member named `next`: an iterator pointing to the next element
  //   in the btree.
  using Base::extract_and_get_next;

  // btree_multimap::merge()
  //
  // Extracts all elements from a given `source` btree_multimap into this
  // `btree_multimap`.
  using Base::merge;

  // btree_multimap::swap(btree_multimap& other)
  //
  // Exchanges the contents of this `btree_multimap` with those of the `other`
  // btree_multimap, avoiding invocation of any move, copy, or swap operations
  // on individual elements.
  //
  // All iterators and references on the `btree_multimap` remain valid,
  // excepting for the past-the-end iterator, which is invalidated.
  using Base::swap;

  // btree_multimap::contains()
  //
  // template <typename K> bool contains(const K& key) const:
  //
  // Determines whether an element comparing equal to the given `key` exists
  // within the `btree_multimap`, returning `true` if so or `false` otherwise.
  //
  // Supports heterogeneous lookup, provided that the map has a compatible
  // heterogeneous comparator.
  using Base::contains;

  // btree_multimap::count()
  //
  // template <typename K> size_type count(const K& key) const:
  //
  // Returns the number of elements comparing equal to the given `key` within
  // the `btree_multimap`.
  //
  // Supports heterogeneous lookup, provided that the map has a compatible
  // heterogeneous comparator.
  using Base::count;

  // btree_multimap::equal_range()
  //
  // Returns a half-open range [first, last), defined by a `std::pair` of two
  // iterators, containing all elements with the passed key in the
  // `btree_multimap`.
  using Base::equal_range;

  // btree_multimap::find()
  //
  // template <typename K> iterator find(const K& key):
  // template <typename K> const_iterator find(const K& key) const:
  //
  // Finds an element with the passed `key` within the `btree_multimap`.
  //
  // Supports heterogeneous lookup, provided that the map has a compatible
  // heterogeneous comparator.
  using Base::find;

  // btree_multimap::lower_bound()
  //
  // template <typename K> iterator lower_bound(const K& key):
  // template <typename K> const_iterator lower_bound(const K& key) const:
  //
  // Finds the first element with a key that is not less than `key` within the
  // `btree_multimap`.
  //
  // Supports heterogeneous lookup, provided that the map has a compatible
  // heterogeneous comparator.
  using Base::lower_bound;

  // btree_multimap::upper_bound()
  //
  // template <typename K> iterator upper_bound(const K& key):
  // template <typename K> const_iterator upper_bound(const K& key) const:
  //
  // Finds the first element with a key that is greater than `key` within the
  // `btree_multimap`.
  //
  // Supports heterogeneous lookup, provided that the map has a compatible
  // heterogeneous comparator.
  using Base::upper_bound;

  // btree_multimap::get_allocator()
  //
  // Returns the allocator function associated with this `btree_multimap`.
  using Base::get_allocator;

  // btree_multimap::key_comp();
  //
  // Returns the key comparator associated with this `btree_multimap`.
  using Base::key_comp;

  // btree_multimap::value_comp();
  //
  // Returns the value comparator associated with this `btree_multimap`.
  using Base::value_comp;
};

// absl::swap(absl::btree_multimap<>, absl::btree_multimap<>)
//
// Swaps the contents of two `absl::btree_multimap` containers.
template <typename K, typename V, typename C, typename A>
void swap(btree_multimap<K, V, C, A> &x, btree_multimap<K, V, C, A> &y) {
  return x.swap(y);
}

// absl::erase_if(absl::btree_multimap<>, Pred)
//
// Erases all elements that satisfy the predicate pred from the container.
// Returns the number of erased elements.
template <typename K, typename V, typename C, typename A, typename Pred>
typename btree_multimap<K, V, C, A>::size_type erase_if(
    btree_multimap<K, V, C, A> &map, Pred pred) {
  return container_internal::btree_access::erase_if(map, std::move(pred));
}

namespace container_internal {

// A parameters structure for holding the type parameters for a btree_map.
// Compare and Alloc should be nothrow copy-constructible.
template <typename Key, typename Data, typename Compare, typename Alloc,
          int TargetNodeSize, bool IsMulti>
struct map_params : common_params<Key, Compare, Alloc, TargetNodeSize, IsMulti,
                                  /*IsMap=*/true, map_slot_policy<Key, Data>> {
  using super_type = typename map_params::common_params;
  using mapped_type = Data;
  // This type allows us to move keys when it is safe to do so. It is safe
  // for maps in which value_type and mutable_value_type are layout compatible.
  using slot_policy = typename super_type::slot_policy;
  using slot_type = typename super_type::slot_type;
  using value_type = typename super_type::value_type;
  using init_type = typename super_type::init_type;

  template <typename V>
  static auto key(const V &value ABSL_ATTRIBUTE_LIFETIME_BOUND)
      -> decltype((value.first)) {
    return value.first;
  }
  static const Key &key(const slot_type *s) { return slot_policy::key(s); }
  static const Key &key(slot_type *s) { return slot_policy::key(s); }
  // For use in node handle.
  static auto mutable_key(slot_type *s)
      -> decltype(slot_policy::mutable_key(s)) {
    return slot_policy::mutable_key(s);
  }
  static mapped_type &value(value_type *value) { return value->second; }
};

}  // namespace container_internal

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_CONTAINER_BTREE_MAP_H_
*Š
{soong/.intermediates/external/abseil-cpp/absl_base_spinlock_wait_hdrs/gen/my_include_dir/absl/base/internal/spinlock_wait.hŠ// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_BASE_INTERNAL_SPINLOCK_WAIT_H_
#define ABSL_BASE_INTERNAL_SPINLOCK_WAIT_H_

// Operations to make atomic transitions on a word, and to allow
// waiting for those transitions to become possible.

#include <stdint.h>
#include <atomic>

#include "absl/base/internal/scheduling_mode.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {

// SpinLockWait() waits until it can perform one of several transitions from
// "from" to "to".  It returns when it performs a transition where done==true.
struct SpinLockWaitTransition {
  uint32_t from;
  uint32_t to;
  bool done;
};

// Wait until *w can transition from trans[i].from to trans[i].to for some i
// satisfying 0<=i<n && trans[i].done, atomically make the transition,
// then return the old value of *w.   Make any other atomic transitions
// where !trans[i].done, but continue waiting.
//
// Wakeups for threads blocked on SpinLockWait do not respect priorities.
uint32_t SpinLockWait(std::atomic<uint32_t> *w, int n,
                      const SpinLockWaitTransition trans[],
                      SchedulingMode scheduling_mode);

// If possible, wake some thread that has called SpinLockDelay(w, ...). If `all`
// is true, wake all such threads. On some systems, this may be a no-op; on
// those systems, threads calling SpinLockDelay() will always wake eventually
// even if SpinLockWake() is never called.
void SpinLockWake(std::atomic<uint32_t> *w, bool all);

// Wait for an appropriate spin delay on iteration "loop" of a
// spin loop on location *w, whose previously observed value was "value".
// SpinLockDelay() may do nothing, may yield the CPU, may sleep a clock tick,
// or may wait for a call to SpinLockWake(w).
void SpinLockDelay(std::atomic<uint32_t> *w, uint32_t value, int loop,
                   base_internal::SchedulingMode scheduling_mode);

// Helper used by AbslInternalSpinLockDelay.
// Returns a suggested delay in nanoseconds for iteration number "loop".
int SpinLockSuggestedDelayNS(int loop);

}  // namespace base_internal
ABSL_NAMESPACE_END
}  // namespace absl

// In some build configurations we pass --detect-odr-violations to the
// gold linker.  This causes it to flag weak symbol overrides as ODR
// violations.  Because ODR only applies to C++ and not C,
// --detect-odr-violations ignores symbols not mangled with C++ names.
// By changing our extension points to be extern "C", we dodge this
// check.
extern "C" {
void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)(std::atomic<uint32_t> *w,
                                                      bool all);
void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)(
    std::atomic<uint32_t> *w, uint32_t value, int loop,
    absl::base_internal::SchedulingMode scheduling_mode);
}

inline void absl::base_internal::SpinLockWake(std::atomic<uint32_t> *w,
                                              bool all) {
  ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)(w, all);
}

inline void absl::base_internal::SpinLockDelay(
    std::atomic<uint32_t> *w, uint32_t value, int loop,
    absl::base_internal::SchedulingMode scheduling_mode) {
  ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)
  (w, value, loop, scheduling_mode);
}

#endif  // ABSL_BASE_INTERNAL_SPINLOCK_WAIT_H_
*™B
`soong/.intermediates/external/abseil-cpp/absl_base_hdrs/gen/my_include_dir/absl/base/call_once.h´A// 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.
//
// -----------------------------------------------------------------------------
// File: call_once.h
// -----------------------------------------------------------------------------
//
// This header file provides an Abseil version of `std::call_once` for invoking
// a given function at most once, across all threads. This Abseil version is
// faster than the C++11 version and incorporates the C++17 argument-passing
// fix, so that (for example) non-const references may be passed to the invoked
// function.

#ifndef ABSL_BASE_CALL_ONCE_H_
#define ABSL_BASE_CALL_ONCE_H_

#include <algorithm>
#include <atomic>
#include <cstdint>
#include <functional>
#include <type_traits>
#include <utility>

#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/low_level_scheduling.h"
#include "absl/base/internal/raw_logging.h"
#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"

namespace absl {
ABSL_NAMESPACE_BEGIN

class once_flag;

namespace base_internal {
std::atomic<uint32_t>* absl_nonnull ControlWord(
    absl::once_flag* absl_nonnull flag);
}  // namespace base_internal

// call_once()
//
// For all invocations using a given `once_flag`, invokes a given `fn` exactly
// once across all threads. The first call to `call_once()` with a particular
// `once_flag` argument (that does not throw an exception) will run the
// specified function with the provided `args`; other calls with the same
// `once_flag` argument will not run the function, but will wait
// for the provided function to finish running (if it is still running).
//
// This mechanism provides a safe, simple, and fast mechanism for one-time
// initialization in a multi-threaded process.
//
// Example:
//
// class MyInitClass {
//  public:
//  ...
//  mutable absl::once_flag once_;
//
//  MyInitClass* init() const {
//    absl::call_once(once_, &MyInitClass::Init, this);
//    return ptr_;
//  }
//
template <typename Callable, typename... Args>
void call_once(absl::once_flag& flag, Callable&& fn, Args&&... args);

// once_flag
//
// Objects of this type are used to distinguish calls to `call_once()` and
// ensure the provided function is only invoked once across all threads. This
// type is not copyable or movable. However, it has a `constexpr`
// constructor, and is safe to use as a namespace-scoped global variable.
class once_flag {
 public:
  constexpr once_flag() : control_(0) {}
  once_flag(const once_flag&) = delete;
  once_flag& operator=(const once_flag&) = delete;

 private:
  friend std::atomic<uint32_t>* absl_nonnull base_internal::ControlWord(
      once_flag* absl_nonnull flag);
  std::atomic<uint32_t> control_;
};

//------------------------------------------------------------------------------
// End of public interfaces.
// Implementation details follow.
//------------------------------------------------------------------------------

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* absl_nonnull flag, Callable&& fn,
                      Args&&... args);

// Disables scheduling while on stack when scheduling mode is non-cooperative.
// No effect for cooperative scheduling modes.
class SchedulingHelper {
 public:
  explicit SchedulingHelper(base_internal::SchedulingMode mode) : mode_(mode) {
    if (mode_ == base_internal::SCHEDULE_KERNEL_ONLY) {
      guard_result_ = base_internal::SchedulingGuard::DisableRescheduling();
    }
  }

  ~SchedulingHelper() {
    if (mode_ == base_internal::SCHEDULE_KERNEL_ONLY) {
      base_internal::SchedulingGuard::EnableRescheduling(guard_result_);
    }
  }

 private:
  base_internal::SchedulingMode mode_;
  bool guard_result_ = false;
};

// Bit patterns for call_once state machine values.  Internal implementation
// detail, not for use by clients.
//
// The bit patterns are arbitrarily chosen from unlikely values, to aid in
// debugging.  However, kOnceInit must be 0, so that a zero-initialized
// once_flag will be valid for immediate use.
enum {
  kOnceInit = 0,
  kOnceRunning = 0x65C2937B,
  kOnceWaiter = 0x05A308D2,
  // A very small constant is chosen for kOnceDone so that it fit in a single
  // compare with immediate instruction for most common ISAs.  This is verified
  // for x86, POWER and ARM.
  kOnceDone = 221,    // Random Number
};

template <typename Callable, typename... Args>
    void
    CallOnceImpl(std::atomic<uint32_t>* absl_nonnull control,
                 base_internal::SchedulingMode scheduling_mode, Callable&& fn,
                 Args&&... args) {
#ifndef NDEBUG
  {
    uint32_t old_control = control->load(std::memory_order_relaxed);
    if (old_control != kOnceInit &&
        old_control != kOnceRunning &&
        old_control != kOnceWaiter &&
        old_control != kOnceDone) {
      ABSL_RAW_LOG(FATAL, "Unexpected value for control word: 0x%lx",
                   static_cast<unsigned long>(old_control));  // NOLINT
    }
  }
#endif  // NDEBUG
  static const base_internal::SpinLockWaitTransition trans[] = {
      {kOnceInit, kOnceRunning, true},
      {kOnceRunning, kOnceWaiter, false},
      {kOnceDone, kOnceDone, true}};

  // Must do this before potentially modifying control word's state.
  base_internal::SchedulingHelper maybe_disable_scheduling(scheduling_mode);
  // Short circuit the simplest case to avoid procedure call overhead.
  // The base_internal::SpinLockWait() call returns either kOnceInit or
  // kOnceDone. If it returns kOnceDone, it must have loaded the control word
  // with std::memory_order_acquire and seen a value of kOnceDone.
  uint32_t old_control = kOnceInit;
  if (control->compare_exchange_strong(old_control, kOnceRunning,
                                       std::memory_order_relaxed) ||
      base_internal::SpinLockWait(control, ABSL_ARRAYSIZE(trans), trans,
                                  scheduling_mode) == kOnceInit) {
    std::invoke(std::forward<Callable>(fn), std::forward<Args>(args)...);
    old_control =
        control->exchange(base_internal::kOnceDone, std::memory_order_release);
    if (old_control == base_internal::kOnceWaiter) {
      base_internal::SpinLockWake(control, true);
    }
  }  // else *control is already kOnceDone
}

inline std::atomic<uint32_t>* absl_nonnull ControlWord(
    once_flag* absl_nonnull flag) {
  return &flag->control_;
}

template <typename Callable, typename... Args>
void LowLevelCallOnce(absl::once_flag* absl_nonnull 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)) {
    base_internal::CallOnceImpl(once, base_internal::SCHEDULE_KERNEL_ONLY,
                                std::forward<Callable>(fn),
                                std::forward<Args>(args)...);
  }
}

}  // namespace base_internal

template <typename Callable, typename... Args>
    void
    call_once(absl::once_flag& flag, Callable&& fn, Args&&... args) {
  std::atomic<uint32_t>* once = base_internal::ControlWord(&flag);
  uint32_t s = once->load(std::memory_order_acquire);
  if (ABSL_PREDICT_FALSE(s != base_internal::kOnceDone)) {
    base_internal::CallOnceImpl(
        once, base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL,
        std::forward<Callable>(fn), std::forward<Args>(args)...);
  }
}

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_BASE_CALL_ONCE_H_
*´"
tsoong/.intermediates/external/abseil-cpp/absl_log_absl_vlog_is_on_hdrs/gen/my_include_dir/absl/log/absl_vlog_is_on.h»!// 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".
//
// Example: --vmodule=module_a=1,module_b=2
//
// Files are matched against globs in `--vmodule` in order, and the first match
// determines the verbosity level.
//
// 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_
*¯*
fsoong/.intermediates/external/abseil-cpp/absl_log_absl_log_hdrs/gen/my_include_dir/absl/log/absl_log.hÄ)// 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_log.h
// -----------------------------------------------------------------------------
//
// This header declares a family of `ABSL_LOG` macros as alternative spellings
// for macros in `log.h`.
//
// Basic invocation looks like this:
//
//   ABSL_LOG(INFO) << "Found " << num_cookies << " cookies";
//
// Most `ABSL_LOG` macros take a severity level argument. The severity levels
// are `INFO`, `WARNING`, `ERROR`, and `FATAL`.
//
// For full documentation, see comments in `log.h`, which includes full
// reference documentation on use of the equivalent `LOG` macro and has an
// identical set of macros without the ABSL_* prefix.

#ifndef ABSL_LOG_ABSL_LOG_H_
#define ABSL_LOG_ABSL_LOG_H_

#include "absl/log/internal/log_impl.h"

#define ABSL_LOG(severity) ABSL_LOG_INTERNAL_LOG_IMPL(_##severity)
#define ABSL_PLOG(severity) ABSL_LOG_INTERNAL_PLOG_IMPL(_##severity)
#define ABSL_DLOG(severity) ABSL_LOG_INTERNAL_DLOG_IMPL(_##severity)

#define ABSL_VLOG(verbose_level) ABSL_LOG_INTERNAL_VLOG_IMPL(verbose_level)
#define ABSL_DVLOG(verbose_level) ABSL_LOG_INTERNAL_DVLOG_IMPL(verbose_level)

#define ABSL_LOG_IF(severity, condition) \
  ABSL_LOG_INTERNAL_LOG_IF_IMPL(_##severity, condition)
#define ABSL_PLOG_IF(severity, condition) \
  ABSL_LOG_INTERNAL_PLOG_IF_IMPL(_##severity, condition)
#define ABSL_DLOG_IF(severity, condition) \
  ABSL_LOG_INTERNAL_DLOG_IF_IMPL(_##severity, condition)

#define ABSL_LOG_EVERY_N(severity, n) \
  ABSL_LOG_INTERNAL_LOG_EVERY_N_IMPL(_##severity, n)
#define ABSL_LOG_FIRST_N(severity, n) \
  ABSL_LOG_INTERNAL_LOG_FIRST_N_IMPL(_##severity, n)
#define ABSL_LOG_EVERY_POW_2(severity) \
  ABSL_LOG_INTERNAL_LOG_EVERY_POW_2_IMPL(_##severity)
#define ABSL_LOG_EVERY_N_SEC(severity, n_seconds) \
  ABSL_LOG_INTERNAL_LOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)

#define ABSL_PLOG_EVERY_N(severity, n) \
  ABSL_LOG_INTERNAL_PLOG_EVERY_N_IMPL(_##severity, n)
#define ABSL_PLOG_FIRST_N(severity, n) \
  ABSL_LOG_INTERNAL_PLOG_FIRST_N_IMPL(_##severity, n)
#define ABSL_PLOG_EVERY_POW_2(severity) \
  ABSL_LOG_INTERNAL_PLOG_EVERY_POW_2_IMPL(_##severity)
#define ABSL_PLOG_EVERY_N_SEC(severity, n_seconds) \
  ABSL_LOG_INTERNAL_PLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)

#define ABSL_DLOG_EVERY_N(severity, n) \
  ABSL_LOG_INTERNAL_DLOG_EVERY_N_IMPL(_##severity, n)
#define ABSL_DLOG_FIRST_N(severity, n) \
  ABSL_LOG_INTERNAL_DLOG_FIRST_N_IMPL(_##severity, n)
#define ABSL_DLOG_EVERY_POW_2(severity) \
  ABSL_LOG_INTERNAL_DLOG_EVERY_POW_2_IMPL(_##severity)
#define ABSL_DLOG_EVERY_N_SEC(severity, n_seconds) \
  ABSL_LOG_INTERNAL_DLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)

#define ABSL_VLOG_EVERY_N(verbose_level, n) \
  ABSL_LOG_INTERNAL_VLOG_EVERY_N_IMPL(verbose_level, n)
#define ABSL_VLOG_FIRST_N(verbose_level, n) \
  ABSL_LOG_INTERNAL_VLOG_FIRST_N_IMPL(verbose_level, n)
#define ABSL_VLOG_EVERY_POW_2(verbose_level, n) \
  ABSL_LOG_INTERNAL_VLOG_EVERY_POW_2_IMPL(verbose_level, n)
#define ABSL_VLOG_EVERY_N_SEC(verbose_level, n) \
  ABSL_LOG_INTERNAL_VLOG_EVERY_N_SEC_IMPL(verbose_level, n)

#define ABSL_LOG_IF_EVERY_N(severity, condition, n) \
  ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_IMPL(_##severity, condition, n)
#define ABSL_LOG_IF_FIRST_N(severity, condition, n) \
  ABSL_LOG_INTERNAL_LOG_IF_FIRST_N_IMPL(_##severity, condition, n)
#define ABSL_LOG_IF_EVERY_POW_2(severity, condition) \
  ABSL_LOG_INTERNAL_LOG_IF_EVERY_POW_2_IMPL(_##severity, condition)
#define ABSL_LOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \
  ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds)

#define ABSL_PLOG_IF_EVERY_N(severity, condition, n) \
  ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_IMPL(_##severity, condition, n)
#define ABSL_PLOG_IF_FIRST_N(severity, condition, n) \
  ABSL_LOG_INTERNAL_PLOG_IF_FIRST_N_IMPL(_##severity, condition, n)
#define ABSL_PLOG_IF_EVERY_POW_2(severity, condition) \
  ABSL_LOG_INTERNAL_PLOG_IF_EVERY_POW_2_IMPL(_##severity, condition)
#define ABSL_PLOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \
  ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds)

#define ABSL_DLOG_IF_EVERY_N(severity, condition, n) \
  ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_IMPL(_##severity, condition, n)
#define ABSL_DLOG_IF_FIRST_N(severity, condition, n) \
  ABSL_LOG_INTERNAL_DLOG_IF_FIRST_N_IMPL(_##severity, condition, n)
#define ABSL_DLOG_IF_EVERY_POW_2(severity, condition) \
  ABSL_LOG_INTERNAL_DLOG_IF_EVERY_POW_2_IMPL(_##severity, condition)
#define ABSL_DLOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \
  ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds)

#endif  // ABSL_LOG_ABSL_LOG_H_
*�
usoong/.intermediates/external/abseil-cpp/absl_strings_hdrs/gen/my_include_dir/absl/strings/internal/string_constant.h‡// 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_STRING_CONSTANT_H_
#define ABSL_STRINGS_INTERNAL_STRING_CONSTANT_H_

#include "absl/meta/type_traits.h"
#include "absl/strings/string_view.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace strings_internal {

// StringConstant<T> represents a compile time string constant.
// It can be accessed via its `absl::string_view value` static member.
// It is guaranteed that the `string_view` returned has constant `.data()`,
// constant `.size()` and constant `value[i]` for all `0 <= i < .size()`
//
// The `T` is an opaque type. It is guaranteed that different string constants
// will have different values of `T`. This allows users to associate the string
// constant with other static state at compile time.
//
// Instances should be made using the `MakeStringConstant()` factory function
// below.
template <typename T>
struct StringConstant {
 private:
  static constexpr bool TryConstexprEval(absl::string_view view) {
    return view.empty() || 2 * view[0] != 1;
  }

 public:
  static constexpr absl::string_view value = T{}();
  constexpr absl::string_view operator()() const { return value; }

  // Check to be sure `view` points to constant data.
  // Otherwise, it can't be constant evaluated.
  static_assert(TryConstexprEval(value),
                "The input string_view must point to constant data.");
};

// Factory function for `StringConstant` instances.
// It supports callables that have a constexpr default constructor and a
// constexpr operator().
// It must return an `absl::string_view` or `const char*` pointing to constant
// data. This is validated at compile time.
template <typename T>
constexpr StringConstant<T> MakeStringConstant(T) {
  return {};
}

}  // namespace strings_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_STRING_CONSTANT_H_
*‚
Œsoong/.intermediates/external/abseil-cpp/absl_synchronization_hdrs/gen/my_include_dir/absl/synchronization/internal/create_thread_identity.hð/*
 * Copyright 2017 The Abseil Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Interface for getting the current ThreadIdentity, creating one if necessary.
// See thread_identity.h.
//
// This file is separate from thread_identity.h because creating a new
// ThreadIdentity requires slightly higher level libraries (per_thread_sem
// and low_level_alloc) than accessing an existing one.  This separation allows
// us to have a smaller //absl/base:base.

#ifndef ABSL_SYNCHRONIZATION_INTERNAL_CREATE_THREAD_IDENTITY_H_
#define ABSL_SYNCHRONIZATION_INTERNAL_CREATE_THREAD_IDENTITY_H_

#include "absl/base/internal/thread_identity.h"
#include "absl/base/port.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace synchronization_internal {

// Allocates and attaches a ThreadIdentity object for the calling thread.
// For private use only.
base_internal::ThreadIdentity* CreateThreadIdentity();

// Returns the ThreadIdentity object representing the calling thread; guaranteed
// to be unique for its lifetime.  The returned object will remain valid for the
// program's lifetime; although it may be re-assigned to a subsequent thread.
// If one does not exist for the calling thread, allocate it now.
inline base_internal::ThreadIdentity* GetOrCreateCurrentThreadIdentity() {
  base_internal::ThreadIdentity* identity =
      base_internal::CurrentThreadIdentityIfPresent();
  if (ABSL_PREDICT_FALSE(identity == nullptr)) {
    return CreateThreadIdentity();
  }
  return identity;
}

}  // namespace synchronization_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_SYNCHRONIZATION_INTERNAL_CREATE_THREAD_IDENTITY_H_
*»
\soong/.intermediates/external/abseil-cpp/absl_time_hdrs/gen/my_include_dir/absl/time/clock.hÚ// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// File: clock.h
// -----------------------------------------------------------------------------
//
// This header file contains utility functions for working with the system-wide
// realtime clock. For descriptions of the main time abstractions used within
// this header file, consult the time.h header file.
#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"

namespace absl {
ABSL_NAMESPACE_BEGIN

// Now()
//
// Returns the current time, expressed as an `absl::Time` absolute time value.
absl::Time Now();

// GetCurrentTimeNanos()
//
// Returns the current time, expressed as a count of nanoseconds since the Unix
// Epoch (https://en.wikipedia.org/wiki/Unix_time). Prefer `absl::Now()` instead
// for all but the most performance-sensitive cases (i.e. when you are calling
// this function hundreds of thousands of times per second).
int64_t GetCurrentTimeNanos();

// SleepFor()
//
// Sleeps for the specified duration, expressed as an `absl::Duration`.
//
// Notes:
// * Signal interruptions will not reduce the sleep duration.
// * Returns immediately when passed a nonpositive duration.
void SleepFor(absl::Duration duration);

ABSL_NAMESPACE_END
}  // namespace absl

// -----------------------------------------------------------------------------
// Implementation Details
// -----------------------------------------------------------------------------

// In some build configurations we pass --detect-odr-violations to the
// gold linker.  This causes it to flag weak symbol overrides as ODR
// violations.  Because ODR only applies to C++ and not C,
// --detect-odr-violations ignores symbols not mangled with C++ names.
// By changing our extension points to be extern "C", we dodge this
// check.
extern "C" {
ABSL_DLL void ABSL_INTERNAL_C_SYMBOL(AbslInternalSleepFor)(
    absl::Duration duration);
}  // extern "C"

inline void absl::SleepFor(absl::Duration duration) {
  ABSL_INTERNAL_C_SYMBOL(AbslInternalSleepFor)(duration);
}

#endif  // ABSL_TIME_CLOCK_H_
*ò%
soong/.intermediates/external/abseil-cpp/absl_base_malloc_internal_hdrs/gen/my_include_dir/absl/base/internal/low_level_alloc.hî$// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#ifndef ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_
#define ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_

// A simple thread-safe memory allocator that does not depend on
// mutexes or thread-specific data.  It is intended to be used
// sparingly, and only when malloc() would introduce an unwanted
// dependency, such as inside the heap-checker, or the Mutex
// implementation.

// IWYU pragma: private, include "base/low_level_alloc.h"

#include <sys/types.h>

#include <cstdint>

#include "absl/base/attributes.h"
#include "absl/base/config.h"

// LowLevelAlloc requires that the platform support low-level
// allocation of virtual memory. Platforms lacking this cannot use
// LowLevelAlloc.
#ifdef ABSL_LOW_LEVEL_ALLOC_MISSING
#error ABSL_LOW_LEVEL_ALLOC_MISSING cannot be directly set
#elif !defined(ABSL_HAVE_MMAP) && !defined(_WIN32)
#define ABSL_LOW_LEVEL_ALLOC_MISSING 1
#endif

// Using LowLevelAlloc with kAsyncSignalSafe isn't supported on Windows or
// asm.js / WebAssembly.
// See https://kripken.github.io/emscripten-site/docs/porting/pthreads.html
// for more information.
#ifdef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
#error ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING cannot be directly set
#elif defined(_WIN32) || defined(__asmjs__) || defined(__wasm__) || \
    defined(__hexagon__)
#define ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING 1
#endif

#include <cstddef>

#include "absl/base/port.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {

class LowLevelAlloc {
 public:
  struct Arena;       // an arena from which memory may be allocated

  // Returns a pointer to a block of at least "request" bytes
  // that have been newly allocated from the specific arena.
  // for Alloc() call the DefaultArena() is used.
  // Returns 0 if passed request==0.
  // Does not return 0 under other circumstances; it crashes if memory
  // is not available.
  static void *Alloc(size_t request) ABSL_ATTRIBUTE_SECTION(malloc_hook);
  static void *AllocWithArena(size_t request, Arena *arena)
      ABSL_ATTRIBUTE_SECTION(malloc_hook);

  // Deallocates a region of memory that was previously allocated with
  // Alloc().   Does nothing if passed 0.   "s" must be either 0,
  // or must have been returned from a call to Alloc() and not yet passed to
  // Free() since that call to Alloc().  The space is returned to the arena
  // from which it was allocated.
  static void Free(void *s) ABSL_ATTRIBUTE_SECTION(malloc_hook);

  // ABSL_ATTRIBUTE_SECTION(malloc_hook) for Alloc* and Free
  // are to put all callers of MallocHook::Invoke* in this module
  // into special section,
  // so that MallocHook::GetCallerStackTrace can function accurately.

  // Create a new arena.
  // The root metadata for the new arena is allocated in the
  // meta_data_arena; the DefaultArena() can be passed for meta_data_arena.
  // These values may be ored into flags:
  enum {
    // Report calls to Alloc() and Free() via the MallocHook interface.
    // Set in the DefaultArena.
    kCallMallocHook = 0x0001,

#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
    // Make calls to Alloc(), Free() be async-signal-safe. Not set in
    // DefaultArena(). Not supported on all platforms.
    kAsyncSignalSafe = 0x0002,
#endif
  };
  // Construct a new arena.  The allocation of the underlying metadata honors
  // the provided flags.  For example, the call NewArena(kAsyncSignalSafe)
  // is itself async-signal-safe, as well as generatating an arena that provides
  // async-signal-safe Alloc/Free.
  static Arena *NewArena(uint32_t flags);

  // Destroys an arena allocated by NewArena and returns true,
  // provided no allocated blocks remain in the arena.
  // If allocated blocks remain in the arena, does nothing and
  // returns false.
  // It is illegal to attempt to destroy the DefaultArena().
  static bool DeleteArena(Arena *arena);

  // The default arena that always exists.
  static Arena *DefaultArena();

 private:
  LowLevelAlloc();      // no instances
};

}  // namespace base_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_
*¦
�soong/.intermediates/external/abseil-cpp/absl_strings_cordz_update_tracker_hdrs/gen/my_include_dir/absl/strings/internal/cordz_update_tracker.h‘// Copyright 2021 The Abseil Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_TRACKER_H_
#define ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_TRACKER_H_

#include <atomic>
#include <cstdint>

#include "absl/base/config.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {

// CordzUpdateTracker tracks counters for Cord update methods.
//
// The purpose of CordzUpdateTracker is to track the number of calls to methods
// updating Cord data for sampled cords. The class internally uses 'lossy'
// atomic operations: Cord is thread-compatible, so there is no need to
// synchronize updates. However, Cordz collection threads may call 'Value()' at
// any point, so the class needs to provide thread safe access.
//
// This class is thread-safe. But as per above comments, all non-const methods
// should be used single-threaded only: updates are thread-safe but lossy.
class CordzUpdateTracker {
 public:
  // Tracked update methods.
  enum MethodIdentifier {
    kUnknown,
    kAppendCord,
    kAppendCordBuffer,
    kAppendExternalMemory,
    kAppendString,
    kAssignCord,
    kAssignString,
    kClear,
    kConstructorCord,
    kConstructorString,
    kCordReader,
    kFlatten,
    kGetAppendBuffer,
    kGetAppendRegion,
    kMakeCordFromExternal,
    kMoveAppendCord,
    kMoveAssignCord,
    kMovePrependCord,
    kPrependCord,
    kPrependCordBuffer,
    kPrependString,
    kRemovePrefix,
    kRemoveSuffix,
    kSetExpectedChecksum,
    kSubCord,

    // kNumMethods defines the number of entries: must be the last entry.
    kNumMethods,
  };

  // Constructs a new instance. All counters are zero-initialized.
  constexpr CordzUpdateTracker() noexcept : values_{} {}

  // Copy constructs a new instance.
  CordzUpdateTracker(const CordzUpdateTracker& rhs) noexcept { *this = rhs; }

  // Assigns the provided value to this instance.
  CordzUpdateTracker& operator=(const CordzUpdateTracker& rhs) noexcept {
    for (int i = 0; i < kNumMethods; ++i) {
      values_[i].store(rhs.values_[i].load(std::memory_order_relaxed),
                       std::memory_order_relaxed);
    }
    return *this;
  }

  // Returns the value for the specified method.
  int64_t Value(MethodIdentifier method) const {
    return values_[method].load(std::memory_order_relaxed);
  }

  // Increases the value for the specified method by `n`
  void LossyAdd(MethodIdentifier method, int64_t n = 1) {
    auto& value = values_[method];
    value.store(value.load(std::memory_order_relaxed) + n,
                std::memory_order_relaxed);
  }

  // Adds all the values from `src` to this instance
  void LossyAdd(const CordzUpdateTracker& src) {
    for (int i = 0; i < kNumMethods; ++i) {
      MethodIdentifier method = static_cast<MethodIdentifier>(i);
      if (int64_t value = src.Value(method)) {
        LossyAdd(method, value);
      }
    }
  }

 private:
  // Until C++20 std::atomic is not constexpr default-constructible, so we need
  // a wrapper for this class to be constexpr constructible.
  class Counter : public std::atomic<int64_t> {
   public:
    constexpr Counter() noexcept : std::atomic<int64_t>(0) {}
  };

  Counter values_[kNumMethods];
};

}  // namespace cord_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_TRACKER_H_
*ˆ
‡soong/.intermediates/external/abseil-cpp/absl_strings_cordz_statistics_hdrs/gen/my_include_dir/absl/strings/internal/cordz_statistics.hû// Copyright 2019 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_STRINGS_INTERNAL_CORDZ_STATISTICS_H_
#define ABSL_STRINGS_INTERNAL_CORDZ_STATISTICS_H_

#include <cstdint>

#include "absl/base/config.h"
#include "absl/strings/internal/cordz_update_tracker.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {

// CordzStatistics captures some meta information about a Cord's shape.
struct CordzStatistics {
  using MethodIdentifier = CordzUpdateTracker::MethodIdentifier;

  // Node counts information
  struct NodeCounts {
    size_t flat = 0;       // #flats
    size_t flat_64 = 0;    // #flats up to 64 bytes
    size_t flat_128 = 0;   // #flats up to 128 bytes
    size_t flat_256 = 0;   // #flats up to 256 bytes
    size_t flat_512 = 0;   // #flats up to 512 bytes
    size_t flat_1k = 0;    // #flats up to 1K bytes
    size_t external = 0;   // #external reps
    size_t substring = 0;  // #substring reps
    size_t concat = 0;     // #concat reps
    size_t ring = 0;       // #ring buffer reps
    size_t btree = 0;      // #btree reps
    size_t crc = 0;        // #crc reps
  };

  // The size of the cord in bytes. This matches the result of Cord::size().
  size_t size = 0;

  // The estimated memory used by the sampled cord. This value matches the
  // value as reported by Cord::EstimatedMemoryUsage().
  // A value of 0 implies the property has not been recorded.
  size_t estimated_memory_usage = 0;

  // The effective memory used by the sampled cord, inversely weighted by the
  // effective indegree of each allocated node. This is a representation of the
  // fair share of memory usage that should be attributed to the sampled cord.
  // This value is more useful for cases where one or more nodes are referenced
  // by multiple Cord instances, and for cases where a Cord includes the same
  // node multiple times (either directly or indirectly).
  // A value of 0 implies the property has not been recorded.
  size_t estimated_fair_share_memory_usage = 0;

  // The total number of nodes referenced by this cord.
  // For ring buffer Cords, this includes the 'ring buffer' node.
  // For btree Cords, this includes all 'CordRepBtree' tree nodes as well as all
  // the substring, flat and external nodes referenced by the tree.
  // A value of 0 implies the property has not been recorded.
  size_t node_count = 0;

  // Detailed node counts per type
  NodeCounts node_counts;

  // The cord method responsible for sampling the cord.
  MethodIdentifier method = MethodIdentifier::kUnknown;

  // The cord method responsible for sampling the parent cord if applicable.
  MethodIdentifier parent_method = MethodIdentifier::kUnknown;

  // Update tracker tracking invocation count per cord method.
  CordzUpdateTracker update_tracker;
};

}  // namespace cord_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_CORDZ_STATISTICS_H_
*�}
‡soong/.intermediates/external/abseil-cpp/absl_base_dynamic_annotations_hdrs/gen/my_include_dir/absl/base/internal/dynamic_annotations.h‚|// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// This file defines dynamic annotations for use with dynamic analysis tool
// such as valgrind, PIN, etc.
//
// Dynamic annotation is a source code annotation that affects the generated
// code (that is, the annotation is not a comment). Each such annotation is
// attached to a particular instruction and/or to a particular object (address)
// in the program.
//
// The annotations that should be used by users are macros in all upper-case
// (e.g., ANNOTATE_THREAD_NAME).
//
// Actual implementation of these macros may differ depending on the dynamic
// analysis tool being used.
//
// This file supports the following configurations:
// - Dynamic Annotations enabled (with static thread-safety warnings disabled).
//   In this case, macros expand to functions implemented by Thread Sanitizer,
//   when building with TSan. When not provided an external implementation,
//   dynamic_annotations.cc provides no-op implementations.
//
// - Static Clang thread-safety warnings enabled.
//   When building with a Clang compiler that supports thread-safety warnings,
//   a subset of annotations can be statically-checked at compile-time. We
//   expand these macros to static-inline functions that can be analyzed for
//   thread-safety, but afterwards elided when building the final binary.
//
// - All annotations are disabled.
//   If neither Dynamic Annotations nor Clang thread-safety warnings are
//   enabled, then all annotation-macros expand to empty.

#ifndef ABSL_BASE_INTERNAL_DYNAMIC_ANNOTATIONS_H_
#define ABSL_BASE_INTERNAL_DYNAMIC_ANNOTATIONS_H_

#include <stddef.h>

#include "absl/base/config.h"

// -------------------------------------------------------------------------
// Decide which features are enabled

#ifndef DYNAMIC_ANNOTATIONS_ENABLED
#define DYNAMIC_ANNOTATIONS_ENABLED 0
#endif

#if defined(__clang__) && !defined(SWIG)
#define ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED 1
#endif

#if DYNAMIC_ANNOTATIONS_ENABLED != 0

#define ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED 1
#define ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED 1
#define ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED 1
#define ABSL_INTERNAL_ANNOTALYSIS_ENABLED 0
#define ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED 1

#else

#define ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED 0
#define ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED 0
#define ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED 0

// Clang provides limited support for static thread-safety analysis through a
// feature called Annotalysis. We configure macro-definitions according to
// whether Annotalysis support is available. When running in opt-mode, GCC
// will issue a warning, if these attributes are compiled. Only include them
// when compiling using Clang.

// ANNOTALYSIS_ENABLED == 1 when IGNORE_READ_ATTRIBUTE_ENABLED == 1
#define ABSL_INTERNAL_ANNOTALYSIS_ENABLED \
  defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED)
// Read/write annotations are enabled in Annotalysis mode; disabled otherwise.
#define ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED \
  ABSL_INTERNAL_ANNOTALYSIS_ENABLED
#endif

// Memory annotations are also made available to LLVM's Memory Sanitizer
#if defined(ABSL_HAVE_MEMORY_SANITIZER) && !defined(__native_client__)
#define ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED 1
#endif

#ifndef ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED
#define ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED 0
#endif

#ifdef __cplusplus
#define ABSL_INTERNAL_BEGIN_EXTERN_C extern "C" {
#define ABSL_INTERNAL_END_EXTERN_C }  // extern "C"
#define ABSL_INTERNAL_GLOBAL_SCOPED(F) ::F
#define ABSL_INTERNAL_STATIC_INLINE inline
#else
#define ABSL_INTERNAL_BEGIN_EXTERN_C  // empty
#define ABSL_INTERNAL_END_EXTERN_C    // empty
#define ABSL_INTERNAL_GLOBAL_SCOPED(F) F
#define ABSL_INTERNAL_STATIC_INLINE static inline
#endif

// -------------------------------------------------------------------------
// Define race annotations.

#if ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED == 1

// -------------------------------------------------------------
// Annotations that suppress errors. It is usually better to express the
// program's synchronization using the other annotations, but these can be used
// when all else fails.

// Report that we may have a benign race at `pointer`, with size
// "sizeof(*(pointer))". `pointer` must be a non-void* pointer. Insert at the
// point where `pointer` has been allocated, preferably close to the point
// where the race happens. See also ANNOTATE_BENIGN_RACE_STATIC.
#define ANNOTATE_BENIGN_RACE(pointer, description)     \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateBenignRaceSized) \
  (__FILE__, __LINE__, pointer, sizeof(*(pointer)), description)

// Same as ANNOTATE_BENIGN_RACE(`address`, `description`), but applies to
// the memory range [`address`, `address`+`size`).
#define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateBenignRaceSized)         \
  (__FILE__, __LINE__, address, size, description)

// Enable (`enable`!=0) or disable (`enable`==0) race detection for all threads.
// This annotation could be useful if you want to skip expensive race analysis
// during some period of program execution, e.g. during initialization.
#define ANNOTATE_ENABLE_RACE_DETECTION(enable)             \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateEnableRaceDetection) \
  (__FILE__, __LINE__, enable)

// -------------------------------------------------------------
// Annotations useful for debugging.

// Report the current thread `name` to a race detector.
#define ANNOTATE_THREAD_NAME(name) \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateThreadName)(__FILE__, __LINE__, name)

// -------------------------------------------------------------
// Annotations useful when implementing locks. They are not normally needed by
// modules that merely use locks. The `lock` argument is a pointer to the lock
// object.

// Report that a lock has been created at address `lock`.
#define ANNOTATE_RWLOCK_CREATE(lock) \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockCreate)(__FILE__, __LINE__, lock)

// Report that a linker initialized lock has been created at address `lock`.
#ifdef ABSL_HAVE_THREAD_SANITIZER
#define ANNOTATE_RWLOCK_CREATE_STATIC(lock)               \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockCreateStatic) \
  (__FILE__, __LINE__, lock)
#else
#define ANNOTATE_RWLOCK_CREATE_STATIC(lock) ANNOTATE_RWLOCK_CREATE(lock)
#endif

// Report that the lock at address `lock` is about to be destroyed.
#define ANNOTATE_RWLOCK_DESTROY(lock) \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockDestroy)(__FILE__, __LINE__, lock)

// Report that the lock at address `lock` has been acquired.
// `is_w`=1 for writer lock, `is_w`=0 for reader lock.
#define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w)          \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockAcquired) \
  (__FILE__, __LINE__, lock, is_w)

// Report that the lock at address `lock` is about to be released.
// `is_w`=1 for writer lock, `is_w`=0 for reader lock.
#define ANNOTATE_RWLOCK_RELEASED(lock, is_w)          \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockReleased) \
  (__FILE__, __LINE__, lock, is_w)

// Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable `static_var`.
#define ANNOTATE_BENIGN_RACE_STATIC(static_var, description)      \
  namespace {                                                     \
  class static_var##_annotator {                                  \
   public:                                                        \
    static_var##_annotator() {                                    \
      ANNOTATE_BENIGN_RACE_SIZED(&static_var, sizeof(static_var), \
                                 #static_var ": " description);   \
    }                                                             \
  };                                                              \
  static static_var##_annotator the##static_var##_annotator;      \
  }  // namespace

#else  // ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED == 0

#define ANNOTATE_RWLOCK_CREATE(lock)                            // empty
#define ANNOTATE_RWLOCK_CREATE_STATIC(lock)                     // empty
#define ANNOTATE_RWLOCK_DESTROY(lock)                           // empty
#define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w)                    // empty
#define ANNOTATE_RWLOCK_RELEASED(lock, is_w)                    // empty
#define ANNOTATE_BENIGN_RACE(address, description)              // empty
#define ANNOTATE_BENIGN_RACE_SIZED(address, size, description)  // empty
#define ANNOTATE_THREAD_NAME(name)                              // empty
#define ANNOTATE_ENABLE_RACE_DETECTION(enable)                  // empty
#define ANNOTATE_BENIGN_RACE_STATIC(static_var, description)    // empty

#endif  // ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED

// -------------------------------------------------------------------------
// Define memory annotations.

#if ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED == 1

#include <sanitizer/msan_interface.h>

#define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \
  __msan_unpoison(address, size)

#define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \
  __msan_allocated_memory(address, size)

#else  // ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED == 0

#if DYNAMIC_ANNOTATIONS_ENABLED == 1
#define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \
  do {                                                \
    (void)(address);                                  \
    (void)(size);                                     \
  } while (0)
#define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \
  do {                                                  \
    (void)(address);                                    \
    (void)(size);                                       \
  } while (0)
#else
#define ANNOTATE_MEMORY_IS_INITIALIZED(address, size)    // empty
#define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size)  // empty
#endif

#endif  // ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED

// -------------------------------------------------------------------------
// Define IGNORE_READS_BEGIN/_END attributes.

#if defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED)

#define ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE \
  __attribute((exclusive_lock_function("*")))
#define ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE \
  __attribute((unlock_function("*")))

#else  // !defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED)

#define ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE  // empty
#define ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE    // empty

#endif  // defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED)

// -------------------------------------------------------------------------
// Define IGNORE_READS_BEGIN/_END annotations.

#if ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED == 1

// Request the analysis tool to ignore all reads in the current thread until
// ANNOTATE_IGNORE_READS_END is called. Useful to ignore intentional racey
// reads, while still checking other reads and all writes.
// See also ANNOTATE_UNPROTECTED_READ.
#define ANNOTATE_IGNORE_READS_BEGIN() \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsBegin)(__FILE__, __LINE__)

// Stop ignoring reads.
#define ANNOTATE_IGNORE_READS_END() \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsEnd)(__FILE__, __LINE__)

#elif defined(ABSL_INTERNAL_ANNOTALYSIS_ENABLED)

// When Annotalysis is enabled without Dynamic Annotations, the use of
// static-inline functions allows the annotations to be read at compile-time,
// while still letting the compiler elide the functions from the final build.
//
// TODO(delesley) -- The exclusive lock here ignores writes as well, but
// allows IGNORE_READS_AND_WRITES to work properly.

#define ANNOTATE_IGNORE_READS_BEGIN() \
  ABSL_INTERNAL_GLOBAL_SCOPED(AbslInternalAnnotateIgnoreReadsBegin)()

#define ANNOTATE_IGNORE_READS_END() \
  ABSL_INTERNAL_GLOBAL_SCOPED(AbslInternalAnnotateIgnoreReadsEnd)()

#else

#define ANNOTATE_IGNORE_READS_BEGIN()  // empty
#define ANNOTATE_IGNORE_READS_END()    // empty

#endif

// -------------------------------------------------------------------------
// Define IGNORE_WRITES_BEGIN/_END annotations.

#if ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED == 1

// Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore writes instead.
#define ANNOTATE_IGNORE_WRITES_BEGIN() \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreWritesBegin)(__FILE__, __LINE__)

// Stop ignoring writes.
#define ANNOTATE_IGNORE_WRITES_END() \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreWritesEnd)(__FILE__, __LINE__)

#else

#define ANNOTATE_IGNORE_WRITES_BEGIN()  // empty
#define ANNOTATE_IGNORE_WRITES_END()    // empty

#endif

// -------------------------------------------------------------------------
// Define the ANNOTATE_IGNORE_READS_AND_WRITES_* annotations using the more
// primitive annotations defined above.
//
//     Instead of doing
//        ANNOTATE_IGNORE_READS_BEGIN();
//        ... = x;
//        ANNOTATE_IGNORE_READS_END();
//     one can use
//        ... = ANNOTATE_UNPROTECTED_READ(x);

#if defined(ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED)

// Start ignoring all memory accesses (both reads and writes).
#define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \
  do {                                           \
    ANNOTATE_IGNORE_READS_BEGIN();               \
    ANNOTATE_IGNORE_WRITES_BEGIN();              \
  } while (0)

// Stop ignoring both reads and writes.
#define ANNOTATE_IGNORE_READS_AND_WRITES_END() \
  do {                                         \
    ANNOTATE_IGNORE_WRITES_END();              \
    ANNOTATE_IGNORE_READS_END();               \
  } while (0)

#ifdef __cplusplus
// ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads.
#define ANNOTATE_UNPROTECTED_READ(x) \
  absl::base_internal::AnnotateUnprotectedRead(x)

#endif

#else

#define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN()  // empty
#define ANNOTATE_IGNORE_READS_AND_WRITES_END()    // empty
#define ANNOTATE_UNPROTECTED_READ(x) (x)

#endif

// -------------------------------------------------------------------------
// Address sanitizer annotations

#ifdef ABSL_HAVE_ADDRESS_SANITIZER
// Describe the current state of a contiguous container such as e.g.
// std::vector or std::string. For more details see
// sanitizer/common_interface_defs.h, which is provided by the compiler.
#include <sanitizer/common_interface_defs.h>

#define ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) \
  __sanitizer_annotate_contiguous_container(beg, end, old_mid, new_mid)
#define ADDRESS_SANITIZER_REDZONE(name)    \
  struct {                                 \
    char x[8] __attribute__((aligned(8))); \
  } name

#else

#define ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid)
#define ADDRESS_SANITIZER_REDZONE(name) static_assert(true, "")

#endif  // ABSL_HAVE_ADDRESS_SANITIZER

// -------------------------------------------------------------------------
// Undefine the macros intended only for this file.

#undef ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED
#undef ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED
#undef ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED
#undef ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED
#undef ABSL_INTERNAL_ANNOTALYSIS_ENABLED
#undef ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED
#undef ABSL_INTERNAL_BEGIN_EXTERN_C
#undef ABSL_INTERNAL_END_EXTERN_C
#undef ABSL_INTERNAL_STATIC_INLINE

#endif  // ABSL_BASE_INTERNAL_DYNAMIC_ANNOTATIONS_H_
*×–
~soong/.intermediates/external/abseil-cpp/absl_base_dynamic_annotations_hdrs/gen/my_include_dir/absl/base/dynamic_annotations.hÓ•// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// This file defines dynamic annotations for use with dynamic analysis tool
// such as valgrind, PIN, etc.
//
// Dynamic annotation is a source code annotation that affects the generated
// code (that is, the annotation is not a comment). Each such annotation is
// attached to a particular instruction and/or to a particular object (address)
// in the program.
//
// The annotations that should be used by users are macros in all upper-case
// (e.g., ABSL_ANNOTATE_THREAD_NAME).
//
// Actual implementation of these macros may differ depending on the dynamic
// analysis tool being used.
//
// This file supports the following configurations:
// - Dynamic Annotations enabled (with static thread-safety warnings disabled).
//   In this case, macros expand to functions implemented by Thread Sanitizer,
//   when building with TSan. When not provided an external implementation,
//   dynamic_annotations.cc provides no-op implementations.
//
// - Static Clang thread-safety warnings enabled.
//   When building with a Clang compiler that supports thread-safety warnings,
//   a subset of annotations can be statically-checked at compile-time. We
//   expand these macros to static-inline functions that can be analyzed for
//   thread-safety, but afterwards elided when building the final binary.
//
// - All annotations are disabled.
//   If neither Dynamic Annotations nor Clang thread-safety warnings are
//   enabled, then all annotation-macros expand to empty.

#ifndef ABSL_BASE_DYNAMIC_ANNOTATIONS_H_
#define ABSL_BASE_DYNAMIC_ANNOTATIONS_H_

#include <stddef.h>
#include <stdint.h>

#include "absl/base/attributes.h"
#include "absl/base/config.h"
#ifdef __cplusplus
#include "absl/base/macros.h"
#endif

#ifdef ABSL_HAVE_HWADDRESS_SANITIZER
#include <sanitizer/hwasan_interface.h>
#endif

// TODO(rogeeff): Remove after the backward compatibility period.
#include "absl/base/internal/dynamic_annotations.h"  // IWYU pragma: export

// -------------------------------------------------------------------------
// Decide which features are enabled.

#ifdef ABSL_HAVE_THREAD_SANITIZER

#define ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED 1
#define ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED 1
#define ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED 1
#define ABSL_INTERNAL_ANNOTALYSIS_ENABLED 0
#define ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED 1

#else

#define ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED 0
#define ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED 0
#define ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED 0

// Clang provides limited support for static thread-safety analysis through a
// feature called Annotalysis. We configure macro-definitions according to
// whether Annotalysis support is available. When running in opt-mode, GCC
// will issue a warning, if these attributes are compiled. Only include them
// when compiling using Clang.

#if defined(__clang__)
#define ABSL_INTERNAL_ANNOTALYSIS_ENABLED 1
#if !defined(SWIG)
#define ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED 1
#endif
#else
#define ABSL_INTERNAL_ANNOTALYSIS_ENABLED 0
#endif

// Read/write annotations are enabled in Annotalysis mode; disabled otherwise.
#define ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED \
  ABSL_INTERNAL_ANNOTALYSIS_ENABLED

#endif  // ABSL_HAVE_THREAD_SANITIZER

#ifdef __cplusplus
#define ABSL_INTERNAL_BEGIN_EXTERN_C extern "C" {
#define ABSL_INTERNAL_END_EXTERN_C }  // extern "C"
#define ABSL_INTERNAL_GLOBAL_SCOPED(F) ::F
#define ABSL_INTERNAL_STATIC_INLINE inline
#else
#define ABSL_INTERNAL_BEGIN_EXTERN_C  // empty
#define ABSL_INTERNAL_END_EXTERN_C    // empty
#define ABSL_INTERNAL_GLOBAL_SCOPED(F) F
#define ABSL_INTERNAL_STATIC_INLINE static inline
#endif

// -------------------------------------------------------------------------
// Define race annotations.

#if ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED == 1
// Some of the symbols used in this section (e.g. AnnotateBenignRaceSized) are
// defined by the compiler-based sanitizer implementation, not by the Abseil
// library. Therefore they do not use ABSL_INTERNAL_C_SYMBOL.

// -------------------------------------------------------------
// Annotations that suppress errors. It is usually better to express the
// program's synchronization using the other annotations, but these can be used
// when all else fails.

// Report that we may have a benign race at `pointer`, with size
// "sizeof(*(pointer))". `pointer` must be a non-void* pointer. Insert at the
// point where `pointer` has been allocated, preferably close to the point
// where the race happens. See also ABSL_ANNOTATE_BENIGN_RACE_STATIC.
#define ABSL_ANNOTATE_BENIGN_RACE(pointer, description) \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateBenignRaceSized)  \
  (__FILE__, __LINE__, pointer, sizeof(*(pointer)), description)

// Same as ABSL_ANNOTATE_BENIGN_RACE(`address`, `description`), but applies to
// the memory range [`address`, `address`+`size`).
#define ABSL_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateBenignRaceSized)              \
  (__FILE__, __LINE__, address, size, description)

// Enable (`enable`!=0) or disable (`enable`==0) race detection for all threads.
// This annotation could be useful if you want to skip expensive race analysis
// during some period of program execution, e.g. during initialization.
#define ABSL_ANNOTATE_ENABLE_RACE_DETECTION(enable)        \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateEnableRaceDetection) \
  (__FILE__, __LINE__, enable)

// -------------------------------------------------------------
// Annotations useful for debugging.

// Report the current thread `name` to a race detector.
#define ABSL_ANNOTATE_THREAD_NAME(name) \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateThreadName)(__FILE__, __LINE__, name)

// -------------------------------------------------------------
// Annotations useful when implementing locks. They are not normally needed by
// modules that merely use locks. The `lock` argument is a pointer to the lock
// object.

// Report that a lock has been created at address `lock`.
#define ABSL_ANNOTATE_RWLOCK_CREATE(lock) \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockCreate)(__FILE__, __LINE__, lock)

// Report that a linker initialized lock has been created at address `lock`.
#ifdef ABSL_HAVE_THREAD_SANITIZER
#define ABSL_ANNOTATE_RWLOCK_CREATE_STATIC(lock)          \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockCreateStatic) \
  (__FILE__, __LINE__, lock)
#else
#define ABSL_ANNOTATE_RWLOCK_CREATE_STATIC(lock) \
  ABSL_ANNOTATE_RWLOCK_CREATE(lock)
#endif

// Report that the lock at address `lock` is about to be destroyed.
#define ABSL_ANNOTATE_RWLOCK_DESTROY(lock) \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockDestroy)(__FILE__, __LINE__, lock)

// Report that the lock at address `lock` has been acquired.
// `is_w`=1 for writer lock, `is_w`=0 for reader lock.
#define ABSL_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w)     \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockAcquired) \
  (__FILE__, __LINE__, lock, is_w)

// Report that the lock at address `lock` is about to be released.
// `is_w`=1 for writer lock, `is_w`=0 for reader lock.
#define ABSL_ANNOTATE_RWLOCK_RELEASED(lock, is_w)     \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockReleased) \
  (__FILE__, __LINE__, lock, is_w)

// Apply ABSL_ANNOTATE_BENIGN_RACE_SIZED to a static variable `static_var`.
#define ABSL_ANNOTATE_BENIGN_RACE_STATIC(static_var, description)      \
  namespace {                                                          \
  class static_var##_annotator {                                       \
   public:                                                             \
    static_var##_annotator() {                                         \
      ABSL_ANNOTATE_BENIGN_RACE_SIZED(&static_var, sizeof(static_var), \
                                      #static_var ": " description);   \
    }                                                                  \
  };                                                                   \
  static static_var##_annotator the##static_var##_annotator;           \
  }  // namespace

// Function prototypes of annotations provided by the compiler-based sanitizer
// implementation.
ABSL_INTERNAL_BEGIN_EXTERN_C
void AnnotateRWLockCreate(const char* file, int line,
                          const volatile void* lock);
void AnnotateRWLockCreateStatic(const char* file, int line,
                                const volatile void* lock);
void AnnotateRWLockDestroy(const char* file, int line,
                           const volatile void* lock);
void AnnotateRWLockAcquired(const char* file, int line,
                            const volatile void* lock, long is_w);  // NOLINT
void AnnotateRWLockReleased(const char* file, int line,
                            const volatile void* lock, long is_w);  // NOLINT
void AnnotateBenignRace(const char* file, int line,
                        const volatile void* address, const char* description);
void AnnotateBenignRaceSized(const char* file, int line,
                             const volatile void* address, size_t size,
                             const char* description);
void AnnotateThreadName(const char* file, int line, const char* name);
void AnnotateEnableRaceDetection(const char* file, int line, int enable);
ABSL_INTERNAL_END_EXTERN_C

#else  // ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED == 0

#define ABSL_ANNOTATE_RWLOCK_CREATE(lock)                            // empty
#define ABSL_ANNOTATE_RWLOCK_CREATE_STATIC(lock)                     // empty
#define ABSL_ANNOTATE_RWLOCK_DESTROY(lock)                           // empty
#define ABSL_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w)                    // empty
#define ABSL_ANNOTATE_RWLOCK_RELEASED(lock, is_w)                    // empty
#define ABSL_ANNOTATE_BENIGN_RACE(address, description)              // empty
#define ABSL_ANNOTATE_BENIGN_RACE_SIZED(address, size, description)  // empty
#define ABSL_ANNOTATE_THREAD_NAME(name)                              // empty
#define ABSL_ANNOTATE_ENABLE_RACE_DETECTION(enable)                  // empty
#define ABSL_ANNOTATE_BENIGN_RACE_STATIC(static_var, description)    // empty

#endif  // ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED

// -------------------------------------------------------------------------
// Define memory annotations.

#ifdef ABSL_HAVE_MEMORY_SANITIZER

#include <sanitizer/msan_interface.h>

#define ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \
  __msan_unpoison(address, size)

#define ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \
  __msan_allocated_memory(address, size)

#else  // !defined(ABSL_HAVE_MEMORY_SANITIZER)

#define ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(address, size)    // empty
#define ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size)  // empty

#endif  // ABSL_HAVE_MEMORY_SANITIZER

// -------------------------------------------------------------------------
// Define IGNORE_READS_BEGIN/_END attributes.

#if defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED)

#define ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE \
  __attribute((exclusive_lock_function("*")))
#define ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE \
  __attribute((unlock_function("*")))

#else  // !defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED)

#define ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE  // empty
#define ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE    // empty

#endif  // defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED)

// -------------------------------------------------------------------------
// Define IGNORE_READS_BEGIN/_END annotations.

#if ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED == 1
// Some of the symbols used in this section (e.g. AnnotateIgnoreReadsBegin) are
// defined by the compiler-based implementation, not by the Abseil
// library. Therefore they do not use ABSL_INTERNAL_C_SYMBOL.

// Request the analysis tool to ignore all reads in the current thread until
// ABSL_ANNOTATE_IGNORE_READS_END is called. Useful to ignore intentional racey
// reads, while still checking other reads and all writes.
// See also ABSL_ANNOTATE_UNPROTECTED_READ.
#define ABSL_ANNOTATE_IGNORE_READS_BEGIN()              \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsBegin) \
  (__FILE__, __LINE__)

// Stop ignoring reads.
#define ABSL_ANNOTATE_IGNORE_READS_END()              \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsEnd) \
  (__FILE__, __LINE__)

// Function prototypes of annotations provided by the compiler-based sanitizer
// implementation.
ABSL_INTERNAL_BEGIN_EXTERN_C
void AnnotateIgnoreReadsBegin(const char* file, int line)
    ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE;
void AnnotateIgnoreReadsEnd(const char* file,
                            int line) ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE;
ABSL_INTERNAL_END_EXTERN_C

#elif defined(ABSL_INTERNAL_ANNOTALYSIS_ENABLED)

// When Annotalysis is enabled without Dynamic Annotations, the use of
// static-inline functions allows the annotations to be read at compile-time,
// while still letting the compiler elide the functions from the final build.
//
// TODO(delesley) -- The exclusive lock here ignores writes as well, but
// allows IGNORE_READS_AND_WRITES to work properly.

#define ABSL_ANNOTATE_IGNORE_READS_BEGIN()                          \
  ABSL_INTERNAL_GLOBAL_SCOPED(                                      \
      ABSL_INTERNAL_C_SYMBOL(AbslInternalAnnotateIgnoreReadsBegin)) \
  ()

#define ABSL_ANNOTATE_IGNORE_READS_END()                          \
  ABSL_INTERNAL_GLOBAL_SCOPED(                                    \
      ABSL_INTERNAL_C_SYMBOL(AbslInternalAnnotateIgnoreReadsEnd)) \
  ()

ABSL_INTERNAL_STATIC_INLINE void ABSL_INTERNAL_C_SYMBOL(
    AbslInternalAnnotateIgnoreReadsBegin)()
    ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE {}

ABSL_INTERNAL_STATIC_INLINE void ABSL_INTERNAL_C_SYMBOL(
    AbslInternalAnnotateIgnoreReadsEnd)()
    ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE {}

#else

#define ABSL_ANNOTATE_IGNORE_READS_BEGIN()  // empty
#define ABSL_ANNOTATE_IGNORE_READS_END()    // empty

#endif

// -------------------------------------------------------------------------
// Define IGNORE_WRITES_BEGIN/_END annotations.

#if ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED == 1

// Similar to ABSL_ANNOTATE_IGNORE_READS_BEGIN, but ignore writes instead.
#define ABSL_ANNOTATE_IGNORE_WRITES_BEGIN() \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreWritesBegin)(__FILE__, __LINE__)

// Stop ignoring writes.
#define ABSL_ANNOTATE_IGNORE_WRITES_END() \
  ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreWritesEnd)(__FILE__, __LINE__)

// Function prototypes of annotations provided by the compiler-based sanitizer
// implementation.
ABSL_INTERNAL_BEGIN_EXTERN_C
void AnnotateIgnoreWritesBegin(const char* file, int line);
void AnnotateIgnoreWritesEnd(const char* file, int line);
ABSL_INTERNAL_END_EXTERN_C

#else

#define ABSL_ANNOTATE_IGNORE_WRITES_BEGIN()  // empty
#define ABSL_ANNOTATE_IGNORE_WRITES_END()    // empty

#endif

// -------------------------------------------------------------------------
// Define the ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_* annotations using the more
// primitive annotations defined above.
//
//     Instead of doing
//        ABSL_ANNOTATE_IGNORE_READS_BEGIN();
//        ... = x;
//        ABSL_ANNOTATE_IGNORE_READS_END();
//     one can use
//        ... = ABSL_ANNOTATE_UNPROTECTED_READ(x);

#if defined(ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED)

// Start ignoring all memory accesses (both reads and writes).
#define ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \
  do {                                                \
    ABSL_ANNOTATE_IGNORE_READS_BEGIN();               \
    ABSL_ANNOTATE_IGNORE_WRITES_BEGIN();              \
  } while (0)

// Stop ignoring both reads and writes.
#define ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END() \
  do {                                              \
    ABSL_ANNOTATE_IGNORE_WRITES_END();              \
    ABSL_ANNOTATE_IGNORE_READS_END();               \
  } while (0)

#ifdef __cplusplus
// ABSL_ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads.
#define ABSL_ANNOTATE_UNPROTECTED_READ(x) \
  absl::base_internal::AnnotateUnprotectedRead(x)

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {

template <typename T>
inline T AnnotateUnprotectedRead(const volatile T& x) {  // NOLINT
  ABSL_ANNOTATE_IGNORE_READS_BEGIN();
  T res = x;
  ABSL_ANNOTATE_IGNORE_READS_END();
  return res;
}

}  // namespace base_internal
ABSL_NAMESPACE_END
}  // namespace absl
#endif

#else

#define ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN()  // empty
#define ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END()    // empty
#define ABSL_ANNOTATE_UNPROTECTED_READ(x) (x)

#endif

// -------------------------------------------------------------------------
// Address sanitizer annotations

#ifdef ABSL_HAVE_ADDRESS_SANITIZER
// Describe the current state of a contiguous container such as e.g.
// std::vector or std::string. For more details see
// sanitizer/common_interface_defs.h, which is provided by the compiler.
#include <sanitizer/common_interface_defs.h>

#define ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) \
  __sanitizer_annotate_contiguous_container(beg, end, old_mid, new_mid)
#define ABSL_ADDRESS_SANITIZER_REDZONE(name) \
  struct {                                   \
    alignas(8) char x[8];                    \
  } name

#else

#define ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid)  // empty
#define ABSL_ADDRESS_SANITIZER_REDZONE(name) static_assert(true, "")

#endif  // ABSL_HAVE_ADDRESS_SANITIZER

// -------------------------------------------------------------------------
// HWAddress sanitizer annotations

#ifdef __cplusplus
namespace absl {
#ifdef ABSL_HAVE_HWADDRESS_SANITIZER
// Under HWASAN changes the tag of the pointer.
template <typename T>
T* HwasanTagPointer(T* ptr, uintptr_t tag) {
  return reinterpret_cast<T*>(__hwasan_tag_pointer(ptr, tag));
}
#else
template <typename T>
T* HwasanTagPointer(T* ptr, uintptr_t) {
  return ptr;
}
#endif
}  // namespace absl
#endif

// -------------------------------------------------------------------------
// Undefine the macros intended only for this file.

#undef ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED
#undef ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED
#undef ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED
#undef ABSL_INTERNAL_ANNOTALYSIS_ENABLED
#undef ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED
#undef ABSL_INTERNAL_BEGIN_EXTERN_C
#undef ABSL_INTERNAL_END_EXTERN_C
#undef ABSL_INTERNAL_STATIC_INLINE

#endif  // ABSL_BASE_DYNAMIC_ANNOTATIONS_H_
*‡g
{soong/.intermediates/external/abseil-cpp/absl_strings_cordz_info_hdrs/gen/my_include_dir/absl/strings/internal/cordz_info.h‡f// Copyright 2019 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_STRINGS_INTERNAL_CORDZ_INFO_H_
#define ABSL_STRINGS_INTERNAL_CORDZ_INFO_H_

#include <atomic>
#include <cstdint>
#include <functional>

#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/internal/spinlock.h"
#include "absl/base/thread_annotations.h"
#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cordz_functions.h"
#include "absl/strings/internal/cordz_handle.h"
#include "absl/strings/internal/cordz_statistics.h"
#include "absl/strings/internal/cordz_update_tracker.h"
#include "absl/synchronization/mutex.h"
#include "absl/types/span.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {

// CordzInfo tracks a profiled Cord. Each of these objects can be in two places.
// If a Cord is alive, the CordzInfo will be in the global_cordz_infos map, and
// can also be retrieved via the linked list starting with
// global_cordz_infos_head and continued via the cordz_info_next() method. When
// a Cord has reached the end of its lifespan, the CordzInfo object will be
// migrated out of the global_cordz_infos list and the global_cordz_infos_map,
// and will either be deleted or appended to the global_delete_queue. If it is
// placed on the global_delete_queue, the CordzInfo object will be cleaned in
// the destructor of a CordzSampleToken object.
class ABSL_LOCKABLE CordzInfo : public CordzHandle {
 public:
  using MethodIdentifier = CordzUpdateTracker::MethodIdentifier;

  // TrackCord creates a CordzInfo instance which tracks important metrics of
  // a sampled cord, and stores the created CordzInfo instance into `cord'. All
  // CordzInfo instances are placed in a global list which is used to discover
  // and snapshot all actively tracked cords. Callers are responsible for
  // calling UntrackCord() before the tracked Cord instance is deleted, or to
  // stop tracking the sampled Cord. Callers are also responsible for guarding
  // changes to the 'tree' value of a Cord (InlineData.tree) through the Lock()
  // and Unlock() calls. Any change resulting in a new tree value for the cord
  // requires a call to SetCordRep() before the old tree has been unreffed
  // and/or deleted. `method` identifies the Cord public API method initiating
  // the cord to be sampled.
  // Requires `cord` to hold a tree, and `cord.cordz_info()` to be null.
  static void TrackCord(InlineData& cord, MethodIdentifier method,
                        int64_t sampling_stride);

  // Identical to TrackCord(), except that this function fills the
  // `parent_stack` and `parent_method` properties of the returned CordzInfo
  // instance from the provided `src` instance if `src` is sampled.
  // This function should be used for sampling 'copy constructed' and 'copy
  // assigned' cords. This function allows 'cord` to be already sampled, in
  // which case the CordzInfo will be newly created from `src`.
  static void TrackCord(InlineData& cord, const InlineData& src,
                        MethodIdentifier method);

  // Maybe sample the cord identified by 'cord' for method 'method'.
  // Uses `cordz_should_profile` to randomly pick cords to be sampled, and if
  // so, invokes `TrackCord` to start sampling `cord`.
  static void MaybeTrackCord(InlineData& cord, MethodIdentifier method);

  // Maybe sample the cord identified by 'cord' for method 'method'.
  // `src` identifies a 'parent' cord which is assigned to `cord`, typically the
  // input cord for a copy constructor, or an assign method such as `operator=`
  // `cord` will be sampled if (and only if) `src` is sampled.
  // If `cord` is currently being sampled and `src` is not being sampled, then
  // this function will stop sampling the cord and reset the cord's cordz_info.
  //
  // Previously this function defined that `cord` will be sampled if either
  // `src` is sampled, or if `cord` is randomly picked for sampling. However,
  // this can cause issues, as there may be paths where some cord is assigned an
  // indirect copy of it's own value. As such a 'string of copies' would then
  // remain sampled (`src.is_profiled`), then assigning such a cord back to
  // 'itself' creates a cycle where the cord will converge to 'always sampled`.
  //
  // For example:
  //
  //   Cord x;
  //   for (...) {
  //     // Copy ctor --> y.is_profiled := x.is_profiled | random(...)
  //     Cord y = x;
  //     ...
  //     // Assign x = y --> x.is_profiled = y.is_profiled | random(...)
  //     //              ==> x.is_profiled |= random(...)
  //     //              ==> x converges to 'always profiled'
  //     x = y;
  //   }
  static void MaybeTrackCord(InlineData& cord, const InlineData& src,
                             MethodIdentifier method);

  // Stops tracking changes for a sampled cord, and deletes the provided info.
  // This function must be called before the sampled cord instance is deleted,
  // and before the root cordrep of the sampled cord is unreffed.
  // This function may extend the lifetime of the cordrep in cases where the
  // CordInfo instance is being held by a concurrent collection thread.
  void Untrack();

  // Invokes UntrackCord() on `info` if `info` is not null.
  static void MaybeUntrackCord(CordzInfo* info);

  CordzInfo() = delete;
  CordzInfo(const CordzInfo&) = delete;
  CordzInfo& operator=(const CordzInfo&) = delete;

  // Retrieves the oldest existing CordzInfo.
  static CordzInfo* Head(const CordzSnapshot& snapshot)
      ABSL_NO_THREAD_SAFETY_ANALYSIS;

  // Retrieves the next oldest existing CordzInfo older than 'this' instance.
  CordzInfo* Next(const CordzSnapshot& snapshot) const
      ABSL_NO_THREAD_SAFETY_ANALYSIS;

  // Locks this instance for the update identified by `method`.
  // Increases the count for `method` in `update_tracker`.
  void Lock(MethodIdentifier method) ABSL_EXCLUSIVE_LOCK_FUNCTION(mutex_);

  // Unlocks this instance. If the contained `rep` has been set to null
  // indicating the Cord has been cleared or is otherwise no longer sampled,
  // then this method will delete this CordzInfo instance.
  void Unlock() ABSL_UNLOCK_FUNCTION(mutex_);

  // Asserts that this CordzInfo instance is locked.
  void AssertHeld() ABSL_ASSERT_EXCLUSIVE_LOCK(mutex_);

  // Updates the `rep` property of this instance. This methods is invoked by
  // Cord logic each time the root node of a sampled Cord changes, and before
  // the old root reference count is deleted. This guarantees that collection
  // code can always safely take a reference on the tracked cord.
  // Requires a lock to be held through the `Lock()` method.
  // TODO(b/117940323): annotate with ABSL_EXCLUSIVE_LOCKS_REQUIRED once all
  // Cord code is in a state where this can be proven true by the compiler.
  void SetCordRep(CordRep* rep);

  // Returns the current `rep` property of this instance with a reference
  // added, or null if this instance represents a cord that has since been
  // deleted or untracked.
  CordRep* RefCordRep() const ABSL_LOCKS_EXCLUDED(mutex_);

  // Returns the current value of `rep_` for testing purposes only.
  CordRep* GetCordRepForTesting() const ABSL_NO_THREAD_SAFETY_ANALYSIS {
    return rep_;
  }

  // Sets the current value of `rep_` for testing purposes only.
  void SetCordRepForTesting(CordRep* rep) ABSL_NO_THREAD_SAFETY_ANALYSIS {
    rep_ = rep;
  }

  // Returns the stack trace for where the cord was first sampled. Cords are
  // potentially sampled when they promote from an inlined cord to a tree or
  // ring representation, which is not necessarily the location where the cord
  // was first created. Some cords are created as inlined cords, and only as
  // data is added do they become a non-inlined cord. However, typically the
  // location represents reasonably well where the cord is 'created'.
  absl::Span<void* const> GetStack() const;

  // Returns the stack trace for a sampled cord's 'parent stack trace'. This
  // value may be set if the cord is sampled (promoted) after being created
  // from, or being assigned the value of an existing (sampled) cord.
  absl::Span<void* const> GetParentStack() const;

  // Retrieves the CordzStatistics associated with this Cord. The statistics
  // are only updated when a Cord goes through a mutation, such as an Append
  // or RemovePrefix.
  CordzStatistics GetCordzStatistics() const;

  int64_t sampling_stride() const { return sampling_stride_; }

 private:
  using SpinLock = absl::base_internal::SpinLock;
  using SpinLockHolder = ::absl::base_internal::SpinLockHolder;

  // Global cordz info list. CordzInfo stores a pointer to the global list
  // instance to harden against ODR violations.
  struct List {
    constexpr explicit List(absl::ConstInitType)
        : mutex(absl::kConstInit,
                absl::base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL) {}

    SpinLock mutex;
    std::atomic<CordzInfo*> head ABSL_GUARDED_BY(mutex){nullptr};
  };

  static constexpr size_t kMaxStackDepth = 64;

  explicit CordzInfo(CordRep* rep, const CordzInfo* src,
                     MethodIdentifier method, int64_t weight);
  ~CordzInfo() override;

  // Sets `rep_` without holding a lock.
  void UnsafeSetCordRep(CordRep* rep) ABSL_NO_THREAD_SAFETY_ANALYSIS;

  void Track();

  // Returns the parent method from `src`, which is either `parent_method_` or
  // `method_` depending on `parent_method_` being kUnknown.
  // Returns kUnknown if `src` is null.
  static MethodIdentifier GetParentMethod(const CordzInfo* src);

  // Fills the provided stack from `src`, copying either `parent_stack_` or
  // `stack_` depending on `parent_stack_` being empty, returning the size of
  // the parent stack.
  // Returns 0 if `src` is null.
  static size_t FillParentStack(const CordzInfo* src, void** stack);

  void ODRCheck() const {
#ifndef NDEBUG
    ABSL_RAW_CHECK(list_ == &global_list_, "ODR violation in Cord");
#endif
  }

  // Non-inlined implementation of `MaybeTrackCord`, which is executed if
  // either `src` is sampled or `cord` is sampled, and either untracks or
  // tracks `cord` as documented per `MaybeTrackCord`.
  static void MaybeTrackCordImpl(InlineData& cord, const InlineData& src,
                                 MethodIdentifier method);

  ABSL_CONST_INIT static List global_list_;
  List* const list_ = &global_list_;

  // ci_prev_ and ci_next_ require the global list mutex to be held.
  // Unfortunately we can't use thread annotations such that the thread safety
  // analysis understands that list_ and global_list_ are one and the same.
  std::atomic<CordzInfo*> ci_prev_{nullptr};
  std::atomic<CordzInfo*> ci_next_{nullptr};

  mutable absl::Mutex mutex_;
  CordRep* rep_ ABSL_GUARDED_BY(mutex_);

  void* stack_[kMaxStackDepth];
  void* parent_stack_[kMaxStackDepth];
  const size_t stack_depth_;
  const size_t parent_stack_depth_;
  const MethodIdentifier method_;
  const MethodIdentifier parent_method_;
  CordzUpdateTracker update_tracker_;
  const absl::Time create_time_;
  const int64_t sampling_stride_;
};

inline ABSL_ATTRIBUTE_ALWAYS_INLINE void CordzInfo::MaybeTrackCord(
    InlineData& cord, MethodIdentifier method) {
  auto stride = cordz_should_profile();
  if (ABSL_PREDICT_FALSE(stride > 0)) {
    TrackCord(cord, method, stride);
  }
}

inline ABSL_ATTRIBUTE_ALWAYS_INLINE void CordzInfo::MaybeTrackCord(
    InlineData& cord, const InlineData& src, MethodIdentifier method) {
  if (ABSL_PREDICT_FALSE(InlineData::is_either_profiled(cord, src))) {
    MaybeTrackCordImpl(cord, src, method);
  }
}

inline ABSL_ATTRIBUTE_ALWAYS_INLINE void CordzInfo::MaybeUntrackCord(
    CordzInfo* info) {
  if (ABSL_PREDICT_FALSE(info)) {
    info->Untrack();
  }
}

inline void CordzInfo::AssertHeld() ABSL_ASSERT_EXCLUSIVE_LOCK(mutex_) {
#ifndef NDEBUG
  mutex_.AssertHeld();
#endif
}

inline void CordzInfo::SetCordRep(CordRep* rep) {
  AssertHeld();
  rep_ = rep;
}

inline void CordzInfo::UnsafeSetCordRep(CordRep* rep) { rep_ = rep; }

// Android local modification: locally silence an incorrect warning that
// causes build failures in code that uses -Werror.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wthread-safety-negative"
inline CordRep* CordzInfo::RefCordRep() const ABSL_LOCKS_EXCLUDED(mutex_) {
  MutexLock lock(&mutex_);
  return rep_ ? CordRep::Ref(rep_) : nullptr;
}
#pragma clang diagnostic pop

}  // namespace cord_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_CORDZ_INFO_H_
*»D
‰soong/.intermediates/external/abseil-cpp/absl_strings_cord_internal_hdrs/gen/my_include_dir/absl/strings/internal/cord_rep_btree_reader.h¬C// Copyright 2021 The Abseil Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_READER_H_
#define ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_READER_H_

#include <cassert>

#include "absl/base/config.h"
#include "absl/strings/internal/cord_data_edge.h"
#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_btree.h"
#include "absl/strings/internal/cord_rep_btree_navigator.h"
#include "absl/strings/internal/cord_rep_flat.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {

// CordRepBtreeReader implements logic to iterate over cord btrees.
// References to the underlying data are returned as absl::string_view values.
// The most typical use case is a forward only iteration over tree data.
// The class also provides `Skip()`, `Seek()` and `Read()` methods similar to
// CordRepBtreeNavigator that allow more advanced navigation.
//
// Example: iterate over all data inside a cord btree:
//
//   CordRepBtreeReader reader;
//   for (string_view sv = reader.Init(tree); !sv.Empty(); sv = sv.Next()) {
//     DoSomethingWithDataIn(sv);
//   }
//
// All navigation methods always return the next 'chunk' of data. The class
// assumes that all data is directly 'consumed' by the caller. For example:
// invoking `Skip()` will skip the desired number of bytes, and directly
// read and return the next chunk of data directly after the skipped bytes.
//
// Example: iterate over all data inside a btree skipping the first 100 bytes:
//
//   CordRepBtreeReader reader;
//   absl::string_view sv = reader.Init(tree);
//   if (sv.length() > 100) {
//     sv.RemovePrefix(100);
//   } else {
//     sv = reader.Skip(100 - sv.length());
//   }
//   while (!sv.empty()) {
//     DoSomethingWithDataIn(sv);
//     absl::string_view sv = reader.Next();
//   }
//
// It is important to notice that `remaining` is based on the end position of
// the last data edge returned to the caller, not the cumulative data returned
// to the caller which can be less in cases of skipping or seeking over data.
//
// For example, consider a cord btree with five data edges: "abc", "def", "ghi",
// "jkl" and "mno":
//
//   absl::string_view sv;
//   CordRepBtreeReader reader;
//
//   sv = reader.Init(tree); // sv = "abc", remaining = 12
//   sv = reader.Skip(4);    // sv = "hi",  remaining = 6
//   sv = reader.Skip(2);    // sv = "l",   remaining = 3
//   sv = reader.Next();     // sv = "mno", remaining = 0
//   sv = reader.Seek(1);    // sv = "bc", remaining = 12
//
class CordRepBtreeReader {
 public:
  using ReadResult = CordRepBtreeNavigator::ReadResult;
  using Position = CordRepBtreeNavigator::Position;

  // Returns true if this instance is not empty.
  explicit operator bool() const { return navigator_.btree() != nullptr; }

  // Returns the tree referenced by this instance or nullptr if empty.
  CordRepBtree* btree() const { return navigator_.btree(); }

  // Returns the current data edge inside the referenced btree.
  // Requires that the current instance is not empty.
  CordRep* node() const { return navigator_.Current(); }

  // Returns the length of the referenced tree.
  // Requires that the current instance is not empty.
  size_t length() const;

  // Returns the number of remaining bytes available for iteration, which is the
  // number of bytes directly following the end of the last chunk returned.
  // This value will be zero if we iterated over the last edge in the bound
  // tree, in which case any call to Next() or Skip() will return an empty
  // string_view reflecting the EOF state.
  // Note that a call to `Seek()` resets `remaining` to a value based on the
  // end position of the chunk returned by that call.
  size_t remaining() const { return remaining_; }

  // Resets this instance to an empty value.
  void Reset() { navigator_.Reset(); }

  // Initializes this instance with `tree`. `tree` must not be null.
  // Returns a reference to the first data edge of the provided tree.
  absl::string_view Init(CordRepBtree* tree);

  // Navigates to and returns the next data edge of the referenced tree.
  // Returns an empty string_view if an attempt is made to read beyond the end
  // of the tree, i.e.: if `remaining()` is zero indicating an EOF condition.
  // Requires that the current instance is not empty.
  absl::string_view Next();

  // Skips the provided amount of bytes and returns a reference to the data
  // directly following the skipped bytes.
  absl::string_view Skip(size_t skip);

  // Reads `n` bytes into `tree`.
  // If `chunk_size` is zero, starts reading at the next data edge. If
  // `chunk_size` is non zero, the read starts at the last `chunk_size` bytes of
  // the last returned data edge. Effectively, this means that the read starts
  // at offset `consumed() - chunk_size`.
  // Requires that `chunk_size` is less than or equal to the length of the
  // last returned data edge. The purpose of `chunk_size` is to simplify code
  // partially consuming a returned chunk and wanting to include the remaining
  // bytes in the Read call. For example, the below code will read 1000 bytes of
  // data into a cord tree if the first chunk starts with "big:":
  //
  //   CordRepBtreeReader reader;
  //   absl::string_view sv = reader.Init(tree);
  //   if (absl::StartsWith(sv, "big:")) {
  //     CordRepBtree tree;
  //     sv = reader.Read(1000, sv.size() - 4 /* "big:" */, &tree);
  //   }
  //
  // This method will return an empty string view if all remaining data was
  // read. If `n` exceeded the amount of remaining data this function will
  // return an empty string view and `tree` will be set to nullptr.
  // In both cases, `consumed` will be set to `length`.
  absl::string_view Read(size_t n, size_t chunk_size, CordRep*& tree);

  // Navigates to the chunk at offset `offset`.
  // Returns a reference into the navigated to chunk, adjusted for the relative
  // position of `offset` into that chunk. For example, calling `Seek(13)` on a
  // cord tree containing 2 chunks of 10 and 20 bytes respectively will return
  // a string view into the second chunk starting at offset 3 with a size of 17.
  // Returns an empty string view if `offset` is equal to or greater than the
  // length of the referenced tree.
  absl::string_view Seek(size_t offset);

 private:
  size_t remaining_ = 0;
  CordRepBtreeNavigator navigator_;
};

inline size_t CordRepBtreeReader::length() const {
  assert(btree() != nullptr);
  return btree()->length;
}

inline absl::string_view CordRepBtreeReader::Init(CordRepBtree* tree) {
  assert(tree != nullptr);
  const CordRep* edge = navigator_.InitFirst(tree);
  remaining_ = tree->length - edge->length;
  return EdgeData(edge);
}

inline absl::string_view CordRepBtreeReader::Next() {
  if (remaining_ == 0) return {};
  const CordRep* edge = navigator_.Next();
  assert(edge != nullptr);
  remaining_ -= edge->length;
  return EdgeData(edge);
}

inline absl::string_view CordRepBtreeReader::Skip(size_t skip) {
  // As we are always positioned on the last 'consumed' edge, we
  // need to skip the current edge as well as `skip`.
  const size_t edge_length = navigator_.Current()->length;
  CordRepBtreeNavigator::Position pos = navigator_.Skip(skip + edge_length);
  if (ABSL_PREDICT_FALSE(pos.edge == nullptr)) {
    remaining_ = 0;
    return {};
  }
  // The combined length of all edges skipped before `pos.edge` is `skip -
  // pos.offset`, all of which are 'consumed', as well as the current edge.
  remaining_ -= skip - pos.offset + pos.edge->length;
  return EdgeData(pos.edge).substr(pos.offset);
}

inline absl::string_view CordRepBtreeReader::Seek(size_t offset) {
  const CordRepBtreeNavigator::Position pos = navigator_.Seek(offset);
  if (ABSL_PREDICT_FALSE(pos.edge == nullptr)) {
    remaining_ = 0;
    return {};
  }
  absl::string_view chunk = EdgeData(pos.edge).substr(pos.offset);
  remaining_ = length() - offset - chunk.length();
  return chunk;
}

}  // namespace cord_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_READER_H_
*Ó;
wsoong/.intermediates/external/abseil-cpp/absl_base_atomic_hook_hdrs/gen/my_include_dir/absl/base/internal/atomic_hook.h×:// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_BASE_INTERNAL_ATOMIC_HOOK_H_
#define ABSL_BASE_INTERNAL_ATOMIC_HOOK_H_

#include <atomic>
#include <cassert>
#include <cstdint>
#include <utility>

#include "absl/base/attributes.h"
#include "absl/base/config.h"

#if defined(_MSC_VER) && !defined(__clang__)
#define ABSL_HAVE_WORKING_CONSTEXPR_STATIC_INIT 0
#else
#define ABSL_HAVE_WORKING_CONSTEXPR_STATIC_INIT 1
#endif

#if defined(_MSC_VER)
#define ABSL_HAVE_WORKING_ATOMIC_POINTER 0
#else
#define ABSL_HAVE_WORKING_ATOMIC_POINTER 1
#endif

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {

template <typename T>
class AtomicHook;

// To workaround AtomicHook not being constant-initializable on some platforms,
// prefer to annotate instances with `ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES`
// instead of `ABSL_CONST_INIT`.
#if ABSL_HAVE_WORKING_CONSTEXPR_STATIC_INIT
#define ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES ABSL_CONST_INIT
#else
#define ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES
#endif

// `AtomicHook` is a helper class, templatized on a raw function pointer type,
// for implementing Abseil customization hooks.  It is a callable object that
// dispatches to the registered hook.  Objects of type `AtomicHook` must have
// static or thread storage duration.
//
// A default constructed object performs a no-op (and returns a default
// constructed object) if no hook has been registered.
//
// Hooks can be pre-registered via constant initialization, for example:
//
// ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES static AtomicHook<void(*)()>
//     my_hook(DefaultAction);
//
// and then changed at runtime via a call to `Store()`.
//
// Reads and writes guarantee memory_order_acquire/memory_order_release
// semantics.
template <typename ReturnType, typename... Args>
class AtomicHook<ReturnType (*)(Args...)> {
 public:
  using FnPtr = ReturnType (*)(Args...);

  // Constructs an object that by default performs a no-op (and
  // returns a default constructed object) when no hook as been registered.
  constexpr AtomicHook() : AtomicHook(DummyFunction) {}

  // Constructs an object that by default dispatches to/returns the
  // pre-registered default_fn when no hook has been registered at runtime.
#if ABSL_HAVE_WORKING_ATOMIC_POINTER && ABSL_HAVE_WORKING_CONSTEXPR_STATIC_INIT
  explicit constexpr AtomicHook(FnPtr default_fn)
      : hook_(default_fn), default_fn_(default_fn) {}
#elif ABSL_HAVE_WORKING_CONSTEXPR_STATIC_INIT
  explicit constexpr AtomicHook(FnPtr default_fn)
      : hook_(kUninitialized), default_fn_(default_fn) {}
#else
  // As of January 2020, on all known versions of MSVC this constructor runs in
  // the global constructor sequence.  If `Store()` is called by a dynamic
  // initializer, we want to preserve the value, even if this constructor runs
  // after the call to `Store()`.  If not, `hook_` will be
  // zero-initialized by the linker and we have no need to set it.
  // https://developercommunity.visualstudio.com/content/problem/336946/class-with-constexpr-constructor-not-using-static.html
  explicit constexpr AtomicHook(FnPtr default_fn)
      : /* hook_(deliberately omitted), */ default_fn_(default_fn) {
    static_assert(kUninitialized == 0, "here we rely on zero-initialization");
  }
#endif

  // Stores the provided function pointer as the value for this hook.
  //
  // This is intended to be called once.  Multiple calls are legal only if the
  // same function pointer is provided for each call.  The store is implemented
  // as a memory_order_release operation, and read accesses are implemented as
  // memory_order_acquire.
  void Store(FnPtr fn) {
    bool success = DoStore(fn);
    static_cast<void>(success);
    assert(success);
  }

  // Invokes the registered callback.  If no callback has yet been registered, a
  // default-constructed object of the appropriate type is returned instead.
  template <typename... CallArgs>
  ReturnType operator()(CallArgs&&... args) const {
    return DoLoad()(std::forward<CallArgs>(args)...);
  }

  // Returns the registered callback, or nullptr if none has been registered.
  // Useful if client code needs to conditionalize behavior based on whether a
  // callback was registered.
  //
  // Note that atomic_hook.Load()() and atomic_hook() have different semantics:
  // operator()() will perform a no-op if no callback was registered, while
  // Load()() will dereference a null function pointer.  Prefer operator()() to
  // Load()() unless you must conditionalize behavior on whether a hook was
  // registered.
  FnPtr Load() const {
    FnPtr ptr = DoLoad();
    return (ptr == DummyFunction) ? nullptr : ptr;
  }

 private:
  static ReturnType DummyFunction(Args...) {
    return ReturnType();
  }

  // Current versions of MSVC (as of September 2017) have a broken
  // implementation of std::atomic<T*>:  Its constructor attempts to do the
  // equivalent of a reinterpret_cast in a constexpr context, which is not
  // allowed.
  //
  // This causes an issue when building with LLVM under Windows.  To avoid this,
  // we use a less-efficient, intptr_t-based implementation on Windows.
#if ABSL_HAVE_WORKING_ATOMIC_POINTER
  // Return the stored value, or DummyFunction if no value has been stored.
  FnPtr DoLoad() const { return hook_.load(std::memory_order_acquire); }

  // Store the given value.  Returns false if a different value was already
  // stored to this object.
  bool DoStore(FnPtr fn) {
    assert(fn);
    FnPtr expected = default_fn_;
    const bool store_succeeded = hook_.compare_exchange_strong(
        expected, fn, std::memory_order_acq_rel, std::memory_order_acquire);
    const bool same_value_already_stored = (expected == fn);
    return store_succeeded || same_value_already_stored;
  }

  std::atomic<FnPtr> hook_;
#else  // !ABSL_HAVE_WORKING_ATOMIC_POINTER
  // Use a sentinel value unlikely to be the address of an actual function.
  static constexpr intptr_t kUninitialized = 0;

  static_assert(sizeof(intptr_t) >= sizeof(FnPtr),
                "intptr_t can't contain a function pointer");

  FnPtr DoLoad() const {
    const intptr_t value = hook_.load(std::memory_order_acquire);
    if (value == kUninitialized) {
      return default_fn_;
    }
    return reinterpret_cast<FnPtr>(value);
  }

  bool DoStore(FnPtr fn) {
    assert(fn);
    const auto value = reinterpret_cast<intptr_t>(fn);
    intptr_t expected = kUninitialized;
    const bool store_succeeded = hook_.compare_exchange_strong(
        expected, value, std::memory_order_acq_rel, std::memory_order_acquire);
    const bool same_value_already_stored = (expected == value);
    return store_succeeded || same_value_already_stored;
  }

  std::atomic<intptr_t> hook_;
#endif

  const FnPtr default_fn_;
};

#undef ABSL_HAVE_WORKING_ATOMIC_POINTER
#undef ABSL_HAVE_WORKING_CONSTEXPR_STATIC_INIT

}  // namespace base_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_BASE_INTERNAL_ATOMIC_HOOK_H_
*÷‘
‹soong/.intermediates/external/abseil-cpp/absl_container_container_memory_hdrs/gen/my_include_dir/absl/container/internal/container_memory.hå�// Copyright 2018 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_CONTAINER_INTERNAL_CONTAINER_MEMORY_H_
#define ABSL_CONTAINER_INTERNAL_CONTAINER_MEMORY_H_

#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <memory>
#include <new>
#include <tuple>
#include <type_traits>
#include <utility>

#include "absl/base/config.h"
#include "absl/memory/memory.h"
#include "absl/meta/type_traits.h"
#include "absl/utility/utility.h"

#ifdef ABSL_HAVE_ADDRESS_SANITIZER
#include <sanitizer/asan_interface.h>
#endif

#ifdef ABSL_HAVE_MEMORY_SANITIZER
#include <sanitizer/msan_interface.h>
#endif

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace container_internal {

template <size_t Alignment>
struct alignas(Alignment) AlignedType {};

// Allocates at least n bytes aligned to the specified alignment.
// Alignment must be a power of 2. It must be positive.
//
// Note that many allocators don't honor alignment requirements above certain
// threshold (usually either alignof(std::max_align_t) or alignof(void*)).
// Allocate() doesn't apply alignment corrections. If the underlying allocator
// returns insufficiently alignment pointer, that's what you are going to get.
template <size_t Alignment, class Alloc>
void* Allocate(Alloc* alloc, size_t n) {
  static_assert(Alignment > 0, "");
  assert(n && "n must be positive");
  using M = AlignedType<Alignment>;
  using A = typename absl::allocator_traits<Alloc>::template rebind_alloc<M>;
  using AT = typename absl::allocator_traits<Alloc>::template rebind_traits<M>;
  // On macOS, "mem_alloc" is a #define with one argument defined in
  // rpc/types.h, so we can't name the variable "mem_alloc" and initialize it
  // with the "foo(bar)" syntax.
  A my_mem_alloc(*alloc);
  void* p = AT::allocate(my_mem_alloc, (n + sizeof(M) - 1) / sizeof(M));
  assert(reinterpret_cast<uintptr_t>(p) % Alignment == 0 &&
         "allocator does not respect alignment");
  return p;
}

// Returns true if the destruction of the value with given Allocator will be
// trivial.
template <class Allocator, class ValueType>
constexpr auto IsDestructionTrivial() {
  constexpr bool result =
      std::is_trivially_destructible<ValueType>::value &&
      std::is_same<typename absl::allocator_traits<
                       Allocator>::template rebind_alloc<char>,
                   std::allocator<char>>::value;
  return std::integral_constant<bool, result>();
}

// The pointer must have been previously obtained by calling
// Allocate<Alignment>(alloc, n).
template <size_t Alignment, class Alloc>
void Deallocate(Alloc* alloc, void* p, size_t n) {
  static_assert(Alignment > 0, "");
  assert(n && "n must be positive");
  using M = AlignedType<Alignment>;
  using A = typename absl::allocator_traits<Alloc>::template rebind_alloc<M>;
  using AT = typename absl::allocator_traits<Alloc>::template rebind_traits<M>;
  // On macOS, "mem_alloc" is a #define with one argument defined in
  // rpc/types.h, so we can't name the variable "mem_alloc" and initialize it
  // with the "foo(bar)" syntax.
  A my_mem_alloc(*alloc);
  AT::deallocate(my_mem_alloc, static_cast<M*>(p),
                 (n + sizeof(M) - 1) / sizeof(M));
}

namespace memory_internal {

// Constructs T into uninitialized storage pointed by `ptr` using the args
// specified in the tuple.
template <class Alloc, class T, class Tuple, size_t... I>
void ConstructFromTupleImpl(Alloc* alloc, T* ptr, Tuple&& t,
                            absl::index_sequence<I...>) {
  absl::allocator_traits<Alloc>::construct(
      *alloc, ptr, std::get<I>(std::forward<Tuple>(t))...);
}

template <class T, class F>
struct WithConstructedImplF {
  template <class... Args>
  decltype(std::declval<F>()(std::declval<T>())) operator()(
      Args&&... args) const {
    return std::forward<F>(f)(T(std::forward<Args>(args)...));
  }
  F&& f;
};

template <class T, class Tuple, size_t... Is, class F>
decltype(std::declval<F>()(std::declval<T>())) WithConstructedImpl(
    Tuple&& t, absl::index_sequence<Is...>, F&& f) {
  return WithConstructedImplF<T, F>{std::forward<F>(f)}(
      std::get<Is>(std::forward<Tuple>(t))...);
}

template <class T, size_t... Is>
auto TupleRefImpl(T&& t, absl::index_sequence<Is...>)
    -> decltype(std::forward_as_tuple(std::get<Is>(std::forward<T>(t))...)) {
  return std::forward_as_tuple(std::get<Is>(std::forward<T>(t))...);
}

// 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>())) {
  return TupleRefImpl(
      std::forward<T>(t),
      absl::make_index_sequence<
          std::tuple_size<typename std::decay<T>::type>::value>());
}

template <class F, class K, class V>
decltype(std::declval<F>()(std::declval<const K&>(), std::piecewise_construct,
                           std::declval<std::tuple<K>>(), std::declval<V>()))
DecomposePairImpl(F&& f, std::pair<std::tuple<K>, V> p) {
  const auto& key = std::get<0>(p.first);
  return std::forward<F>(f)(key, std::piecewise_construct, std::move(p.first),
                            std::move(p.second));
}

}  // namespace memory_internal

// Constructs T into uninitialized storage pointed by `ptr` using the args
// specified in the tuple.
template <class Alloc, class T, class Tuple>
void ConstructFromTuple(Alloc* alloc, T* ptr, Tuple&& t) {
  memory_internal::ConstructFromTupleImpl(
      alloc, ptr, std::forward<Tuple>(t),
      absl::make_index_sequence<
          std::tuple_size<typename std::decay<Tuple>::type>::value>());
}

// 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) {
  return memory_internal::WithConstructedImpl<T>(
      std::forward<Tuple>(t),
      absl::make_index_sequence<
          std::tuple_size<typename std::decay<Tuple>::type>::value>(),
      std::forward<F>(f));
}

// Given arguments of an std::pair's constructor, PairArgs() returns a pair of
// tuples with references to the passed arguments. The tuples contain
// constructor arguments for the first and the second elements of the pair.
//
// The following two snippets are equivalent.
//
// 1. std::pair<F, S> p(args...);
//
// 2. auto a = PairArgs(args...);
//    std::pair<F, S> p(std::piecewise_construct,
//                      std::move(a.first), std::move(a.second));
inline std::pair<std::tuple<>, std::tuple<>> PairArgs() { return {}; }
template <class F, class S>
std::pair<std::tuple<F&&>, std::tuple<S&&>> PairArgs(F&& f, S&& s) {
  return {std::piecewise_construct, std::forward_as_tuple(std::forward<F>(f)),
          std::forward_as_tuple(std::forward<S>(s))};
}
template <class F, class S>
std::pair<std::tuple<const F&>, std::tuple<const S&>> PairArgs(
    const std::pair<F, S>& p) {
  return PairArgs(p.first, p.second);
}
template <class F, class S>
std::pair<std::tuple<F&&>, std::tuple<S&&>> PairArgs(std::pair<F, S>&& p) {
  return PairArgs(std::forward<F>(p.first), std::forward<S>(p.second));
}
template <class F, class S>
auto PairArgs(std::piecewise_construct_t, F&& f, S&& s)
    -> decltype(std::make_pair(memory_internal::TupleRef(std::forward<F>(f)),
                               memory_internal::TupleRef(std::forward<S>(s)))) {
  return std::make_pair(memory_internal::TupleRef(std::forward<F>(f)),
                        memory_internal::TupleRef(std::forward<S>(s)));
}

// A helper function for implementing apply() in map policies.
template <class F, class... Args>
auto DecomposePair(F&& f, Args&&... args)
    -> decltype(memory_internal::DecomposePairImpl(
        std::forward<F>(f), PairArgs(std::forward<Args>(args)...))) {
  return memory_internal::DecomposePairImpl(
      std::forward<F>(f), PairArgs(std::forward<Args>(args)...));
}

// A helper function for implementing apply() in set policies.
template <class F, class Arg>
decltype(std::declval<F>()(std::declval<const Arg&>(), std::declval<Arg>()))
DecomposeValue(F&& f, Arg&& arg) {
  const auto& key = arg;
  return std::forward<F>(f)(key, std::forward<Arg>(arg));
}

// Helper functions for asan and msan.
inline void SanitizerPoisonMemoryRegion(const void* m, size_t s) {
#ifdef ABSL_HAVE_ADDRESS_SANITIZER
  ASAN_POISON_MEMORY_REGION(m, s);
#endif
#ifdef ABSL_HAVE_MEMORY_SANITIZER
  __msan_poison(m, s);
#endif
  (void)m;
  (void)s;
}

inline void SanitizerUnpoisonMemoryRegion(const void* m, size_t s) {
#ifdef ABSL_HAVE_ADDRESS_SANITIZER
  ASAN_UNPOISON_MEMORY_REGION(m, s);
#endif
#ifdef ABSL_HAVE_MEMORY_SANITIZER
  __msan_unpoison(m, s);
#endif
  (void)m;
  (void)s;
}

template <typename T>
inline void SanitizerPoisonObject(const T* object) {
  SanitizerPoisonMemoryRegion(object, sizeof(T));
}

template <typename T>
inline void SanitizerUnpoisonObject(const T* object) {
  SanitizerUnpoisonMemoryRegion(object, sizeof(T));
}

namespace memory_internal {

// If Pair is a standard-layout type, OffsetOf<Pair>::kFirst and
// OffsetOf<Pair>::kSecond are equivalent to offsetof(Pair, first) and
// offsetof(Pair, second) respectively. Otherwise they are -1.
//
// The purpose of OffsetOf is to avoid calling offsetof() on non-standard-layout
// type, which is non-portable.
template <class Pair, class = std::true_type>
struct OffsetOf {
  static constexpr size_t kFirst = static_cast<size_t>(-1);
  static constexpr size_t kSecond = static_cast<size_t>(-1);
};

template <class Pair>
struct OffsetOf<Pair, typename std::is_standard_layout<Pair>::type> {
  static constexpr size_t kFirst = offsetof(Pair, first);
  static constexpr size_t kSecond = offsetof(Pair, second);
};

template <class K, class V>
struct IsLayoutCompatible {
 private:
  struct Pair {
    K first;
    V second;
  };

  // Is P layout-compatible with Pair?
  template <class P>
  static constexpr bool LayoutCompatible() {
    return std::is_standard_layout<P>() && sizeof(P) == sizeof(Pair) &&
           alignof(P) == alignof(Pair) &&
           memory_internal::OffsetOf<P>::kFirst ==
               memory_internal::OffsetOf<Pair>::kFirst &&
           memory_internal::OffsetOf<P>::kSecond ==
               memory_internal::OffsetOf<Pair>::kSecond;
  }

 public:
  // Whether pair<const K, V> and pair<K, V> are layout-compatible. If they are,
  // then it is safe to store them in a union and read from either.
  static constexpr bool value = std::is_standard_layout<K>() &&
                                std::is_standard_layout<Pair>() &&
                                memory_internal::OffsetOf<Pair>::kFirst == 0 &&
                                LayoutCompatible<std::pair<K, V>>() &&
                                LayoutCompatible<std::pair<const K, V>>();
};

}  // namespace memory_internal

// The internal storage type for key-value containers like flat_hash_map.
//
// It is convenient for the value_type of a flat_hash_map<K, V> to be
// pair<const K, V>; the "const K" prevents accidental modification of the key
// when dealing with the reference returned from find() and similar methods.
// However, this creates other problems; we want to be able to emplace(K, V)
// efficiently with move operations, and similarly be able to move a
// pair<K, V> in insert().
//
// The solution is this union, which aliases the const and non-const versions
// of the pair. This also allows flat_hash_map<const K, V> to work, even though
// that has the same efficiency issues with move in emplace() and insert() -
// but people do it anyway.
//
// If kMutableKeys is false, only the value member can be accessed.
//
// If kMutableKeys is true, key can be accessed through all slots while value
// and mutable_value must be accessed only via INITIALIZED slots. Slots are
// created and destroyed via mutable_value so that the key can be moved later.
//
// Accessing one of the union fields while the other is active is safe as
// long as they are layout-compatible, which is guaranteed by the definition of
// kMutableKeys. For C++11, the relevant section of the standard is
// https://timsong-cpp.github.io/cppwp/n3337/class.mem#19 (9.2.19)
template <class K, class V>
union map_slot_type {
  map_slot_type() {}
  ~map_slot_type() = delete;
  using value_type = std::pair<const K, V>;
  using mutable_value_type =
      std::pair<absl::remove_const_t<K>, absl::remove_const_t<V>>;

  value_type value;
  mutable_value_type mutable_value;
  absl::remove_const_t<K> key;
};

template <class K, class V>
struct map_slot_policy {
  using slot_type = map_slot_type<K, V>;
  using value_type = std::pair<const K, V>;
  using mutable_value_type =
      std::pair<absl::remove_const_t<K>, absl::remove_const_t<V>>;

 private:
  static void emplace(slot_type* slot) {
    // The construction of union doesn't do anything at runtime but it allows us
    // to access its members without violating aliasing rules.
    new (slot) slot_type;
  }
  // If pair<const K, V> and pair<K, V> are layout-compatible, we can accept one
  // or the other via slot_type. We are also free to access the key via
  // slot_type::key in this case.
  using kMutableKeys = memory_internal::IsLayoutCompatible<K, V>;

 public:
  static value_type& element(slot_type* slot) { return slot->value; }
  static const value_type& element(const slot_type* slot) {
    return slot->value;
  }

  static K& mutable_key(slot_type* slot) {
    // Still check for kMutableKeys so that we can avoid calling std::launder
    // unless necessary because it can interfere with optimizations.
    return kMutableKeys::value ? slot->key
                               : *std::launder(const_cast<K*>(
                                     std::addressof(slot->value.first)));
  }

  static const K& key(const slot_type* slot) {
    return kMutableKeys::value ? slot->key : slot->value.first;
  }

  template <class Allocator, class... Args>
  static void construct(Allocator* alloc, slot_type* slot, Args&&... args) {
    emplace(slot);
    if (kMutableKeys::value) {
      absl::allocator_traits<Allocator>::construct(*alloc, &slot->mutable_value,
                                                   std::forward<Args>(args)...);
    } else {
      absl::allocator_traits<Allocator>::construct(*alloc, &slot->value,
                                                   std::forward<Args>(args)...);
    }
  }

  // Construct this slot by moving from another slot.
  template <class Allocator>
  static void construct(Allocator* alloc, slot_type* slot, slot_type* other) {
    emplace(slot);
    if (kMutableKeys::value) {
      absl::allocator_traits<Allocator>::construct(
          *alloc, &slot->mutable_value, std::move(other->mutable_value));
    } else {
      absl::allocator_traits<Allocator>::construct(*alloc, &slot->value,
                                                   std::move(other->value));
    }
  }

  // Construct this slot by copying from another slot.
  template <class Allocator>
  static void construct(Allocator* alloc, slot_type* slot,
                        const slot_type* other) {
    emplace(slot);
    absl::allocator_traits<Allocator>::construct(*alloc, &slot->value,
                                                 other->value);
  }

  template <class Allocator>
  static auto destroy(Allocator* alloc, slot_type* slot) {
    if (kMutableKeys::value) {
      absl::allocator_traits<Allocator>::destroy(*alloc, &slot->mutable_value);
    } else {
      absl::allocator_traits<Allocator>::destroy(*alloc, &slot->value);
    }
    return IsDestructionTrivial<Allocator, value_type>();
  }

  template <class Allocator>
  static auto transfer(Allocator* alloc, slot_type* new_slot,
                       slot_type* old_slot) {
    // This should really just be
    // typename absl::is_trivially_relocatable<value_type>::type()
    // but std::pair is not trivially copyable in C++23 in some standard
    // library versions.
    // See https://github.com/llvm/llvm-project/pull/95444 for instance.
    auto is_relocatable = typename std::conjunction<
        absl::is_trivially_relocatable<typename value_type::first_type>,
        absl::is_trivially_relocatable<typename value_type::second_type>>::
        type();

    emplace(new_slot);
    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 is_relocatable;
    }

    if (kMutableKeys::value) {
      absl::allocator_traits<Allocator>::construct(
          *alloc, &new_slot->mutable_value, std::move(old_slot->mutable_value));
    } else {
      absl::allocator_traits<Allocator>::construct(*alloc, &new_slot->value,
                                                   std::move(old_slot->value));
    }
    destroy(alloc, old_slot);
    return is_relocatable;
  }
};

// Type erased function for computing hash of the slot.
using HashSlotFn = size_t (*)(const void* hash_fn, void* slot);

// Type erased function to apply `Fn` to data inside of the `slot`.
// The data is expected to have type `T`.
template <class Fn, class T>
size_t TypeErasedApplyToSlotFn(const void* fn, void* slot) {
  const auto* f = static_cast<const Fn*>(fn);
  return (*f)(*static_cast<const T*>(slot));
}

// Type erased function to apply `Fn` to data inside of the `*slot_ptr`.
// The data is expected to have type `T`.
template <class Fn, class T>
size_t TypeErasedDerefAndApplyToSlotFn(const void* fn, void* slot_ptr) {
  const auto* f = static_cast<const Fn*>(fn);
  const T* slot = *static_cast<const T**>(slot_ptr);
  return (*f)(*slot);
}

}  // namespace container_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_CONTAINER_INTERNAL_CONTAINER_MEMORY_H_
*š†
�soong/.intermediates/external/abseil-cpp/absl_strings_cord_internal_hdrs/gen/my_include_dir/absl/strings/internal/cord_internal.h’…// Copyright 2021 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_STRINGS_INTERNAL_CORD_INTERNAL_H_
#define ABSL_STRINGS_INTERNAL_CORD_INTERNAL_H_

#include <atomic>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <string>

#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/container/internal/compressed_tuple.h"
#include "absl/container/internal/container_memory.h"
#include "absl/strings/string_view.h"

// We can only add poisoning if we can detect consteval executions.
#if defined(ABSL_HAVE_CONSTANT_EVALUATED) && \
    (defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
     defined(ABSL_HAVE_MEMORY_SANITIZER))
#define ABSL_INTERNAL_CORD_HAVE_SANITIZER 1
#endif

#define ABSL_CORD_INTERNAL_NO_SANITIZE \
  ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {

// The overhead of a vtable is too much for Cord, so we roll our own subclasses
// using only a single byte to differentiate classes from each other - the "tag"
// byte.  Define the subclasses first so we can provide downcasting helper
// functions in the base class.
struct CordRep;
struct CordRepConcat;
struct CordRepExternal;
struct CordRepFlat;
struct CordRepSubstring;
struct CordRepCrc;
class CordRepBtree;

class CordzInfo;

// Default feature enable states for cord ring buffers
enum CordFeatureDefaults { kCordShallowSubcordsDefault = false };

extern std::atomic<bool> shallow_subcords_enabled;

inline void enable_shallow_subcords(bool enable) {
  shallow_subcords_enabled.store(enable, std::memory_order_relaxed);
}

enum Constants {
  // The inlined size to use with absl::InlinedVector.
  //
  // Note: The InlinedVectors in this file (and in cord.h) do not need to use
  // the same value for their inlined size. The fact that they do is historical.
  // It may be desirable for each to use a different inlined size optimized for
  // that InlinedVector's usage.
  //
  // TODO(jgm): Benchmark to see if there's a more optimal value than 47 for
  // the inlined vector size (47 exists for backward compatibility).
  kInlinedVectorSize = 47,

  // Prefer copying blocks of at most this size, otherwise reference count.
  kMaxBytesToCopy = 511
};

// Emits a fatal error "Unexpected node type: xyz" and aborts the program.
[[noreturn]] void LogFatalNodeType(CordRep* rep);

// Fast implementation of memmove for up to 15 bytes. This implementation is
// safe for overlapping regions. If nullify_tail is true, the destination is
// padded with '\0' up to 15 bytes.
template <bool nullify_tail = false>
inline void SmallMemmove(char* dst, const char* src, size_t n) {
  if (n >= 8) {
    assert(n <= 15);
    uint64_t buf1;
    uint64_t buf2;
    memcpy(&buf1, src, 8);
    memcpy(&buf2, src + n - 8, 8);
    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;
    memcpy(&buf1, src, 4);
    memcpy(&buf2, src + n - 4, 4);
    if (nullify_tail) {
      memset(dst + 4, 0, 4);
      memset(dst + 7, 0, 8);
    }
    memcpy(dst, &buf1, 4);
    memcpy(dst + n - 4, &buf2, 4);
  } else {
    if (n != 0) {
      dst[0] = src[0];
      dst[n / 2] = src[n / 2];
      dst[n - 1] = src[n - 1];
    }
    if (nullify_tail) {
      memset(dst + 7, 0, 8);
      memset(dst + n, 0, 8);
    }
  }
}

// Compact class for tracking the reference count and state flags for CordRep
// instances.  Data is stored in an atomic int32_t for compactness and speed.
class RefcountAndFlags {
 public:
  constexpr RefcountAndFlags() : count_{kRefIncrement} {}
  struct Immortal {};
  explicit constexpr RefcountAndFlags(Immortal) : count_(kImmortalFlag) {}

  // Increments the reference count. Imposes no memory ordering.
  inline void Increment() {
    count_.fetch_add(kRefIncrement, std::memory_order_relaxed);
  }

  // Asserts that the current refcount is greater than 0. If the refcount is
  // greater than 1, decrements the reference count.
  //
  // Returns false if there are no references outstanding; true otherwise.
  // Inserts barriers to ensure that state written before this method returns
  // false will be visible to a thread that just observed this method returning
  // false.  Always returns false when the immortal bit is set.
  inline bool Decrement() {
    int32_t refcount = count_.load(std::memory_order_acquire);
    assert(refcount > 0 || refcount & kImmortalFlag);
    return refcount != kRefIncrement &&
           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 > 0 || refcount & kImmortalFlag);
    return refcount != kRefIncrement;
  }

  // Returns the current reference count using acquire semantics.
  inline size_t Get() const {
    return static_cast<size_t>(count_.load(std::memory_order_acquire) >>
                               kNumFlags);
  }

  // Returns whether the atomic integer is 1.
  // If the reference count is used in the conventional way, a
  // reference count of 1 implies that the current thread owns the
  // reference and no other thread shares it.
  // 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.
  inline bool IsOne() {
    return count_.load(std::memory_order_acquire) == kRefIncrement;
  }

  bool IsImmortal() const {
    return (count_.load(std::memory_order_relaxed) & kImmortalFlag) != 0;
  }

 private:
  // 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.
  enum Flags {
    kNumFlags = 1,

    kImmortalFlag = 0x1,
    kRefIncrement = (1 << kNumFlags),
  };

  std::atomic<int32_t> count_;
};

// Various representations that we allow
enum CordRepKind {
  UNUSED_0 = 0,
  SUBSTRING = 1,
  CRC = 2,
  BTREE = 3,
  UNUSED_4 = 4,
  EXTERNAL = 5,

  // We have different tags for different sized flat arrays,
  // starting with FLAT, and limited to MAX_FLAT_TAG. The below values map to an
  // allocated range of 32 bytes to 256 KB. The current granularity is:
  // - 8 byte granularity for flat sizes in [32 - 512]
  // - 64 byte granularity for flat sizes in (512 - 8KiB]
  // - 4KiB byte granularity for flat sizes in (8KiB, 256 KiB]
  // If a new tag is needed in the future, then 'FLAT' and 'MAX_FLAT_TAG' should
  // be adjusted as well as the Tag <---> Size mapping logic so that FLAT still
  // represents the minimum flat allocation size. (32 bytes as of now).
  FLAT = 6,
  MAX_FLAT_TAG = 248
};

// 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'
// 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(FLAT == EXTERNAL + 1, "EXTERNAL and FLAT not consecutive");

struct CordRep {
  // Result from an `extract edge` operation. Contains the (possibly changed)
  // tree node as well as the extracted edge, or {tree, nullptr} if no edge
  // could be extracted.
  // On success, the returned `tree` value is null if `extracted` was the only
  // data edge inside the tree, a data edge if there were only two data edges in
  // the tree, or the (possibly new / smaller) remaining tree with the extracted
  // data edge removed.
  struct ExtractResult {
    CordRep* tree;
    CordRep* extracted;
  };

  CordRep() = default;
  constexpr CordRep(RefcountAndFlags::Immortal immortal, size_t l)
      : length(l), refcount(immortal), tag(EXTERNAL), storage{} {}

  // The following three fields have to be less than 32 bytes since
  // that is the smallest supported flat node size. Some code optimizations rely
  // on the specific layout of these fields. Notably: the non-trivial field
  // `refcount` being preceded by `length`, and being tailed by POD data
  // members only.
  // LINT.IfChange
  size_t length;
  RefcountAndFlags refcount;
  // If tag < FLAT, it represents CordRepKind and indicates the type of node.
  // Otherwise, the node type is CordRepFlat and the tag is the encoded size.
  uint8_t tag;

  // `storage` provides two main purposes:
  // - the starting point for FlatCordRep.Data() [flexible-array-member]
  // - 3 bytes of additional storage for use by derived classes.
  // The latter is used by CordrepConcat and CordRepBtree. CordRepConcat stores
  // a 'depth' value in storage[0], and the (future) CordRepBtree class stores
  // `height`, `begin` and `end` in the 3 entries. Otherwise we would need to
  // allocate room for these in the derived class, as not all compilers reuse
  // padding space from the base class (clang and gcc do, MSVC does not, etc)
  uint8_t storage[3];
  // LINT.ThenChange(cord_rep_btree.h:copy_raw)

  // Returns true if this instance's tag matches the requested type.
  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 CordRepSubstring* substring();
  inline const CordRepSubstring* substring() const;
  inline CordRepCrc* crc();
  inline const CordRepCrc* crc() const;
  inline CordRepExternal* external();
  inline const CordRepExternal* external() const;
  inline CordRepFlat* flat();
  inline const CordRepFlat* flat() const;
  inline CordRepBtree* btree();
  inline const CordRepBtree* btree() const;

  // --------------------------------------------------------------------
  // Memory management

  // Destroys the provided `rep`.
  static void Destroy(CordRep* rep);

  // Increments the reference count of `rep`.
  // Requires `rep` to be a non-null pointer value.
  static inline CordRep* Ref(CordRep* rep);

  // Decrements the reference count of `rep`. Destroys rep if count reaches
  // zero. Requires `rep` to be a non-null pointer value.
  static inline void Unref(CordRep* rep);
};

struct CordRepSubstring : public CordRep {
  size_t start;  // Starting offset of substring in child
  CordRep* child;

  // Creates a substring on `child`, adopting a reference on `child`.
  // Requires `child` to be either a flat or external node, and `pos` and `n` to
  // form a non-empty partial sub range of `'child`, i.e.:
  // `n > 0 && n < length && n + pos <= length`
  static inline CordRepSubstring* Create(CordRep* child, size_t pos, size_t n);

  // Creates a substring of `rep`. Does not adopt a reference on `rep`.
  // Requires `IsDataEdge(rep) && n > 0 && pos + n <= rep->length`.
  // If `n == rep->length` then this method returns `CordRep::Ref(rep)`
  // If `rep` is a substring of a flat or external node, then this method will
  // return a new substring of that flat or external node with `pos` adjusted
  // with the original `start` position.
  static inline CordRep* Substring(CordRep* rep, size_t pos, size_t n);
};

// Type for function pointer that will invoke the releaser function and also
// delete the `CordRepExternalImpl` corresponding to the passed in
// `CordRepExternal`.
using ExternalReleaserInvoker = void (*)(CordRepExternal*);

// External CordReps are allocated together with a type erased releaser. The
// releaser is stored in the memory directly following the CordRepExternal.
struct CordRepExternal : public CordRep {
  CordRepExternal() = default;
  explicit constexpr CordRepExternal(absl::string_view str)
      : CordRep(RefcountAndFlags::Immortal{}, str.size()),
        base(str.data()),
        releaser_invoker(nullptr) {}

  const char* base;
  // Pointer to function that knows how to call and destroy the releaser.
  ExternalReleaserInvoker releaser_invoker;

  // Deletes (releases) the external rep.
  // Requires rep != nullptr and rep->IsExternal()
  static void Delete(CordRep* rep);
};

// Use go/ranked-overloads for dispatching.
struct Rank0 {};
struct Rank1 : Rank0 {};

template <typename Releaser,
          typename = ::std::invoke_result_t<Releaser, absl::string_view>>
void InvokeReleaser(Rank1, Releaser&& releaser, absl::string_view data) {
  ::std::invoke(std::forward<Releaser>(releaser), data);
}

template <typename Releaser, typename = ::std::invoke_result_t<Releaser>>
void InvokeReleaser(Rank0, Releaser&& releaser, absl::string_view) {
  ::std::invoke(std::forward<Releaser>(releaser));
}

// We use CompressedTuple so that we can benefit from EBCO.
template <typename Releaser>
struct CordRepExternalImpl
    : public CordRepExternal,
      public ::absl::container_internal::CompressedTuple<Releaser> {
  // The extra int arg is so that we can avoid interfering with copy/move
  // constructors while still benefitting from perfect forwarding.
  template <typename T>
  CordRepExternalImpl(T&& releaser, int)
      : CordRepExternalImpl::CompressedTuple(std::forward<T>(releaser)) {
    this->releaser_invoker = &Release;
  }

  ~CordRepExternalImpl() {
    InvokeReleaser(Rank1{}, std::move(this->template get<0>()),
                   absl::string_view(base, length));
  }

  static void Release(CordRepExternal* rep) {
    delete static_cast<CordRepExternalImpl*>(rep);
  }
};

inline CordRepSubstring* CordRepSubstring::Create(CordRep* child, size_t pos,
                                                  size_t n) {
  assert(child != nullptr);
  assert(n > 0);
  assert(n < child->length);
  assert(pos < child->length);
  assert(n <= child->length - pos);

  // Move to strategical places inside the Cord logic and make this an assert.
  if (ABSL_PREDICT_FALSE(!(child->IsExternal() || child->IsFlat()))) {
    LogFatalNodeType(child);
  }

  CordRepSubstring* rep = new CordRepSubstring();
  rep->length = n;
  rep->tag = SUBSTRING;
  rep->start = pos;
  rep->child = child;
  return rep;
}

inline CordRep* CordRepSubstring::Substring(CordRep* rep, size_t pos,
                                            size_t n) {
  assert(rep != nullptr);
  assert(n != 0);
  assert(pos < rep->length);
  assert(n <= rep->length - pos);
  if (n == rep->length) return CordRep::Ref(rep);
  if (rep->IsSubstring()) {
    pos += rep->substring()->start;
    rep = rep->substring()->child;
  }
  CordRepSubstring* substr = new CordRepSubstring();
  substr->length = n;
  substr->tag = SUBSTRING;
  substr->start = pos;
  substr->child = CordRep::Ref(rep);
  return substr;
}

inline void CordRepExternal::Delete(CordRep* rep) {
  assert(rep != nullptr && rep->IsExternal());
  auto* rep_external = static_cast<CordRepExternal*>(rep);
  assert(rep_external->releaser_invoker != nullptr);
  rep_external->releaser_invoker(rep_external);
}

template <typename Str>
struct ConstInitExternalStorage {
  ABSL_CONST_INIT static CordRepExternal value;
};

template <typename Str>
ABSL_CONST_INIT CordRepExternal
    ConstInitExternalStorage<Str>::value(Str::value);

enum {
  kMaxInline = 15,
};

constexpr char GetOrNull(absl::string_view data, size_t pos) {
  return pos < data.size() ? data[pos] : '\0';
}

// We store cordz_info as 64 bit pointer value in little endian format. This
// guarantees that the least significant byte of cordz_info matches the first
// byte of the inline data representation in `data`, which holds the inlined
// size or the 'is_tree' bit.
using cordz_info_t = int64_t;

// Assert that the `cordz_info` pointer value perfectly overlaps the last half
// of `data` and can hold a pointer value.
static_assert(sizeof(cordz_info_t) * 2 == kMaxInline + 1, "");
static_assert(sizeof(cordz_info_t) >= sizeof(intptr_t), "");

// LittleEndianByte() creates a little endian representation of 'value', i.e.:
// a little endian value where the first byte in the host's representation
// holds 'value`, with all other bytes being 0.
static constexpr cordz_info_t LittleEndianByte(unsigned char value) {
#if defined(ABSL_IS_BIG_ENDIAN)
  return static_cast<cordz_info_t>(value) << ((sizeof(cordz_info_t) - 1) * 8);
#else
  return value;
#endif
}

class InlineData {
 public:
  // DefaultInitType forces the use of the default initialization constructor.
  enum DefaultInitType { kDefaultInit };

  // kNullCordzInfo holds the little endian representation of intptr_t(1)
  // This is the 'null' / initial value of 'cordz_info'. The null value
  // is specifically big endian 1 as with 64-bit pointers, the last
  // byte of cordz_info overlaps with the last byte holding the tag.
  static constexpr cordz_info_t kNullCordzInfo = LittleEndianByte(1);

  // kTagOffset contains the offset of the control byte / tag. This constant is
  // intended mostly for debugging purposes: do not remove this constant as it
  // is actively inspected and used by gdb pretty printing code.
  static constexpr size_t kTagOffset = 0;

  // Implement `~InlineData()` conditionally: we only need this destructor to
  // unpoison poisoned instances under *SAN, and it will only compile correctly
  // if the current compiler supports `absl::is_constant_evaluated()`.
#ifdef ABSL_INTERNAL_CORD_HAVE_SANITIZER
  ~InlineData() noexcept { unpoison(); }
#endif

  constexpr InlineData() noexcept { poison_this(); }

  explicit InlineData(DefaultInitType) noexcept : rep_(kDefaultInit) {
    poison_this();
  }

  explicit InlineData(CordRep* rep) noexcept : rep_(rep) {
    ABSL_ASSERT(rep != nullptr);
  }

  // Explicit constexpr constructor to create a constexpr InlineData
  // value. Creates an inlined SSO value if `rep` is null, otherwise
  // creates a tree instance value.
  constexpr InlineData(absl::string_view sv, CordRep* rep) noexcept
      : rep_(rep ? Rep(rep) : Rep(sv)) {
    poison();
  }

  constexpr InlineData(const InlineData& rhs) noexcept;
  InlineData& operator=(const InlineData& rhs) noexcept;
  friend void swap(InlineData& lhs, InlineData& rhs) noexcept;

  friend bool operator==(const InlineData& lhs, const InlineData& rhs) {
#ifdef ABSL_INTERNAL_CORD_HAVE_SANITIZER
    const Rep l = lhs.rep_.SanitizerSafeCopy();
    const Rep r = rhs.rep_.SanitizerSafeCopy();
    return memcmp(&l, &r, sizeof(l)) == 0;
#else
    return memcmp(&lhs, &rhs, sizeof(lhs)) == 0;
#endif
  }
  friend bool operator!=(const InlineData& lhs, const InlineData& rhs) {
    return !operator==(lhs, rhs);
  }

  // Poisons the unused inlined SSO data if the current instance
  // is inlined, else un-poisons the entire instance.
  constexpr void poison();

  // Un-poisons this instance.
  constexpr void unpoison();

  // Poisons the current instance. This is used on default initialization.
  constexpr void poison_this();

  // Returns true if the current instance is empty.
  // The 'empty value' is an inlined data value of zero length.
  bool is_empty() const { return rep_.tag() == 0; }

  // Returns true if the current instance holds a tree value.
  bool is_tree() const { return (rep_.tag() & 1) != 0; }

  // Returns true if the current instance holds a cordz_info value.
  // Requires the current instance to hold a tree value.
  bool is_profiled() const {
    assert(is_tree());
    return rep_.cordz_info() != kNullCordzInfo;
  }

  // Returns true if either of the provided instances hold a cordz_info value.
  // This method is more efficient than the equivalent `data1.is_profiled() ||
  // data2.is_profiled()`. Requires both arguments to hold a tree.
  static bool is_either_profiled(const InlineData& data1,
                                 const InlineData& data2) {
    assert(data1.is_tree() && data2.is_tree());
    return (data1.rep_.cordz_info() | data2.rep_.cordz_info()) !=
           kNullCordzInfo;
  }

  // Returns the cordz_info sampling instance for this instance, or nullptr
  // if the current instance is not sampled and does not have CordzInfo data.
  // Requires the current instance to hold a tree value.
  CordzInfo* cordz_info() const {
    assert(is_tree());
    intptr_t info = static_cast<intptr_t>(absl::little_endian::ToHost64(
        static_cast<uint64_t>(rep_.cordz_info())));
    assert(info & 1);
    return reinterpret_cast<CordzInfo*>(info - 1);
  }

  // Sets the current cordz_info sampling instance for this instance, or nullptr
  // if the current instance is not sampled and does not have CordzInfo data.
  // Requires the current instance to hold a tree value.
  void set_cordz_info(CordzInfo* cordz_info) {
    assert(is_tree());
    uintptr_t info = reinterpret_cast<uintptr_t>(cordz_info) | 1;
    rep_.set_cordz_info(
        static_cast<cordz_info_t>(absl::little_endian::FromHost64(info)));
  }

  // Resets the current cordz_info to null / empty.
  void clear_cordz_info() {
    assert(is_tree());
    rep_.set_cordz_info(kNullCordzInfo);
  }

  // Returns a read only pointer to the character data inside this instance.
  // Requires the current instance to hold inline data.
  const char* as_chars() const {
    assert(!is_tree());
    return rep_.as_chars();
  }

  // Returns a mutable pointer to the character data inside this instance.
  // Should be used for 'write only' operations setting an inlined value.
  // Applications can set the value of inlined data either before or after
  // setting the inlined size, i.e., both of the below are valid:
  //
  //   // Set inlined data and inline size
  //   memcpy(data_.as_chars(), data, size);
  //   data_.set_inline_size(size);
  //
  //   // Set inlined size and inline data
  //   data_.set_inline_size(size);
  //   memcpy(data_.as_chars(), data, size);
  //
  // It's an error to read from the returned pointer without a preceding write
  // if the current instance does not hold inline data, i.e.: is_tree() == true.
  char* as_chars() { return rep_.as_chars(); }

  // Returns the tree value of this value.
  // Requires the current instance to hold a tree value.
  CordRep* as_tree() const {
    assert(is_tree());
    return rep_.tree();
  }

  void set_inline_data(const char* data, size_t n) {
    ABSL_ASSERT(n <= kMaxInline);
    unpoison();
    rep_.set_tag(static_cast<int8_t>(n << 1));
    SmallMemmove<true>(rep_.as_chars(), data, n);
    poison();
  }

  void CopyInlineToString(std::string* dst) const {
    assert(!is_tree());
    // As Cord can store only 15 bytes it is smaller than std::string's
    // small string optimization buffer size. Therefore we will always trigger
    // the fast assign short path.
    //
    // Copying with a size equal to the maximum allows more efficient, wider
    // stores to be used and no branching.
    dst->assign(rep_.SanitizerSafeCopy().as_chars(), kMaxInline);
    // After the copy we then change the size and put in a 0 byte.
    dst->erase(inline_size());
  }

  void copy_max_inline_to(char* dst) const {
    assert(!is_tree());
    memcpy(dst, rep_.SanitizerSafeCopy().as_chars(), kMaxInline);
  }

  // Initialize this instance to holding the tree value `rep`,
  // initializing the cordz_info to null, i.e.: 'not profiled'.
  void make_tree(CordRep* rep) {
    unpoison();
    rep_.make_tree(rep);
  }

  // Set the tree value of this instance to 'rep`.
  // Requires the current instance to already hold a tree value.
  // Does not affect the value of cordz_info.
  void set_tree(CordRep* rep) {
    assert(is_tree());
    rep_.set_tree(rep);
  }

  // Returns the size of the inlined character data inside this instance.
  // Requires the current instance to hold inline data.
  size_t inline_size() const { return rep_.inline_size(); }

  // Sets the size of the inlined character data inside this instance.
  // Requires `size` to be <= kMaxInline.
  // See the documentation on 'as_chars()' for more information and examples.
  void set_inline_size(size_t size) {
    unpoison();
    rep_.set_inline_size(size);
    poison();
  }

  // Compares 'this' inlined data  with rhs. The comparison is a straightforward
  // lexicographic comparison. `Compare()` returns values as follows:
  //
  //   -1  'this' InlineData instance is smaller
  //    0  the InlineData instances are equal
  //    1  'this' InlineData instance larger
  int Compare(const InlineData& rhs) const {
    return Compare(rep_.SanitizerSafeCopy(), rhs.rep_.SanitizerSafeCopy());
  }

 private:
  struct Rep {
    // See cordz_info_t for forced alignment and size of `cordz_info` details.
    struct AsTree {
      explicit constexpr AsTree(absl::cord_internal::CordRep* tree)
          : rep(tree) {}
      cordz_info_t cordz_info = kNullCordzInfo;
      absl::cord_internal::CordRep* rep;
    };

    explicit Rep(DefaultInitType) {}
    constexpr Rep() : data{0} {}
    constexpr Rep(const Rep&) = default;
    constexpr Rep& operator=(const Rep&) = default;

    explicit constexpr Rep(CordRep* rep) : as_tree(rep) {}

    explicit constexpr Rep(absl::string_view chars)
        : data{static_cast<char>((chars.size() << 1)),
               GetOrNull(chars, 0),
               GetOrNull(chars, 1),
               GetOrNull(chars, 2),
               GetOrNull(chars, 3),
               GetOrNull(chars, 4),
               GetOrNull(chars, 5),
               GetOrNull(chars, 6),
               GetOrNull(chars, 7),
               GetOrNull(chars, 8),
               GetOrNull(chars, 9),
               GetOrNull(chars, 10),
               GetOrNull(chars, 11),
               GetOrNull(chars, 12),
               GetOrNull(chars, 13),
               GetOrNull(chars, 14)} {}

#ifdef ABSL_INTERNAL_CORD_HAVE_SANITIZER
    // Break compiler optimization for cases when value is allocated on the
    // stack. Compiler assumes that the the variable is fully accessible
    // regardless of our poisoning.
    // Missing report: https://github.com/llvm/llvm-project/issues/100640
    const Rep* self() const {
      const Rep* volatile ptr = this;
      return ptr;
    }
    Rep* self() {
      Rep* volatile ptr = this;
      return ptr;
    }
#else
    constexpr const Rep* self() const { return this; }
    constexpr Rep* self() { return this; }
#endif

    // Disable sanitizer as we must always be able to read `tag`.
    ABSL_CORD_INTERNAL_NO_SANITIZE
    int8_t tag() const { return reinterpret_cast<const int8_t*>(this)[0]; }
    void set_tag(int8_t rhs) { reinterpret_cast<int8_t*>(self())[0] = rhs; }

    char* as_chars() { return self()->data + 1; }
    const char* as_chars() const { return self()->data + 1; }

    bool is_tree() const { return (self()->tag() & 1) != 0; }

    size_t inline_size() const {
      ABSL_ASSERT(!self()->is_tree());
      return static_cast<size_t>(self()->tag()) >> 1;
    }

    void set_inline_size(size_t size) {
      ABSL_ASSERT(size <= kMaxInline);
      self()->set_tag(static_cast<int8_t>(size << 1));
    }

    CordRep* tree() const { return self()->as_tree.rep; }
    void set_tree(CordRep* rhs) { self()->as_tree.rep = rhs; }

    cordz_info_t cordz_info() const { return self()->as_tree.cordz_info; }
    void set_cordz_info(cordz_info_t rhs) { self()->as_tree.cordz_info = rhs; }

    void make_tree(CordRep* tree) {
      self()->as_tree.rep = tree;
      self()->as_tree.cordz_info = kNullCordzInfo;
    }

#ifdef ABSL_INTERNAL_CORD_HAVE_SANITIZER
    constexpr Rep SanitizerSafeCopy() const {
      if (!absl::is_constant_evaluated()) {
        Rep res;
        if (is_tree()) {
          res = *this;
        } else {
          res.set_tag(tag());
          memcpy(res.as_chars(), as_chars(), inline_size());
        }
        return res;
      } else {
        return *this;
      }
    }
#else
    constexpr const Rep& SanitizerSafeCopy() const { return *this; }
#endif

    // If the data has length <= kMaxInline, we store it in `data`, and
    // store the size in the first char of `data` shifted left + 1.
    // Else we store it in a tree and store a pointer to that tree in
    // `as_tree.rep` with a tagged pointer to make `tag() & 1` non zero.
    union {
      char data[kMaxInline + 1];
      AsTree as_tree;
    };

    // TODO(b/145829486): see swap(InlineData, InlineData) for more info.
    inline void SwapValue(Rep rhs, Rep& refrhs) {
      memcpy(&refrhs, this, sizeof(*this));
      memcpy(this, &rhs, sizeof(*this));
    }
  };

  // Private implementation of `Compare()`
  static inline int Compare(const Rep& lhs, const Rep& rhs) {
    uint64_t x, y;
    memcpy(&x, lhs.as_chars(), sizeof(x));
    memcpy(&y, rhs.as_chars(), sizeof(y));
    if (x == y) {
      memcpy(&x, lhs.as_chars() + 7, sizeof(x));
      memcpy(&y, rhs.as_chars() + 7, sizeof(y));
      if (x == y) {
        if (lhs.inline_size() == rhs.inline_size()) return 0;
        return lhs.inline_size() < rhs.inline_size() ? -1 : 1;
      }
    }
    x = absl::big_endian::FromHost64(x);
    y = absl::big_endian::FromHost64(y);
    return x < y ? -1 : 1;
  }

  Rep rep_;
};

static_assert(sizeof(InlineData) == kMaxInline + 1, "");

#ifdef ABSL_INTERNAL_CORD_HAVE_SANITIZER

constexpr InlineData::InlineData(const InlineData& rhs) noexcept
    : rep_(rhs.rep_.SanitizerSafeCopy()) {
  poison();
}

inline InlineData& InlineData::operator=(const InlineData& rhs) noexcept {
  unpoison();
  rep_ = rhs.rep_.SanitizerSafeCopy();
  poison();
  return *this;
}

constexpr void InlineData::poison_this() {
  if (!absl::is_constant_evaluated()) {
    container_internal::SanitizerPoisonObject(this);
  }
}

constexpr void InlineData::unpoison() {
  if (!absl::is_constant_evaluated()) {
    container_internal::SanitizerUnpoisonObject(this);
  }
}

constexpr void InlineData::poison() {
  if (!absl::is_constant_evaluated()) {
    if (is_tree()) {
      container_internal::SanitizerUnpoisonObject(this);
    } else if (const size_t size = inline_size()) {
      if (size < kMaxInline) {
        const char* end = rep_.as_chars() + size;
        container_internal::SanitizerPoisonMemoryRegion(end, kMaxInline - size);
      }
    } else {
      container_internal::SanitizerPoisonObject(this);
    }
  }
}

#else  // ABSL_INTERNAL_CORD_HAVE_SANITIZER

constexpr InlineData::InlineData(const InlineData&) noexcept = default;
inline InlineData& InlineData::operator=(const InlineData&) noexcept = default;

constexpr void InlineData::poison_this() {}
constexpr void InlineData::unpoison() {}
constexpr void InlineData::poison() {}

#endif  // ABSL_INTERNAL_CORD_HAVE_SANITIZER

inline CordRepSubstring* CordRep::substring() {
  assert(IsSubstring());
  return static_cast<CordRepSubstring*>(this);
}

inline const CordRepSubstring* CordRep::substring() const {
  assert(IsSubstring());
  return static_cast<const CordRepSubstring*>(this);
}

inline CordRepExternal* CordRep::external() {
  assert(IsExternal());
  return static_cast<CordRepExternal*>(this);
}

inline const CordRepExternal* CordRep::external() const {
  assert(IsExternal());
  return static_cast<const CordRepExternal*>(this);
}

inline CordRep* CordRep::Ref(CordRep* rep) {
  // ABSL_ASSUME is a workaround for
  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105585
  ABSL_ASSUME(rep != nullptr);
  rep->refcount.Increment();
  return rep;
}

inline void CordRep::Unref(CordRep* rep) {
  assert(rep != nullptr);
  // Expect refcount to be 0. Avoiding the cost of an atomic decrement should
  // typically outweigh the cost of an extra branch checking for ref == 1.
  if (ABSL_PREDICT_FALSE(!rep->refcount.DecrementExpectHighRefcount())) {
    Destroy(rep);
  }
}

inline void swap(InlineData& lhs, InlineData& rhs) noexcept {
  lhs.unpoison();
  rhs.unpoison();
  // TODO(b/145829486): `std::swap(lhs.rep_, rhs.rep_)` results in bad codegen
  // on clang, spilling the temporary swap value on the stack. Since `Rep` is
  // trivial, we can make clang DTRT by calling a hand-rolled `SwapValue` where
  // we pass `rhs` both by value (register allocated) and by reference. The IR
  // then folds and inlines correctly into an optimized swap without spill.
  lhs.rep_.SwapValue(rhs.rep_, rhs.rep_);
  rhs.poison();
  lhs.poison();
}

}  // namespace cord_internal

ABSL_NAMESPACE_END
}  // namespace absl
#endif  // ABSL_STRINGS_INTERNAL_CORD_INTERNAL_H_
*¸
osoong/.intermediates/external/abseil-cpp/absl_strings_cord_hdrs/gen/my_include_dir/absl/strings/cord_analysis.hÄ// Copyright 2021 The Abseil Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_STRINGS_CORD_ANALYSIS_H_
#define ABSL_STRINGS_CORD_ANALYSIS_H_

#include <cstddef>
#include <cstdint>

#include "absl/base/config.h"
#include "absl/base/nullability.h"
#include "absl/strings/internal/cord_internal.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
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* absl_nonnull 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
// `GetEstimatedMemoryUsage()`, except that if the cord has multiple references
// to the same memory, that memory is only counted once.
//
// For example:
//   absl::Cord cord;
//   cord.append(some_other_cord);
//   cord.append(some_other_cord);
//    // Calls GetEstimatedMemoryUsage() and counts `other_cord` twice:
//   cord.EstimatedMemoryUsage(kTotal);
//    // Calls GetMorePreciseMemoryUsage() and counts `other_cord` once:
//   cord.EstimatedMemoryUsage(kTotalMorePrecise);
//
// This is more expensive than `GetEstimatedMemoryUsage()` as it requires
// deduplicating all memory references.
size_t GetMorePreciseMemoryUsage(const CordRep* absl_nonnull 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* absl_nonnull rep);

}  // namespace cord_internal
ABSL_NAMESPACE_END
}  // namespace absl


#endif  // ABSL_STRINGS_CORD_ANALYSIS_H_
*‘f
~soong/.intermediates/external/abseil-cpp/absl_functional_any_invocable_hdrs/gen/my_include_dir/absl/functional/any_invocable.hŽe// 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: any_invocable.h
// -----------------------------------------------------------------------------
//
// This header file defines an `absl::AnyInvocable` type that assumes ownership
// and wraps an object of an invocable type. (Invocable types adhere to the
// concept specified in https://en.cppreference.com/w/cpp/concepts/invocable.)
//
// In general, prefer `absl::AnyInvocable` when you need a type-erased
// function parameter that needs to take ownership of the type.
//
// NOTE: `absl::AnyInvocable` is similar to the C++23 `std::move_only_function`
// abstraction, but has a slightly different API and is not designed to be a
// drop-in replacement or backfill of that type.
//
// Credits to Matt Calabrese (https://github.com/mattcalabrese) for the original
// implementation.

#ifndef ABSL_FUNCTIONAL_ANY_INVOCABLE_H_
#define ABSL_FUNCTIONAL_ANY_INVOCABLE_H_

#include <cstddef>
#include <functional>
#include <initializer_list>
#include <type_traits>
#include <utility>

#include "absl/base/config.h"
#include "absl/functional/internal/any_invocable.h"
#include "absl/meta/type_traits.h"
#include "absl/utility/utility.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

// absl::AnyInvocable
//
// `absl::AnyInvocable` is a functional wrapper type, like `std::function`, that
// assumes ownership of an invocable object. Unlike `std::function`, an
// `absl::AnyInvocable` is more type-safe and provides the following additional
// benefits:
//
// * Properly adheres to const correctness of the underlying type
// * Is move-only so avoids concurrency problems with copied invocables and
//   unnecessary copies in general.
// * Supports reference qualifiers allowing it to perform unique actions (noted
//   below).
//
// `absl::AnyInvocable` is a template, and an `absl::AnyInvocable` instantiation
// may wrap any invocable object with a compatible function signature, e.g.
// having arguments and return types convertible to types matching the
// `absl::AnyInvocable` signature, and also matching any stated reference
// qualifiers, as long as that type is moveable. It therefore provides broad
// type erasure for functional objects.
//
// An `absl::AnyInvocable` is typically used as a type-erased function parameter
// for accepting various functional objects:
//
// // Define a function taking an AnyInvocable parameter.
// void my_func(absl::AnyInvocable<int()> f) {
//   ...
// };
//
// // That function can accept any invocable type:
//
// // Accept a function reference. We don't need to move a reference.
// int func1() { return 0; };
// my_func(func1);
//
// // Accept a lambda. We use std::move here because otherwise my_func would
// // copy the lambda.
// auto lambda = []() { return 0; };
// my_func(std::move(lambda));
//
// // Accept a function pointer. We don't need to move a function pointer.
// func2 = &func1;
// my_func(func2);
//
// // Accept an std::function by moving it. Note that the lambda is copyable
// // (satisfying std::function requirements) and moveable (satisfying
// // absl::AnyInvocable requirements).
// std::function<int()> func6 = []() { return 0; };
// my_func(std::move(func6));
//
// `AnyInvocable` also properly respects `const` qualifiers, reference
// qualifiers, and the `noexcept` specification  as part of the user-specified
// function type (e.g. `AnyInvocable<void() const && noexcept>`). These
// qualifiers will be applied to the `AnyInvocable` object's `operator()`, and
// the underlying invocable must be compatible with those qualifiers.
//
// Comparison of const and non-const function types:
//
//   // Store a closure inside of `func` with the function type `int()`.
//   // Note that we have made `func` itself `const`.
//   const AnyInvocable<int()> func = [](){ return 0; };
//
//   func();  // Compile-error: the passed type `int()` isn't `const`.
//
//   // Store a closure inside of `const_func` with the function type
//   // `int() const`.
//   // Note that we have also made `const_func` itself `const`.
//   const AnyInvocable<int() const> const_func = [](){ return 0; };
//
//   const_func();  // Fine: `int() const` is `const`.
//
// In the above example, the call `func()` would have compiled if
// `std::function` were used even though the types are not const compatible.
// This is a bug, and using `absl::AnyInvocable` properly detects that bug.
//
// In addition to affecting the signature of `operator()`, the `const` and
// reference qualifiers of the function type also appropriately constrain which
// kinds of invocable objects you are allowed to place into the `AnyInvocable`
// instance. If you specify a function type that is const-qualified, then
// anything that you attempt to put into the `AnyInvocable` must be callable on
// a `const` instance of that type.
//
// Constraint example:
//
//   // Fine because the lambda is callable when `const`.
//   AnyInvocable<int() const> func = [=](){ return 0; };
//
//   // This is a compile-error because the lambda isn't callable when `const`.
//   AnyInvocable<int() const> error = [=]() mutable { return 0; };
//
// An `&&` qualifier can be used to express that an `absl::AnyInvocable`
// instance should be invoked at most once:
//
//   // Invokes `continuation` with the logical result of an operation when
//   // that operation completes (common in asynchronous code).
//   void CallOnCompletion(AnyInvocable<void(int)&&> continuation) {
//     int result_of_foo = foo();
//
//     // `std::move` is required because the `operator()` of `continuation` is
//     // rvalue-reference qualified.
//     std::move(continuation)(result_of_foo);
//   }
//
// Attempting to call `absl::AnyInvocable` multiple times in such a case
// results in undefined behavior.
//
// Invoking an empty `absl::AnyInvocable` results in undefined behavior:
//
//   // Create an empty instance using the default constructor.
//   AnyInvocable<void()> empty;
//   empty();  // WARNING: Undefined behavior!
template <class Sig>
class AnyInvocable : private internal_any_invocable::Impl<Sig> {
 private:
  static_assert(
      std::is_function<Sig>::value,
      "The template argument of AnyInvocable must be a function type.");

  using Impl = internal_any_invocable::Impl<Sig>;

 public:
  // The return type of Sig
  using result_type = typename Impl::result_type;

  // Constructors

  // Constructs the `AnyInvocable` in an empty state.
  // Invoking it results in undefined behavior.
  AnyInvocable() noexcept = default;
  AnyInvocable(std::nullptr_t) noexcept {}  // NOLINT

  // Constructs the `AnyInvocable` from an existing `AnyInvocable` by a move.
  // Note that `f` is not guaranteed to be empty after move-construction,
  // although it may be.
  AnyInvocable(AnyInvocable&& /*f*/) noexcept = default;

  // Constructs an `AnyInvocable` from an invocable object.
  //
  // Upon construction, `*this` is only empty if `f` is a function pointer or
  // member pointer type and is null, or if `f` is an `AnyInvocable` that is
  // empty.
  template <class F, typename = absl::enable_if_t<
                         internal_any_invocable::CanConvert<Sig, F>::value>>
  AnyInvocable(F&& f)  // NOLINT
      : Impl(internal_any_invocable::ConversionConstruct(),
             std::forward<F>(f)) {}

  // Constructs an `AnyInvocable` that holds an invocable object of type `T`,
  // which is constructed in-place from the given arguments.
  //
  // Example:
  //
  //   AnyInvocable<int(int)> func(
  //       absl::in_place_type<PossiblyImmovableType>, arg1, arg2);
  //
  template <class T, class... Args,
            typename = absl::enable_if_t<
                internal_any_invocable::CanEmplace<Sig, T, Args...>::value>>
  explicit AnyInvocable(absl::in_place_type_t<T>, Args&&... args)
      : Impl(absl::in_place_type<absl::decay_t<T>>,
             std::forward<Args>(args)...) {
    static_assert(std::is_same<T, absl::decay_t<T>>::value,
                  "The explicit template argument of in_place_type is required "
                  "to be an unqualified object type.");
  }

  // Overload of the above constructor to support list-initialization.
  template <class T, class U, class... Args,
            typename = absl::enable_if_t<internal_any_invocable::CanEmplace<
                Sig, T, std::initializer_list<U>&, Args...>::value>>
  explicit AnyInvocable(absl::in_place_type_t<T>,
                        std::initializer_list<U> ilist, Args&&... args)
      : Impl(absl::in_place_type<absl::decay_t<T>>, ilist,
             std::forward<Args>(args)...) {
    static_assert(std::is_same<T, absl::decay_t<T>>::value,
                  "The explicit template argument of in_place_type is required "
                  "to be an unqualified object type.");
  }

  // Assignment Operators

  // Assigns an `AnyInvocable` through move-assignment.
  // Note that `f` is not guaranteed to be empty after move-assignment
  // although it may be.
  AnyInvocable& operator=(AnyInvocable&& /*f*/) noexcept = default;

  // Assigns an `AnyInvocable` from a nullptr, clearing the `AnyInvocable`. If
  // not empty, destroys the target, putting `*this` into an empty state.
  AnyInvocable& operator=(std::nullptr_t) noexcept {
    this->Clear();
    return *this;
  }

  // Assigns an `AnyInvocable` from an existing `AnyInvocable` instance.
  //
  // Upon assignment, `*this` is only empty if `f` is a function pointer or
  // member pointer type and is null, or if `f` is an `AnyInvocable` that is
  // empty.
  template <class F, typename = absl::enable_if_t<
                         internal_any_invocable::CanAssign<Sig, F>::value>>
  AnyInvocable& operator=(F&& f) {
    *this = AnyInvocable(std::forward<F>(f));
    return *this;
  }

  // Assigns an `AnyInvocable` from a reference to an invocable object.
  // Upon assignment, stores a reference to the invocable object in the
  // `AnyInvocable` instance.
  template <
      class F,
      typename = absl::enable_if_t<
          internal_any_invocable::CanAssignReferenceWrapper<Sig, F>::value>>
  AnyInvocable& operator=(std::reference_wrapper<F> f) noexcept {
    *this = AnyInvocable(f);
    return *this;
  }

  // Destructor

  // If not empty, destroys the target.
  ~AnyInvocable() = default;

  // absl::AnyInvocable::swap()
  //
  // Exchanges the targets of `*this` and `other`.
  void swap(AnyInvocable& other) noexcept { std::swap(*this, other); }

  // absl::AnyInvocable::operator bool()
  //
  // Returns `true` if `*this` is not empty.
  //
  // WARNING: An `AnyInvocable` that wraps an empty `std::function` is not
  // itself empty. This behavior is consistent with the standard equivalent
  // `std::move_only_function`. In the following example, `a()` will actually
  // invoke `f()`, leading to an `std::bad_function_call` exception:
  //   std::function<void()> f;  // empty
  //   absl::AnyInvocable<void()> a = f;  // not empty
  //
  // Invoking an empty `AnyInvocable` results in undefined behavior.
  explicit operator bool() const noexcept { return this->HasValue(); }

  // Invokes the target object of `*this`. `*this` must not be empty.
  //
  // Note: The signature of this function call operator is the same as the
  //       template parameter `Sig`.
  using Impl::operator();

  // Equality operators

  // Returns `true` if `*this` is empty.
  friend bool operator==(const AnyInvocable& f, std::nullptr_t) noexcept {
    return !f.HasValue();
  }

  // Returns `true` if `*this` is empty.
  friend bool operator==(std::nullptr_t, const AnyInvocable& f) noexcept {
    return !f.HasValue();
  }

  // Returns `false` if `*this` is empty.
  friend bool operator!=(const AnyInvocable& f, std::nullptr_t) noexcept {
    return f.HasValue();
  }

  // Returns `false` if `*this` is empty.
  friend bool operator!=(std::nullptr_t, const AnyInvocable& f) noexcept {
    return f.HasValue();
  }

  // swap()
  //
  // Exchanges the targets of `f1` and `f2`.
  friend void swap(AnyInvocable& f1, AnyInvocable& f2) noexcept { f1.swap(f2); }

 private:
  // Friending other instantiations is necessary for conversions.
  template <bool /*SigIsNoexcept*/, class /*ReturnType*/, class... /*P*/>
  friend class internal_any_invocable::CoreImpl;
};

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_FUNCTIONAL_ANY_INVOCABLE_H_
*Ù-
|soong/.intermediates/external/abseil-cpp/absl_functional_function_ref_hdrs/gen/my_include_dir/absl/functional/function_ref.hØ,// Copyright 2019 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// File: function_ref.h
// -----------------------------------------------------------------------------
//
// This header file defines the `absl::FunctionRef` type for holding a
// non-owning reference to an object of any invocable type. This function
// reference is typically most useful as a type-erased argument type for
// accepting function types that neither take ownership nor copy the type; using
// the reference type in this case avoids a copy and an allocation. Best
// practices of other non-owning reference-like objects (such as
// `absl::string_view`) apply here.
//
//  An `absl::FunctionRef` is similar in usage to a `std::function` but has the
//  following differences:
//
//  * It doesn't own the underlying object.
//  * It doesn't have a null or empty state.
//  * It never performs deep copies or allocations.
//  * It's much faster and cheaper to construct.
//  * It's trivially copyable and destructable.
//
// Generally, `absl::FunctionRef` should not be used as a return value, data
// member, or to initialize a `std::function`. Such usages will often lead to
// problematic lifetime issues. Once you convert something to an
// `absl::FunctionRef` you cannot make a deep copy later.
//
// This class is suitable for use wherever a "const std::function<>&"
// would be used without making a copy. ForEach functions and other versions of
// the visitor pattern are a good example of when this class should be used.
//
// This class is trivial to copy and should be passed by value.
#ifndef ABSL_FUNCTIONAL_FUNCTION_REF_H_
#define ABSL_FUNCTIONAL_FUNCTION_REF_H_

#include <cassert>
#include <functional>
#include <type_traits>

#include "absl/base/attributes.h"
#include "absl/functional/internal/function_ref.h"
#include "absl/meta/type_traits.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

// FunctionRef
//
// Dummy class declaration to allow the partial specialization based on function
// types below.
template <typename T>
class FunctionRef;

// FunctionRef
//
// An `absl::FunctionRef` is a lightweight wrapper to any invocable object with
// a compatible signature. Generally, an `absl::FunctionRef` should only be used
// as an argument type and should be preferred as an argument over a const
// reference to a `std::function`. `absl::FunctionRef` itself does not allocate,
// although the wrapped invocable may.
//
// Example:
//
//   // The following function takes a function callback by const reference
//   bool Visitor(const std::function<void(my_proto&,
//                                         absl::string_view)>& callback);
//
//   // Assuming that the function is not stored or otherwise copied, it can be
//   // replaced by an `absl::FunctionRef`:
//   bool Visitor(absl::FunctionRef<void(my_proto&, absl::string_view)>
//                  callback);
template <typename R, typename... Args>
class FunctionRef<R(Args...)> {
 private:
  // Used to disable constructors for objects that are not compatible with the
  // signature of this FunctionRef.
  template <typename F, typename FR = std::invoke_result_t<F, Args&&...>>
  using EnableIfCompatible =
      typename std::enable_if<std::is_void<R>::value ||
                              std::is_convertible<FR, R>::value>::type;

 public:
  // Constructs a FunctionRef from any invocable type.
  template <typename F, typename = EnableIfCompatible<const F&>>
  // NOLINTNEXTLINE(runtime/explicit)
  FunctionRef(const F& f ABSL_ATTRIBUTE_LIFETIME_BOUND)
      : invoker_(&absl::functional_internal::InvokeObject<F, R, Args...>) {
    absl::functional_internal::AssertNonNull(f);
    ptr_.obj = &f;
  }

  // Overload for function pointers. This eliminates a level of indirection that
  // would happen if the above overload was used (it lets us store the pointer
  // instead of a pointer to a pointer).
  //
  // This overload is also used for references to functions, since references to
  // functions can decay to function pointers implicitly.
  template <
      typename F, typename = EnableIfCompatible<F*>,
      absl::functional_internal::EnableIf<absl::is_function<F>::value> = 0>
  FunctionRef(F* f)  // NOLINT(runtime/explicit)
      : invoker_(&absl::functional_internal::InvokeFunction<F*, R, Args...>) {
    assert(f != nullptr);
    ptr_.fun = reinterpret_cast<decltype(ptr_.fun)>(f);
  }

  FunctionRef& operator=(const FunctionRef& rhs) = default;
  FunctionRef(const FunctionRef& rhs) = default;

  // Call the underlying object.
  R operator()(Args... args) const {
    return invoker_(ptr_, std::forward<Args>(args)...);
  }

 private:
  absl::functional_internal::VoidPtr ptr_;
  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

#endif  // ABSL_FUNCTIONAL_FUNCTION_REF_H_
*ðN
‹soong/.intermediates/external/abseil-cpp/absl_strings_str_format_internal_hdrs/gen/my_include_dir/absl/strings/internal/str_format/parser.hßM// 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_STR_FORMAT_PARSER_H_
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_PARSER_H_

#include <stddef.h>
#include <stdlib.h>

#include <cassert>
#include <cstring>
#include <initializer_list>
#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
namespace str_format_internal {

std::string LengthModToString(LengthMod v);

const char* ConsumeUnboundConversionNoInline(const char* p, const char* end,
                                             UnboundConversion* conv,
                                             int* next_arg);

// Parse the format string provided in 'src' and pass the identified items into
// 'consumer'.
// Text runs will be passed by calling
//   Consumer::Append(string_view);
// ConversionItems will be passed by calling
//   Consumer::ConvertOne(UnboundConversion, string_view);
// In the case of ConvertOne, the string_view that is passed is the
// portion of the format string corresponding to the conversion, not including
// the leading %. On success, it returns true. On failure, it stops and returns
// false.
template <typename Consumer>
bool ParseFormatString(string_view src, Consumer consumer) {
  int next_arg = 0;
  const char* p = src.data();
  const char* const end = p + src.size();
  while (p != end) {
    const char* percent =
        static_cast<const char*>(memchr(p, '%', static_cast<size_t>(end - p)));
    if (!percent) {
      // We found the last substring.
      return consumer.Append(string_view(p, static_cast<size_t>(end - p)));
    }
    // We found a percent, so push the text run then process the percent.
    if (ABSL_PREDICT_FALSE(!consumer.Append(
            string_view(p, static_cast<size_t>(percent - p))))) {
      return false;
    }
    if (ABSL_PREDICT_FALSE(percent + 1 >= end)) return false;

    auto tag = GetTagForChar(percent[1]);
    if (tag.is_conv()) {
      if (ABSL_PREDICT_FALSE(next_arg < 0)) {
        // This indicates an error in the format string.
        // The only way to get `next_arg < 0` here is to have a positional
        // argument first which sets next_arg to -1 and then a non-positional
        // argument.
        return false;
      }
      p = percent + 2;

      // Keep this case separate from the one below.
      // ConvertOne is more efficient when the compiler can see that the `basic`
      // flag is set.
      UnboundConversion conv;
      conv.conv = tag.as_conv();
      conv.arg_position = ++next_arg;
      if (ABSL_PREDICT_FALSE(
              !consumer.ConvertOne(conv, string_view(percent + 1, 1)))) {
        return false;
      }
    } else if (percent[1] != '%') {
      UnboundConversion conv;
      p = ConsumeUnboundConversionNoInline(percent + 1, end, &conv, &next_arg);
      if (ABSL_PREDICT_FALSE(p == nullptr)) return false;
      if (ABSL_PREDICT_FALSE(!consumer.ConvertOne(
              conv, string_view(percent + 1,
                                static_cast<size_t>(p - (percent + 1)))))) {
        return false;
      }
    } else {
      if (ABSL_PREDICT_FALSE(!consumer.Append("%"))) return false;
      p = percent + 2;
      continue;
    }
  }
  return true;
}

// Always returns true, or fails to compile in a constexpr context if s does not
// point to a constexpr char array.
constexpr bool EnsureConstexpr(string_view s) {
  return s.empty() || s[0] == s[0];
}

class ParsedFormatBase {
 public:
  explicit ParsedFormatBase(
      string_view format, bool allow_ignored,
      std::initializer_list<FormatConversionCharSet> convs);

  ParsedFormatBase(const ParsedFormatBase& other) { *this = other; }

  ParsedFormatBase(ParsedFormatBase&& other) { *this = std::move(other); }

  ParsedFormatBase& operator=(const ParsedFormatBase& other) {
    if (this == &other) return *this;
    has_error_ = other.has_error_;
    items_ = other.items_;
    size_t text_size = items_.empty() ? 0 : items_.back().text_end;
    data_ = std::make_unique<char[]>(text_size);
    if (text_size > 0) {
      memcpy(data_.get(), other.data_.get(), text_size);
    }
    return *this;
  }

  ParsedFormatBase& operator=(ParsedFormatBase&& other) {
    if (this == &other) return *this;
    has_error_ = other.has_error_;
    data_ = std::move(other.data_);
    items_ = std::move(other.items_);
    // Reset the vector to make sure the invariants hold.
    other.items_.clear();
    return *this;
  }

  template <typename Consumer>
  bool ProcessFormat(Consumer consumer) const {
    const char* const base = data_.get();
    string_view text(base, 0);
    for (const auto& item : items_) {
      const char* const end = text.data() + text.size();
      text =
          string_view(end, static_cast<size_t>((base + item.text_end) - end));
      if (item.is_conversion) {
        if (!consumer.ConvertOne(item.conv, text)) return false;
      } else {
        if (!consumer.Append(text)) return false;
      }
    }
    return !has_error_;
  }

  bool has_error() const { return has_error_; }

 private:
  // Returns whether the conversions match and if !allow_ignored it verifies
  // that all conversions are used by the format.
  bool MatchesConversions(
      bool allow_ignored,
      std::initializer_list<FormatConversionCharSet> convs) const;

  struct ParsedFormatConsumer;

  struct ConversionItem {
    bool is_conversion;
    // Points to the past-the-end location of this element in the data_ array.
    size_t text_end;
    UnboundConversion conv;
  };

  bool has_error_;
  std::unique_ptr<char[]> data_;
  std::vector<ConversionItem> items_;
};


// A value type representing a preparsed format.  These can be created, copied
// around, and reused to speed up formatting loops.
// The user must specify through the template arguments the conversion
// characters used in the format. This will be checked at compile time.
//
// This class uses Conv enum values to specify each argument.
// This allows for more flexibility as you can specify multiple possible
// conversion characters for each argument.
// ParsedFormat<char...> is a simplified alias for when the user only
// needs to specify a single conversion character for each argument.
//
// Example:
//   // Extended format supports multiple characters per argument:
//   using MyFormat = ExtendedParsedFormat<Conv::d | Conv::x>;
//   MyFormat GetFormat(bool use_hex) {
//     if (use_hex) return MyFormat("foo %x bar");
//     return MyFormat("foo %d bar");
//   }
//   // 'format' can be used with any value that supports 'd' and 'x',
//   // like `int`.
//   auto format = GetFormat(use_hex);
//   value = StringF(format, i);
//
// This class also supports runtime format checking with the ::New() and
// ::NewAllowIgnored() factory functions.
// This is the only API that allows the user to pass a runtime specified format
// string. These factory functions will return NULL if the format does not match
// the conversions requested by the user.
template <FormatConversionCharSet... C>
class ExtendedParsedFormat : public str_format_internal::ParsedFormatBase {
 public:
  explicit ExtendedParsedFormat(string_view format)
#ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
      __attribute__((
          enable_if(str_format_internal::EnsureConstexpr(format),
                    "Format string is not constexpr."),
          enable_if(str_format_internal::ValidFormatImpl<C...>(format),
                    "Format specified does not match the template arguments.")))
#endif  // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
      : ExtendedParsedFormat(format, false) {
  }

  // ExtendedParsedFormat factory function.
  // The user still has to specify the conversion characters, but they will not
  // be checked at compile time. Instead, it will be checked at runtime.
  // This delays the checking to runtime, but allows the user to pass
  // dynamically sourced formats.
  // It returns NULL if the format does not match the conversion characters.
  // The user is responsible for checking the return value before using it.
  //
  // The 'New' variant will check that all the specified arguments are being
  // consumed by the format and return NULL if any argument is being ignored.
  // The 'NewAllowIgnored' variant will not verify this and will allow formats
  // that ignore arguments.
  static std::unique_ptr<ExtendedParsedFormat> New(string_view format) {
    return New(format, false);
  }
  static std::unique_ptr<ExtendedParsedFormat> NewAllowIgnored(
      string_view format) {
    return New(format, true);
  }

 private:
  static std::unique_ptr<ExtendedParsedFormat> New(string_view format,
                                                   bool allow_ignored) {
    std::unique_ptr<ExtendedParsedFormat> conv(
        new ExtendedParsedFormat(format, allow_ignored));
    if (conv->has_error()) return nullptr;
    return conv;
  }

  ExtendedParsedFormat(string_view s, bool allow_ignored)
      : ParsedFormatBase(s, allow_ignored, {C...}) {}
};
}  // namespace str_format_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_STR_FORMAT_PARSER_H_
*Ú
nsoong/.intermediates/external/abseil-cpp/absl_base_core_headers_hdrs/gen/my_include_dir/absl/base/const_init.hç// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// kConstInit
// -----------------------------------------------------------------------------
//
// A constructor tag used to mark an object as safe for use as a global
// variable, avoiding the usual lifetime issues that can affect globals.

#ifndef ABSL_BASE_CONST_INIT_H_
#define ABSL_BASE_CONST_INIT_H_

#include "absl/base/config.h"

// In general, objects with static storage duration (such as global variables)
// can trigger tricky object lifetime situations.  Attempting to access them
// from the constructors or destructors of other global objects can result in
// undefined behavior, unless their constructors and destructors are designed
// with this issue in mind.
//
// The normal way to deal with this issue in C++11 is to use constant
// initialization and trivial destructors.
//
// Constant initialization is guaranteed to occur before any other code
// executes.  Constructors that are declared 'constexpr' are eligible for
// constant initialization.  You can annotate a variable declaration with the
// ABSL_CONST_INIT macro to express this intent.  For compilers that support
// it, this annotation will cause a compilation error for declarations that
// aren't subject to constant initialization (perhaps because a runtime value
// was passed as a constructor argument).
//
// On program shutdown, lifetime issues can be avoided on global objects by
// ensuring that they contain  trivial destructors.  A class has a trivial
// destructor unless it has a user-defined destructor, a virtual method or base
// class, or a data member or base class with a non-trivial destructor of its
// own.  Objects with static storage duration and a trivial destructor are not
// cleaned up on program shutdown, and are thus safe to access from other code
// running during shutdown.
//
// For a few core Abseil classes, we make a best effort to allow for safe global
// instances, even though these classes have non-trivial destructors.  These
// objects can be created with the absl::kConstInit tag.  For example:
//   ABSL_CONST_INIT absl::Mutex global_mutex(absl::kConstInit);
//
// The line above declares a global variable of type absl::Mutex which can be
// accessed at any point during startup or shutdown.  global_mutex's destructor
// will still run, but will not invalidate the object.  Note that C++ specifies
// that accessing an object after its destructor has run results in undefined
// behavior, but this pattern works on the toolchains we support.
//
// The absl::kConstInit tag should only be used to define objects with static
// or thread_local storage duration.

namespace absl {
ABSL_NAMESPACE_BEGIN

enum ConstInitType {
  kConstInit,
};

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_BASE_CONST_INIT_H_
*®k
•soong/.intermediates/external/abseil-cpp/absl_strings_str_format_internal_hdrs/gen/my_include_dir/absl/strings/internal/str_format/constexpr_parser.h“j// 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.

#ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_CONSTEXPR_PARSER_H_
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_CONSTEXPR_PARSER_H_

#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 {

// The analyzed properties of a single specified conversion.
struct UnboundConversion {
  // This is a user defined default constructor on purpose to skip the
  // initialization of parts of the object that are not necessary.
  UnboundConversion() {}  // NOLINT

  // This constructor is provided for the static checker. We don't want to do
  // the unnecessary initialization in the normal case.
  explicit constexpr UnboundConversion(absl::ConstInitType)
      : arg_position{}, width{}, precision{} {}

  class InputValue {
   public:
    constexpr void set_value(int value) {
      assert(value >= 0);
      value_ = value;
    }
    constexpr int value() const { return value_; }

    // Marks the value as "from arg". aka the '*' format.
    // Requires `value >= 1`.
    // When set, is_from_arg() return true and get_from_arg() returns the
    // original value.
    // `value()`'s return value is unspecified in this state.
    constexpr void set_from_arg(int value) {
      assert(value > 0);
      value_ = -value - 1;
    }
    constexpr bool is_from_arg() const { return value_ < -1; }
    constexpr int get_from_arg() const {
      assert(is_from_arg());
      return -value_ - 1;
    }

   private:
    int value_ = -1;
  };

  // No need to initialize. It will always be set in the parser.
  int arg_position;

  InputValue width;
  InputValue precision;

  Flags flags = Flags::kBasic;
  LengthMod length_mod = LengthMod::none;
  FormatConversionChar conv = FormatConversionCharInternal::kNone;
};

// Helper tag class for the table below.
// It allows fast `char -> ConversionChar/LengthMod/Flags` checking and
// conversions.
class ConvTag {
 public:
  constexpr ConvTag(FormatConversionChar conversion_char)  // NOLINT
      : tag_(static_cast<uint8_t>(conversion_char)) {}
  constexpr ConvTag(LengthMod length_mod)  // NOLINT
      : tag_(0x80 | static_cast<uint8_t>(length_mod)) {}
  constexpr ConvTag(Flags flags)  // NOLINT
      : tag_(0xc0 | static_cast<uint8_t>(flags)) {}
  constexpr ConvTag() : tag_(0xFF) {}

  constexpr bool is_conv() const { return (tag_ & 0x80) == 0; }
  constexpr bool is_length() const { return (tag_ & 0xC0) == 0x80; }
  constexpr bool is_flags() const { return (tag_ & 0xE0) == 0xC0; }

  constexpr FormatConversionChar as_conv() const {
    assert(is_conv());
    assert(!is_length());
    assert(!is_flags());
    return static_cast<FormatConversionChar>(tag_);
  }
  constexpr LengthMod as_length() const {
    assert(!is_conv());
    assert(is_length());
    assert(!is_flags());
    return static_cast<LengthMod>(tag_ & 0x3F);
  }
  constexpr Flags as_flags() const {
    assert(!is_conv());
    assert(!is_length());
    assert(is_flags());
    return static_cast<Flags>(tag_ & 0x1F);
  }

 private:
  uint8_t tag_;
};

struct ConvTagHolder {
  using CC = FormatConversionCharInternal;
  using LM = LengthMod;

  // Abbreviations to fit in the table below.
  static constexpr auto kFSign = Flags::kSignCol;
  static constexpr auto kFAlt = Flags::kAlt;
  static constexpr auto kFPos = Flags::kShowPos;
  static constexpr auto kFLeft = Flags::kLeft;
  static constexpr auto kFZero = Flags::kZero;

  static constexpr ConvTag value[256] = {
      {},     {},    {},    {},    {},    {},     {},    {},     // 00-07
      {},     {},    {},    {},    {},    {},     {},    {},     // 08-0f
      {},     {},    {},    {},    {},    {},     {},    {},     // 10-17
      {},     {},    {},    {},    {},    {},     {},    {},     // 18-1f
      kFSign, {},    {},    kFAlt, {},    {},     {},    {},     //  !"#$%&'
      {},     {},    {},    kFPos, {},    kFLeft, {},    {},     // ()*+,-./
      kFZero, {},    {},    {},    {},    {},     {},    {},     // 01234567
      {},     {},    {},    {},    {},    {},     {},    {},     // 89:;<=>?
      {},     CC::A, {},    {},    {},    CC::E,  CC::F, CC::G,  // @ABCDEFG
      {},     {},    {},    {},    LM::L, {},     {},    {},     // HIJKLMNO
      {},     {},    {},    {},    {},    {},     {},    {},     // PQRSTUVW
      CC::X,  {},    {},    {},    {},    {},     {},    {},     // XYZ[\]^_
      {},     CC::a, {},    CC::c, CC::d, CC::e,  CC::f, CC::g,  // `abcdefg
      LM::h,  CC::i, LM::j, {},    LM::l, {},     CC::n, CC::o,  // hijklmno
      CC::p,  LM::q, {},    CC::s, LM::t, CC::u,  CC::v, {},     // pqrstuvw
      CC::x,  {},    LM::z, {},    {},    {},     {},    {},     // xyz{|}!
      {},     {},    {},    {},    {},    {},     {},    {},     // 80-87
      {},     {},    {},    {},    {},    {},     {},    {},     // 88-8f
      {},     {},    {},    {},    {},    {},     {},    {},     // 90-97
      {},     {},    {},    {},    {},    {},     {},    {},     // 98-9f
      {},     {},    {},    {},    {},    {},     {},    {},     // a0-a7
      {},     {},    {},    {},    {},    {},     {},    {},     // a8-af
      {},     {},    {},    {},    {},    {},     {},    {},     // b0-b7
      {},     {},    {},    {},    {},    {},     {},    {},     // b8-bf
      {},     {},    {},    {},    {},    {},     {},    {},     // c0-c7
      {},     {},    {},    {},    {},    {},     {},    {},     // c8-cf
      {},     {},    {},    {},    {},    {},     {},    {},     // d0-d7
      {},     {},    {},    {},    {},    {},     {},    {},     // d8-df
      {},     {},    {},    {},    {},    {},     {},    {},     // e0-e7
      {},     {},    {},    {},    {},    {},     {},    {},     // e8-ef
      {},     {},    {},    {},    {},    {},     {},    {},     // f0-f7
      {},     {},    {},    {},    {},    {},     {},    {},     // f8-ff
  };
};

// Keep a single table for all the conversion chars and length modifiers.
constexpr ConvTag GetTagForChar(char c) {
  return ConvTagHolder::value[static_cast<unsigned char>(c)];
}

constexpr bool CheckFastPathSetting(const UnboundConversion& conv) {
  bool width_precision_needed =
      conv.width.value() >= 0 || conv.precision.value() >= 0;
  if (width_precision_needed && conv.flags == Flags::kBasic) {
#if defined(__clang__)
    // Some compilers complain about this in constexpr even when not executed,
    // so only enable the error dump in clang.
    fprintf(stderr,
            "basic=%d left=%d show_pos=%d sign_col=%d alt=%d zero=%d "
            "width=%d precision=%d\n",
            conv.flags == Flags::kBasic ? 1 : 0,
            FlagsContains(conv.flags, Flags::kLeft) ? 1 : 0,
            FlagsContains(conv.flags, Flags::kShowPos) ? 1 : 0,
            FlagsContains(conv.flags, Flags::kSignCol) ? 1 : 0,
            FlagsContains(conv.flags, Flags::kAlt) ? 1 : 0,
            FlagsContains(conv.flags, Flags::kZero) ? 1 : 0, conv.width.value(),
            conv.precision.value());
#endif  // defined(__clang__)
    return false;
  }
  return true;
}

constexpr int ParseDigits(char& c, const char*& pos, const char* const end) {
  int digits = c - '0';
  // We do not want to overflow `digits` so we consume at most digits10
  // digits. If there are more digits the parsing will fail later on when the
  // digit doesn't match the expected characters.
  int num_digits = std::numeric_limits<int>::digits10;
  for (;;) {
    if (ABSL_PREDICT_FALSE(pos == end)) break;
    c = *pos++;
    if ('0' > c || c > '9') break;
    --num_digits;
    if (ABSL_PREDICT_FALSE(!num_digits)) break;
    digits = 10 * digits + c - '0';
  }
  return digits;
}

template <bool is_positional>
constexpr const char* ConsumeConversion(const char* pos, const char* const end,
                                        UnboundConversion* conv,
                                        int* next_arg) {
  const char* const original_pos = pos;
  char c = 0;
  // Read the next char into `c` and update `pos`. Returns false if there are
  // no more chars to read.
#define ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR()          \
  do {                                                  \
    if (ABSL_PREDICT_FALSE(pos == end)) return nullptr; \
    c = *pos++;                                         \
  } while (0)

  if (is_positional) {
    ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();
    if (ABSL_PREDICT_FALSE(c < '1' || c > '9')) return nullptr;
    conv->arg_position = ParseDigits(c, pos, end);
    assert(conv->arg_position > 0);
    if (ABSL_PREDICT_FALSE(c != '$')) return nullptr;
  }

  ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();

  // We should start with the basic flag on.
  assert(conv->flags == Flags::kBasic);

  // Any non alpha character makes this conversion not basic.
  // This includes flags (-+ #0), width (1-9, *) or precision (.).
  // All conversion characters and length modifiers are alpha characters.
  if (c < 'A') {
    while (c <= '0') {
      auto tag = GetTagForChar(c);
      if (tag.is_flags()) {
        conv->flags = conv->flags | tag.as_flags();
        ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();
      } else {
        break;
      }
    }

    if (c <= '9') {
      if (c >= '0') {
        int maybe_width = ParseDigits(c, pos, end);
        if (!is_positional && c == '$') {
          if (ABSL_PREDICT_FALSE(*next_arg != 0)) return nullptr;
          // Positional conversion.
          *next_arg = -1;
          return ConsumeConversion<true>(original_pos, end, conv, next_arg);
        }
        conv->flags = conv->flags | Flags::kNonBasic;
        conv->width.set_value(maybe_width);
      } else if (c == '*') {
        conv->flags = conv->flags | Flags::kNonBasic;
        ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();
        if (is_positional) {
          if (ABSL_PREDICT_FALSE(c < '1' || c > '9')) return nullptr;
          conv->width.set_from_arg(ParseDigits(c, pos, end));
          if (ABSL_PREDICT_FALSE(c != '$')) return nullptr;
          ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();
        } else {
          conv->width.set_from_arg(++*next_arg);
        }
      }
    }

    if (c == '.') {
      conv->flags = conv->flags | Flags::kNonBasic;
      ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();
      if ('0' <= c && c <= '9') {
        conv->precision.set_value(ParseDigits(c, pos, end));
      } else if (c == '*') {
        ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();
        if (is_positional) {
          if (ABSL_PREDICT_FALSE(c < '1' || c > '9')) return nullptr;
          conv->precision.set_from_arg(ParseDigits(c, pos, end));
          if (c != '$') return nullptr;
          ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();
        } else {
          conv->precision.set_from_arg(++*next_arg);
        }
      } else {
        conv->precision.set_value(0);
      }
    }
  }

  auto tag = GetTagForChar(c);

  if (ABSL_PREDICT_FALSE(c == 'v' && conv->flags != Flags::kBasic)) {
    return nullptr;
  }

  if (ABSL_PREDICT_FALSE(!tag.is_conv())) {
    if (ABSL_PREDICT_FALSE(!tag.is_length())) return nullptr;

    // It is a length modifier.
    LengthMod length_mod = tag.as_length();
    ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();
    if (c == 'h' && length_mod == LengthMod::h) {
      conv->length_mod = LengthMod::hh;
      ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();
    } else if (c == 'l' && length_mod == LengthMod::l) {
      conv->length_mod = LengthMod::ll;
      ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();
    } else {
      conv->length_mod = length_mod;
    }
    tag = GetTagForChar(c);

    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

  assert(CheckFastPathSetting(*conv));
  (void)(&CheckFastPathSetting);

  conv->conv = tag.as_conv();
  if (!is_positional) conv->arg_position = ++*next_arg;
  return pos;
}

// Consume conversion spec prefix (not including '%') of [p, end) if valid.
// Examples of valid specs would be e.g.: "s", "d", "-12.6f".
// If valid, it returns the first character following the conversion spec,
// and the spec part is broken down and returned in 'conv'.
// If invalid, returns nullptr.
constexpr const char* ConsumeUnboundConversion(const char* p, const char* end,
                                               UnboundConversion* conv,
                                               int* next_arg) {
  if (*next_arg < 0) return ConsumeConversion<true>(p, end, conv, next_arg);
  return ConsumeConversion<false>(p, end, conv, next_arg);
}

}  // namespace str_format_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_STR_FORMAT_CONSTEXPR_PARSER_H_
*¢Y
asoong/.intermediates/external/abseil-cpp/absl_memory_hdrs/gen/my_include_dir/absl/memory/memory.h¼X// 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.
//
// -----------------------------------------------------------------------------
// File: memory.h
// -----------------------------------------------------------------------------
//
// This header file contains utility functions for managing the creation and
// conversion of smart pointers. This file is an extension to the C++
// standard <memory> library header file.

#ifndef ABSL_MEMORY_MEMORY_H_
#define ABSL_MEMORY_MEMORY_H_

#include <cstddef>
#include <limits>
#include <memory>
#include <new>
#include <type_traits>
#include <utility>

#include "absl/base/macros.h"
#include "absl/meta/type_traits.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

// -----------------------------------------------------------------------------
// Function Template: WrapUnique()
// -----------------------------------------------------------------------------
//
// Adopts ownership from a raw pointer and transfers it to the returned
// `std::unique_ptr`, whose type is deduced. Because of this deduction, *do not*
// specify the template type `T` when calling `WrapUnique`.
//
// Example:
//   X* NewX(int, int);
//   auto x = WrapUnique(NewX(1, 2));  // 'x' is std::unique_ptr<X>.
//
// Do not call WrapUnique with an explicit type, as in
// `WrapUnique<X>(NewX(1, 2))`.  The purpose of WrapUnique is to automatically
// deduce the pointer type. If you wish to make the type explicit, just use
// `std::unique_ptr` directly.
//
//   auto x = std::unique_ptr<X>(NewX(1, 2));
//                  - or -
//   std::unique_ptr<X> x(NewX(1, 2));
//
// While `absl::WrapUnique` is useful for capturing the output of a raw
// pointer factory, prefer 'absl::make_unique<T>(args...)' over
// 'absl::WrapUnique(new T(args...))'.
//
//   auto x = WrapUnique(new X(1, 2));  // works, but nonideal.
//   auto x = make_unique<X>(1, 2);     // safer, standard, avoids raw 'new'.
//
// Note that `absl::WrapUnique(p)` is valid only if `delete p` is a valid
// expression. In particular, `absl::WrapUnique()` cannot wrap pointers to
// arrays, functions or void, and it must not be used to capture pointers
// obtained from array-new expressions (even though that would compile!).
template <typename T>
std::unique_ptr<T> WrapUnique(T* ptr) {
  static_assert(!std::is_array<T>::value, "array types are unsupported");
  static_assert(std::is_object<T>::value, "non-object types are unsupported");
  return std::unique_ptr<T>(ptr);
}

// -----------------------------------------------------------------------------
// Function Template: make_unique<T>()
// -----------------------------------------------------------------------------
//
// Creates a `std::unique_ptr<>`, while avoiding issues creating temporaries
// during the construction process. `absl::make_unique<>` also avoids redundant
// type declarations, by avoiding the need to explicitly use the `new` operator.
//
// https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique
//
// For more background on why `std::unique_ptr<T>(new T(a,b))` is problematic,
// see Herb Sutter's explanation on
// (Exception-Safe Function Calls)[https://herbsutter.com/gotw/_102/].
// (In general, reviewers should treat `new T(a,b)` with scrutiny.)
//
// Historical note: Abseil once provided a C++11 compatible implementation of
// the C++14's `std::make_unique`. Now that C++11 support has been sunsetted,
// `absl::make_unique` simply uses the STL-provided implementation. New code
// should use `std::make_unique`.
using std::make_unique;

// -----------------------------------------------------------------------------
// Function Template: RawPtr()
// -----------------------------------------------------------------------------
//
// Extracts the raw pointer from a pointer-like value `ptr`. `absl::RawPtr` is
// useful within templates that need to handle a complement of raw pointers,
// `std::nullptr_t`, and smart pointers.
template <typename T>
auto RawPtr(T&& ptr) -> decltype(std::addressof(*ptr)) {
  // ptr is a forwarding reference to support Ts with non-const operators.
  return (ptr != nullptr) ? std::addressof(*ptr) : nullptr;
}
inline std::nullptr_t RawPtr(std::nullptr_t) { return nullptr; }

// -----------------------------------------------------------------------------
// Function Template: ShareUniquePtr()
// -----------------------------------------------------------------------------
//
// Adopts a `std::unique_ptr` rvalue and returns a `std::shared_ptr` of deduced
// type. Ownership (if any) of the held value is transferred to the returned
// shared pointer.
//
// Example:
//
//     auto up = absl::make_unique<int>(10);
//     auto sp = absl::ShareUniquePtr(std::move(up));  // shared_ptr<int>
//     CHECK_EQ(*sp, 10);
//     CHECK(up == nullptr);
//
// Note that this conversion is correct even when T is an array type, and more
// generally it works for *any* deleter of the `unique_ptr` (single-object
// deleter, array deleter, or any custom deleter), since the deleter is adopted
// by the shared pointer as well. The deleter is copied (unless it is a
// reference).
//
// Implements the resolution of [LWG 2415](http://wg21.link/lwg2415), by which a
// null shared pointer does not attempt to call the deleter.
template <typename T, typename D>
std::shared_ptr<T> ShareUniquePtr(std::unique_ptr<T, D>&& ptr) {
  return ptr ? std::shared_ptr<T>(std::move(ptr)) : std::shared_ptr<T>();
}

// -----------------------------------------------------------------------------
// Function Template: WeakenPtr()
// -----------------------------------------------------------------------------
//
// Creates a weak pointer associated with a given shared pointer. The returned
// value is a `std::weak_ptr` of deduced type.
//
// Example:
//
//    auto sp = std::make_shared<int>(10);
//    auto wp = absl::WeakenPtr(sp);
//    CHECK_EQ(sp.get(), wp.lock().get());
//    sp.reset();
//    CHECK(wp.lock() == nullptr);
//
template <typename T>
std::weak_ptr<T> WeakenPtr(const std::shared_ptr<T>& ptr) {
  return std::weak_ptr<T>(ptr);
}

// -----------------------------------------------------------------------------
// Class Template: pointer_traits
// -----------------------------------------------------------------------------
//
// Historical note: Abseil once provided an implementation of
// `std::pointer_traits` for platforms that had not yet provided it. Those
// platforms are no longer supported. New code should simply use
// `std::pointer_traits`.
using std::pointer_traits;

// -----------------------------------------------------------------------------
// Class Template: allocator_traits
// -----------------------------------------------------------------------------
//
// Historical note: Abseil once provided an implementation of
// `std::allocator_traits` for platforms that had not yet provided it. Those
// platforms are no longer supported. New code should simply use
// `std::allocator_traits`.
using std::allocator_traits;

namespace memory_internal {

// ExtractOr<E, O, D>::type evaluates to E<O> if possible. Otherwise, D.
template <template <typename> class Extract, typename Obj, typename Default,
          typename>
struct ExtractOr {
  using type = Default;
};

template <template <typename> class Extract, typename Obj, typename Default>
struct ExtractOr<Extract, Obj, Default, void_t<Extract<Obj>>> {
  using type = Extract<Obj>;
};

template <template <typename> class Extract, typename Obj, typename Default>
using ExtractOrT = typename ExtractOr<Extract, Obj, Default, void>::type;

// This template alias transforms Alloc::is_nothrow into a metafunction with
// Alloc as a parameter so it can be used with ExtractOrT<>.
template <typename Alloc>
using GetIsNothrow = typename Alloc::is_nothrow;

}  // namespace memory_internal

// ABSL_ALLOCATOR_NOTHROW is a build time configuration macro for user to
// specify whether the default allocation function can throw or never throws.
// If the allocation function never throws, user should define it to a non-zero
// value (e.g. via `-DABSL_ALLOCATOR_NOTHROW`).
// If the allocation function can throw, user should leave it undefined or
// define it to zero.
//
// allocator_is_nothrow<Alloc> is a traits class that derives from
// Alloc::is_nothrow if present, otherwise std::false_type. It's specialized
// for Alloc = std::allocator<T> for any type T according to the state of
// ABSL_ALLOCATOR_NOTHROW.
//
// default_allocator_is_nothrow is a class that derives from std::true_type
// when the default allocator (global operator new) never throws, and
// std::false_type when it can throw. It is a convenience shorthand for writing
// allocator_is_nothrow<std::allocator<T>> (T can be any type).
// NOTE: allocator_is_nothrow<std::allocator<T>> is guaranteed to derive from
// the same type for all T, because users should specialize neither
// allocator_is_nothrow nor std::allocator.
template <typename Alloc>
struct allocator_is_nothrow
    : memory_internal::ExtractOrT<memory_internal::GetIsNothrow, Alloc,
                                  std::false_type> {};

#if defined(ABSL_ALLOCATOR_NOTHROW) && ABSL_ALLOCATOR_NOTHROW
template <typename T>
struct allocator_is_nothrow<std::allocator<T>> : std::true_type {};
struct default_allocator_is_nothrow : std::true_type {};
#else
struct default_allocator_is_nothrow : std::false_type {};
#endif

namespace memory_internal {
template <typename Allocator, typename Iterator, typename... Args>
void ConstructRange(Allocator& alloc, Iterator first, Iterator last,
                    const Args&... args) {
  for (Iterator cur = first; cur != last; ++cur) {
    ABSL_INTERNAL_TRY {
      std::allocator_traits<Allocator>::construct(alloc, std::addressof(*cur),
                                                  args...);
    }
    ABSL_INTERNAL_CATCH_ANY {
      while (cur != first) {
        --cur;
        std::allocator_traits<Allocator>::destroy(alloc, std::addressof(*cur));
      }
      ABSL_INTERNAL_RETHROW;
    }
  }
}

template <typename Allocator, typename Iterator, typename InputIterator>
void CopyRange(Allocator& alloc, Iterator destination, InputIterator first,
               InputIterator last) {
  for (Iterator cur = destination; first != last;
       static_cast<void>(++cur), static_cast<void>(++first)) {
    ABSL_INTERNAL_TRY {
      std::allocator_traits<Allocator>::construct(alloc, std::addressof(*cur),
                                                  *first);
    }
    ABSL_INTERNAL_CATCH_ANY {
      while (cur != destination) {
        --cur;
        std::allocator_traits<Allocator>::destroy(alloc, std::addressof(*cur));
      }
      ABSL_INTERNAL_RETHROW;
    }
  }
}
}  // namespace memory_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_MEMORY_MEMORY_H_
*×P
‹soong/.intermediates/external/abseil-cpp/absl_container_compressed_tuple_hdrs/gen/my_include_dir/absl/container/internal/compressed_tuple.hÆO// 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.
//
// Helper class to perform the Empty Base Optimization.
// Ts can contain classes and non-classes, empty or not. For the ones that
// are empty classes, we perform the optimization. If all types in Ts are empty
// classes, then CompressedTuple<Ts...> is itself an empty class.
//
// To access the members, use member get<N>() function.
//
// Eg:
//   absl::container_internal::CompressedTuple<int, T1, T2, T3> value(7, t1, t2,
//                                                                    t3);
//   assert(value.get<0>() == 7);
//   T1& t1 = value.get<1>();
//   const T2& t2 = value.get<2>();
//   ...
//
// https://en.cppreference.com/w/cpp/language/ebo

#ifndef ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_
#define ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_

#include <initializer_list>
#include <tuple>
#include <type_traits>
#include <utility>

#include "absl/utility/utility.h"

#if defined(_MSC_VER) && !defined(__NVCC__)
// We need to mark these classes with this declspec to ensure that
// CompressedTuple happens.
#define ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC __declspec(empty_bases)
#else
#define ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC
#endif

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace container_internal {

template <typename... Ts>
class CompressedTuple;

namespace internal_compressed_tuple {

template <typename D, size_t I>
struct Elem;
template <typename... B, size_t I>
struct Elem<CompressedTuple<B...>, I>
    : std::tuple_element<I, std::tuple<B...>> {};
template <typename D, size_t I>
using ElemT = typename Elem<D, I>::type;

// We can't use EBCO on other CompressedTuples because that would mean that we
// derive from multiple Storage<> instantiations with the same I parameter,
// and potentially from multiple identical Storage<> instantiations.  So anytime
// we use type inheritance rather than encapsulation, we mark
// CompressedTupleImpl, to make this easy to detect.
struct uses_inheritance {};

template <typename T>
constexpr bool ShouldUseBase() {
  return std::is_class<T>::value && std::is_empty<T>::value &&
         !std::is_final<T>::value &&
         !std::is_base_of<uses_inheritance, T>::value;
}

// The storage class provides two specializations:
//  - For empty classes, it stores T as a base class.
//  - For everything else, it stores T as a member.
template <typename T, size_t I, bool UseBase = ShouldUseBase<T>()>
struct Storage {
  T value;
  constexpr Storage() = default;
  template <typename V>
  explicit constexpr Storage(absl::in_place_t, V&& v)
      : value(std::forward<V>(v)) {}
  constexpr const T& get() const& { return value; }
  constexpr T& get() & { return value; }
  constexpr const T&& get() const&& { return std::move(*this).value; }
  constexpr T&& get() && { return std::move(*this).value; }
};

template <typename T, size_t I>
struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC Storage<T, I, true> : T {
  constexpr Storage() = default;

  template <typename V>
  explicit constexpr Storage(absl::in_place_t, V&& v) : T(std::forward<V>(v)) {}

  constexpr const T& get() const& { return *this; }
  constexpr T& get() & { return *this; }
  constexpr const T&& get() const&& { return std::move(*this); }
  constexpr T&& get() && { return std::move(*this); }
};

template <typename D, typename I, bool ShouldAnyUseBase>
struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTupleImpl;

template <typename... Ts, size_t... I, bool ShouldAnyUseBase>
struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTupleImpl<
    CompressedTuple<Ts...>, absl::index_sequence<I...>, ShouldAnyUseBase>
    // We use the dummy identity function through std::integral_constant to
    // convince MSVC of accepting and expanding I in that context. Without it
    // you would get:
    //   error C3548: 'I': parameter pack cannot be used in this context
    : uses_inheritance,
      Storage<Ts, std::integral_constant<size_t, I>::value>... {
  constexpr CompressedTupleImpl() = default;
  template <typename... Vs>
  explicit constexpr CompressedTupleImpl(absl::in_place_t, Vs&&... args)
      : Storage<Ts, I>(absl::in_place, std::forward<Vs>(args))... {}
  friend CompressedTuple<Ts...>;
};

template <typename... Ts, size_t... I>
struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTupleImpl<
    CompressedTuple<Ts...>, absl::index_sequence<I...>, false>
    // We use the dummy identity function as above...
    : Storage<Ts, std::integral_constant<size_t, I>::value, false>... {
  constexpr CompressedTupleImpl() = default;
  template <typename... Vs>
  explicit constexpr CompressedTupleImpl(absl::in_place_t, Vs&&... args)
      : Storage<Ts, I, false>(absl::in_place, std::forward<Vs>(args))... {}
  friend CompressedTuple<Ts...>;
};

std::false_type Or(std::initializer_list<std::false_type>);
std::true_type Or(std::initializer_list<bool>);

// MSVC requires this to be done separately rather than within the declaration
// of CompressedTuple below.
template <typename... Ts>
constexpr bool ShouldAnyUseBase() {
  return decltype(
      Or({std::integral_constant<bool, ShouldUseBase<Ts>()>()...})){};
}

template <typename T, typename V>
using TupleElementMoveConstructible =
    typename std::conditional<std::is_reference<T>::value,
                              std::is_convertible<V, T>,
                              std::is_constructible<T, V&&>>::type;

template <bool SizeMatches, class T, class... Vs>
struct TupleMoveConstructible : std::false_type {};

template <class... Ts, class... Vs>
struct TupleMoveConstructible<true, CompressedTuple<Ts...>, Vs...>
    : std::integral_constant<
          bool, absl::conjunction<
                    TupleElementMoveConstructible<Ts, Vs&&>...>::value> {};

template <typename T>
struct compressed_tuple_size;

template <typename... Es>
struct compressed_tuple_size<CompressedTuple<Es...>>
    : public std::integral_constant<std::size_t, sizeof...(Es)> {};

template <class T, class... Vs>
struct TupleItemsMoveConstructible
    : std::integral_constant<
          bool, TupleMoveConstructible<compressed_tuple_size<T>::value ==
                                           sizeof...(Vs),
                                       T, Vs...>::value> {};

}  // namespace internal_compressed_tuple

// Helper class to perform the Empty Base Class Optimization.
// Ts can contain classes and non-classes, empty or not. For the ones that
// are empty classes, we perform the CompressedTuple. If all types in Ts are
// empty classes, then CompressedTuple<Ts...> is itself an empty class.  (This
// does not apply when one or more of those empty classes is itself an empty
// CompressedTuple.)
//
// To access the members, use member .get<N>() function.
//
// Eg:
//   absl::container_internal::CompressedTuple<int, T1, T2, T3> value(7, t1, t2,
//                                                                    t3);
//   assert(value.get<0>() == 7);
//   T1& t1 = value.get<1>();
//   const T2& t2 = value.get<2>();
//   ...
//
// https://en.cppreference.com/w/cpp/language/ebo
template <typename... Ts>
class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple
    : private internal_compressed_tuple::CompressedTupleImpl<
          CompressedTuple<Ts...>, absl::index_sequence_for<Ts...>,
          internal_compressed_tuple::ShouldAnyUseBase<Ts...>()> {
 private:
  template <int I>
  using ElemT = internal_compressed_tuple::ElemT<CompressedTuple, I>;

  template <int I>
  using StorageT = internal_compressed_tuple::Storage<ElemT<I>, I>;

 public:
  // There seems to be a bug in MSVC dealing in which using '=default' here will
  // cause the compiler to ignore the body of other constructors. The work-
  // around is to explicitly implement the default constructor.
#if defined(_MSC_VER)
  constexpr CompressedTuple() : CompressedTuple::CompressedTupleImpl() {}
#else
  constexpr CompressedTuple() = default;
#endif
  explicit constexpr CompressedTuple(const Ts&... base)
      : CompressedTuple::CompressedTupleImpl(absl::in_place, base...) {}

  template <typename First, typename... Vs,
            absl::enable_if_t<
                absl::conjunction<
                    // Ensure we are not hiding default copy/move constructors.
                    absl::negation<std::is_same<void(CompressedTuple),
                                                void(absl::decay_t<First>)>>,
                    internal_compressed_tuple::TupleItemsMoveConstructible<
                        CompressedTuple<Ts...>, First, Vs...>>::value,
                bool> = true>
  explicit constexpr CompressedTuple(First&& first, Vs&&... base)
      : CompressedTuple::CompressedTupleImpl(absl::in_place,
                                             std::forward<First>(first),
                                             std::forward<Vs>(base)...) {}

  template <int I>
  constexpr ElemT<I>& get() & {
    return StorageT<I>::get();
  }

  template <int I>
  constexpr const ElemT<I>& get() const& {
    return StorageT<I>::get();
  }

  template <int I>
  constexpr ElemT<I>&& get() && {
    return std::move(*this).StorageT<I>::get();
  }

  template <int I>
  constexpr const ElemT<I>&& get() const&& {
    return std::move(*this).StorageT<I>::get();
  }
};

// Explicit specialization for a zero-element tuple
// (needed to avoid ambiguous overloads for the default constructor).
template <>
class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple<> {};

}  // namespace container_internal
ABSL_NAMESPACE_END
}  // namespace absl

#undef ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC

#endif  // ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_
*ø
ˆsoong/.intermediates/external/abseil-cpp/absl_base_iterator_traits_internal_hdrs/gen/my_include_dir/absl/base/internal/iterator_traits.hê// Copyright 2025 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: internal/iterator_traits.h
// -----------------------------------------------------------------------------
//
// Helpers for querying traits of iterators, for implementing containers, etc.

#ifndef ABSL_BASE_INTERNAL_ITERATOR_TRAITS_H_
#define ABSL_BASE_INTERNAL_ITERATOR_TRAITS_H_

#include <iterator>
#include <type_traits>

#include "absl/base/config.h"
#include "absl/meta/type_traits.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {

template <typename Iterator, typename = void>
struct IteratorCategory {};

template <typename Iterator>
struct IteratorCategory<
    Iterator,
    absl::void_t<typename std::iterator_traits<Iterator>::iterator_category>> {
  using type = typename std::iterator_traits<Iterator>::iterator_category;
};

template <typename Iterator, typename = void>
struct IteratorConceptImpl : IteratorCategory<Iterator> {};

template <typename Iterator>
struct IteratorConceptImpl<
    Iterator,
    absl::void_t<typename std::iterator_traits<Iterator>::iterator_concept>> {
  using type = typename std::iterator_traits<Iterator>::iterator_concept;
};

// The newer `std::iterator_traits<Iterator>::iterator_concept` if available,
// else `std::iterator_traits<Iterator>::iterator_category`.
template <typename Iterator>
using IteratorConcept = typename IteratorConceptImpl<Iterator>::type;

template <typename IteratorTag, typename Iterator>
using IsAtLeastIterator =
    std::is_convertible<IteratorConcept<Iterator>, IteratorTag>;

template <typename Iterator>
using IsAtLeastForwardIterator =
    IsAtLeastIterator<std::forward_iterator_tag, Iterator>;

}  // namespace base_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_BASE_INTERNAL_ITERATOR_TRAITS_H_
*Ý@
‰soong/.intermediates/external/abseil-cpp/absl_strings_str_format_internal_hdrs/gen/my_include_dir/absl/strings/internal/str_format/bind.hÎ?// 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_STR_FORMAT_BIND_H_
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_BIND_H_

#include <cassert>
#include <cstdio>
#include <ostream>
#include <string>

#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"

namespace absl {
ABSL_NAMESPACE_BEGIN

class UntypedFormatSpec;

namespace str_format_internal {

class BoundConversion : public FormatConversionSpecImpl {
 public:
  const FormatArgImpl* arg() const { return arg_; }
  void set_arg(const FormatArgImpl* a) { arg_ = a; }

 private:
  const FormatArgImpl* arg_;
};

// This is the type-erased class that the implementation uses.
class UntypedFormatSpecImpl {
 public:
  UntypedFormatSpecImpl() = delete;

  explicit UntypedFormatSpecImpl(string_view s)
      : data_(s.data()), size_(s.size()) {}
  explicit UntypedFormatSpecImpl(
      const str_format_internal::ParsedFormatBase* pc)
      : data_(pc), size_(~size_t{}) {}

  bool has_parsed_conversion() const { return size_ == ~size_t{}; }

  string_view str() const {
    assert(!has_parsed_conversion());
    return string_view(static_cast<const char*>(data_), size_);
  }
  const str_format_internal::ParsedFormatBase* parsed_conversion() const {
    assert(has_parsed_conversion());
    return static_cast<const str_format_internal::ParsedFormatBase*>(data_);
  }

  template <typename T>
  static const UntypedFormatSpecImpl& Extract(const T& s) {
    return s.spec_;
  }

 private:
  const void* data_;
  size_t size_;
};

template <typename T, FormatConversionCharSet...>
struct MakeDependent {
  using type = T;
};

// Implicitly convertible from `const char*`, `string_view`, and the
// `ExtendedParsedFormat` type. This abstraction allows all format functions to
// operate on any without providing too many overloads.
template <FormatConversionCharSet... Args>
class FormatSpecTemplate
    : public MakeDependent<UntypedFormatSpec, Args...>::type {
  using Base = typename MakeDependent<UntypedFormatSpec, Args...>::type;

  template <bool res>
  struct ErrorMaker {
    constexpr bool operator()(int) const { return res; }
  };

  template <int i, int j>
  static constexpr bool CheckArity(ErrorMaker<true> SpecifierCount = {},
                                   ErrorMaker<i == j> ParametersPassed = {}) {
    static_assert(SpecifierCount(i) == ParametersPassed(j),
                  "Number of arguments passed must match the number of "
                  "conversion specifiers.");
    return true;
  }

  template <FormatConversionCharSet specified, FormatConversionCharSet passed,
            int arg>
  static constexpr bool CheckMatch(
      ErrorMaker<Contains(specified, passed)> MismatchedArgumentNumber = {}) {
    static_assert(MismatchedArgumentNumber(arg),
                  "Passed argument must match specified format.");
    return true;
  }

  template <FormatConversionCharSet... C, size_t... I>
  static bool CheckMatches(absl::index_sequence<I...>) {
    bool res[] = {true, CheckMatch<Args, C, I + 1>()...};
    (void)res;
    return true;
  }

 public:
#ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER

  // Honeypot overload for when the string is not constexpr.
  // We use the 'unavailable' attribute to give a better compiler error than
  // just 'method is deleted'.
  FormatSpecTemplate(...)  // NOLINT
      __attribute__((unavailable("Format string is not constexpr.")));

  // Honeypot overload for when the format is constexpr and invalid.
  // We use the 'unavailable' attribute to give a better compiler error than
  // just 'method is deleted'.
  // To avoid checking the format twice, we just check that the format is
  // constexpr. If it is valid, then the overload below will kick in.
  // We add the template here to make this overload have lower priority.
  template <typename = void>
  FormatSpecTemplate(const char* s)  // NOLINT
      __attribute__((
          enable_if(str_format_internal::EnsureConstexpr(s), "constexpr trap"),
          unavailable(
              "Format specified does not match the arguments passed.")));

  template <typename T = void>
  FormatSpecTemplate(string_view s)  // NOLINT
      __attribute__((enable_if(str_format_internal::EnsureConstexpr(s),
                               "constexpr trap")))
      : Base("to avoid noise in the compiler error") {
    static_assert(sizeof(T*) == 0,
                  "Format specified does not match the arguments passed.");
  }

  // Good format overload.
  FormatSpecTemplate(const char* s)  // NOLINT
      __attribute__((enable_if(ValidFormatImpl<Args...>(s), "bad format trap")))
      : Base(s) {}

  FormatSpecTemplate(string_view s)  // NOLINT
      __attribute__((enable_if(ValidFormatImpl<Args...>(s), "bad format trap")))
      : Base(s) {}

#else  // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER

  FormatSpecTemplate(const char* s) : Base(s) {}  // NOLINT
  FormatSpecTemplate(string_view s) : Base(s) {}  // NOLINT

#endif  // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER

  template <FormatConversionCharSet... C>
  FormatSpecTemplate(const ExtendedParsedFormat<C...>& pc)  // NOLINT
      : Base(&pc) {
    CheckArity<sizeof...(C), sizeof...(Args)>();
    CheckMatches<C...>(absl::make_index_sequence<sizeof...(C)>{});
  }
};

class Streamable {
 public:
  Streamable(const UntypedFormatSpecImpl& format,
             absl::Span<const FormatArgImpl> args)
      : format_(format), args_(args.begin(), args.end()) {}

  std::ostream& Print(std::ostream& os) const;

  friend std::ostream& operator<<(std::ostream& os, const Streamable& l) {
    return l.Print(os);
  }

 private:
  const UntypedFormatSpecImpl& format_;
  absl::InlinedVector<FormatArgImpl, 4> args_;
};

// for testing
std::string Summarize(UntypedFormatSpecImpl format,
                      absl::Span<const FormatArgImpl> args);
bool BindWithPack(const UnboundConversion* props,
                  absl::Span<const FormatArgImpl> pack, BoundConversion* bound);

bool FormatUntyped(FormatRawSinkImpl raw_sink, UntypedFormatSpecImpl format,
                   absl::Span<const FormatArgImpl> args);

std::string& AppendPack(std::string* out, UntypedFormatSpecImpl format,
                        absl::Span<const FormatArgImpl> args);

std::string FormatPack(UntypedFormatSpecImpl format,
                       absl::Span<const FormatArgImpl> args);

int FprintF(std::FILE* output, UntypedFormatSpecImpl format,
            absl::Span<const FormatArgImpl> args);
int SnprintF(char* output, size_t size, UntypedFormatSpecImpl format,
             absl::Span<const FormatArgImpl> args);

// Returned by Streamed(v). Converts via '%s' to the std::string created
// by std::ostream << v.
template <typename T>
class StreamedWrapper {
 public:
  explicit StreamedWrapper(const T& v) : v_(v) {}

 private:
  template <typename S>
  friend ArgConvertResult<FormatConversionCharSetUnion(
      FormatConversionCharSetInternal::s, FormatConversionCharSetInternal::v)>
  FormatConvertImpl(const StreamedWrapper<S>& v, FormatConversionSpecImpl conv,
                    FormatSinkImpl* out);
  const T& v_;
};

}  // namespace str_format_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_STR_FORMAT_BIND_H_
*™q
Žsoong/.intermediates/external/abseil-cpp/absl_strings_str_format_internal_hdrs/gen/my_include_dir/absl/strings/internal/str_format/extension.h…p//
// 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.
//
#ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_


#include <cstddef>
#include <cstdint>
#include <cstring>
#include <ostream>
#include <string>

#include "absl/base/config.h"
#include "absl/strings/internal/str_format/output.h"
#include "absl/strings/string_view.h"

namespace absl {
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 {

class FormatRawSinkImpl {
 public:
  // Implicitly convert from any type that provides the hook function as
  // described above.
  template <typename T, decltype(str_format_internal::InvokeFlush(
                            std::declval<T*>(), string_view()))* = nullptr>
  FormatRawSinkImpl(T* raw)  // NOLINT
      : sink_(raw), write_(&FormatRawSinkImpl::Flush<T>) {}

  void Write(string_view s) { write_(sink_, s); }

  template <typename T>
  static FormatRawSinkImpl Extract(T s) {
    return s.sink_;
  }

 private:
  template <typename T>
  static void Flush(void* r, string_view s) {
    str_format_internal::InvokeFlush(static_cast<T*>(r), s);
  }

  void* sink_;
  void (*write_)(void*, string_view);
};

// An abstraction to which conversions write their string data.
class FormatSinkImpl {
 public:
  explicit FormatSinkImpl(FormatRawSinkImpl raw) : raw_(raw) {}

  ~FormatSinkImpl() { Flush(); }

  void Flush() {
    raw_.Write(string_view(buf_, static_cast<size_t>(pos_ - buf_)));
    pos_ = buf_;
  }

  void Append(size_t n, char c) {
    if (n == 0) return;
    size_ += n;
    auto raw_append = [&](size_t count) {
      memset(pos_, c, count);
      pos_ += count;
    };
    while (n > Avail()) {
      n -= Avail();
      if (Avail() > 0) {
        raw_append(Avail());
      }
      Flush();
    }
    raw_append(n);
  }

  void Append(string_view v) {
    size_t n = v.size();
    if (n == 0) return;
    size_ += n;
    if (n >= Avail()) {
      Flush();
      raw_.Write(v);
      return;
    }
    memcpy(pos_, v.data(), n);
    pos_ += n;
  }

  size_t size() const { return size_; }

  // Put 'v' to 'sink' with specified width, precision, and left flag.
  bool PutPaddedString(string_view v, int width, int precision, bool left);

  template <typename T>
  T Wrap() {
    return T(this);
  }

  template <typename T>
  static FormatSinkImpl* Extract(T* s) {
    return s->sink_;
  }

 private:
  size_t Avail() const {
    return static_cast<size_t>(buf_ + sizeof(buf_) - pos_);
  }

  FormatRawSinkImpl raw_;
  size_t size_ = 0;
  char* pos_ = buf_;
  char buf_[1024];
};

enum class Flags : uint8_t {
  kBasic = 0,
  kLeft = 1 << 0,
  kShowPos = 1 << 1,
  kSignCol = 1 << 2,
  kAlt = 1 << 3,
  kZero = 1 << 4,
  // This is not a real flag. It just exists to turn off kBasic when no other
  // flags are set. This is for when width/precision are specified, or a length
  // modifier affects the behavior ("%lc").
  kNonBasic = 1 << 5,
};

constexpr Flags operator|(Flags a, Flags b) {
  return static_cast<Flags>(static_cast<uint8_t>(a) | static_cast<uint8_t>(b));
}

constexpr bool FlagsContains(Flags haystack, Flags needle) {
  return (static_cast<uint8_t>(haystack) & static_cast<uint8_t>(needle)) ==
         static_cast<uint8_t>(needle);
}

std::string FlagsToString(Flags v);

inline std::ostream& operator<<(std::ostream& os, Flags v) {
  return os << FlagsToString(v);
}

// clang-format off
#define ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(X_VAL, X_SEP) \
  /* text */ \
  X_VAL(c) X_SEP X_VAL(s) X_SEP \
  /* ints */ \
  X_VAL(d) X_SEP X_VAL(i) X_SEP X_VAL(o) X_SEP \
  X_VAL(u) X_SEP X_VAL(x) X_SEP X_VAL(X) X_SEP \
  /* floats */ \
  X_VAL(f) X_SEP X_VAL(F) X_SEP X_VAL(e) X_SEP X_VAL(E) X_SEP \
  X_VAL(g) X_SEP X_VAL(G) X_SEP X_VAL(a) X_SEP X_VAL(A) X_SEP \
  /* misc */ \
  X_VAL(n) X_SEP X_VAL(p) X_SEP X_VAL(v)
// clang-format on

// This type should not be referenced, it exists only to provide labels
// internally that match the values declared in FormatConversionChar in
// str_format.h. This is meant to allow internal libraries to use the same
// declared interface type as the public interface
// (absl::StrFormatConversionChar) while keeping the definition in a public
// header.
// Internal libraries should use the form
// `FormatConversionCharInternal::c`, `FormatConversionCharInternal::kNone` for
// comparisons.  Use in switch statements is not recommended due to a bug in how
// gcc 4.9 -Wswitch handles declared but undefined enums.
struct FormatConversionCharInternal {
  FormatConversionCharInternal() = delete;

 private:
  // clang-format off
  enum class Enum : uint8_t {
    c, s,                    // text
    d, i, o, u, x, X,        // int
    f, F, e, E, g, G, a, A,  // float
    n, p, v,                    // misc
    kNone
  };
  // clang-format on
 public:
#define ABSL_INTERNAL_X_VAL(id)              \
  static constexpr FormatConversionChar id = \
      static_cast<FormatConversionChar>(Enum::id);
  ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_X_VAL, )
#undef ABSL_INTERNAL_X_VAL
  static constexpr FormatConversionChar kNone =
      static_cast<FormatConversionChar>(Enum::kNone);
};
// clang-format on

inline FormatConversionChar FormatConversionCharFromChar(char c) {
  switch (c) {
#define ABSL_INTERNAL_X_VAL(id) \
  case #id[0]:                  \
    return FormatConversionCharInternal::id;
    ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_X_VAL, )
#undef ABSL_INTERNAL_X_VAL
  }
  return FormatConversionCharInternal::kNone;
}

inline bool FormatConversionCharIsUpper(FormatConversionChar c) {
  if (c == FormatConversionCharInternal::X ||
      c == FormatConversionCharInternal::F ||
      c == FormatConversionCharInternal::E ||
      c == FormatConversionCharInternal::G ||
      c == FormatConversionCharInternal::A) {
    return true;
  } else {
    return false;
  }
}

inline bool FormatConversionCharIsFloat(FormatConversionChar c) {
  if (c == FormatConversionCharInternal::a ||
      c == FormatConversionCharInternal::e ||
      c == FormatConversionCharInternal::f ||
      c == FormatConversionCharInternal::g ||
      c == FormatConversionCharInternal::A ||
      c == FormatConversionCharInternal::E ||
      c == FormatConversionCharInternal::F ||
      c == FormatConversionCharInternal::G) {
    return true;
  } else {
    return false;
  }
}

inline char FormatConversionCharToChar(FormatConversionChar c) {
  if (c == FormatConversionCharInternal::kNone) {
    return '\0';

#define ABSL_INTERNAL_X_VAL(e)                       \
  } else if (c == FormatConversionCharInternal::e) { \
    return #e[0];
#define ABSL_INTERNAL_X_SEP
  ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_X_VAL,
                                         ABSL_INTERNAL_X_SEP)
  } else {
    return '\0';
  }

#undef ABSL_INTERNAL_X_VAL
#undef ABSL_INTERNAL_X_SEP
}

// The associated char.
inline std::ostream& operator<<(std::ostream& os, FormatConversionChar v) {
  char c = FormatConversionCharToChar(v);
  if (!c) c = '?';
  return os << c;
}

struct FormatConversionSpecImplFriend;

class FormatConversionSpecImpl {
 public:
  // Width and precision are not specified, no flags are set.
  bool is_basic() const { return flags_ == Flags::kBasic; }
  bool has_left_flag() const { return FlagsContains(flags_, Flags::kLeft); }
  bool has_show_pos_flag() const {
    return FlagsContains(flags_, Flags::kShowPos);
  }
  bool has_sign_col_flag() const {
    return FlagsContains(flags_, Flags::kSignCol);
  }
  bool has_alt_flag() const { return FlagsContains(flags_, Flags::kAlt); }
  bool has_zero_flag() const { return FlagsContains(flags_, Flags::kZero); }

  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.
    static_assert(offsetof(FormatConversionSpecImpl, conv_) == 0, "");
    return conv_;
  }

  void set_conversion_char(FormatConversionChar c) { conv_ = c; }

  // Returns the specified width. If width is unspecfied, it returns a negative
  // value.
  int width() const { return width_; }
  // Returns the specified precision. If precision is unspecfied, it returns a
  // negative value.
  int precision() const { return precision_; }

  template <typename T>
  T Wrap() {
    return T(*this);
  }

 private:
  friend struct str_format_internal::FormatConversionSpecImplFriend;
  FormatConversionChar conv_ = FormatConversionCharInternal::kNone;
  Flags flags_;
  LengthMod length_mod_ = LengthMod::none;
  int width_;
  int precision_;
};

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;
  }
  static void SetWidth(int w, FormatConversionSpecImpl* conv) {
    conv->width_ = w;
  }
  static void SetPrecision(int p, FormatConversionSpecImpl* conv) {
    conv->precision_ = p;
  }
  static std::string FlagsToString(const FormatConversionSpecImpl& spec) {
    return str_format_internal::FlagsToString(spec.flags_);
  }
};

// Type safe OR operator.
// We need this for two reasons:
//  1. operator| on enums makes them decay to integers and the result is an
//     integer. We need the result to stay as an enum.
//  2. We use "enum class" which would not work even if we accepted the decay.
constexpr FormatConversionCharSet FormatConversionCharSetUnion(
    FormatConversionCharSet a) {
  return a;
}

template <typename... CharSet>
constexpr FormatConversionCharSet FormatConversionCharSetUnion(
    FormatConversionCharSet a, CharSet... rest) {
  return static_cast<FormatConversionCharSet>(
      static_cast<uint64_t>(a) |
      static_cast<uint64_t>(FormatConversionCharSetUnion(rest...)));
}

constexpr uint64_t FormatConversionCharToConvInt(FormatConversionChar c) {
  return uint64_t{1} << (1 + static_cast<uint8_t>(c));
}

constexpr uint64_t FormatConversionCharToConvInt(char conv) {
  return
#define ABSL_INTERNAL_CHAR_SET_CASE(c)                                 \
  conv == #c[0]                                                        \
      ? FormatConversionCharToConvInt(FormatConversionCharInternal::c) \
      :
      ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_CHAR_SET_CASE, )
#undef ABSL_INTERNAL_CHAR_SET_CASE
                  conv == '*'
          ? 1
          : 0;
}

constexpr FormatConversionCharSet FormatConversionCharToConvValue(char conv) {
  return static_cast<FormatConversionCharSet>(
      FormatConversionCharToConvInt(conv));
}

struct FormatConversionCharSetInternal {
#define ABSL_INTERNAL_CHAR_SET_CASE(c)         \
  static constexpr FormatConversionCharSet c = \
      FormatConversionCharToConvValue(#c[0]);
  ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_CHAR_SET_CASE, )
#undef ABSL_INTERNAL_CHAR_SET_CASE

  // Used for width/precision '*' specification.
  static constexpr FormatConversionCharSet kStar =
      FormatConversionCharToConvValue('*');

  static constexpr FormatConversionCharSet kIntegral =
      FormatConversionCharSetUnion(d, i, u, o, x, X);
  static constexpr FormatConversionCharSet kFloating =
      FormatConversionCharSetUnion(a, e, f, g, A, E, F, G);
  static constexpr FormatConversionCharSet kNumeric =
      FormatConversionCharSetUnion(kIntegral, kFloating);
  static constexpr FormatConversionCharSet kPointer = p;
};

// Type safe OR operator.
// We need this for two reasons:
//  1. operator| on enums makes them decay to integers and the result is an
//     integer. We need the result to stay as an enum.
//  2. We use "enum class" which would not work even if we accepted the decay.
constexpr FormatConversionCharSet operator|(FormatConversionCharSet a,
                                            FormatConversionCharSet b) {
  return FormatConversionCharSetUnion(a, b);
}

// Overloaded conversion functions to support absl::ParsedFormat.
// Get a conversion with a single character in it.
constexpr FormatConversionCharSet ToFormatConversionCharSet(char c) {
  return static_cast<FormatConversionCharSet>(
      FormatConversionCharToConvValue(c));
}

// Get a conversion with a single character in it.
constexpr FormatConversionCharSet ToFormatConversionCharSet(
    FormatConversionCharSet c) {
  return c;
}

template <typename T>
void ToFormatConversionCharSet(T) = delete;

// Checks whether `c` exists in `set`.
constexpr bool Contains(FormatConversionCharSet set, char c) {
  return (static_cast<uint64_t>(set) &
          static_cast<uint64_t>(FormatConversionCharToConvValue(c))) != 0;
}

// Checks whether all the characters in `c` are contained in `set`
constexpr bool Contains(FormatConversionCharSet set,
                        FormatConversionCharSet c) {
  return (static_cast<uint64_t>(set) & static_cast<uint64_t>(c)) ==
         static_cast<uint64_t>(c);
}

// Checks whether all the characters in `c` are contained in `set`
constexpr bool Contains(FormatConversionCharSet set, FormatConversionChar c) {
  return (static_cast<uint64_t>(set) & FormatConversionCharToConvInt(c)) != 0;
}

// Return capacity - used, clipped to a minimum of 0.
inline size_t Excess(size_t used, size_t capacity) {
  return used < capacity ? capacity - used : 0;
}

}  // namespace str_format_internal

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_
*²_
ysoong/.intermediates/external/abseil-cpp/absl_numeric_int128_hdrs/gen/my_include_dir/absl/numeric/int128_no_intrinsic.inc´^//
// 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.

// This file contains :int128 implementation details that depend on internal
// representation when ABSL_HAVE_INTRINSIC_INT128 is *not* defined. This file
// is included by int128.h and relies on ABSL_INTERNAL_WCHAR_T being defined.

constexpr uint64_t Int128Low64(int128 v) { return v.lo_; }

constexpr int64_t Int128High64(int128 v) { return v.hi_; }

#if defined(ABSL_IS_LITTLE_ENDIAN)

constexpr int128::int128(int64_t high, uint64_t low) : lo_(low), hi_(high) {}

constexpr int128::int128(int v)
    : lo_{static_cast<uint64_t>(v)}, hi_{v < 0 ? ~int64_t{0} : 0} {}
constexpr int128::int128(long v)  // NOLINT(runtime/int)
    : lo_{static_cast<uint64_t>(v)}, hi_{v < 0 ? ~int64_t{0} : 0} {}
constexpr int128::int128(long long v)  // NOLINT(runtime/int)
    : lo_{static_cast<uint64_t>(v)}, hi_{v < 0 ? ~int64_t{0} : 0} {}

constexpr int128::int128(unsigned int v) : lo_{v}, hi_{0} {}
// NOLINTNEXTLINE(runtime/int)
constexpr int128::int128(unsigned long v) : lo_{v}, hi_{0} {}
// NOLINTNEXTLINE(runtime/int)
constexpr int128::int128(unsigned long long v) : lo_{v}, hi_{0} {}

constexpr int128::int128(uint128 v)
    : lo_{Uint128Low64(v)}, hi_{static_cast<int64_t>(Uint128High64(v))} {}

#elif defined(ABSL_IS_BIG_ENDIAN)

constexpr int128::int128(int64_t high, uint64_t low) : hi_{high}, lo_{low} {}

constexpr int128::int128(int v)
    : hi_{v < 0 ? ~int64_t{0} : 0}, lo_{static_cast<uint64_t>(v)} {}
constexpr int128::int128(long v)  // NOLINT(runtime/int)
    : hi_{v < 0 ? ~int64_t{0} : 0}, lo_{static_cast<uint64_t>(v)} {}
constexpr int128::int128(long long v)  // NOLINT(runtime/int)
    : hi_{v < 0 ? ~int64_t{0} : 0}, lo_{static_cast<uint64_t>(v)} {}

constexpr int128::int128(unsigned int v) : hi_{0}, lo_{v} {}
// NOLINTNEXTLINE(runtime/int)
constexpr int128::int128(unsigned long v) : hi_{0}, lo_{v} {}
// NOLINTNEXTLINE(runtime/int)
constexpr int128::int128(unsigned long long v) : hi_{0}, lo_{v} {}

constexpr int128::int128(uint128 v)
    : hi_{static_cast<int64_t>(Uint128High64(v))}, lo_{Uint128Low64(v)} {}

#else  // byte order
#error "Unsupported byte order: must be little-endian or big-endian."
#endif  // byte order

constexpr int128::operator bool() const { return lo_ || hi_; }

constexpr int128::operator char() const {
  // NOLINTNEXTLINE(runtime/int)
  return static_cast<char>(static_cast<long long>(*this));
}

constexpr int128::operator signed char() const {
  // NOLINTNEXTLINE(runtime/int)
  return static_cast<signed char>(static_cast<long long>(*this));
}

constexpr int128::operator unsigned char() const {
  return static_cast<unsigned char>(lo_);
}

constexpr int128::operator char16_t() const {
  return static_cast<char16_t>(lo_);
}

constexpr int128::operator char32_t() const {
  return static_cast<char32_t>(lo_);
}

constexpr int128::operator ABSL_INTERNAL_WCHAR_T() const {
  // NOLINTNEXTLINE(runtime/int)
  return static_cast<ABSL_INTERNAL_WCHAR_T>(static_cast<long long>(*this));
}

constexpr int128::operator short() const {  // NOLINT(runtime/int)
  // NOLINTNEXTLINE(runtime/int)
  return static_cast<short>(static_cast<long long>(*this));
}

constexpr int128::operator unsigned short() const {  // NOLINT(runtime/int)
  return static_cast<unsigned short>(lo_);           // NOLINT(runtime/int)
}

constexpr int128::operator int() const {
  // NOLINTNEXTLINE(runtime/int)
  return static_cast<int>(static_cast<long long>(*this));
}

constexpr int128::operator unsigned int() const {
  return static_cast<unsigned int>(lo_);
}

constexpr int128::operator long() const {  // NOLINT(runtime/int)
  // NOLINTNEXTLINE(runtime/int)
  return static_cast<long>(static_cast<long long>(*this));
}

constexpr int128::operator unsigned long() const {  // NOLINT(runtime/int)
  return static_cast<unsigned long>(lo_);           // NOLINT(runtime/int)
}

constexpr int128::operator long long() const {  // NOLINT(runtime/int)
  // We don't bother checking the value of hi_. If *this < 0, lo_'s high bit
  // must be set in order for the value to fit into a long long. Conversely, if
  // lo_'s high bit is set, *this must be < 0 for the value to fit.
  return int128_internal::BitCastToSigned(lo_);
}

constexpr int128::operator unsigned long long() const {  // NOLINT(runtime/int)
  return static_cast<unsigned long long>(lo_);           // NOLINT(runtime/int)
}

inline int128::operator float() const {
  // We must convert the absolute value and then negate as needed, because
  // floating point types are typically sign-magnitude. Otherwise, the
  // difference between the high and low 64 bits when interpreted as two's
  // complement overwhelms the precision of the mantissa.
  //
  // Also check to make sure we don't negate Int128Min()
  constexpr float pow_2_64 = 18446744073709551616.0f;
  return hi_ < 0 && *this != Int128Min()
             ? -static_cast<float>(-*this)
             : static_cast<float>(lo_) +
                   static_cast<float>(hi_) * pow_2_64;
}

inline int128::operator double() const {
  // See comment in int128::operator float() above.
  constexpr double pow_2_64 = 18446744073709551616.0;
  return hi_ < 0 && *this != Int128Min()
             ? -static_cast<double>(-*this)
             : static_cast<double>(lo_) +
                   static_cast<double>(hi_) * pow_2_64;
}

inline int128::operator long double() const {
  // See comment in int128::operator float() above.
  constexpr long double pow_2_64 = 18446744073709551616.0L;
  return hi_ < 0 && *this != Int128Min()
             ? -static_cast<long double>(-*this)
             : static_cast<long double>(lo_) +
                   static_cast<long double>(hi_) * pow_2_64;
}

// Comparison operators.

constexpr bool operator==(int128 lhs, int128 rhs) {
  return (Int128Low64(lhs) == Int128Low64(rhs) &&
          Int128High64(lhs) == Int128High64(rhs));
}

constexpr bool operator!=(int128 lhs, int128 rhs) { return !(lhs == rhs); }

constexpr bool operator<(int128 lhs, int128 rhs) {
  return (Int128High64(lhs) == Int128High64(rhs))
             ? (Int128Low64(lhs) < Int128Low64(rhs))
             : (Int128High64(lhs) < Int128High64(rhs));
}

constexpr bool operator>(int128 lhs, int128 rhs) {
  return (Int128High64(lhs) == Int128High64(rhs))
             ? (Int128Low64(lhs) > Int128Low64(rhs))
             : (Int128High64(lhs) > Int128High64(rhs));
}

constexpr bool operator<=(int128 lhs, int128 rhs) { return !(lhs > rhs); }

constexpr bool operator>=(int128 lhs, int128 rhs) { return !(lhs < rhs); }

#ifdef __cpp_impl_three_way_comparison
constexpr absl::strong_ordering operator<=>(int128 lhs, int128 rhs) {
  if (int64_t lhs_high = Int128High64(lhs), rhs_high = Int128High64(rhs);
      lhs_high < rhs_high) {
    return absl::strong_ordering::less;
  } else if (lhs_high > rhs_high) {
    return absl::strong_ordering::greater;
  } else if (uint64_t lhs_low = Uint128Low64(lhs), rhs_low = Uint128Low64(rhs);
             lhs_low < rhs_low) {
    return absl::strong_ordering::less;
  } else if (lhs_low > rhs_low) {
    return absl::strong_ordering::greater;
  } else {
    return absl::strong_ordering::equal;
  }
}
#endif

// Unary operators.

constexpr int128 operator-(int128 v) {
  return MakeInt128(~Int128High64(v) + (Int128Low64(v) == 0),
                    ~Int128Low64(v) + 1);
}

constexpr bool operator!(int128 v) {
  return !Int128Low64(v) && !Int128High64(v);
}

constexpr int128 operator~(int128 val) {
  return MakeInt128(~Int128High64(val), ~Int128Low64(val));
}

// Arithmetic operators.

namespace int128_internal {
constexpr int128 SignedAddResult(int128 result, int128 lhs) {
  // check for carry
  return (Int128Low64(result) < Int128Low64(lhs))
             ? MakeInt128(Int128High64(result) + 1, Int128Low64(result))
             : result;
}
}  // namespace int128_internal
constexpr int128 operator+(int128 lhs, int128 rhs) {
  return int128_internal::SignedAddResult(
      MakeInt128(Int128High64(lhs) + Int128High64(rhs),
                 Int128Low64(lhs) + Int128Low64(rhs)),
      lhs);
}

namespace int128_internal {
constexpr int128 SignedSubstructResult(int128 result, int128 lhs, int128 rhs) {
  // check for carry
  return (Int128Low64(lhs) < Int128Low64(rhs))
             ? MakeInt128(Int128High64(result) - 1, Int128Low64(result))
             : result;
}
}  // namespace int128_internal
constexpr int128 operator-(int128 lhs, int128 rhs) {
  return int128_internal::SignedSubstructResult(
      MakeInt128(Int128High64(lhs) - Int128High64(rhs),
                 Int128Low64(lhs) - Int128Low64(rhs)),
      lhs, rhs);
}

inline int128 operator*(int128 lhs, int128 rhs) {
  return MakeInt128(
      int128_internal::BitCastToSigned(Uint128High64(uint128(lhs) * rhs)),
      Uint128Low64(uint128(lhs) * rhs));
}

inline int128 int128::operator++(int) {
  int128 tmp(*this);
  *this += 1;
  return tmp;
}

inline int128 int128::operator--(int) {
  int128 tmp(*this);
  *this -= 1;
  return tmp;
}

inline int128& int128::operator++() {
  *this += 1;
  return *this;
}

inline int128& int128::operator--() {
  *this -= 1;
  return *this;
}

constexpr int128 operator|(int128 lhs, int128 rhs) {
  return MakeInt128(Int128High64(lhs) | Int128High64(rhs),
                    Int128Low64(lhs) | Int128Low64(rhs));
}

constexpr int128 operator&(int128 lhs, int128 rhs) {
  return MakeInt128(Int128High64(lhs) & Int128High64(rhs),
                    Int128Low64(lhs) & Int128Low64(rhs));
}

constexpr int128 operator^(int128 lhs, int128 rhs) {
  return MakeInt128(Int128High64(lhs) ^ Int128High64(rhs),
                    Int128Low64(lhs) ^ Int128Low64(rhs));
}

constexpr int128 operator<<(int128 lhs, int amount) {
  // int64_t shifts of >= 63 are undefined, so we need some special-casing.
  assert(amount >= 0 && amount < 127);
  if (amount <= 0) {
    return lhs;
  } else if (amount < 63) {
    return MakeInt128(
        (Int128High64(lhs) << amount) |
            static_cast<int64_t>(Int128Low64(lhs) >> (64 - amount)),
        Int128Low64(lhs) << amount);
  } else if (amount == 63) {
    return MakeInt128(((Int128High64(lhs) << 32) << 31) |
                          static_cast<int64_t>(Int128Low64(lhs) >> 1),
                      (Int128Low64(lhs) << 32) << 31);
  } else if (amount == 127) {
    return MakeInt128(static_cast<int64_t>(Int128Low64(lhs) << 63), 0);
  } else if (amount > 127) {
    return MakeInt128(0, 0);
  } else {
    // amount >= 64 && amount < 127
    return MakeInt128(static_cast<int64_t>(Int128Low64(lhs) << (amount - 64)),
                      0);
  }
}

constexpr int128 operator>>(int128 lhs, int amount) {
  // int64_t shifts of >= 63 are undefined, so we need some special-casing.
  assert(amount >= 0 && amount < 127);
  if (amount <= 0) {
    return lhs;
  } else if (amount < 63) {
    return MakeInt128(
        Int128High64(lhs) >> amount,
        Int128Low64(lhs) >> amount | static_cast<uint64_t>(Int128High64(lhs))
                                         << (64 - amount));
  } else if (amount == 63) {
    return MakeInt128((Int128High64(lhs) >> 32) >> 31,
                      static_cast<uint64_t>(Int128High64(lhs) << 1) |
                          (Int128Low64(lhs) >> 32) >> 31);

  } else if (amount >= 127) {
    return MakeInt128((Int128High64(lhs) >> 32) >> 31,
                      static_cast<uint64_t>((Int128High64(lhs) >> 32) >> 31));
  } else {
    // amount >= 64 && amount < 127
    return MakeInt128(
        (Int128High64(lhs) >> 32) >> 31,
        static_cast<uint64_t>(Int128High64(lhs) >> (amount - 64)));
  }
}
*í—
hsoong/.intermediates/external/abseil-cpp/absl_types_compare_hdrs/gen/my_include_dir/absl/types/compare.hÿ–// Copyright 2018 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// compare.h
// -----------------------------------------------------------------------------
//
// This header file defines the `absl::partial_ordering`, `absl::weak_ordering`,
// and `absl::strong_ordering` types for storing the results of three way
// comparisons.
//
// Example:
//   absl::weak_ordering compare(const std::string& a, const std::string& b);
//
// These are C++11 compatible versions of the C++20 corresponding types
// (`std::partial_ordering`, etc.) and are designed to be drop-in replacements
// for code compliant with C++20.

#ifndef ABSL_TYPES_COMPARE_H_
#define ABSL_TYPES_COMPARE_H_

#include "absl/base/config.h"

#ifdef ABSL_USES_STD_ORDERING

#include <compare>  // IWYU pragma: export
#include <type_traits>

#include "absl/meta/type_traits.h"

#else

#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <type_traits>

#include "absl/base/attributes.h"
#include "absl/base/macros.h"
#include "absl/meta/type_traits.h"

#endif

namespace absl {
ABSL_NAMESPACE_BEGIN

#ifdef ABSL_USES_STD_ORDERING

using std::partial_ordering;
using std::strong_ordering;
using std::weak_ordering;

#else

namespace compare_internal {

using value_type = int8_t;

class OnlyLiteralZero {
 public:
#if ABSL_HAVE_ATTRIBUTE(enable_if)
  // On clang, we can avoid triggering modernize-use-nullptr by only enabling
  // this overload when the value is a compile time integer constant equal to 0.
  //
  // In c++20, this could be a static_assert in a consteval function.
  constexpr OnlyLiteralZero(int n)  // NOLINT
      __attribute__((enable_if(n == 0, "Only literal `0` is allowed."))) {}
#else  // ABSL_HAVE_ATTRIBUTE(enable_if)
  // Accept only literal zero since it can be implicitly converted to a pointer
  // to member type. nullptr constants will be caught by the other constructor
  // which accepts a nullptr_t.
  //
  // This constructor is not used for clang since it triggers
  // modernize-use-nullptr.
  constexpr OnlyLiteralZero(int OnlyLiteralZero::*) noexcept {}  // NOLINT
#endif

  // Fails compilation when `nullptr` or integral type arguments other than
  // `int` are passed. This constructor doesn't accept `int` because literal `0`
  // has type `int`. Literal `0` arguments will be implicitly converted to
  // `std::nullptr_t` and accepted by the above constructor, while other `int`
  // arguments will fail to be converted and cause compilation failure.
  template <typename T, typename = typename std::enable_if<
                            std::is_same<T, std::nullptr_t>::value ||
                            (std::is_integral<T>::value &&
                             !std::is_same<T, int>::value)>::type>
  OnlyLiteralZero(T) {  // NOLINT
    static_assert(sizeof(T) < 0, "Only literal `0` is allowed.");
  }
};

enum class eq : value_type {
  equal = 0,
  equivalent = equal,
  nonequal = 1,
  nonequivalent = nonequal,
};

enum class ord : value_type { less = -1, greater = 1 };

enum class ncmp : value_type { unordered = -127 };

// Define macros to allow for creation or emulation of C++17 inline variables
// based on whether the feature is supported. Note: we can't use
// ABSL_INTERNAL_INLINE_CONSTEXPR here because the variables here are of
// incomplete types so they need to be defined after the types are complete.
#ifdef __cpp_inline_variables

// A no-op expansion that can be followed by a semicolon at class level.
#define ABSL_COMPARE_INLINE_BASECLASS_DECL(name) static_assert(true, "")

#define ABSL_COMPARE_INLINE_SUBCLASS_DECL(type, name) \
  static const type name

#define ABSL_COMPARE_INLINE_INIT(type, name, init) \
  inline constexpr type type::name(init)

#else  // __cpp_inline_variables

#define ABSL_COMPARE_INLINE_BASECLASS_DECL(name) \
  ABSL_CONST_INIT static const T name

// A no-op expansion that can be followed by a semicolon at class level.
#define ABSL_COMPARE_INLINE_SUBCLASS_DECL(type, name) static_assert(true, "")

#define ABSL_COMPARE_INLINE_INIT(type, name, init) \
  template <typename T>                            \
  const T compare_internal::type##_base<T>::name(init)

#endif  // __cpp_inline_variables

// These template base classes allow for defining the values of the constants
// in the header file (for performance) without using inline variables (which
// aren't available in C++11).
template <typename T>
struct partial_ordering_base {
  ABSL_COMPARE_INLINE_BASECLASS_DECL(less);
  ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent);
  ABSL_COMPARE_INLINE_BASECLASS_DECL(greater);
  ABSL_COMPARE_INLINE_BASECLASS_DECL(unordered);
};

template <typename T>
struct weak_ordering_base {
  ABSL_COMPARE_INLINE_BASECLASS_DECL(less);
  ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent);
  ABSL_COMPARE_INLINE_BASECLASS_DECL(greater);
};

template <typename T>
struct strong_ordering_base {
  ABSL_COMPARE_INLINE_BASECLASS_DECL(less);
  ABSL_COMPARE_INLINE_BASECLASS_DECL(equal);
  ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent);
  ABSL_COMPARE_INLINE_BASECLASS_DECL(greater);
};

}  // namespace compare_internal

class partial_ordering
    : public compare_internal::partial_ordering_base<partial_ordering> {
  explicit constexpr partial_ordering(compare_internal::eq v) noexcept
      : value_(static_cast<compare_internal::value_type>(v)) {}
  explicit constexpr partial_ordering(compare_internal::ord v) noexcept
      : value_(static_cast<compare_internal::value_type>(v)) {}
  explicit constexpr partial_ordering(compare_internal::ncmp v) noexcept
      : value_(static_cast<compare_internal::value_type>(v)) {}
  friend struct compare_internal::partial_ordering_base<partial_ordering>;

  constexpr bool is_ordered() const noexcept {
    return value_ !=
           compare_internal::value_type(compare_internal::ncmp::unordered);
  }

 public:
  ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, less);
  ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, equivalent);
  ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, greater);
  ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, unordered);

  // Comparisons
  friend constexpr bool operator==(
      partial_ordering v, compare_internal::OnlyLiteralZero) noexcept {
    return v.is_ordered() && v.value_ == 0;
  }
  friend constexpr bool operator!=(
      partial_ordering v, compare_internal::OnlyLiteralZero) noexcept {
    return !v.is_ordered() || v.value_ != 0;
  }
  friend constexpr bool operator<(
      partial_ordering v, compare_internal::OnlyLiteralZero) noexcept {
    return v.is_ordered() && v.value_ < 0;
  }
  friend constexpr bool operator<=(
      partial_ordering v, compare_internal::OnlyLiteralZero) noexcept {
    return v.is_ordered() && v.value_ <= 0;
  }
  friend constexpr bool operator>(
      partial_ordering v, compare_internal::OnlyLiteralZero) noexcept {
    return v.is_ordered() && v.value_ > 0;
  }
  friend constexpr bool operator>=(
      partial_ordering v, compare_internal::OnlyLiteralZero) noexcept {
    return v.is_ordered() && v.value_ >= 0;
  }
  friend constexpr bool operator==(compare_internal::OnlyLiteralZero,
                                   partial_ordering v) noexcept {
    return v.is_ordered() && 0 == v.value_;
  }
  friend constexpr bool operator!=(compare_internal::OnlyLiteralZero,
                                   partial_ordering v) noexcept {
    return !v.is_ordered() || 0 != v.value_;
  }
  friend constexpr bool operator<(compare_internal::OnlyLiteralZero,
                                  partial_ordering v) noexcept {
    return v.is_ordered() && 0 < v.value_;
  }
  friend constexpr bool operator<=(compare_internal::OnlyLiteralZero,
                                   partial_ordering v) noexcept {
    return v.is_ordered() && 0 <= v.value_;
  }
  friend constexpr bool operator>(compare_internal::OnlyLiteralZero,
                                  partial_ordering v) noexcept {
    return v.is_ordered() && 0 > v.value_;
  }
  friend constexpr bool operator>=(compare_internal::OnlyLiteralZero,
                                   partial_ordering v) noexcept {
    return v.is_ordered() && 0 >= v.value_;
  }
  friend constexpr bool operator==(partial_ordering v1,
                                   partial_ordering v2) noexcept {
    return v1.value_ == v2.value_;
  }
  friend constexpr bool operator!=(partial_ordering v1,
                                   partial_ordering v2) noexcept {
    return v1.value_ != v2.value_;
  }

 private:
  compare_internal::value_type value_;
};
ABSL_COMPARE_INLINE_INIT(partial_ordering, less, compare_internal::ord::less);
ABSL_COMPARE_INLINE_INIT(partial_ordering, equivalent,
                         compare_internal::eq::equivalent);
ABSL_COMPARE_INLINE_INIT(partial_ordering, greater,
                         compare_internal::ord::greater);
ABSL_COMPARE_INLINE_INIT(partial_ordering, unordered,
                         compare_internal::ncmp::unordered);

class weak_ordering
    : public compare_internal::weak_ordering_base<weak_ordering> {
  explicit constexpr weak_ordering(compare_internal::eq v) noexcept
      : value_(static_cast<compare_internal::value_type>(v)) {}
  explicit constexpr weak_ordering(compare_internal::ord v) noexcept
      : value_(static_cast<compare_internal::value_type>(v)) {}
  friend struct compare_internal::weak_ordering_base<weak_ordering>;

 public:
  ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, less);
  ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, equivalent);
  ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, greater);

  // Conversions
  constexpr operator partial_ordering() const noexcept {  // NOLINT
    return value_ == 0 ? partial_ordering::equivalent
                       : (value_ < 0 ? partial_ordering::less
                                     : partial_ordering::greater);
  }
  // Comparisons
  friend constexpr bool operator==(
      weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
    return v.value_ == 0;
  }
  friend constexpr bool operator!=(
      weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
    return v.value_ != 0;
  }
  friend constexpr bool operator<(
      weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
    return v.value_ < 0;
  }
  friend constexpr bool operator<=(
      weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
    return v.value_ <= 0;
  }
  friend constexpr bool operator>(
      weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
    return v.value_ > 0;
  }
  friend constexpr bool operator>=(
      weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
    return v.value_ >= 0;
  }
  friend constexpr bool operator==(compare_internal::OnlyLiteralZero,
                                   weak_ordering v) noexcept {
    return 0 == v.value_;
  }
  friend constexpr bool operator!=(compare_internal::OnlyLiteralZero,
                                   weak_ordering v) noexcept {
    return 0 != v.value_;
  }
  friend constexpr bool operator<(compare_internal::OnlyLiteralZero,
                                  weak_ordering v) noexcept {
    return 0 < v.value_;
  }
  friend constexpr bool operator<=(compare_internal::OnlyLiteralZero,
                                   weak_ordering v) noexcept {
    return 0 <= v.value_;
  }
  friend constexpr bool operator>(compare_internal::OnlyLiteralZero,
                                  weak_ordering v) noexcept {
    return 0 > v.value_;
  }
  friend constexpr bool operator>=(compare_internal::OnlyLiteralZero,
                                   weak_ordering v) noexcept {
    return 0 >= v.value_;
  }
  friend constexpr bool operator==(weak_ordering v1,
                                   weak_ordering v2) noexcept {
    return v1.value_ == v2.value_;
  }
  friend constexpr bool operator!=(weak_ordering v1,
                                   weak_ordering v2) noexcept {
    return v1.value_ != v2.value_;
  }

 private:
  compare_internal::value_type value_;
};
ABSL_COMPARE_INLINE_INIT(weak_ordering, less, compare_internal::ord::less);
ABSL_COMPARE_INLINE_INIT(weak_ordering, equivalent,
                         compare_internal::eq::equivalent);
ABSL_COMPARE_INLINE_INIT(weak_ordering, greater,
                         compare_internal::ord::greater);

class strong_ordering
    : public compare_internal::strong_ordering_base<strong_ordering> {
  explicit constexpr strong_ordering(compare_internal::eq v) noexcept
      : value_(static_cast<compare_internal::value_type>(v)) {}
  explicit constexpr strong_ordering(compare_internal::ord v) noexcept
      : value_(static_cast<compare_internal::value_type>(v)) {}
  friend struct compare_internal::strong_ordering_base<strong_ordering>;

 public:
  ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, less);
  ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, equal);
  ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, equivalent);
  ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, greater);

  // Conversions
  constexpr operator partial_ordering() const noexcept {  // NOLINT
    return value_ == 0 ? partial_ordering::equivalent
                       : (value_ < 0 ? partial_ordering::less
                                     : partial_ordering::greater);
  }
  constexpr operator weak_ordering() const noexcept {  // NOLINT
    return value_ == 0
               ? weak_ordering::equivalent
               : (value_ < 0 ? weak_ordering::less : weak_ordering::greater);
  }
  // Comparisons
  friend constexpr bool operator==(
      strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
    return v.value_ == 0;
  }
  friend constexpr bool operator!=(
      strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
    return v.value_ != 0;
  }
  friend constexpr bool operator<(
      strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
    return v.value_ < 0;
  }
  friend constexpr bool operator<=(
      strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
    return v.value_ <= 0;
  }
  friend constexpr bool operator>(
      strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
    return v.value_ > 0;
  }
  friend constexpr bool operator>=(
      strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
    return v.value_ >= 0;
  }
  friend constexpr bool operator==(compare_internal::OnlyLiteralZero,
                                   strong_ordering v) noexcept {
    return 0 == v.value_;
  }
  friend constexpr bool operator!=(compare_internal::OnlyLiteralZero,
                                   strong_ordering v) noexcept {
    return 0 != v.value_;
  }
  friend constexpr bool operator<(compare_internal::OnlyLiteralZero,
                                  strong_ordering v) noexcept {
    return 0 < v.value_;
  }
  friend constexpr bool operator<=(compare_internal::OnlyLiteralZero,
                                   strong_ordering v) noexcept {
    return 0 <= v.value_;
  }
  friend constexpr bool operator>(compare_internal::OnlyLiteralZero,
                                  strong_ordering v) noexcept {
    return 0 > v.value_;
  }
  friend constexpr bool operator>=(compare_internal::OnlyLiteralZero,
                                   strong_ordering v) noexcept {
    return 0 >= v.value_;
  }
  friend constexpr bool operator==(strong_ordering v1,
                                   strong_ordering v2) noexcept {
    return v1.value_ == v2.value_;
  }
  friend constexpr bool operator!=(strong_ordering v1,
                                   strong_ordering v2) noexcept {
    return v1.value_ != v2.value_;
  }

 private:
  compare_internal::value_type value_;
};
ABSL_COMPARE_INLINE_INIT(strong_ordering, less, compare_internal::ord::less);
ABSL_COMPARE_INLINE_INIT(strong_ordering, equal, compare_internal::eq::equal);
ABSL_COMPARE_INLINE_INIT(strong_ordering, equivalent,
                         compare_internal::eq::equivalent);
ABSL_COMPARE_INLINE_INIT(strong_ordering, greater,
                         compare_internal::ord::greater);

#undef ABSL_COMPARE_INLINE_BASECLASS_DECL
#undef ABSL_COMPARE_INLINE_SUBCLASS_DECL
#undef ABSL_COMPARE_INLINE_INIT

#endif  // ABSL_USES_STD_ORDERING

namespace compare_internal {
// We also provide these comparator adapter functions for internal absl use.

// Helper functions to do a boolean comparison of two keys given a boolean
// or three-way comparator.
// SFINAE prevents implicit conversions to bool (such as from int).
template <typename BoolT,
          absl::enable_if_t<std::is_same<bool, BoolT>::value, int> = 0>
constexpr bool compare_result_as_less_than(const BoolT r) { return r; }
constexpr bool compare_result_as_less_than(const absl::weak_ordering r) {
  return r < 0;
}

template <typename Compare, typename K, typename LK>
constexpr bool do_less_than_comparison(const Compare &compare, const K &x,
                                       const LK &y) {
  return compare_result_as_less_than(compare(x, y));
}

// Helper functions to do a three-way comparison of two keys given a boolean or
// three-way comparator.
// SFINAE prevents implicit conversions to int (such as from bool).
template <typename Int,
          absl::enable_if_t<std::is_same<int, Int>::value, int> = 0>
constexpr absl::weak_ordering compare_result_as_ordering(const Int c) {
  return c < 0 ? absl::weak_ordering::less
               : c == 0 ? absl::weak_ordering::equivalent
                        : absl::weak_ordering::greater;
}
constexpr absl::weak_ordering compare_result_as_ordering(
    const absl::weak_ordering c) {
  return c;
}

template <
    typename Compare, typename K, typename LK,
    absl::enable_if_t<!std::is_same<bool, absl::result_of_t<Compare(
                                              const K &, const LK &)>>::value,
                      int> = 0>
constexpr absl::weak_ordering do_three_way_comparison(const Compare &compare,
                                                      const K &x, const LK &y) {
  return compare_result_as_ordering(compare(x, y));
}
template <
    typename Compare, typename K, typename LK,
    absl::enable_if_t<std::is_same<bool, absl::result_of_t<Compare(
                                             const K &, const LK &)>>::value,
                      int> = 0>
constexpr absl::weak_ordering do_three_way_comparison(const Compare &compare,
                                                      const K &x, const LK &y) {
  return compare(x, y) ? absl::weak_ordering::less
                       : compare(y, x) ? absl::weak_ordering::greater
                                       : absl::weak_ordering::equivalent;
}

}  // namespace compare_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_TYPES_COMPARE_H_
*×š
rsoong/.intermediates/external/abseil-cpp/absl_strings_str_format_hdrs/gen/my_include_dir/absl/strings/str_format.hß™//
// Copyright 2018 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// File: str_format.h
// -----------------------------------------------------------------------------
//
// The `str_format` library is a typesafe replacement for the family of
// `printf()` string formatting routines within the `<cstdio>` standard library
// header. Like the `printf` family, `str_format` uses a "format string" to
// perform argument substitutions based on types. See the `FormatSpec` section
// below for format string documentation.
//
// Example:
//
//   std::string s = absl::StrFormat(
//                      "%s %s You have $%d!", "Hello", name, dollars);
//
// The library consists of the following basic utilities:
//
//   * `absl::StrFormat()`, a type-safe replacement for `std::sprintf()`, to
//     write a format string to a `string` value.
//   * `absl::StrAppendFormat()` to append a format string to a `string`
//   * `absl::StreamFormat()` to more efficiently write a format string to a
//     stream, such as`std::cout`.
//   * `absl::PrintF()`, `absl::FPrintF()` and `absl::SNPrintF()` as
//     drop-in replacements for `std::printf()`, `std::fprintf()` and
//     `std::snprintf()`.
//
//     Note: An `absl::SPrintF()` drop-in replacement is not supported as it
//     is generally unsafe due to buffer overflows. Use `absl::StrFormat` which
//     returns the string as output instead of expecting a pre-allocated buffer.
//
// Additionally, you can provide a format string (and its associated arguments)
// using one of the following abstractions:
//
//   * A `FormatSpec` class template fully encapsulates a format string and its
//     type arguments and is usually provided to `str_format` functions as a
//     variadic argument of type `FormatSpec<Arg...>`. The `FormatSpec<Args...>`
//     template is evaluated at compile-time, providing type safety.
//   * A `ParsedFormat` instance, which encapsulates a specific, pre-compiled
//     format string for a specific set of type(s), and which can be passed
//     between API boundaries. (The `FormatSpec` type should not be used
//     directly except as an argument type for wrapper functions.)
//
// The `str_format` library provides the ability to output its format strings to
// arbitrary sink types:
//
//   * A generic `Format()` function to write outputs to arbitrary sink types,
//     which must implement a `FormatRawSink` interface.
//
//   * A `FormatUntyped()` function that is similar to `Format()` except it is
//     loosely typed. `FormatUntyped()` is not a template and does not perform
//     any compile-time checking of the format string; instead, it returns a
//     boolean from a runtime check.
//
// In addition, the `str_format` library provides extension points for
// augmenting formatting to new types.  See "StrFormat Extensions" below.

#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

// UntypedFormatSpec
//
// A type-erased class that can be used directly within untyped API entry
// points. An `UntypedFormatSpec` is specifically used as an argument to
// `FormatUntyped()`.
//
// Example:
//
//   absl::UntypedFormatSpec format("%d");
//   std::string out;
//   CHECK(absl::FormatUntyped(&out, format, {absl::FormatArg(1)}));
class UntypedFormatSpec {
 public:
  UntypedFormatSpec() = delete;
  UntypedFormatSpec(const UntypedFormatSpec&) = delete;
  UntypedFormatSpec& operator=(const UntypedFormatSpec&) = delete;

  explicit UntypedFormatSpec(string_view s) : spec_(s) {}

 protected:
  explicit UntypedFormatSpec(
      const str_format_internal::ParsedFormatBase* absl_nonnull pc)
      : spec_(pc) {}

 private:
  friend str_format_internal::UntypedFormatSpecImpl;
  str_format_internal::UntypedFormatSpecImpl spec_;
};

// FormatStreamed()
//
// Takes a streamable argument and returns an object that can print it
// with '%s'. Allows printing of types that have an `operator<<` but no
// intrinsic type support within `StrFormat()` itself.
//
// Example:
//
//   absl::StrFormat("%s", absl::FormatStreamed(obj));
template <typename T>
str_format_internal::StreamedWrapper<T> FormatStreamed(const T& v) {
  return str_format_internal::StreamedWrapper<T>(v);
}

// FormatCountCapture
//
// This class provides a way to safely wrap `StrFormat()` captures of `%n`
// conversions, which denote the number of characters written by a formatting
// operation to this point, into an integer value.
//
// This wrapper is designed to allow safe usage of `%n` within `StrFormat(); in
// the `printf()` family of functions, `%n` is not safe to use, as the `int *`
// buffer can be used to capture arbitrary data.
//
// Example:
//
//   int n = 0;
//   std::string s = absl::StrFormat("%s%d%n", "hello", 123,
//                       absl::FormatCountCapture(&n));
//   EXPECT_EQ(8, n);
class FormatCountCapture {
 public:
  explicit FormatCountCapture(int* absl_nonnull p) : p_(p) {}

 private:
  // FormatCountCaptureHelper is used to define FormatConvertImpl() for this
  // class.
  friend struct str_format_internal::FormatCountCaptureHelper;
  // 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* absl_nonnull Unused() { return p_; }
  int* absl_nonnull p_;
};

// FormatSpec
//
// The `FormatSpec` type defines the makeup of a format string within the
// `str_format` library. It is a variadic class template that is evaluated at
// compile-time, according to the format string and arguments that are passed to
// it.
//
// You should not need to manipulate this type directly. You should only name it
// if you are writing wrapper functions which accept format arguments that will
// be provided unmodified to functions in this library. Such a wrapper function
// might be a class method that provides format arguments and/or internally uses
// the result of formatting.
//
// For a `FormatSpec` to be valid at compile-time, it must be provided as
// either:
//
// * A `constexpr` literal or `absl::string_view`, which is how it is most often
//   used.
// * A `ParsedFormat` instantiation, which ensures the format string is
//   valid before use. (See below.)
//
// Example:
//
//   // Provided as a string literal.
//   absl::StrFormat("Welcome to %s, Number %d!", "The Village", 6);
//
//   // Provided as a constexpr absl::string_view.
//   constexpr absl::string_view formatString = "Welcome to %s, Number %d!";
//   absl::StrFormat(formatString, "The Village", 6);
//
//   // Provided as a pre-compiled ParsedFormat object.
//   // Note that this example is useful only for illustration purposes.
//   absl::ParsedFormat<'s', 'd'> formatString("Welcome to %s, Number %d!");
//   absl::StrFormat(formatString, "TheVillage", 6);
//
// A format string generally follows the POSIX syntax as used within the POSIX
// `printf` specification. (Exceptions are noted below.)
//
// (See http://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html)
//
// In specific, the `FormatSpec` supports the following type specifiers:
//   * `c` for characters
//   * `s` for strings
//   * `d` or `i` for integers
//   * `o` for unsigned integer conversions into octal
//   * `x` or `X` for unsigned integer conversions into hex
//   * `u` for unsigned integers
//   * `f` or `F` for floating point values into decimal notation
//   * `e` or `E` for floating point values into exponential notation
//   * `a` or `A` for floating point values into hex exponential notation
//   * `g` or `G` for floating point values into decimal or exponential
//     notation based on their precision
//   * `p` for pointer address values
//   * `n` for the special case of writing out the number of characters
//     written to this point. The resulting value must be captured within an
//     `absl::FormatCountCapture` type.
//   * `v` for values using the default format for a deduced type. These deduced
//     types include many of the primitive types denoted here as well as
//     user-defined types containing the proper extensions. (See below for more
//     information.)
//
// Implementation-defined behavior:
//   * A null pointer provided to "%s" or "%p" is output as "(nil)".
//   * A non-null pointer provided to "%p" is output in hex as if by %#x or
//     %#lx.
//
// NOTE: `o`, `x\X` and `u` will convert signed values to their unsigned
// counterpart before formatting.
//
// Examples:
//     "%c", 'a'                -> "a"
//     "%c", 32                 -> " "
//     "%s", "C"                -> "C"
//     "%s", std::string("C++") -> "C++"
//     "%d", -10                -> "-10"
//     "%o", 10                 -> "12"
//     "%x", 16                 -> "10"
//     "%f", 123456789          -> "123456789.000000"
//     "%e", .01                -> "1.00000e-2"
//     "%a", -3.0               -> "-0x1.8p+1"
//     "%g", .01                -> "1e-2"
//     "%p", (void*)&value      -> "0x7ffdeb6ad2a4"
//
//     int n = 0;
//     std::string s = absl::StrFormat(
//         "%s%d%n", "hello", 123, absl::FormatCountCapture(&n));
//     EXPECT_EQ(8, n);
//
// NOTE: the `v` specifier (for "value") is a type specifier not present in the
// POSIX specification. %v will format values according to their deduced type.
// `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 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`, `wchar_t`
// *   Integers: `int`, `short`, `unsigned short`, `unsigned`, `long`,
//         `unsigned long`, `long long`, `unsigned long long`
// *   Enums: printed as their underlying integral value
// *   Floating-point: `float`, `double`, `long double`
//
// 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`, `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<
    str_format_internal::ArgumentToConv<Args>()...>;

// ParsedFormat
//
// A `ParsedFormat` is a class template representing a preparsed `FormatSpec`,
// with template arguments specifying the conversion characters used within the
// format string. Such characters must be valid format type specifiers, and
// these type specifiers are checked at compile-time.
//
// Instances of `ParsedFormat` can be created, copied, and reused to speed up
// formatting loops. A `ParsedFormat` may either be constructed statically, or
// dynamically through its `New()` factory function, which only constructs a
// runtime object if the format is valid at that time.
//
// Example:
//
//   // Verified at compile time.
//   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);
//   if (format_runtime) {
//     value = absl::StrFormat(*format_runtime, i);
//   } else {
//     ... error case ...
//   }

#if defined(__cpp_nontype_template_parameter_auto)
// If C++17 is available, an 'extended' format is also allowed that can specify
// multiple conversion characters per format argument, using a combination of
// `absl::FormatConversionCharSet` enum values (logically a set union)
//  via the `|` operator. (Single character-based arguments are still accepted,
// but cannot be combined). Some common conversions also have predefined enum
// values, such as `absl::FormatConversionCharSet::kIntegral`.
//
// Example:
//   // Extended format supports multiple conversion characters per argument,
//   // specified via a combination of `FormatConversionCharSet` enums.
//   using MyFormat = absl::ParsedFormat<absl::FormatConversionCharSet::d |
//                                       absl::FormatConversionCharSet::x>;
//   MyFormat GetFormat(bool use_hex) {
//     if (use_hex) return MyFormat("foo %x bar");
//     return MyFormat("foo %d bar");
//   }
//   // `format` can be used with any value that supports 'd' and 'x',
//   // like `int`.
//   auto format = GetFormat(use_hex);
//   value = StringF(format, i);
template <auto... Conv>
using ParsedFormat = absl::str_format_internal::ExtendedParsedFormat<
    absl::str_format_internal::ToFormatConversionCharSet(Conv)...>;
#else
template <char... Conv>
using ParsedFormat = str_format_internal::ExtendedParsedFormat<
    absl::str_format_internal::ToFormatConversionCharSet(Conv)...>;
#endif  // defined(__cpp_nontype_template_parameter_auto)

// StrFormat()
//
// Returns a `string` given a `printf()`-style format string and zero or more
// additional arguments. Use it as you would `sprintf()`. `StrFormat()` is the
// primary formatting function within the `str_format` library, and should be
// used in most cases where you need type-safe conversion of types into
// formatted strings.
//
// The format string generally consists of ordinary character data along with
// one or more format conversion specifiers (denoted by the `%` character).
// Ordinary character data is returned unchanged into the result string, while
// each conversion specification performs a type substitution from
// `StrFormat()`'s other arguments. See the comments for `FormatSpec` for full
// information on the makeup of this format string.
//
// Example:
//
//   std::string s = absl::StrFormat(
//       "Welcome to %s, Number %d!", "The Village", 6);
//   EXPECT_EQ("Welcome to The Village, Number 6!", s);
//
// Returns an empty string in case of error.
template <typename... Args>
[[nodiscard]] std::string StrFormat(const FormatSpec<Args...>& format,
                                    const Args&... args) {
  return str_format_internal::FormatPack(
      str_format_internal::UntypedFormatSpecImpl::Extract(format),
      {str_format_internal::FormatArgImpl(args)...});
}

// StrAppendFormat()
//
// Appends to a `dst` string given a format string, and zero or more additional
// arguments, returning `*dst` as a convenience for chaining purposes. Appends
// nothing in case of error (but possibly alters its capacity).
//
// Example:
//
//   std::string orig("For example PI is approximately ");
//   std::cout << StrAppendFormat(&orig, "%12.6f", 3.14);
template <typename... Args>
std::string& StrAppendFormat(std::string* absl_nonnull dst,
                             const FormatSpec<Args...>& format,
                             const Args&... args) {
  return str_format_internal::AppendPack(
      dst, str_format_internal::UntypedFormatSpecImpl::Extract(format),
      {str_format_internal::FormatArgImpl(args)...});
}

// StreamFormat()
//
// 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
// expression ends.
//
// Example:
//
//   std::cout << StreamFormat("%12.6f", 3.14);
template <typename... Args>
[[nodiscard]] str_format_internal::Streamable StreamFormat(
    const FormatSpec<Args...>& format, const Args&... args) {
  return str_format_internal::Streamable(
      str_format_internal::UntypedFormatSpecImpl::Extract(format),
      {str_format_internal::FormatArgImpl(args)...});
}

// PrintF()
//
// Writes to stdout given a format string and zero or more arguments. This
// function is functionally equivalent to `std::printf()` (and type-safe);
// prefer `absl::PrintF()` over `std::printf()`.
//
// Example:
//
//   std::string_view s = "Ulaanbaatar";
//   absl::PrintF("The capital of Mongolia is %s", s);
//
//   Outputs: "The capital of Mongolia is Ulaanbaatar"
//
template <typename... Args>
int PrintF(const FormatSpec<Args...>& format, const Args&... args) {
  return str_format_internal::FprintF(
      stdout, str_format_internal::UntypedFormatSpecImpl::Extract(format),
      {str_format_internal::FormatArgImpl(args)...});
}

// FPrintF()
//
// Writes to a file given a format string and zero or more arguments. This
// function is functionally equivalent to `std::fprintf()` (and type-safe);
// prefer `absl::FPrintF()` over `std::fprintf()`.
//
// Example:
//
//   std::string_view s = "Ulaanbaatar";
//   absl::FPrintF(stdout, "The capital of Mongolia is %s", s);
//
//   Outputs: "The capital of Mongolia is Ulaanbaatar"
//
template <typename... Args>
int FPrintF(std::FILE* absl_nonnull output, const FormatSpec<Args...>& format,
            const Args&... args) {
  return str_format_internal::FprintF(
      output, str_format_internal::UntypedFormatSpecImpl::Extract(format),
      {str_format_internal::FormatArgImpl(args)...});
}

// SNPrintF()
//
// Writes to a sized buffer given a format string and zero or more arguments.
// This function is functionally equivalent to `std::snprintf()` (and
// type-safe); prefer `absl::SNPrintF()` over `std::snprintf()`.
//
// In particular, a successful call to `absl::SNPrintF()` writes at most `size`
// bytes of the formatted output to `output`, including a NUL-terminator, and
// returns the number of bytes that would have been written if truncation did
// not occur. In the event of an error, a negative value is returned and `errno`
// is set.
//
// Example:
//
//   std::string_view s = "Ulaanbaatar";
//   char output[128];
//   absl::SNPrintF(output, sizeof(output),
//                  "The capital of Mongolia is %s", s);
//
//   Post-condition: output == "The capital of Mongolia is Ulaanbaatar"
//
template <typename... Args>
int SNPrintF(char* absl_nonnull 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)...});
}

// -----------------------------------------------------------------------------
// Custom Output Formatting Functions
// -----------------------------------------------------------------------------

// FormatRawSink
//
// FormatRawSink is a type erased wrapper around arbitrary sink objects
// specifically used as an argument to `Format()`.
//
// All the object has to do define an overload of `AbslFormatFlush()` for the
// sink, usually by adding a ADL-based free function in the same namespace as
// the sink:
//
//   void AbslFormatFlush(MySink* dest, absl::string_view part);
//
// where `dest` is the pointer passed to `absl::Format()`. The function should
// append `part` to `dest`.
//
// FormatRawSink does not own the passed sink object. The passed object must
// outlive the FormatRawSink.
class FormatRawSink {
 public:
  // Implicitly convert from any type that provides the hook function as
  // described above.
  template <typename T,
            typename = typename std::enable_if<std::is_constructible<
                str_format_internal::FormatRawSinkImpl, T*>::value>::type>
  FormatRawSink(T* absl_nonnull raw)  // NOLINT
      : sink_(raw) {}

 private:
  friend str_format_internal::FormatRawSinkImpl;
  str_format_internal::FormatRawSinkImpl sink_;
};

// Format()
//
// Writes a formatted string to an arbitrary sink object (implementing the
// `absl::FormatRawSink` interface), using a format string and zero or more
// additional arguments.
//
// By default, `std::string`, `std::ostream`, and `absl::Cord` are supported as
// destination objects. If a `std::string` is used the formatted string is
// appended to it.
//
// `absl::Format()` is a generic version of `absl::StrAppendFormat()`, for
// custom sinks. The format string, like format strings for `StrFormat()`, is
// checked at compile-time.
//
// On failure, this function returns `false` and the state of the sink is
// unspecified.
template <typename... Args>
bool Format(FormatRawSink raw_sink, const FormatSpec<Args...>& format,
            const Args&... args) {
  return str_format_internal::FormatUntyped(
      str_format_internal::FormatRawSinkImpl::Extract(raw_sink),
      str_format_internal::UntypedFormatSpecImpl::Extract(format),
      {str_format_internal::FormatArgImpl(args)...});
}

// FormatArg
//
// A type-erased handle to a format argument specifically used as an argument to
// `FormatUntyped()`. You may construct `FormatArg` by passing
// reference-to-const of any printable type. `FormatArg` is both copyable and
// assignable. The source data must outlive the `FormatArg` instance. See
// example below.
//
using FormatArg = str_format_internal::FormatArgImpl;

// FormatUntyped()
//
// Writes a formatted string to an arbitrary sink object (implementing the
// `absl::FormatRawSink` interface), using an `UntypedFormatSpec` and zero or
// more additional arguments.
//
// This function acts as the most generic formatting function in the
// `str_format` library. The caller provides a raw sink, an unchecked format
// string, and (usually) a runtime specified list of arguments; no compile-time
// checking of formatting is performed within this function. As a result, a
// caller should check the return value to verify that no error occurred.
// On failure, this function returns `false` and the state of the sink is
// unspecified.
//
// The arguments are provided in an `absl::Span<const absl::FormatArg>`.
// Each `absl::FormatArg` object binds to a single argument and keeps a
// reference to it. The values used to create the `FormatArg` objects must
// outlive this function call.
//
// Example:
//
//   std::optional<std::string> FormatDynamic(
//       const std::string& in_format,
//       const vector<std::string>& in_args) {
//     std::string out;
//     std::vector<absl::FormatArg> args;
//     for (const auto& v : in_args) {
//       // It is important that 'v' is a reference to the objects in in_args.
//       // The values we pass to FormatArg must outlive the call to
//       // FormatUntyped.
//       args.emplace_back(v);
//     }
//     absl::UntypedFormatSpec format(in_format);
//     if (!absl::FormatUntyped(&out, format, args)) {
//       return std::nullopt;
//     }
//     return std::move(out);
//   }
//
[[nodiscard]] inline bool FormatUntyped(FormatRawSink raw_sink,
                                        const UntypedFormatSpec& format,
                                        absl::Span<const FormatArg> args) {
  return str_format_internal::FormatUntyped(
      str_format_internal::FormatRawSinkImpl::Extract(raw_sink),
      str_format_internal::UntypedFormatSpecImpl::Extract(format), args);
}

//------------------------------------------------------------------------------
// StrFormat Extensions
//------------------------------------------------------------------------------
//
// AbslStringify()
//
// A simpler customization API for formatting user-defined types using
// absl::StrFormat(). The API relies on detecting an overload in the
// user-defined type's namespace of a free (non-member) `AbslStringify()`
// function as a friend definition with the following signature:
//
// template <typename Sink>
// void AbslStringify(Sink& sink, const X& value);
//
// An `AbslStringify()` overload for a type should only be declared in the same
// file and namespace as said type.
//
// Note that unlike with AbslFormatConvert(), AbslStringify() does not allow
// customization of allowed conversion characters. AbslStringify() uses `%v` as
// the underlying conversion specifier. Additionally, AbslStringify() supports
// use with absl::StrCat while AbslFormatConvert() does not.
//
// Example:
//
// struct Point {
//   // To add formatting support to `Point`, we simply need to add a free
//   // (non-member) function `AbslStringify()`. This method prints in the
//   // request format using the underlying `%v` specifier. You can add such a
//   // free function using a friend declaration within the body of the class.
//   // The sink parameter is a templated type to avoid requiring dependencies.
//   template <typename Sink>
//   friend void AbslStringify(Sink& sink, const Point& p) {
//     absl::Format(&sink, "(%v, %v)", p.x, p.y);
//   }
//
//   int x;
//   int y;
// };
//
// AbslFormatConvert()
//
// The StrFormat library provides a customization API for formatting
// user-defined types using absl::StrFormat(). The API relies on detecting an
// overload in the user-defined type's namespace of a free (non-member)
// `AbslFormatConvert()` function, usually as a friend definition with the
// following signature:
//
// absl::FormatConvertResult<...> AbslFormatConvert(
//     const X& value,
//     const absl::FormatConversionSpec& spec,
//     absl::FormatSink *sink);
//
// An `AbslFormatConvert()` overload for a type should only be declared in the
// same file and namespace as said type.
//
// The abstractions within this definition include:
//
// * An `absl::FormatConversionSpec` to specify the fields to pull from a
//   user-defined type's format string
// * An `absl::FormatSink` to hold the converted string data during the
//   conversion process.
// * An `absl::FormatConvertResult` to hold the status of the returned
//   formatting operation
//
// The return type encodes all the conversion characters that your
// AbslFormatConvert() routine accepts.  The return value should be {true}.
// A return value of {false} will result in `StrFormat()` returning
// an empty string.  This result will be propagated to the result of
// `FormatUntyped`.
//
// Example:
//
// struct Point {
//   // To add formatting support to `Point`, we simply need to add a free
//   // (non-member) function `AbslFormatConvert()`.  This method interprets
//   // `spec` to print in the request format. The allowed conversion characters
//   // can be restricted via the type of the result, in this example
//   // string and integral formatting are allowed (but not, for instance
//   // floating point characters like "%f").  You can add such a free function
//   // using a friend declaration within the body of the class:
//   friend absl::FormatConvertResult<absl::FormatConversionCharSet::kString |
//                                    absl::FormatConversionCharSet::kIntegral>
//   AbslFormatConvert(const Point& p, const absl::FormatConversionSpec& spec,
//                     absl::FormatSink* s) {
//     if (spec.conversion_char() == absl::FormatConversionChar::s) {
//       absl::Format(s, "x=%vy=%v", p.x, p.y);
//     } else {
//       absl::Format(s, "%v,%v", p.x, p.y);
//     }
//     return {true};
//   }
//
//   int x;
//   int y;
// };

// clang-format off

// FormatConversionChar
//
// Specifies the formatting character provided in the format string
// passed to `StrFormat()`.
enum class FormatConversionChar : uint8_t {
  c, s,                    // text
  d, i, o, u, x, X,        // int
  f, F, e, E, g, G, a, A,  // float
  n, p, v                  // misc
};
// clang-format on

// FormatConversionSpec
//
// Specifies modifications to the conversion of the format string, through use
// of one or more format flags in the source format string.
class FormatConversionSpec {
 public:
  // FormatConversionSpec::is_basic()
  //
  // Indicates that width and precision are not specified, and no additional
  // flags are set for this conversion character in the format string.
  bool is_basic() const { return impl_.is_basic(); }

  // FormatConversionSpec::has_left_flag()
  //
  // Indicates whether the result should be left justified for this conversion
  // character in the format string. This flag is set through use of a '-'
  // character in the format string. E.g. "%-s"
  bool has_left_flag() const { return impl_.has_left_flag(); }

  // FormatConversionSpec::has_show_pos_flag()
  //
  // Indicates whether a sign column is prepended to the result for this
  // conversion character in the format string, even if the result is positive.
  // This flag is set through use of a '+' character in the format string.
  // E.g. "%+d"
  bool has_show_pos_flag() const { return impl_.has_show_pos_flag(); }

  // FormatConversionSpec::has_sign_col_flag()
  //
  // Indicates whether a mandatory sign column is added to the result for this
  // conversion character. This flag is set through use of a space character
  // (' ') in the format string. E.g. "% i"
  bool has_sign_col_flag() const { return impl_.has_sign_col_flag(); }

  // FormatConversionSpec::has_alt_flag()
  //
  // Indicates whether an "alternate" format is applied to the result for this
  // conversion character. Alternative forms depend on the type of conversion
  // character, and unallowed alternatives are undefined. This flag is set
  // through use of a '#' character in the format string. E.g. "%#h"
  bool has_alt_flag() const { return impl_.has_alt_flag(); }

  // FormatConversionSpec::has_zero_flag()
  //
  // Indicates whether zeroes should be prepended to the result for this
  // conversion character instead of spaces. This flag is set through use of the
  // '0' character in the format string. E.g. "%0f"
  bool has_zero_flag() const { return impl_.has_zero_flag(); }

  // FormatConversionSpec::conversion_char()
  //
  // Returns the underlying conversion character.
  FormatConversionChar conversion_char() const {
    return impl_.conversion_char();
  }

  // FormatConversionSpec::width()
  //
  // Returns the specified width (indicated through use of a non-zero integer
  // value or '*' character) of the conversion character. If width is
  // unspecified, it returns a negative value.
  int width() const { return impl_.width(); }

  // FormatConversionSpec::precision()
  //
  // Returns the specified precision (through use of the '.' character followed
  // by a non-zero integer value or '*' character) of the conversion character.
  // If precision is unspecified, it returns a negative value.
  int precision() const { return impl_.precision(); }

 private:
  explicit FormatConversionSpec(
      str_format_internal::FormatConversionSpecImpl impl)
      : impl_(impl) {}

  friend str_format_internal::FormatConversionSpecImpl;

  absl::str_format_internal::FormatConversionSpecImpl impl_;
};

// Type safe OR operator for FormatConversionCharSet to allow accepting multiple
// conversion chars in custom format converters.
constexpr FormatConversionCharSet operator|(FormatConversionCharSet a,
                                            FormatConversionCharSet b) {
  return static_cast<FormatConversionCharSet>(static_cast<uint64_t>(a) |
                                              static_cast<uint64_t>(b));
}

// FormatConversionCharSet
//
// Specifies the _accepted_ conversion types as a template parameter to
// FormatConvertResult for custom implementations of `AbslFormatConvert`.
// Note the helper predefined alias definitions (kIntegral, etc.) below.
enum class FormatConversionCharSet : uint64_t {
  // text
  c = str_format_internal::FormatConversionCharToConvInt('c'),
  s = str_format_internal::FormatConversionCharToConvInt('s'),
  // integer
  d = str_format_internal::FormatConversionCharToConvInt('d'),
  i = str_format_internal::FormatConversionCharToConvInt('i'),
  o = str_format_internal::FormatConversionCharToConvInt('o'),
  u = str_format_internal::FormatConversionCharToConvInt('u'),
  x = str_format_internal::FormatConversionCharToConvInt('x'),
  X = str_format_internal::FormatConversionCharToConvInt('X'),
  // Float
  f = str_format_internal::FormatConversionCharToConvInt('f'),
  F = str_format_internal::FormatConversionCharToConvInt('F'),
  e = str_format_internal::FormatConversionCharToConvInt('e'),
  E = str_format_internal::FormatConversionCharToConvInt('E'),
  g = str_format_internal::FormatConversionCharToConvInt('g'),
  G = str_format_internal::FormatConversionCharToConvInt('G'),
  a = str_format_internal::FormatConversionCharToConvInt('a'),
  A = str_format_internal::FormatConversionCharToConvInt('A'),
  // misc
  n = str_format_internal::FormatConversionCharToConvInt('n'),
  p = str_format_internal::FormatConversionCharToConvInt('p'),
  v = str_format_internal::FormatConversionCharToConvInt('v'),

  // Used for width/precision '*' specification.
  kStar = static_cast<uint64_t>(
      absl::str_format_internal::FormatConversionCharSetInternal::kStar),
  // Some predefined values:
  kIntegral = d | i | u | o | x | X,
  kFloating = a | e | f | g | A | E | F | G,
  kNumeric = kIntegral | kFloating,
  kString = s,
  kPointer = p,
};

// FormatSink
//
// A format sink is a generic abstraction to which conversions may write their
// formatted string data. `absl::FormatConvert()` uses this sink to write its
// formatted string.
//
class FormatSink {
 public:
  // FormatSink::Append()
  //
  // Appends `count` copies of `ch` to the format sink.
  void Append(size_t count, char ch) { sink_->Append(count, ch); }

  // Overload of FormatSink::Append() for appending the characters of a string
  // view to a format sink.
  void Append(string_view v) { sink_->Append(v); }

  // FormatSink::PutPaddedString()
  //
  // Appends `precision` number of bytes of `v` to the format sink. If this is
  // less than `width`, spaces will be appended first (if `left` is false), or
  // after (if `left` is true) to ensure the total amount appended is
  // at least `width`.
  bool PutPaddedString(string_view v, int width, int precision, bool left) {
    return sink_->PutPaddedString(v, width, precision, left);
  }

  // Support `absl::Format(&sink, format, args...)`.
  friend void AbslFormatFlush(FormatSink* absl_nonnull sink,
                              absl::string_view v) {
    sink->Append(v);
  }

 private:
  friend str_format_internal::FormatSinkImpl;
  explicit FormatSink(str_format_internal::FormatSinkImpl* absl_nonnull s)
      : sink_(s) {}
  str_format_internal::FormatSinkImpl* absl_nonnull sink_;
};

// FormatConvertResult
//
// Indicates whether a call to AbslFormatConvert() was successful.
// This return type informs the StrFormat extension framework (through
// ADL but using the return type) of what conversion characters are supported.
// It is strongly discouraged to return {false}, as this will result in an
// empty string in StrFormat.
template <FormatConversionCharSet C>
struct FormatConvertResult {
  bool value;
};

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_STR_FORMAT_H_
*Ì‚
fsoong/.intermediates/external/abseil-cpp/absl_strings_cord_hdrs/gen/my_include_dir/absl/strings/cord.hà�// 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.
//
// -----------------------------------------------------------------------------
// File: cord.h
// -----------------------------------------------------------------------------
//
// This file defines the `absl::Cord` data structure and operations on that data
// structure. A Cord is a string-like sequence of characters optimized for
// specific use cases. Unlike a `std::string`, which stores an array of
// contiguous characters, Cord data is stored in a structure consisting of
// separate, reference-counted "chunks."
//
// Because a Cord consists of these chunks, data can be added to or removed from
// a Cord during its lifetime. Chunks may also be shared between Cords. Unlike a
// `std::string`, a Cord can therefore accommodate data that changes over its
// lifetime, though it's not quite "mutable"; it can change only in the
// attachment, detachment, or rearrangement of chunks of its constituent data.
//
// A Cord provides some benefit over `std::string` under the following (albeit
// narrow) circumstances:
//
//   * Cord data is designed to grow and shrink over a Cord's lifetime. Cord
//     provides efficient insertions and deletions at the start and end of the
//     character sequences, avoiding copies in those cases. Static data should
//     generally be stored as strings.
//   * External memory consisting of string-like data can be directly added to
//     a Cord without requiring copies or allocations.
//   * Cord data may be shared and copied cheaply. Cord provides a copy-on-write
//     implementation and cheap sub-Cord operations. Copying a Cord is an O(1)
//     operation.
//
// As a consequence to the above, Cord data is generally large. Small data
// should generally use strings, as construction of a Cord requires some
// overhead. Small Cords (<= 15 bytes) are represented inline, but most small
// Cords are expected to grow over their lifetimes.
//
// Note that because a Cord is made up of separate chunked data, random access
// to character data within a Cord is slower than within a `std::string`.
//
// Thread Safety
//
// Cord has the same thread-safety properties as many other types like
// std::string, std::vector<>, int, etc -- it is thread-compatible. In
// particular, if threads do not call non-const methods, then it is safe to call
// const methods without synchronization. Copying a Cord produces a new instance
// that can be used concurrently with the original in arbitrary ways.

#ifndef ABSL_STRINGS_CORD_H_
#define ABSL_STRINGS_CORD_H_

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <iosfwd>
#include <iterator>
#include <string>
#include <type_traits>
#include <utility>

#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/endian.h"
#include "absl/base/macros.h"
#include "absl/base/nullability.h"
#include "absl/base/optimization.h"
#include "absl/crc/internal/crc_cord_state.h"
#include "absl/functional/function_ref.h"
#include "absl/hash/internal/weakly_mixed_integer.h"
#include "absl/meta/type_traits.h"
#include "absl/strings/cord_analysis.h"
#include "absl/strings/cord_buffer.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_btree_reader.h"
#include "absl/strings/internal/cord_rep_crc.h"
#include "absl/strings/internal/cord_rep_flat.h"
#include "absl/strings/internal/cordz_info.h"
#include "absl/strings/internal/cordz_update_scope.h"
#include "absl/strings/internal/cordz_update_tracker.h"
#include "absl/strings/internal/string_constant.h"
#include "absl/strings/string_view.h"
#include "absl/types/compare.h"
#include "absl/types/optional.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
class Cord;
class CordTestPeer;
template <typename Releaser>
Cord MakeCordFromExternal(absl::string_view, Releaser&&);
void CopyCordToString(const Cord& src, std::string* absl_nonnull dst);
void AppendCordToString(const Cord& src, std::string* absl_nonnull dst);

// Cord memory accounting modes
enum class CordMemoryAccounting {
  // Counts 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.
  // See also comment on `kTotalMorePrecise` on internally shared memory.
  kTotal,

  // Counts the *approximate* number of bytes held in full or in part by this
  // Cord for the distinct memory held by this cord. This option is similar
  // to `kTotal`, except that if the cord has multiple references to the same
  // memory, that memory is only counted once.
  //
  // For example:
  //   absl::Cord cord;
  //   cord.Append(some_other_cord);
  //   cord.Append(some_other_cord);
  //   // Counts `some_other_cord` twice:
  //   cord.EstimatedMemoryUsage(kTotal);
  //   // Counts `some_other_cord` once:
  //   cord.EstimatedMemoryUsage(kTotalMorePrecise);
  //
  // The `kTotalMorePrecise` number is more expensive to compute as it requires
  // deduplicating all memory references. Applications should prefer to use
  // `kFairShare` or `kTotal` unless they really need a more precise estimate
  // on "how much memory is potentially held / kept alive by this cord?"
  kTotalMorePrecise,

  // Counts the *approximate* number of bytes held in full or in part by this
  // Cord weighted by the sharing ratio of that data. For example, if some data
  // edge is shared by 4 different Cords, then each cord is attributed 1/4th of
  // the total memory usage as a 'fair share' of the total memory usage.
  kFairShare,
};

// Cord
//
// A Cord is a sequence of characters, designed to be more efficient than a
// `std::string` in certain circumstances: namely, large string data that needs
// to change over its lifetime or shared, especially when such data is shared
// across API boundaries.
//
// A Cord stores its character data in a structure that allows efficient prepend
// and append operations. This makes a Cord useful for large string data sent
// over in a wire format that may need to be prepended or appended at some point
// during the data exchange (e.g. HTTP, protocol buffers). For example, a
// Cord is useful for storing an HTTP request, and prepending an HTTP header to
// such a request.
//
// Cords should not be used for storing general string data, however. They
// require overhead to construct and are slower than strings for random access.
//
// The Cord API provides the following common API operations:
//
// * Create or assign Cords out of existing string data, memory, or other Cords
// * Append and prepend data to an existing Cord
// * Create new Sub-Cords from existing Cord data
// * Swap Cord data and compare Cord equality
// * Write out Cord data by constructing a `std::string`
//
// Additionally, the API provides iterator utilities to iterate through Cord
// data via chunks or character bytes.
//
class Cord {
 private:
  template <typename T>
  using EnableIfString =
      absl::enable_if_t<std::is_same<T, std::string>::value, int>;

 public:
  // Cord::Cord() Constructors.

  // Creates an empty Cord.
  constexpr Cord() noexcept;

  // Creates a Cord from an existing Cord. Cord is copyable and efficiently
  // movable. The moved-from state is valid but unspecified.
  Cord(const Cord& src);
  Cord(Cord&& src) noexcept;
  Cord& operator=(const Cord& x);
  Cord& operator=(Cord&& x) noexcept;

  // Creates a Cord from a `src` string. This constructor is marked explicit to
  // prevent implicit Cord constructions from arguments convertible to an
  // `absl::string_view`.
  explicit Cord(absl::string_view src);
  Cord& operator=(absl::string_view src);

  // Creates a Cord from a `std::string&&` rvalue. These constructors are
  // templated to avoid ambiguities for types that are convertible to both
  // `absl::string_view` and `std::string`, such as `const char*`.
  template <typename T, EnableIfString<T> = 0>
  explicit Cord(T&& src);
  template <typename T, EnableIfString<T> = 0>
  Cord& operator=(T&& src);

  // Cord::~Cord()
  //
  // Destructs the Cord.
  ~Cord() {
    if (contents_.is_tree()) DestroyCordSlow();
  }

  // MakeCordFromExternal()
  //
  // Creates a Cord that takes ownership of external string memory. The
  // contents of `data` are not copied to the Cord; instead, the external
  // memory is added to the Cord and reference-counted. This data may not be
  // changed for the life of the Cord, though it may be prepended or appended
  // to.
  //
  // `MakeCordFromExternal()` takes a callable "releaser" that is invoked when
  // the reference count for `data` reaches zero. As noted above, this data must
  // remain live until the releaser is invoked. The callable releaser also must:
  //
  //   * be move constructible
  //   * support `void operator()(absl::string_view) const` or `void operator()`
  //
  // Example:
  //
  // Cord MakeCord(BlockPool* pool) {
  //   Block* block = pool->NewBlock();
  //   FillBlock(block);
  //   return absl::MakeCordFromExternal(
  //       block->ToStringView(),
  //       [pool, block](absl::string_view v) {
  //         pool->FreeBlock(block, v);
  //       });
  // }
  //
  // WARNING: Because a Cord can be reference-counted, it's likely a bug if your
  // releaser doesn't do anything. For example, consider the following:
  //
  // void Foo(const char* buffer, int len) {
  //   auto c = absl::MakeCordFromExternal(absl::string_view(buffer, len),
  //                                       [](absl::string_view) {});
  //
  //   // BUG: If Bar() copies its cord for any reason, including keeping a
  //   // substring of it, the lifetime of buffer might be extended beyond
  //   // when Foo() returns.
  //   Bar(c);
  // }
  template <typename Releaser>
  friend Cord MakeCordFromExternal(absl::string_view data, Releaser&& releaser);

  // Cord::Clear()
  //
  // Releases the Cord data. Any nodes that share data with other Cords, if
  // applicable, will have their reference counts reduced by 1.
  ABSL_ATTRIBUTE_REINITIALIZES void Clear();

  // Cord::Append()
  //
  // Appends data to the Cord, which may come from another Cord or other string
  // data.
  void Append(const Cord& src);
  void Append(Cord&& src);
  void Append(absl::string_view src);
  template <typename T, EnableIfString<T> = 0>
  void Append(T&& src);

  // Appends `buffer` to this cord, unless `buffer` has a zero length in which
  // case this method has no effect on this cord instance.
  // This method is guaranteed to consume `buffer`.
  void Append(CordBuffer buffer);

  // Returns a CordBuffer, re-using potential existing capacity in this cord.
  //
  // Cord instances may have additional unused capacity in the last (or first)
  // nodes of the underlying tree to facilitate amortized growth. This method
  // allows applications to explicitly use this spare capacity if available,
  // or create a new CordBuffer instance otherwise.
  // If this cord has a final non-shared node with at least `min_capacity`
  // available, then this method will return that buffer including its data
  // contents. I.e.; the returned buffer will have a non-zero length, and
  // a capacity of at least `buffer.length + min_capacity`. Otherwise, this
  // method will return `CordBuffer::CreateWithDefaultLimit(capacity)`.
  //
  // Below an example of using GetAppendBuffer. Notice that in this example we
  // use `GetAppendBuffer()` only on the first iteration. As we know nothing
  // about any initial extra capacity in `cord`, we may be able to use the extra
  // capacity. But as we add new buffers with fully utilized contents after that
  // we avoid calling `GetAppendBuffer()` on subsequent iterations: while this
  // works fine, it results in an unnecessary inspection of cord contents:
  //
  //   void AppendRandomDataToCord(absl::Cord &cord, size_t n) {
  //     bool first = true;
  //     while (n > 0) {
  //       CordBuffer buffer = first ? cord.GetAppendBuffer(n)
  //                                 : CordBuffer::CreateWithDefaultLimit(n);
  //       absl::Span<char> data = buffer.available_up_to(n);
  //       FillRandomValues(data.data(), data.size());
  //       buffer.IncreaseLengthBy(data.size());
  //       cord.Append(std::move(buffer));
  //       n -= data.size();
  //       first = false;
  //     }
  //   }
  CordBuffer GetAppendBuffer(size_t capacity, size_t min_capacity = 16);

  // Returns a CordBuffer, re-using potential existing capacity in this cord.
  //
  // This function is identical to `GetAppendBuffer`, except that in the case
  // where a new `CordBuffer` is allocated, it is allocated using the provided
  // custom limit instead of the default limit. `GetAppendBuffer` will default
  // to `CordBuffer::CreateWithDefaultLimit(capacity)` whereas this method
  // will default to `CordBuffer::CreateWithCustomLimit(block_size, capacity)`.
  // This method is equivalent to `GetAppendBuffer` if `block_size` is zero.
  // See the documentation for `CreateWithCustomLimit` for more details on the
  // restrictions and legal values for `block_size`.
  CordBuffer GetCustomAppendBuffer(size_t block_size, size_t capacity,
                                   size_t min_capacity = 16);

  // Cord::Prepend()
  //
  // Prepends data to the Cord, which may come from another Cord or other string
  // data.
  void Prepend(const Cord& src);
  void Prepend(absl::string_view src);
  template <typename T, EnableIfString<T> = 0>
  void Prepend(T&& src);

  // Prepends `buffer` to this cord, unless `buffer` has a zero length in which
  // case this method has no effect on this cord instance.
  // This method is guaranteed to consume `buffer`.
  void Prepend(CordBuffer buffer);

  // Cord::RemovePrefix()
  //
  // Removes the first `n` bytes of a Cord.
  void RemovePrefix(size_t n);
  void RemoveSuffix(size_t n);

  // Cord::Subcord()
  //
  // Returns a new Cord representing the subrange [pos, pos + new_size) of
  // *this. If pos >= size(), the result is empty(). If
  // (pos + new_size) >= size(), the result is the subrange [pos, size()).
  Cord Subcord(size_t pos, size_t new_size) const;

  // Cord::swap()
  //
  // Swaps the contents of the Cord with `other`.
  void swap(Cord& other) noexcept;

  // swap()
  //
  // Swaps the contents of two Cords.
  friend void swap(Cord& x, Cord& y) noexcept { x.swap(y); }

  // Cord::size()
  //
  // Returns the size of the Cord.
  size_t size() const;

  // Cord::empty()
  //
  // Determines whether the given Cord is empty, returning `true` if so.
  bool empty() const;

  // Cord::EstimatedMemoryUsage()
  //
  // Returns the *approximate* number of bytes held by this cord.
  // See CordMemoryAccounting for more information on the accounting method.
  size_t EstimatedMemoryUsage(CordMemoryAccounting accounting_method =
                                  CordMemoryAccounting::kTotal) const;

  // Cord::Compare()
  //
  // Compares 'this' Cord with rhs. This function and its relatives treat Cords
  // as sequences of unsigned bytes. The comparison is a straightforward
  // lexicographic comparison. `Cord::Compare()` returns values as follows:
  //
  //   -1  'this' Cord is smaller
  //    0  two Cords are equal
  //    1  'this' Cord is larger
  int Compare(absl::string_view rhs) const;
  int Compare(const Cord& rhs) const;

  // Cord::StartsWith()
  //
  // Determines whether the Cord starts with the passed string data `rhs`.
  bool StartsWith(const Cord& rhs) const;
  bool StartsWith(absl::string_view rhs) const;

  // Cord::EndsWith()
  //
  // Determines whether the Cord ends with the passed string data `rhs`.
  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
  // prevent unintended Cord usage in functions that take a string.
  explicit operator std::string() const;

  // CopyCordToString()
  //
  // Copies the contents of a `src` Cord into a `*dst` string.
  //
  // This function optimizes the case of reusing the destination string since it
  // can reuse previously allocated capacity. However, this function does not
  // 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* absl_nonnull dst);

  // AppendCordToString()
  //
  // Appends the contents of a `src` Cord to a `*dst` string.
  //
  // This function optimizes the case of appending to a non-empty destination
  // string. If `*dst` already has capacity to store the contents of the cord,
  // this function does not invalidate pointers previously returned by
  // `dst->data()`. If `*dst` is a new object, prefer to simply use the
  // conversion operator to `std::string`.
  friend void AppendCordToString(const Cord& src,
                                 std::string* absl_nonnull dst);

  class CharIterator;

  //----------------------------------------------------------------------------
  // Cord::ChunkIterator
  //----------------------------------------------------------------------------
  //
  // A `Cord::ChunkIterator` allows iteration over the constituent chunks of its
  // Cord. Such iteration allows you to perform non-const operations on the data
  // of a Cord without modifying it.
  //
  // Generally, you do not instantiate a `Cord::ChunkIterator` directly;
  // instead, you create one implicitly through use of the `Cord::Chunks()`
  // member function.
  //
  // The `Cord::ChunkIterator` has the following properties:
  //
  //   * The iterator is invalidated after any non-const operation on the
  //     Cord object over which it iterates.
  //   * The `string_view` returned by dereferencing a valid, non-`end()`
  //     iterator is guaranteed to be non-empty.
  //   * Two `ChunkIterator` objects can be compared equal if and only if they
  //     remain valid and iterate over the same Cord.
  //   * The iterator in this case is a proxy iterator; the `string_view`
  //     returned by the iterator does not live inside the Cord, and its
  //     lifetime is limited to the lifetime of the iterator itself. To help
  //     prevent lifetime issues, `ChunkIterator::reference` is not a true
  //     reference type and is equivalent to `value_type`.
  //   * The iterator keeps state that can grow for Cords that contain many
  //     nodes and are imbalanced due to sharing. Prefer to pass this type by
  //     const reference instead of by value.
  class ChunkIterator {
   public:
    using iterator_category = std::input_iterator_tag;
    using value_type = absl::string_view;
    using difference_type = ptrdiff_t;
    using pointer = const value_type* absl_nonnull;
    using reference = value_type;

    ChunkIterator() = default;

    ChunkIterator& operator++();
    ChunkIterator operator++(int);
    bool operator==(const ChunkIterator& other) const;
    bool operator!=(const ChunkIterator& other) const;
    reference operator*() const;
    pointer operator->() const;

    friend class Cord;
    friend class CharIterator;

   private:
    using CordRep = absl::cord_internal::CordRep;
    using CordRepBtree = absl::cord_internal::CordRepBtree;
    using CordRepBtreeReader = absl::cord_internal::CordRepBtreeReader;

    // Constructs a `begin()` iterator from `tree`.
    explicit ChunkIterator(cord_internal::CordRep* absl_nonnull tree);

    // Constructs a `begin()` iterator from `cord`.
    explicit ChunkIterator(const Cord* absl_nonnull cord);

    // Initializes this instance from a tree. Invoked by constructors.
    void InitTree(cord_internal::CordRep* absl_nonnull tree);

    // Removes `n` bytes from `current_chunk_`. Expects `n` to be smaller than
    // `current_chunk_.size()`.
    void RemoveChunkPrefix(size_t n);
    Cord AdvanceAndReadBytes(size_t n);
    void AdvanceBytes(size_t n);

    // Btree specific operator++
    ChunkIterator& AdvanceBtree();
    void AdvanceBytesBtree(size_t n);

    // A view into bytes of the current `CordRep`. It may only be a view to a
    // suffix of bytes if this is being used by `CharIterator`.
    absl::string_view current_chunk_;
    // 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* absl_nullable current_leaf_ = nullptr;
    // The number of bytes left in the `Cord` over which we are iterating.
    size_t bytes_remaining_ = 0;

    // Cord reader for cord btrees. Empty if not traversing a btree.
    CordRepBtreeReader btree_reader_;
  };

  // Cord::chunk_begin()
  //
  // Returns an iterator to the first chunk of the `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 are not useful.
  //
  // Example:
  //
  //   absl::Cord::ChunkIterator FindAsChunk(const absl::Cord& c,
  //                                         absl::string_view s) {
  //     return std::find(c.chunk_begin(), c.chunk_end(), s);
  //   }
  ChunkIterator chunk_begin() const ABSL_ATTRIBUTE_LIFETIME_BOUND;

  // Cord::chunk_end()
  //
  // Returns an iterator one increment past the last chunk of the `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 ABSL_ATTRIBUTE_LIFETIME_BOUND;

  //----------------------------------------------------------------------------
  // Cord::ChunkRange
  //----------------------------------------------------------------------------
  //
  // `ChunkRange` is a helper class for iterating over the chunks of the `Cord`,
  // producing an iterator which can be used within a range-based for loop.
  // Construction of a `ChunkRange` will return an iterator pointing to the
  // first chunk of the Cord. Generally, do not construct a `ChunkRange`
  // directly; instead, prefer to use the `Cord::Chunks()` method.
  //
  // Implementation note: `ChunkRange` is simply a convenience wrapper over
  // `Cord::chunk_begin()` and `Cord::chunk_end()`.
  class ChunkRange {
   public:
    // Fulfill minimum c++ container requirements [container.requirements]
    // These (partial) container type definitions allow ChunkRange to be used
    // in various utilities expecting a subset of [container.requirements].
    // For example, the below enables using `::testing::ElementsAre(...)`
    using value_type = absl::string_view;
    using reference = value_type&;
    using const_reference = const value_type&;
    using iterator = ChunkIterator;
    using const_iterator = ChunkIterator;

    explicit ChunkRange(const Cord* absl_nonnull cord) : cord_(cord) {}

    ChunkIterator begin() const;
    ChunkIterator end() const;

   private:
    const Cord* absl_nonnull cord_;
  };

  // Cord::Chunks()
  //
  // Returns a `Cord::ChunkRange` for iterating over the chunks of a `Cord` with
  // a range-based for-loop. For most iteration tasks on a Cord, use
  // `Cord::Chunks()` to retrieve this iterator.
  //
  // Example:
  //
  //   void ProcessChunks(const Cord& cord) {
  //     for (absl::string_view chunk : cord.Chunks()) { ... }
  //   }
  //
  // Note that the ordinary caveats of temporary lifetime extension apply:
  //
  //   void Process() {
  //     for (absl::string_view chunk : CordFactory().Chunks()) {
  //       // The temporary Cord returned by CordFactory has been destroyed!
  //     }
  //   }
  ChunkRange Chunks() const ABSL_ATTRIBUTE_LIFETIME_BOUND;

  //----------------------------------------------------------------------------
  // Cord::CharIterator
  //----------------------------------------------------------------------------
  //
  // A `Cord::CharIterator` allows iteration over the constituent characters of
  // a `Cord`.
  //
  // Generally, you do not instantiate a `Cord::CharIterator` directly; instead,
  // you create one implicitly through use of the `Cord::Chars()` member
  // function.
  //
  // A `Cord::CharIterator` has the following properties:
  //
  //   * The iterator is invalidated after any non-const operation on the
  //     Cord object over which it iterates.
  //   * Two `CharIterator` objects can be compared equal if and only if they
  //     remain valid and iterate over the same Cord.
  //   * The iterator keeps state that can grow for Cords that contain many
  //     nodes and are imbalanced due to sharing. Prefer to pass this type by
  //     const reference instead of by value.
  //   * This type cannot act as a forward iterator because a `Cord` can reuse
  //     sections of memory. This fact violates the requirement for forward
  //     iterators to compare equal if dereferencing them returns the same
  //     object.
  class CharIterator {
   public:
    using iterator_category = std::input_iterator_tag;
    using value_type = char;
    using difference_type = ptrdiff_t;
    using pointer = const char* absl_nonnull;
    using reference = const char&;

    CharIterator() = default;

    CharIterator& operator++();
    CharIterator operator++(int);
    bool operator==(const CharIterator& other) const;
    bool operator!=(const CharIterator& other) const;
    reference operator*() const;

    friend Cord;

   private:
    explicit CharIterator(const Cord* absl_nonnull cord)
        : chunk_iterator_(cord) {}

    ChunkIterator chunk_iterator_;
  };

  // Cord::AdvanceAndRead()
  //
  // Advances the `Cord::CharIterator` by `n_bytes` and returns the bytes
  // 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* absl_nonnull 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* absl_nonnull it, size_t n_bytes);

  // Cord::ChunkRemaining()
  //
  // Returns the longest contiguous view starting at the iterator's position.
  //
  // `it` must be dereferenceable.
  static absl::string_view ChunkRemaining(const CharIterator& it);

  // Cord::Distance()
  //
  // Returns the distance between `first` and `last`, as if
  // `std::distance(first, last)` was called.
  static ptrdiff_t Distance(const CharIterator& first,
                            const CharIterator& last);

  // Cord::char_begin()
  //
  // Returns an iterator to the first character of the `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 ABSL_ATTRIBUTE_LIFETIME_BOUND;

  // Cord::char_end()
  //
  // Returns an iterator to one past the last character of the `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 ABSL_ATTRIBUTE_LIFETIME_BOUND;

  // Cord::CharRange
  //
  // `CharRange` is a helper class for iterating over the characters of a
  // producing an iterator which can be used within a range-based for loop.
  // Construction of a `CharRange` will return an iterator pointing to the first
  // character of the Cord. Generally, do not construct a `CharRange` directly;
  // instead, prefer to use the `Cord::Chars()` method shown below.
  //
  // Implementation note: `CharRange` is simply a convenience wrapper over
  // `Cord::char_begin()` and `Cord::char_end()`.
  class CharRange {
   public:
    // Fulfill minimum c++ container requirements [container.requirements]
    // These (partial) container type definitions allow CharRange to be used
    // in various utilities expecting a subset of [container.requirements].
    // For example, the below enables using `::testing::ElementsAre(...)`
    using value_type = char;
    using reference = value_type&;
    using const_reference = const value_type&;
    using iterator = CharIterator;
    using const_iterator = CharIterator;

    explicit CharRange(const Cord* absl_nonnull cord) : cord_(cord) {}

    CharIterator begin() const;
    CharIterator end() const;

   private:
    const Cord* absl_nonnull cord_;
  };

  // Cord::Chars()
  //
  // Returns a `Cord::CharRange` for iterating over the characters of a `Cord`
  // with a range-based for-loop. For most character-based iteration tasks on a
  // Cord, use `Cord::Chars()` to retrieve this iterator.
  //
  // Example:
  //
  //   void ProcessCord(const Cord& cord) {
  //     for (char c : cord.Chars()) { ... }
  //   }
  //
  // Note that the ordinary caveats of temporary lifetime extension apply:
  //
  //   void Process() {
  //     for (char c : CordFactory().Chars()) {
  //       // The temporary Cord returned by CordFactory has been destroyed!
  //     }
  //   }
  CharRange Chars() const ABSL_ATTRIBUTE_LIFETIME_BOUND;

  // Cord::operator[]
  //
  // Gets the "i"th character of the Cord and returns it, provided that
  // 0 <= i < Cord.size().
  //
  // NOTE: This routine is reasonably efficient. It is roughly
  // logarithmic based on the number of chunks that make up the cord. Still,
  // if you need to iterate over the contents of a cord, you should
  // use a CharIterator/ChunkIterator rather than call operator[] or Get()
  // repeatedly in a loop.
  char operator[](size_t i) const;

  // Cord::TryFlat()
  //
  // 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_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_ATTRIBUTE_LIFETIME_BOUND;

  // Cord::Find()
  //
  // Returns an iterator to the first occurrence 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* absl_nonnull 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
  // retrieval.
  //
  // The expected checksum is a number stored out-of-band, alongside the data.
  // It is preserved across copies and assignments, but any mutations to a cord
  // will cause it to lose its expected checksum.
  //
  // The expected checksum is not part of a Cord's value, and does not affect
  // operations such as equality or hashing.
  //
  // This field is intended to store a CRC32C checksum for later validation, to
  // help support end-to-end checksum workflows.  However, the Cord API itself
  // does no CRC validation, and assigns no meaning to this number.
  //
  // This call has no effect if this cord is empty.
  void SetExpectedChecksum(uint32_t crc);

  // Returns this cord's expected checksum, if it has one.  Otherwise, returns
  // nullopt.
  absl::optional<uint32_t> ExpectedChecksum() const;

  template <typename H>
  friend H AbslHashValue(H hash_state, const absl::Cord& c) {
    absl::optional<absl::string_view> maybe_flat = c.TryFlat();
    if (maybe_flat.has_value()) {
      return H::combine(std::move(hash_state), *maybe_flat);
    }
    return c.HashFragmented(std::move(hash_state));
  }

  // Create a Cord with the contents of StringConstant<T>::value.
  // No allocations will be done and no data will be copied.
  // This is an INTERNAL API and subject to change or removal. This API can only
  // be used by spelling absl::strings_internal::MakeStringConstant, which is
  // also an internal API.
  template <typename T>
  // NOLINTNEXTLINE(google-explicit-constructor)
  constexpr Cord(strings_internal::StringConstant<T>);

 private:
  using CordRep = absl::cord_internal::CordRep;
  using CordRepFlat = absl::cord_internal::CordRepFlat;
  using CordzInfo = cord_internal::CordzInfo;
  using CordzUpdateScope = cord_internal::CordzUpdateScope;
  using CordzUpdateTracker = cord_internal::CordzUpdateTracker;
  using InlineData = cord_internal::InlineData;
  using MethodIdentifier = CordzUpdateTracker::MethodIdentifier;

  // Creates a cord instance with `method` representing the originating
  // public API call causing the cord to be created.
  explicit Cord(absl::string_view src, MethodIdentifier method);

  friend class CordTestPeer;
  friend bool operator==(const Cord& lhs, const Cord& rhs);
  friend bool operator==(const Cord& lhs, absl::string_view rhs);

#ifdef __cpp_impl_three_way_comparison

  // Cords support comparison with other Cords and string_views via operator<
  // and others; here we provide a wrapper for the C++20 three-way comparison
  // <=> operator.

  static inline std::strong_ordering ConvertCompareResultToStrongOrdering(
      int c) {
    if (c == 0) {
      return std::strong_ordering::equal;
    } else if (c < 0) {
      return std::strong_ordering::less;
    } else {
      return std::strong_ordering::greater;
    }
  }

  friend inline std::strong_ordering operator<=>(const Cord& x, const Cord& y) {
    return ConvertCompareResultToStrongOrdering(x.Compare(y));
  }

  friend inline std::strong_ordering operator<=>(const Cord& lhs,
                                                 absl::string_view rhs) {
    return ConvertCompareResultToStrongOrdering(lhs.Compare(rhs));
  }

  friend inline std::strong_ordering operator<=>(absl::string_view lhs,
                                                 const Cord& rhs) {
    return ConvertCompareResultToStrongOrdering(-rhs.Compare(lhs));
  }
#endif

  friend const CordzInfo* absl_nullable GetCordzInfoForTesting(
      const Cord& cord);

  // Calls the provided function once for each cord chunk, in order.  Unlike
  // Chunks(), this API will not allocate memory.
  void ForEachChunk(absl::FunctionRef<void(absl::string_view)>) const;

  // Allocates new contiguous storage for the contents of the cord. This is
  // called by Flatten() when the cord was not already flat.
  absl::string_view FlattenSlowPath();

  // Actual cord contents are hidden inside the following simple
  // class so that we can isolate the bulk of cord.cc from changes
  // to the representation.
  //
  // InlineRep holds either a tree pointer, or an array of kMaxInline bytes.
  class InlineRep {
   public:
    static constexpr unsigned char kMaxInline = cord_internal::kMaxInline;
    static_assert(kMaxInline >= sizeof(absl::cord_internal::CordRep*), "");

    constexpr InlineRep() : data_() {}
    explicit InlineRep(InlineData::DefaultInitType init) : data_(init) {}
    InlineRep(const InlineRep& src);
    InlineRep(InlineRep&& src);
    InlineRep& operator=(const InlineRep& src);
    InlineRep& operator=(InlineRep&& src) noexcept;

    explicit constexpr InlineRep(absl::string_view sv,
                                 CordRep* absl_nullable rep);

    void Swap(InlineRep* absl_nonnull rhs);
    size_t size() const;
    // Returns nullptr if holding pointer
    const char* absl_nullable data() const;
    // Discards pointer, if any
    void set_data(const char* absl_nonnull data, size_t n);
    char* absl_nonnull set_data(size_t n);  // Write data to the result
    // Returns nullptr if holding bytes
    absl::cord_internal::CordRep* absl_nullable tree() const;
    absl::cord_internal::CordRep* absl_nonnull as_tree() const;
    const char* absl_nonnull as_chars() const;
    // Returns non-null iff was holding a pointer
    absl::cord_internal::CordRep* absl_nullable clear();
    // Converts to pointer if necessary.
    void reduce_size(size_t n);    // REQUIRES: holding data
    void remove_prefix(size_t n);  // REQUIRES: holding data
    void AppendArray(absl::string_view src, MethodIdentifier method);
    absl::string_view FindFlatStartPiece() const;

    // Creates a CordRepFlat instance from the current inlined data with `extra'
    // bytes of desired additional capacity.
    CordRepFlat* absl_nonnull 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* absl_nonnull 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* absl_nullable 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* absl_nonnull 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* absl_nonnull 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* absl_nullable old_rep,
                    CordRep* absl_nonnull rep, const CordzUpdateScope& scope,
                    MethodIdentifier method);

    void AppendTreeToInlined(CordRep* absl_nonnull tree,
                             MethodIdentifier method);
    void AppendTreeToTree(CordRep* absl_nonnull tree, MethodIdentifier method);
    void AppendTree(CordRep* absl_nonnull tree, MethodIdentifier method);
    void PrependTreeToInlined(CordRep* absl_nonnull tree,
                              MethodIdentifier method);
    void PrependTreeToTree(CordRep* absl_nonnull tree, MethodIdentifier method);
    void PrependTree(CordRep* absl_nonnull tree, MethodIdentifier method);

    bool IsSame(const InlineRep& other) const { return data_ == other.data_; }

    // Copies the inline contents into `dst`. Assumes the cord is not empty.
    void CopyTo(std::string* absl_nonnull dst) const {
      data_.CopyInlineToString(dst);
    }

    // Copies the inline contents into `dst`. Assumes the cord is not empty.
    void CopyToArray(char* absl_nonnull dst) const;

    bool is_tree() const { return data_.is_tree(); }

    // Returns true if the Cord is being profiled by cordz.
    bool is_profiled() const { return data_.is_tree() && data_.is_profiled(); }

    // Returns the available inlined capacity, or 0 if is_tree() == true.
    size_t remaining_inline_capacity() const {
      return data_.is_tree() ? 0 : kMaxInline - data_.inline_size();
    }

    // Returns the profiled CordzInfo, or nullptr if not sampled.
    absl::cord_internal::CordzInfo* absl_nullable cordz_info() const {
      return data_.cordz_info();
    }

    // Sets the profiled CordzInfo.
    void set_cordz_info(cord_internal::CordzInfo* absl_nonnull cordz_info) {
      assert(cordz_info != nullptr);
      data_.set_cordz_info(cordz_info);
    }

    // Resets the current cordz_info to null / empty.
    void clear_cordz_info() { data_.clear_cordz_info(); }

   private:
    friend class Cord;

    void AssignSlow(const InlineRep& src);
    // Unrefs the tree and stops profiling.
    void UnrefTree();

    void ResetToEmpty() { data_ = {}; }

    void set_inline_size(size_t size) { data_.set_inline_size(size); }
    size_t inline_size() const { return data_.inline_size(); }

    // Empty cords that carry a checksum have a CordRepCrc node with a null
    // child node. The code can avoid lots of special cases where it would
    // otherwise transition from tree to inline storage if we just remove the
    // CordRepCrc node before mutations. Must never be called inside a
    // CordzUpdateScope since it untracks the cordz info.
    void MaybeRemoveEmptyCrcNode();

    cord_internal::InlineData data_;
  };
  InlineRep contents_;

  // Helper for GetFlat() and TryFlat().
  static bool GetFlatAux(absl::cord_internal::CordRep* absl_nonnull rep,
                         absl::string_view* absl_nonnull fragment);

  // Helper for ForEachChunk().
  static void ForEachChunkAux(
      absl::cord_internal::CordRep* absl_nonnull 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* absl_nonnull 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,
                      size_t size_to_compare) const;
  bool EqualsImpl(absl::string_view rhs, size_t size_to_compare) const;
  bool EqualsImpl(const Cord& rhs, size_t size_to_compare) const;
  int CompareImpl(const Cord& rhs) const;

  template <typename ResultType, typename RHS>
  friend ResultType GenericCompare(const Cord& lhs, const RHS& rhs,
                                   size_t size_to_compare);
  static absl::string_view GetFirstChunk(const Cord& c);
  static absl::string_view GetFirstChunk(absl::string_view sv);

  // Returns a new reference to contents_.tree(), or steals an existing
  // reference if called on an rvalue.
  absl::cord_internal::CordRep* absl_nonnull TakeRep() const&;
  absl::cord_internal::CordRep* absl_nonnull TakeRep() &&;

  // Helper for Append().
  template <typename C>
  void AppendImpl(C&& src);

  // Appends / Prepends `src` to this instance, using precise sizing.
  // This method does explicitly not attempt to use any spare capacity
  // in any pending last added private owned flat.
  // Requires `src` to be <= kMaxFlatLength.
  void AppendPrecise(absl::string_view src, MethodIdentifier method);
  void PrependPrecise(absl::string_view src, MethodIdentifier method);

  CordBuffer GetAppendBufferSlowPath(size_t block_size, size_t capacity,
                                     size_t min_capacity);

  // Prepends the provided data to this instance. `method` contains the public
  // API method for this action which is tracked for Cordz sampling purposes.
  void PrependArray(absl::string_view src, MethodIdentifier method);

  // Assigns the value in 'src' to this instance, 'stealing' its contents.
  // Requires src.length() > kMaxBytesToCopy.
  Cord& AssignLargeString(std::string&& src);

  // Helper for AbslHashValue().
  template <typename H>
  H HashFragmented(H hash_state) const {
    typename H::AbslInternalPiecewiseCombiner combiner;
    ForEachChunk([&combiner, &hash_state](absl::string_view chunk) {
      hash_state = combiner.add_buffer(std::move(hash_state), chunk.data(),
                                       chunk.size());
    });
    return H::combine(combiner.finalize(std::move(hash_state)),
                      hash_internal::WeaklyMixedInteger{size()});
  }

  friend class CrcCord;
  void SetCrcCordState(crc_internal::CrcCordState state);
  const crc_internal::CrcCordState* absl_nullable MaybeGetCrcCordState() const;

  CharIterator FindImpl(CharIterator it, absl::string_view needle) const;

  void CopyToArrayImpl(char* absl_nonnull dst) const;
};

ABSL_NAMESPACE_END
}  // namespace absl

namespace absl {
ABSL_NAMESPACE_BEGIN

// allow a Cord to be logged
extern std::ostream& operator<<(std::ostream& out, const Cord& cord);

// ------------------------------------------------------------------
// Internal details follow.  Clients should ignore.

namespace cord_internal {

// Does non-template-specific `CordRepExternal` initialization.
// Requires `data` to be non-empty.
void InitializeCordRepExternal(absl::string_view data,
                               CordRepExternal* absl_nonnull 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* absl_nonnull NewExternalRep(absl::string_view data,
                                     Releaser&& releaser) {
  assert(!data.empty());
  using ReleaserType = absl::decay_t<Releaser>;
  CordRepExternal* rep = new CordRepExternalImpl<ReleaserType>(
      std::forward<Releaser>(releaser), 0);
  InitializeCordRepExternal(data, rep);
  return rep;
}

// 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* absl_nonnull NewExternalRep(
    absl::string_view data, void (&releaser)(absl::string_view)) {
  return NewExternalRep(data, &releaser);
}

}  // namespace cord_internal

template <typename Releaser>
Cord MakeCordFromExternal(absl::string_view data, Releaser&& releaser) {
  Cord cord;
  if (ABSL_PREDICT_TRUE(!data.empty())) {
    cord.contents_.EmplaceTree(::absl::cord_internal::NewExternalRep(
                                   data, std::forward<Releaser>(releaser)),
                               Cord::MethodIdentifier::kMakeCordFromExternal);
  } else {
    using ReleaserType = absl::decay_t<Releaser>;
    cord_internal::InvokeReleaser(
        cord_internal::Rank1{}, ReleaserType(std::forward<Releaser>(releaser)),
        data);
  }
  return cord;
}

constexpr Cord::InlineRep::InlineRep(absl::string_view sv,
                                     CordRep* absl_nullable rep)
    : data_(sv, rep) {}

inline Cord::InlineRep::InlineRep(const Cord::InlineRep& src)
    : data_(InlineData::kDefaultInit) {
  if (CordRep* tree = src.tree()) {
    EmplaceTree(CordRep::Ref(tree), src.data_,
                CordzUpdateTracker::kConstructorCord);
  } else {
    data_ = src.data_;
  }
}

inline Cord::InlineRep::InlineRep(Cord::InlineRep&& src) : data_(src.data_) {
  src.ResetToEmpty();
}

inline Cord::InlineRep& Cord::InlineRep::operator=(const Cord::InlineRep& src) {
  if (this == &src) {
    return *this;
  }
  if (!is_tree() && !src.is_tree()) {
    data_ = src.data_;
    return *this;
  }
  AssignSlow(src);
  return *this;
}

inline Cord::InlineRep& Cord::InlineRep::operator=(
    Cord::InlineRep&& src) noexcept {
  if (is_tree()) {
    UnrefTree();
  }
  data_ = src.data_;
  src.ResetToEmpty();
  return *this;
}

inline void Cord::InlineRep::Swap(Cord::InlineRep* absl_nonnull rhs) {
  if (rhs == this) {
    return;
  }
  using std::swap;
  swap(data_, rhs->data_);
}

inline const char* absl_nullable Cord::InlineRep::data() const {
  return is_tree() ? nullptr : data_.as_chars();
}

inline const char* absl_nonnull Cord::InlineRep::as_chars() const {
  assert(!data_.is_tree());
  return data_.as_chars();
}

inline absl::cord_internal::CordRep* absl_nonnull Cord::InlineRep::as_tree()
    const {
  assert(data_.is_tree());
  return data_.as_tree();
}

inline absl::cord_internal::CordRep* absl_nullable Cord::InlineRep::tree()
    const {
  if (is_tree()) {
    return as_tree();
  } else {
    return nullptr;
  }
}

inline size_t Cord::InlineRep::size() const {
  return is_tree() ? as_tree()->length : inline_size();
}

inline cord_internal::CordRepFlat* absl_nonnull
Cord::InlineRep::MakeFlatWithExtraCapacity(size_t extra) {
  static_assert(cord_internal::kMinFlatLength >= sizeof(data_), "");
  size_t len = data_.inline_size();
  auto* result = CordRepFlat::New(len + extra);
  result->length = len;
  data_.copy_max_inline_to(result->Data());
  return result;
}

inline void Cord::InlineRep::EmplaceTree(CordRep* absl_nonnull rep,
                                         MethodIdentifier method) {
  assert(rep);
  data_.make_tree(rep);
  CordzInfo::MaybeTrackCord(data_, method);
}

inline void Cord::InlineRep::EmplaceTree(CordRep* absl_nonnull rep,
                                         const InlineData& parent,
                                         MethodIdentifier method) {
  data_.make_tree(rep);
  CordzInfo::MaybeTrackCord(data_, parent, method);
}

inline void Cord::InlineRep::SetTree(CordRep* absl_nonnull rep,
                                     const CordzUpdateScope& scope) {
  assert(rep);
  assert(data_.is_tree());
  data_.set_tree(rep);
  scope.SetCordRep(rep);
}

inline void Cord::InlineRep::SetTreeOrEmpty(CordRep* absl_nullable rep,
                                            const CordzUpdateScope& scope) {
  assert(data_.is_tree());
  if (rep) {
    data_.set_tree(rep);
  } else {
    data_ = {};
  }
  scope.SetCordRep(rep);
}

inline void Cord::InlineRep::CommitTree(const CordRep* absl_nullable old_rep,
                                        CordRep* absl_nonnull rep,
                                        const CordzUpdateScope& scope,
                                        MethodIdentifier method) {
  if (old_rep) {
    SetTree(rep, scope);
  } else {
    EmplaceTree(rep, method);
  }
}

inline absl::cord_internal::CordRep* absl_nullable Cord::InlineRep::clear() {
  if (is_tree()) {
    CordzInfo::MaybeUntrackCord(cordz_info());
  }
  absl::cord_internal::CordRep* result = tree();
  ResetToEmpty();
  return result;
}

inline void Cord::InlineRep::CopyToArray(char* absl_nonnull dst) const {
  assert(!is_tree());
  size_t n = inline_size();
  assert(n != 0);
  cord_internal::SmallMemmove(dst, data_.as_chars(), n);
}

inline void Cord::InlineRep::MaybeRemoveEmptyCrcNode() {
  CordRep* rep = tree();
  if (rep == nullptr || ABSL_PREDICT_TRUE(rep->length > 0)) {
    return;
  }
  assert(rep->IsCrc());
  assert(rep->crc()->child == nullptr);
  CordzInfo::MaybeUntrackCord(cordz_info());
  CordRep::Unref(rep);
  ResetToEmpty();
}

constexpr inline Cord::Cord() noexcept {}

inline Cord::Cord(absl::string_view src)
    : Cord(src, CordzUpdateTracker::kConstructorString) {}

template <typename T>
constexpr Cord::Cord(strings_internal::StringConstant<T>)
    : contents_(strings_internal::StringConstant<T>::value,
                strings_internal::StringConstant<T>::value.size() <=
                        cord_internal::kMaxInline
                    ? nullptr
                    : &cord_internal::ConstInitExternalStorage<
                          strings_internal::StringConstant<T>>::value) {}

inline Cord& Cord::operator=(const Cord& x) {
  contents_ = x.contents_;
  return *this;
}

template <typename T, Cord::EnableIfString<T>>
Cord& Cord::operator=(T&& src) {
  if (src.size() <= cord_internal::kMaxBytesToCopy) {
    return operator=(absl::string_view(src));
  } else {
    return AssignLargeString(std::forward<T>(src));
  }
}

inline Cord::Cord(const Cord& src) : contents_(src.contents_) {}

inline Cord::Cord(Cord&& src) noexcept : contents_(std::move(src.contents_)) {}

inline void Cord::swap(Cord& other) noexcept {
  contents_.Swap(&other.contents_);
}

inline Cord& Cord::operator=(Cord&& x) noexcept {
  contents_ = std::move(x.contents_);
  return *this;
}

extern template Cord::Cord(std::string&& src);

inline size_t Cord::size() const {
  // Length is 1st field in str.rep_
  return contents_.size();
}

inline bool Cord::empty() const { return size() == 0; }

inline size_t Cord::EstimatedMemoryUsage(
    CordMemoryAccounting accounting_method) const {
  size_t result = sizeof(Cord);
  if (const absl::cord_internal::CordRep* rep = contents_.tree()) {
    switch (accounting_method) {
      case CordMemoryAccounting::kFairShare:
        result += cord_internal::GetEstimatedFairShareMemoryUsage(rep);
        break;
      case CordMemoryAccounting::kTotalMorePrecise:
        result += cord_internal::GetMorePreciseMemoryUsage(rep);
        break;
      case CordMemoryAccounting::kTotal:
        result += cord_internal::GetEstimatedMemoryUsage(rep);
        break;
    }
  }
  return result;
}

inline absl::optional<absl::string_view> Cord::TryFlat() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  absl::cord_internal::CordRep* rep = contents_.tree();
  if (rep == nullptr) {
    return absl::string_view(contents_.data(), contents_.size());
  }
  absl::string_view fragment;
  if (GetFlatAux(rep, &fragment)) {
    return fragment;
  }
  return absl::nullopt;
}

inline absl::string_view Cord::Flatten() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  absl::cord_internal::CordRep* rep = contents_.tree();
  if (rep == nullptr) {
    return absl::string_view(contents_.data(), contents_.size());
  } else {
    absl::string_view already_flat_contents;
    if (GetFlatAux(rep, &already_flat_contents)) {
      return already_flat_contents;
    }
  }
  return FlattenSlowPath();
}

inline void Cord::Append(absl::string_view src) {
  contents_.AppendArray(src, CordzUpdateTracker::kAppendString);
}

inline void Cord::Prepend(absl::string_view src) {
  PrependArray(src, CordzUpdateTracker::kPrependString);
}

inline void Cord::Append(CordBuffer buffer) {
  if (ABSL_PREDICT_FALSE(buffer.length() == 0)) return;
  contents_.MaybeRemoveEmptyCrcNode();
  absl::string_view short_value;
  if (CordRep* rep = buffer.ConsumeValue(short_value)) {
    contents_.AppendTree(rep, CordzUpdateTracker::kAppendCordBuffer);
  } else {
    AppendPrecise(short_value, CordzUpdateTracker::kAppendCordBuffer);
  }
}

inline void Cord::Prepend(CordBuffer buffer) {
  if (ABSL_PREDICT_FALSE(buffer.length() == 0)) return;
  contents_.MaybeRemoveEmptyCrcNode();
  absl::string_view short_value;
  if (CordRep* rep = buffer.ConsumeValue(short_value)) {
    contents_.PrependTree(rep, CordzUpdateTracker::kPrependCordBuffer);
  } else {
    PrependPrecise(short_value, CordzUpdateTracker::kPrependCordBuffer);
  }
}

inline CordBuffer Cord::GetAppendBuffer(size_t capacity, size_t min_capacity) {
  if (empty()) return CordBuffer::CreateWithDefaultLimit(capacity);
  return GetAppendBufferSlowPath(0, capacity, min_capacity);
}

inline CordBuffer Cord::GetCustomAppendBuffer(size_t block_size,
                                              size_t capacity,
                                              size_t min_capacity) {
  if (empty()) {
    return block_size ? CordBuffer::CreateWithCustomLimit(block_size, capacity)
                      : CordBuffer::CreateWithDefaultLimit(capacity);
  }
  return GetAppendBufferSlowPath(block_size, capacity, min_capacity);
}

extern template void Cord::Append(std::string&& src);
extern template void Cord::Prepend(std::string&& src);

inline int Cord::Compare(const Cord& rhs) const {
  if (!contents_.is_tree() && !rhs.contents_.is_tree()) {
    return contents_.data_.Compare(rhs.contents_.data_);
  }

  return CompareImpl(rhs);
}

// Does 'this' cord start/end with rhs
inline bool Cord::StartsWith(const Cord& rhs) const {
  if (contents_.IsSame(rhs.contents_)) return true;
  size_t rhs_size = rhs.size();
  if (size() < rhs_size) return false;
  return EqualsImpl(rhs, rhs_size);
}

inline bool Cord::StartsWith(absl::string_view rhs) const {
  size_t rhs_size = rhs.size();
  if (size() < rhs_size) return false;
  return EqualsImpl(rhs, rhs_size);
}

inline void Cord::CopyToArrayImpl(char* absl_nonnull dst) const {
  if (!contents_.is_tree()) {
    if (!empty()) contents_.CopyToArray(dst);
  } else {
    CopyToArraySlowPath(dst);
  }
}

inline void Cord::ChunkIterator::InitTree(
    cord_internal::CordRep* absl_nonnull tree) {
  tree = cord_internal::SkipCrcNode(tree);
  if (tree->tag == cord_internal::BTREE) {
    current_chunk_ = btree_reader_.Init(tree->btree());
  } else {
    current_leaf_ = tree;
    current_chunk_ = cord_internal::EdgeData(tree);
  }
}

inline Cord::ChunkIterator::ChunkIterator(
    cord_internal::CordRep* absl_nonnull tree) {
  bytes_remaining_ = tree->length;
  InitTree(tree);
}

inline Cord::ChunkIterator::ChunkIterator(const Cord* absl_nonnull cord) {
  if (CordRep* tree = cord->contents_.tree()) {
    bytes_remaining_ = tree->length;
    if (ABSL_PREDICT_TRUE(bytes_remaining_ != 0)) {
      InitTree(tree);
    } else {
      current_chunk_ = {};
    }
  } else {
    bytes_remaining_ = cord->contents_.inline_size();
    current_chunk_ = {cord->contents_.data(), bytes_remaining_};
  }
}

inline Cord::ChunkIterator& Cord::ChunkIterator::AdvanceBtree() {
  current_chunk_ = btree_reader_.Next();
  return *this;
}

inline void Cord::ChunkIterator::AdvanceBytesBtree(size_t n) {
  assert(n >= current_chunk_.size());
  bytes_remaining_ -= n;
  if (bytes_remaining_) {
    if (n == current_chunk_.size()) {
      current_chunk_ = btree_reader_.Next();
    } else {
      size_t offset = btree_reader_.length() - bytes_remaining_;
      current_chunk_ = btree_reader_.Seek(offset);
    }
  } else {
    current_chunk_ = {};
  }
}

inline Cord::ChunkIterator& Cord::ChunkIterator::operator++() {
  ABSL_HARDENING_ASSERT(bytes_remaining_ > 0 &&
                        "Attempted to iterate past `end()`");
  assert(bytes_remaining_ >= current_chunk_.size());
  bytes_remaining_ -= current_chunk_.size();
  if (bytes_remaining_ > 0) {
    if (btree_reader_) {
      return AdvanceBtree();
    } else {
      assert(!current_chunk_.empty());  // Called on invalid iterator.
    }
    current_chunk_ = {};
  }
  return *this;
}

inline Cord::ChunkIterator Cord::ChunkIterator::operator++(int) {
  ChunkIterator tmp(*this);
  operator++();
  return tmp;
}

inline bool Cord::ChunkIterator::operator==(const ChunkIterator& other) const {
  return bytes_remaining_ == other.bytes_remaining_;
}

inline bool Cord::ChunkIterator::operator!=(const ChunkIterator& other) const {
  return !(*this == other);
}

inline Cord::ChunkIterator::reference Cord::ChunkIterator::operator*() const {
  ABSL_HARDENING_ASSERT(bytes_remaining_ != 0);
  return current_chunk_;
}

inline Cord::ChunkIterator::pointer Cord::ChunkIterator::operator->() const {
  ABSL_HARDENING_ASSERT(bytes_remaining_ != 0);
  return &current_chunk_;
}

inline void Cord::ChunkIterator::RemoveChunkPrefix(size_t n) {
  assert(n < current_chunk_.size());
  current_chunk_.remove_prefix(n);
  bytes_remaining_ -= n;
}

inline void Cord::ChunkIterator::AdvanceBytes(size_t n) {
  assert(bytes_remaining_ >= n);
  if (ABSL_PREDICT_TRUE(n < current_chunk_.size())) {
    RemoveChunkPrefix(n);
  } else if (n != 0) {
    if (btree_reader_) {
      AdvanceBytesBtree(n);
    } else {
      bytes_remaining_ = 0;
    }
  }
}

inline Cord::ChunkIterator Cord::chunk_begin() const {
  return ChunkIterator(this);
}

inline Cord::ChunkIterator Cord::chunk_end() const { return ChunkIterator(); }

inline Cord::ChunkIterator Cord::ChunkRange::begin() const {
  return cord_->chunk_begin();
}

inline Cord::ChunkIterator Cord::ChunkRange::end() const {
  return cord_->chunk_end();
}

inline Cord::ChunkRange Cord::Chunks() const { return ChunkRange(this); }

inline Cord::CharIterator& Cord::CharIterator::operator++() {
  if (ABSL_PREDICT_TRUE(chunk_iterator_->size() > 1)) {
    chunk_iterator_.RemoveChunkPrefix(1);
  } else {
    ++chunk_iterator_;
  }
  return *this;
}

inline Cord::CharIterator Cord::CharIterator::operator++(int) {
  CharIterator tmp(*this);
  operator++();
  return tmp;
}

inline bool Cord::CharIterator::operator==(const CharIterator& other) const {
  return chunk_iterator_ == other.chunk_iterator_;
}

inline bool Cord::CharIterator::operator!=(const CharIterator& other) const {
  return !(*this == other);
}

inline Cord::CharIterator::reference Cord::CharIterator::operator*() const {
  return *chunk_iterator_->data();
}

inline Cord Cord::AdvanceAndRead(CharIterator* absl_nonnull it,
                                 size_t n_bytes) {
  assert(it != nullptr);
  return it->chunk_iterator_.AdvanceAndReadBytes(n_bytes);
}

inline void Cord::Advance(CharIterator* absl_nonnull it, size_t n_bytes) {
  assert(it != nullptr);
  it->chunk_iterator_.AdvanceBytes(n_bytes);
}

inline absl::string_view Cord::ChunkRemaining(const CharIterator& it) {
  return *it.chunk_iterator_;
}

inline ptrdiff_t Cord::Distance(const CharIterator& first,
                                const CharIterator& last) {
  return static_cast<ptrdiff_t>(first.chunk_iterator_.bytes_remaining_ -
                                last.chunk_iterator_.bytes_remaining_);
}

inline Cord::CharIterator Cord::char_begin() const {
  return CharIterator(this);
}

inline Cord::CharIterator Cord::char_end() const { return CharIterator(); }

inline Cord::CharIterator Cord::CharRange::begin() const {
  return cord_->char_begin();
}

inline Cord::CharIterator Cord::CharRange::end() const {
  return cord_->char_end();
}

inline Cord::CharRange Cord::Chars() const { return CharRange(this); }

inline void Cord::ForEachChunk(
    absl::FunctionRef<void(absl::string_view)> callback) const {
  absl::cord_internal::CordRep* rep = contents_.tree();
  if (rep == nullptr) {
    callback(absl::string_view(contents_.data(), contents_.size()));
  } else {
    ForEachChunkAux(rep, callback);
  }
}

// Nonmember Cord-to-Cord relational operators.
inline bool operator==(const Cord& lhs, const Cord& rhs) {
  if (lhs.contents_.IsSame(rhs.contents_)) return true;
  size_t rhs_size = rhs.size();
  if (lhs.size() != rhs_size) return false;
  return lhs.EqualsImpl(rhs, rhs_size);
}

inline bool operator!=(const Cord& x, const Cord& y) { return !(x == y); }
inline bool operator<(const Cord& x, const Cord& y) { return x.Compare(y) < 0; }
inline bool operator>(const Cord& x, const Cord& y) { return x.Compare(y) > 0; }
inline bool operator<=(const Cord& x, const Cord& y) {
  return x.Compare(y) <= 0;
}
inline bool operator>=(const Cord& x, const Cord& y) {
  return x.Compare(y) >= 0;
}

// Nonmember Cord-to-absl::string_view relational operators.
//
// Due to implicit conversions, these also enable comparisons of Cord with
// 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();
  if (lhs_size != rhs_size) return false;
  return lhs.EqualsImpl(rhs, rhs_size);
}

inline bool operator==(absl::string_view x, const Cord& y) { return y == x; }
inline bool operator!=(const Cord& x, absl::string_view y) { return !(x == y); }
inline bool operator!=(absl::string_view x, const Cord& y) { return !(x == y); }
inline bool operator<(const Cord& x, absl::string_view y) {
  return x.Compare(y) < 0;
}
inline bool operator<(absl::string_view x, const Cord& y) {
  return y.Compare(x) > 0;
}
inline bool operator>(const Cord& x, absl::string_view y) { return y < x; }
inline bool operator>(absl::string_view x, const Cord& y) { return y < x; }
inline bool operator<=(const Cord& x, absl::string_view y) { return !(y < x); }
inline bool operator<=(absl::string_view x, const Cord& y) { return !(y < x); }
inline bool operator>=(const Cord& x, absl::string_view y) { return !(x < y); }
inline bool operator>=(absl::string_view x, const Cord& y) { return !(x < y); }

// Some internals exposed to test code.
namespace strings_internal {
class CordTestAccess {
 public:
  static size_t FlatOverhead();
  static size_t MaxFlatLength();
  static size_t SizeofCordRepExternal();
  static size_t SizeofCordRepSubstring();
  static size_t FlatTagToLength(uint8_t tag);
  static uint8_t LengthToTag(size_t s);
};
}  // namespace strings_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_CORD_H_
*Âd
osoong/.intermediates/external/abseil-cpp/absl_numeric_bits_hdrs/gen/my_include_dir/absl/numeric/internal/bits.hÎc// 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_NUMERIC_INTERNAL_BITS_H_
#define ABSL_NUMERIC_INTERNAL_BITS_H_

#include <cstdint>
#include <limits>
#include <type_traits>

// Clang on Windows has __builtin_clzll; otherwise we need to use the
// windows intrinsic functions.
#if defined(_MSC_VER) && !defined(__clang__)
#include <intrin.h>
#endif

#include "absl/base/attributes.h"
#include "absl/base/config.h"

#if defined(__GNUC__) && !defined(__clang__)
// GCC
#define ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(x) 1
#else
#define ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(x) ABSL_HAVE_BUILTIN(x)
#endif

#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_popcountl) && \
    ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_popcountll)
#define ABSL_INTERNAL_CONSTEXPR_POPCOUNT constexpr
#define ABSL_INTERNAL_HAS_CONSTEXPR_POPCOUNT 1
#else
#define ABSL_INTERNAL_CONSTEXPR_POPCOUNT
#define ABSL_INTERNAL_HAS_CONSTEXPR_POPCOUNT 0
#endif

#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_clz) && \
    ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_clzll)
#define ABSL_INTERNAL_CONSTEXPR_CLZ constexpr
#define ABSL_INTERNAL_HAS_CONSTEXPR_CLZ 1
#else
#define ABSL_INTERNAL_CONSTEXPR_CLZ
#define ABSL_INTERNAL_HAS_CONSTEXPR_CLZ 0
#endif

#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_ctz) && \
    ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_ctzll)
#define ABSL_INTERNAL_CONSTEXPR_CTZ constexpr
#define ABSL_INTERNAL_HAS_CONSTEXPR_CTZ 1
#else
#define ABSL_INTERNAL_CONSTEXPR_CTZ
#define ABSL_INTERNAL_HAS_CONSTEXPR_CTZ 0
#endif

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace numeric_internal {

constexpr bool IsPowerOf2(unsigned int x) noexcept {
  return x != 0 && (x & (x - 1)) == 0;
}

template <class T>
[[nodiscard]] ABSL_ATTRIBUTE_ALWAYS_INLINE constexpr T RotateRight(
    T x, int s) noexcept {
  static_assert(std::is_unsigned<T>::value, "T must be unsigned");
  static_assert(IsPowerOf2(std::numeric_limits<T>::digits),
                "T must have a power-of-2 size");

  return static_cast<T>(x >> (s & (std::numeric_limits<T>::digits - 1))) |
         static_cast<T>(x << ((-s) & (std::numeric_limits<T>::digits - 1)));
}

template <class T>
[[nodiscard]] ABSL_ATTRIBUTE_ALWAYS_INLINE constexpr T RotateLeft(
    T x, int s) noexcept {
  static_assert(std::is_unsigned<T>::value, "T must be unsigned");
  static_assert(IsPowerOf2(std::numeric_limits<T>::digits),
                "T must have a power-of-2 size");

  return static_cast<T>(x << (s & (std::numeric_limits<T>::digits - 1))) |
         static_cast<T>(x >> ((-s) & (std::numeric_limits<T>::digits - 1)));
}

ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline int
Popcount32(uint32_t x) noexcept {
#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_popcount)
  static_assert(sizeof(unsigned int) == sizeof(x),
                "__builtin_popcount does not take 32-bit arg");
  return __builtin_popcount(x);
#else
  x -= ((x >> 1) & 0x55555555);
  x = ((x >> 2) & 0x33333333) + (x & 0x33333333);
  return static_cast<int>((((x + (x >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24);
#endif
}

ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline int
Popcount64(uint64_t x) noexcept {
#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_popcountll)
  static_assert(sizeof(unsigned long long) == sizeof(x),  // NOLINT(runtime/int)
                "__builtin_popcount does not take 64-bit arg");
  return __builtin_popcountll(x);
#else
  x -= (x >> 1) & 0x5555555555555555ULL;
  x = ((x >> 2) & 0x3333333333333333ULL) + (x & 0x3333333333333333ULL);
  return static_cast<int>(
      (((x + (x >> 4)) & 0xF0F0F0F0F0F0F0FULL) * 0x101010101010101ULL) >> 56);
#endif
}

template <class T>
ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline int
Popcount(T x) noexcept {
  static_assert(std::is_unsigned<T>::value, "T must be unsigned");
  static_assert(IsPowerOf2(std::numeric_limits<T>::digits),
                "T must have a power-of-2 size");
  static_assert(sizeof(x) <= sizeof(uint64_t), "T is too large");
  if constexpr (sizeof(x) <= sizeof(uint32_t)) {
    return Popcount32(x);
  } else {
    return Popcount64(x);
  }
}

ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline int
CountLeadingZeroes32(uint32_t x) {
#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_clz)
  // Use __builtin_clz, which uses the following instructions:
  //  x86: bsr, lzcnt
  //  ARM64: clz
  //  PPC: cntlzd

  static_assert(sizeof(unsigned int) == sizeof(x),
                "__builtin_clz does not take 32-bit arg");
  // Handle 0 as a special case because __builtin_clz(0) is undefined.
  return x == 0 ? 32 : __builtin_clz(x);
#elif defined(_MSC_VER) && !defined(__clang__)
  unsigned long result = 0;  // NOLINT(runtime/int)
  if (_BitScanReverse(&result, x)) {
    return 31 - result;
  }
  return 32;
#else
  int zeroes = 28;
  if (x >> 16) {
    zeroes -= 16;
    x >>= 16;
  }
  if (x >> 8) {
    zeroes -= 8;
    x >>= 8;
  }
  if (x >> 4) {
    zeroes -= 4;
    x >>= 4;
  }
  return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[x] + zeroes;
#endif
}

ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline int
CountLeadingZeroes16(uint16_t x) {
#if ABSL_HAVE_BUILTIN(__builtin_clzg)
  return x == 0 ? 16 : __builtin_clzg(x);
#elif ABSL_HAVE_BUILTIN(__builtin_clzs)
  static_assert(sizeof(unsigned short) == sizeof(x),  // NOLINT(runtime/int)
                "__builtin_clzs does not take 16-bit arg");
  return x == 0 ? 16 : __builtin_clzs(x);
#else
  return CountLeadingZeroes32(x) - 16;
#endif
}

ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline int
CountLeadingZeroes64(uint64_t x) {
#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_clzll)
  // Use __builtin_clzll, which uses the following instructions:
  //  x86: bsr, lzcnt
  //  ARM64: clz
  //  PPC: cntlzd
  static_assert(sizeof(unsigned long long) == sizeof(x),  // NOLINT(runtime/int)
                "__builtin_clzll does not take 64-bit arg");

  // Handle 0 as a special case because __builtin_clzll(0) is undefined.
  return x == 0 ? 64 : __builtin_clzll(x);
#elif defined(_MSC_VER) && !defined(__clang__) && \
    (defined(_M_X64) || defined(_M_ARM64))
  // MSVC does not have __buitin_clzll. Use _BitScanReverse64.
  unsigned long result = 0;  // NOLINT(runtime/int)
  if (_BitScanReverse64(&result, x)) {
    return 63 - result;
  }
  return 64;
#elif defined(_MSC_VER) && !defined(__clang__)
  // MSVC does not have __buitin_clzll. Compose two calls to _BitScanReverse
  unsigned long result = 0;  // NOLINT(runtime/int)
  if ((x >> 32) &&
      _BitScanReverse(&result, static_cast<unsigned long>(x >> 32))) {
    return 31 - result;
  }
  if (_BitScanReverse(&result, static_cast<unsigned long>(x))) {
    return 63 - result;
  }
  return 64;
#else
  int zeroes = 60;
  if (x >> 32) {
    zeroes -= 32;
    x >>= 32;
  }
  if (x >> 16) {
    zeroes -= 16;
    x >>= 16;
  }
  if (x >> 8) {
    zeroes -= 8;
    x >>= 8;
  }
  if (x >> 4) {
    zeroes -= 4;
    x >>= 4;
  }
  return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[x] + zeroes;
#endif
}

template <typename T>
ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline int
CountLeadingZeroes(T x) {
  static_assert(std::is_unsigned<T>::value, "T must be unsigned");
  static_assert(IsPowerOf2(std::numeric_limits<T>::digits),
                "T must have a power-of-2 size");
  static_assert(sizeof(T) <= sizeof(uint64_t), "T too large");
  return sizeof(T) <= sizeof(uint16_t)
             ? CountLeadingZeroes16(static_cast<uint16_t>(x)) -
                   (std::numeric_limits<uint16_t>::digits -
                    std::numeric_limits<T>::digits)
             : (sizeof(T) <= sizeof(uint32_t)
                    ? CountLeadingZeroes32(static_cast<uint32_t>(x)) -
                          (std::numeric_limits<uint32_t>::digits -
                           std::numeric_limits<T>::digits)
                    : CountLeadingZeroes64(x));
}

ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CTZ inline int
CountTrailingZeroesNonzero32(uint32_t x) {
#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_ctz)
  static_assert(sizeof(unsigned int) == sizeof(x),
                "__builtin_ctz does not take 32-bit arg");
  return __builtin_ctz(x);
#elif defined(_MSC_VER) && !defined(__clang__)
  unsigned long result = 0;  // NOLINT(runtime/int)
  _BitScanForward(&result, x);
  return result;
#else
  int c = 31;
  x &= ~x + 1;
  if (x & 0x0000FFFF) c -= 16;
  if (x & 0x00FF00FF) c -= 8;
  if (x & 0x0F0F0F0F) c -= 4;
  if (x & 0x33333333) c -= 2;
  if (x & 0x55555555) c -= 1;
  return c;
#endif
}

ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CTZ inline int
CountTrailingZeroesNonzero64(uint64_t x) {
#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_ctzll)
  static_assert(sizeof(unsigned long long) == sizeof(x),  // NOLINT(runtime/int)
                "__builtin_ctzll does not take 64-bit arg");
  return __builtin_ctzll(x);
#elif defined(_MSC_VER) && !defined(__clang__) && \
    (defined(_M_X64) || defined(_M_ARM64))
  unsigned long result = 0;  // NOLINT(runtime/int)
  _BitScanForward64(&result, x);
  return result;
#elif defined(_MSC_VER) && !defined(__clang__)
  unsigned long result = 0;  // NOLINT(runtime/int)
  if (static_cast<uint32_t>(x) == 0) {
    _BitScanForward(&result, static_cast<unsigned long>(x >> 32));
    return result + 32;
  }
  _BitScanForward(&result, static_cast<unsigned long>(x));
  return result;
#else
  int c = 63;
  x &= ~x + 1;
  if (x & 0x00000000FFFFFFFF) c -= 32;
  if (x & 0x0000FFFF0000FFFF) c -= 16;
  if (x & 0x00FF00FF00FF00FF) c -= 8;
  if (x & 0x0F0F0F0F0F0F0F0F) c -= 4;
  if (x & 0x3333333333333333) c -= 2;
  if (x & 0x5555555555555555) c -= 1;
  return c;
#endif
}

ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CTZ inline int
CountTrailingZeroesNonzero16(uint16_t x) {
#if ABSL_HAVE_BUILTIN(__builtin_ctzg)
  return __builtin_ctzg(x);
#elif ABSL_HAVE_BUILTIN(__builtin_ctzs)
  static_assert(sizeof(unsigned short) == sizeof(x),  // NOLINT(runtime/int)
                "__builtin_ctzs does not take 16-bit arg");
  return __builtin_ctzs(x);
#else
  return CountTrailingZeroesNonzero32(x);
#endif
}

template <class T>
ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CTZ inline int
CountTrailingZeroes(T x) noexcept {
  static_assert(std::is_unsigned<T>::value, "T must be unsigned");
  static_assert(IsPowerOf2(std::numeric_limits<T>::digits),
                "T must have a power-of-2 size");
  static_assert(sizeof(T) <= sizeof(uint64_t), "T too large");
  return x == 0 ? std::numeric_limits<T>::digits
                : (sizeof(T) <= sizeof(uint16_t)
                       ? CountTrailingZeroesNonzero16(static_cast<uint16_t>(x))
                       : (sizeof(T) <= sizeof(uint32_t)
                              ? CountTrailingZeroesNonzero32(
                                    static_cast<uint32_t>(x))
                              : CountTrailingZeroesNonzero64(x)));
}

// If T is narrower than unsigned, T{1} << bit_width will be promoted.  We
// want to force it to wraparound so that bit_ceil of an invalid value are not
// core constant expressions.
template <class T>
ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline
    typename std::enable_if<std::is_unsigned<T>::value, T>::type
    BitCeilPromotionHelper(T x, T promotion) {
  return (T{1} << (x + promotion)) >> promotion;
}

template <class T>
ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline
    typename std::enable_if<std::is_unsigned<T>::value, T>::type
    BitCeilNonPowerOf2(T x) {
  // If T is narrower than unsigned, it undergoes promotion to unsigned when we
  // shift.  We calculate the number of bits added by the wider type.
  return BitCeilPromotionHelper(
      static_cast<T>(std::numeric_limits<T>::digits - CountLeadingZeroes(x)),
      T{sizeof(T) >= sizeof(unsigned) ? 0
                                      : std::numeric_limits<unsigned>::digits -
                                            std::numeric_limits<T>::digits});
}

}  // namespace numeric_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_NUMERIC_INTERNAL_BITS_H_
* I
msoong/.intermediates/external/abseil-cpp/absl_base_endian_hdrs/gen/my_include_dir/absl/base/internal/endian.h®H// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// This file is for Abseil internal use only.
// See //absl/numeric/bits.h for supported functions related to endian-ness.

#ifndef ABSL_BASE_INTERNAL_ENDIAN_H_
#define ABSL_BASE_INTERNAL_ENDIAN_H_

#include <cstdint>
#include <cstdlib>

#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 {
ABSL_NAMESPACE_BEGIN

constexpr uint64_t gbswap_64(uint64_t x) {
#if ABSL_HAVE_BUILTIN(__builtin_bswap64) || defined(__GNUC__)
  return __builtin_bswap64(x);
#else
  return (((x & uint64_t{0xFF}) << 56) |
          ((x & uint64_t{0xFF00}) << 40) |
          ((x & uint64_t{0xFF0000}) << 24) |
          ((x & uint64_t{0xFF000000}) << 8) |
          ((x & uint64_t{0xFF00000000}) >> 8) |
          ((x & uint64_t{0xFF0000000000}) >> 24) |
          ((x & uint64_t{0xFF000000000000}) >> 40) |
          ((x & uint64_t{0xFF00000000000000}) >> 56));
#endif
}

constexpr uint32_t gbswap_32(uint32_t x) {
#if ABSL_HAVE_BUILTIN(__builtin_bswap32) || defined(__GNUC__)
  return __builtin_bswap32(x);
#else
  return (((x & uint32_t{0xFF}) << 24) |
          ((x & uint32_t{0xFF00}) << 8) |
          ((x & uint32_t{0xFF0000}) >> 8) |
          ((x & uint32_t{0xFF000000}) >> 24));
#endif
}

constexpr uint16_t gbswap_16(uint16_t x) {
#if ABSL_HAVE_BUILTIN(__builtin_bswap16) || defined(__GNUC__)
  return __builtin_bswap16(x);
#else
  return (((x & uint16_t{0xFF}) << 8) |
          ((x & uint16_t{0xFF00}) >> 8));
#endif
}

#ifdef ABSL_IS_LITTLE_ENDIAN

// Portable definitions for htonl (host-to-network) and friends on little-endian
// architectures.
inline uint16_t ghtons(uint16_t x) { return gbswap_16(x); }
inline uint32_t ghtonl(uint32_t x) { return gbswap_32(x); }
inline uint64_t ghtonll(uint64_t x) { return gbswap_64(x); }

#elif defined ABSL_IS_BIG_ENDIAN

// Portable definitions for htonl (host-to-network) etc on big-endian
// architectures. These definitions are simpler since the host byte order is the
// same as network byte order.
inline uint16_t ghtons(uint16_t x) { return x; }
inline uint32_t ghtonl(uint32_t x) { return x; }
inline uint64_t ghtonll(uint64_t x) { return x; }

#else
#error \
    "Unsupported byte order: Either ABSL_IS_BIG_ENDIAN or " \
       "ABSL_IS_LITTLE_ENDIAN must be defined"
#endif  // byte order

inline uint16_t gntohs(uint16_t x) { return ghtons(x); }
inline uint32_t gntohl(uint32_t x) { return ghtonl(x); }
inline uint64_t gntohll(uint64_t x) { return ghtonll(x); }

// Utilities to convert numbers between the current hosts's native byte
// order and little-endian byte order
//
// Load/Store methods are alignment safe
namespace little_endian {
// Conversion functions.
#ifdef ABSL_IS_LITTLE_ENDIAN

inline uint16_t FromHost16(uint16_t x) { return x; }
inline uint16_t ToHost16(uint16_t x) { return x; }

inline uint32_t FromHost32(uint32_t x) { return x; }
inline uint32_t ToHost32(uint32_t x) { return x; }

inline uint64_t FromHost64(uint64_t x) { return x; }
inline uint64_t ToHost64(uint64_t x) { return x; }

inline constexpr bool IsLittleEndian() { return true; }

#elif defined ABSL_IS_BIG_ENDIAN

inline uint16_t FromHost16(uint16_t x) { return gbswap_16(x); }
inline uint16_t ToHost16(uint16_t x) { return gbswap_16(x); }

inline uint32_t FromHost32(uint32_t x) { return gbswap_32(x); }
inline uint32_t ToHost32(uint32_t x) { return gbswap_32(x); }

inline uint64_t FromHost64(uint64_t x) { return gbswap_64(x); }
inline uint64_t ToHost64(uint64_t x) { return gbswap_64(x); }

inline constexpr bool IsLittleEndian() { return false; }

#endif /* ENDIAN */

inline uint8_t FromHost(uint8_t x) { return x; }
inline uint16_t FromHost(uint16_t x) { return FromHost16(x); }
inline uint32_t FromHost(uint32_t x) { return FromHost32(x); }
inline uint64_t FromHost(uint64_t x) { return FromHost64(x); }
inline uint8_t ToHost(uint8_t x) { return x; }
inline uint16_t ToHost(uint16_t x) { return ToHost16(x); }
inline uint32_t ToHost(uint32_t x) { return ToHost32(x); }
inline uint64_t ToHost(uint64_t x) { return ToHost64(x); }

inline int8_t FromHost(int8_t x) { return x; }
inline int16_t FromHost(int16_t x) {
  return bit_cast<int16_t>(FromHost16(bit_cast<uint16_t>(x)));
}
inline int32_t FromHost(int32_t x) {
  return bit_cast<int32_t>(FromHost32(bit_cast<uint32_t>(x)));
}
inline int64_t FromHost(int64_t x) {
  return bit_cast<int64_t>(FromHost64(bit_cast<uint64_t>(x)));
}
inline int8_t ToHost(int8_t x) { return x; }
inline int16_t ToHost(int16_t x) {
  return bit_cast<int16_t>(ToHost16(bit_cast<uint16_t>(x)));
}
inline int32_t ToHost(int32_t x) {
  return bit_cast<int32_t>(ToHost32(bit_cast<uint32_t>(x)));
}
inline int64_t ToHost(int64_t x) {
  return bit_cast<int64_t>(ToHost64(bit_cast<uint64_t>(x)));
}

// Functions to do unaligned loads and stores in little-endian order.
inline uint16_t Load16(const void* absl_nonnull p) {
  return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p));
}

inline void Store16(void* absl_nonnull p, uint16_t v) {
  ABSL_INTERNAL_UNALIGNED_STORE16(p, FromHost16(v));
}

inline uint32_t Load32(const void* absl_nonnull p) {
  return ToHost32(ABSL_INTERNAL_UNALIGNED_LOAD32(p));
}

inline void Store32(void* absl_nonnull p, uint32_t v) {
  ABSL_INTERNAL_UNALIGNED_STORE32(p, FromHost32(v));
}

inline uint64_t Load64(const void* absl_nonnull p) {
  return ToHost64(ABSL_INTERNAL_UNALIGNED_LOAD64(p));
}

inline void Store64(void* absl_nonnull p, uint64_t v) {
  ABSL_INTERNAL_UNALIGNED_STORE64(p, FromHost64(v));
}

}  // namespace little_endian

// Utilities to convert numbers between the current hosts's native byte
// order and big-endian byte order (same as network byte order)
//
// Load/Store methods are alignment safe
namespace big_endian {
#ifdef ABSL_IS_LITTLE_ENDIAN

inline uint16_t FromHost16(uint16_t x) { return gbswap_16(x); }
inline uint16_t ToHost16(uint16_t x) { return gbswap_16(x); }

inline uint32_t FromHost32(uint32_t x) { return gbswap_32(x); }
inline uint32_t ToHost32(uint32_t x) { return gbswap_32(x); }

inline uint64_t FromHost64(uint64_t x) { return gbswap_64(x); }
inline uint64_t ToHost64(uint64_t x) { return gbswap_64(x); }

inline constexpr bool IsLittleEndian() { return true; }

#elif defined ABSL_IS_BIG_ENDIAN

inline uint16_t FromHost16(uint16_t x) { return x; }
inline uint16_t ToHost16(uint16_t x) { return x; }

inline uint32_t FromHost32(uint32_t x) { return x; }
inline uint32_t ToHost32(uint32_t x) { return x; }

inline uint64_t FromHost64(uint64_t x) { return x; }
inline uint64_t ToHost64(uint64_t x) { return x; }

inline constexpr bool IsLittleEndian() { return false; }

#endif /* ENDIAN */

inline uint8_t FromHost(uint8_t x) { return x; }
inline uint16_t FromHost(uint16_t x) { return FromHost16(x); }
inline uint32_t FromHost(uint32_t x) { return FromHost32(x); }
inline uint64_t FromHost(uint64_t x) { return FromHost64(x); }
inline uint8_t ToHost(uint8_t x) { return x; }
inline uint16_t ToHost(uint16_t x) { return ToHost16(x); }
inline uint32_t ToHost(uint32_t x) { return ToHost32(x); }
inline uint64_t ToHost(uint64_t x) { return ToHost64(x); }

inline int8_t FromHost(int8_t x) { return x; }
inline int16_t FromHost(int16_t x) {
  return bit_cast<int16_t>(FromHost16(bit_cast<uint16_t>(x)));
}
inline int32_t FromHost(int32_t x) {
  return bit_cast<int32_t>(FromHost32(bit_cast<uint32_t>(x)));
}
inline int64_t FromHost(int64_t x) {
  return bit_cast<int64_t>(FromHost64(bit_cast<uint64_t>(x)));
}
inline int8_t ToHost(int8_t x) { return x; }
inline int16_t ToHost(int16_t x) {
  return bit_cast<int16_t>(ToHost16(bit_cast<uint16_t>(x)));
}
inline int32_t ToHost(int32_t x) {
  return bit_cast<int32_t>(ToHost32(bit_cast<uint32_t>(x)));
}
inline int64_t ToHost(int64_t x) {
  return bit_cast<int64_t>(ToHost64(bit_cast<uint64_t>(x)));
}

// Functions to do unaligned loads and stores in big-endian order.
inline uint16_t Load16(const void* absl_nonnull p) {
  return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p));
}

inline void Store16(void* absl_nonnull p, uint16_t v) {
  ABSL_INTERNAL_UNALIGNED_STORE16(p, FromHost16(v));
}

inline uint32_t Load32(const void* absl_nonnull p) {
  return ToHost32(ABSL_INTERNAL_UNALIGNED_LOAD32(p));
}

inline void Store32(void* absl_nonnull p, uint32_t v) {
  ABSL_INTERNAL_UNALIGNED_STORE32(p, FromHost32(v));
}

inline uint64_t Load64(const void* absl_nonnull p) {
  return ToHost64(ABSL_INTERNAL_UNALIGNED_LOAD64(p));
}

inline void Store64(void* absl_nonnull p, uint64_t v) {
  ABSL_INTERNAL_UNALIGNED_STORE64(p, FromHost64(v));
}

}  // namespace big_endian

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_BASE_INTERNAL_ENDIAN_H_
*¸?
fsoong/.intermediates/external/abseil-cpp/absl_numeric_bits_hdrs/gen/my_include_dir/absl/numeric/bits.hÍ>// 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.
//
// -----------------------------------------------------------------------------
// File: bits.h
// -----------------------------------------------------------------------------
//
// This file contains implementations of C++20's bitwise math functions, as
// defined by:
//
// P0553R4:
//  http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0553r4.html
// P0556R3:
//  http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0556r3.html
// P1355R2:
//  http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1355r2.html
// P1956R1:
//  http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1956r1.pdf
// P0463R1
//  https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0463r1.html
// P1272R4
//  https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1272r4.html
//
// When using a standard library that implements these functions, we use the
// standard library's implementation.

#ifndef ABSL_NUMERIC_BITS_H_
#define ABSL_NUMERIC_BITS_H_

#include <cstdint>
#include <limits>
#include <type_traits>

#include "absl/base/config.h"

#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
#include <bit>
#endif

#include "absl/base/attributes.h"
#include "absl/base/internal/endian.h"
#include "absl/numeric/internal/bits.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

// 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>
[[nodiscard]] constexpr
    typename std::enable_if<std::is_unsigned<T>::value, T>::type
    rotl(T x, int s) noexcept {
  return numeric_internal::RotateLeft(x, s);
}

template <class T>
[[nodiscard]] constexpr
    typename std::enable_if<std::is_unsigned<T>::value, T>::type
    rotr(T x, int s) noexcept {
  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
// not be marked as constexpr due to constraints of the compiler/available
// intrinsics.
template <class T>
ABSL_INTERNAL_CONSTEXPR_CLZ inline
    typename std::enable_if<std::is_unsigned<T>::value, int>::type
    countl_zero(T x) noexcept {
  return numeric_internal::CountLeadingZeroes(x);
}

template <class T>
ABSL_INTERNAL_CONSTEXPR_CLZ inline
    typename std::enable_if<std::is_unsigned<T>::value, int>::type
    countl_one(T x) noexcept {
  // Avoid integer promotion to a wider type
  return countl_zero(static_cast<T>(~x));
}

template <class T>
ABSL_INTERNAL_CONSTEXPR_CTZ inline
    typename std::enable_if<std::is_unsigned<T>::value, int>::type
    countr_zero(T x) noexcept {
  return numeric_internal::CountTrailingZeroes(x);
}

template <class T>
ABSL_INTERNAL_CONSTEXPR_CTZ inline
    typename std::enable_if<std::is_unsigned<T>::value, int>::type
    countr_one(T x) noexcept {
  // Avoid integer promotion to a wider type
  return countr_zero(static_cast<T>(~x));
}

template <class T>
ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline
    typename std::enable_if<std::is_unsigned<T>::value, int>::type
    popcount(T x) noexcept {
  return numeric_internal::Popcount(x);
}

#endif

#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
has_single_bit(T x) noexcept {
  return x != 0 && (x & (x - 1)) == 0;
}

// Returns: If x == 0, 0; otherwise one plus the base-2 logarithm of x, with any
// fractional part discarded.
template <class T>
ABSL_INTERNAL_CONSTEXPR_CLZ inline
    typename std::enable_if<std::is_unsigned<T>::value, int>::type
    bit_width(T x) noexcept {
  return std::numeric_limits<T>::digits - countl_zero(x);
}

// Returns: If x == 0, 0; otherwise the maximal value y such that
// has_single_bit(y) is true and y <= x.
template <class T>
ABSL_INTERNAL_CONSTEXPR_CLZ inline
    typename std::enable_if<std::is_unsigned<T>::value, T>::type
    bit_floor(T x) noexcept {
  return x == 0 ? 0 : T{1} << (bit_width(x) - 1);
}

// Returns: N, where N is the smallest power of 2 greater than or equal to x.
//
// Preconditions: N is representable as a value of type T.
template <class T>
ABSL_INTERNAL_CONSTEXPR_CLZ inline
    typename std::enable_if<std::is_unsigned<T>::value, T>::type
    bit_ceil(T x) {
  // If T is narrower than unsigned, T{1} << bit_width will be promoted.  We
  // want to force it to wraparound so that bit_ceil of an invalid value are not
  // core constant expressions.
  //
  // BitCeilNonPowerOf2 triggers an overflow in constexpr contexts if we would
  // undergo promotion to unsigned but not fit the result into T without
  // truncation.
  return has_single_bit(x) ? T{1} << (bit_width(x) - 1)
                           : numeric_internal::BitCeilNonPowerOf2(x);
}

#endif

#if defined(__cpp_lib_endian) && __cpp_lib_endian >= 201907L

// https://en.cppreference.com/w/cpp/types/endian
//
// Indicates the endianness of all scalar types:
//   * If all scalar types are little-endian, `absl::endian::native` equals
//     absl::endian::little.
//   * If all scalar types are big-endian, `absl::endian::native` equals
//     `absl::endian::big`.
//   * Platforms that use anything else are unsupported.
using std::endian;

#else

enum class endian {
  little,
  big,
#if defined(ABSL_IS_LITTLE_ENDIAN)
  native = little
#elif defined(ABSL_IS_BIG_ENDIAN)
  native = big
#else
#error "Endian detection needs to be set up for this platform"
#endif
};

#endif  // defined(__cpp_lib_endian) && __cpp_lib_endian >= 201907L

#if defined(__cpp_lib_byteswap) && __cpp_lib_byteswap >= 202110L

// https://en.cppreference.com/w/cpp/numeric/byteswap
//
// Reverses the bytes in the given integer value `x`.
//
// `absl::byteswap` participates in overload resolution only if `T` satisfies
// integral, i.e., `T` is an integer type. The program is ill-formed if `T` has
// padding bits.
using std::byteswap;

#else

template <class T>
[[nodiscard]] constexpr T byteswap(T x) noexcept {
  static_assert(std::is_integral_v<T>,
                "byteswap requires an integral argument");
  static_assert(
      sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8,
      "byteswap works only with 8, 16, 32, or 64-bit integers");
  if constexpr (sizeof(T) == 1) {
    return x;
  } else if constexpr (sizeof(T) == 2) {
    return static_cast<T>(gbswap_16(static_cast<uint16_t>(x)));
  } else if constexpr (sizeof(T) == 4) {
    return static_cast<T>(gbswap_32(static_cast<uint32_t>(x)));
  } else if constexpr (sizeof(T) == 8) {
    return static_cast<T>(gbswap_64(static_cast<uint64_t>(x)));
  }
}

#endif  // defined(__cpp_lib_byteswap) && __cpp_lib_byteswap >= 202110L

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_NUMERIC_BITS_H_
*�]
|soong/.intermediates/external/abseil-cpp/absl_log_internal_conditions_hdrs/gen/my_include_dir/absl/log/internal/conditions.h�\// 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/internal/conditions.h
// -----------------------------------------------------------------------------
//
// This file contains implementation of conditional log statements, like LOG_IF
// including all the ABSL_LOG_INTERNAL_..._CONDITION_... macros and
// various condition classes like LogEveryNState.

#ifndef ABSL_LOG_INTERNAL_CONDITIONS_H_
#define ABSL_LOG_INTERNAL_CONDITIONS_H_

#if defined(_WIN32) || defined(__hexagon__)
#include <cstdlib>
#else
#include <unistd.h>
#endif
#include <stdlib.h>

#include <atomic>
#include <cstdint>

#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/log/internal/voidify.h"

// `ABSL_LOG_INTERNAL_CONDITION` prefixes another macro that expands to a
// temporary `LogMessage` instantiation followed by zero or more streamed
// expressions.  This definition is tricky to read correctly.  It evaluates to
// either
//
//   (void)0;
//
// or
//
//   ::absl::log_internal::Voidify() &&
//       ::absl::log_internal::LogMessage(...) << "the user's message";
//
// If the condition is evaluable at compile time, as is often the case, it
// compiles away to just one side or the other.
//
// Although this is not used anywhere a statement (e.g. `if`) could not go,
// the ternary expression does a better job avoiding spurious diagnostics
// (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 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.
#define ABSL_LOG_INTERNAL_STATELESS_CONDITION(condition) \
  switch (0)                                             \
  case 0:                                                \
  default:                                               \
    !(condition) ? (void)0 : ::absl::log_internal::Voidify() &&

// `ABSL_LOG_INTERNAL_STATEFUL_CONDITION` applies a condition like
// `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`.
//
// `for`-loops are used to declare scoped variables without braces (to permit
// streaming into the macro's expansion) and without the dangling-`else`
// problems/diagnostics that come with `if`.
//
// Two more variables are declared in separate `for`-loops:
//
// * `COUNTER` implements a streamable token whose value when streamed is the
//   number of times execution has passed through the macro.
// * A boolean flag is used to prevent any of the `for`-loops from ever actually
//   looping.
#define ABSL_LOG_INTERNAL_STATEFUL_CONDITION(condition)             \
  for (bool absl_log_internal_stateful_condition_do_log(condition); \
       absl_log_internal_stateful_condition_do_log;                 \
       absl_log_internal_stateful_condition_do_log = false)         \
  ABSL_LOG_INTERNAL_STATEFUL_CONDITION_IMPL
#define ABSL_LOG_INTERNAL_STATEFUL_CONDITION_IMPL(kind, ...)              \
  for (static ::absl::log_internal::Log##kind##State                      \
           absl_log_internal_stateful_condition_state;                    \
       absl_log_internal_stateful_condition_do_log &&                     \
       absl_log_internal_stateful_condition_state.ShouldLog(__VA_ARGS__); \
       absl_log_internal_stateful_condition_do_log = false)               \
    for (const uint32_t COUNTER ABSL_ATTRIBUTE_UNUSED =                   \
             absl_log_internal_stateful_condition_state.counter();        \
         absl_log_internal_stateful_condition_do_log;                     \
         absl_log_internal_stateful_condition_do_log = false)             \
  ::absl::log_internal::Voidify() &&

// `ABSL_LOG_INTERNAL_CONDITION_*` serve to combine any conditions from the
// macro (e.g. `LOG_IF` or `VLOG`) with inherent conditions (e.g.
// `ABSL_MIN_LOG_LEVEL`) into a single boolean expression.  We could chain
// ternary operators instead, however some versions of Clang sometimes issue
// spurious diagnostics after such expressions due to a control flow analysis
// bug.
#ifdef ABSL_MIN_LOG_LEVEL
#define ABSL_LOG_INTERNAL_CONDITION_INFO(type, condition) \
  ABSL_LOG_INTERNAL_##type##_CONDITION(                   \
      (condition) && ::absl::LogSeverity::kInfo >=        \
                         static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL))
#define ABSL_LOG_INTERNAL_CONDITION_WARNING(type, condition) \
  ABSL_LOG_INTERNAL_##type##_CONDITION(                      \
      (condition) && ::absl::LogSeverity::kWarning >=        \
                         static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL))
#define ABSL_LOG_INTERNAL_CONDITION_ERROR(type, condition) \
  ABSL_LOG_INTERNAL_##type##_CONDITION(                    \
      (condition) && ::absl::LogSeverity::kError >=        \
                         static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL))
#define ABSL_LOG_INTERNAL_CONDITION_DO_NOT_SUBMIT(type, condition) \
  ABSL_LOG_INTERNAL_CONDITION_ERROR(type, condition)
// NOTE: Use ternary operators instead of short-circuiting to mitigate
// https://bugs.llvm.org/show_bug.cgi?id=51928.
#define ABSL_LOG_INTERNAL_CONDITION_FATAL(type, condition)                 \
  ABSL_LOG_INTERNAL_##type##_CONDITION(                                    \
      ((condition)                                                         \
           ? (::absl::LogSeverity::kFatal >=                               \
                      static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) \
                  ? true                                                   \
                  : (::absl::log_internal::AbortQuietly(), false))         \
           : false))
// NOTE: Use ternary operators instead of short-circuiting to mitigate
// https://bugs.llvm.org/show_bug.cgi?id=51928.
#define ABSL_LOG_INTERNAL_CONDITION_QFATAL(type, condition)                \
  ABSL_LOG_INTERNAL_##type##_CONDITION(                                    \
      ((condition)                                                         \
           ? (::absl::LogSeverity::kFatal >=                               \
                      static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) \
                  ? true                                                   \
                  : (::absl::log_internal::ExitQuietly(), false))          \
           : false))
#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) &&                                                     \
          (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)
#define ABSL_LOG_INTERNAL_CONDITION_WARNING(type, condition) \
  ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
#define ABSL_LOG_INTERNAL_CONDITION_ERROR(type, condition) \
  ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
#define ABSL_LOG_INTERNAL_CONDITION_DO_NOT_SUBMIT(type, condition) \
  ABSL_LOG_INTERNAL_CONDITION_ERROR(type, condition)
#define ABSL_LOG_INTERNAL_CONDITION_FATAL(type, condition) \
  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_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)
#endif  // ndef ABSL_MIN_LOG_LEVEL

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace log_internal {

// Stateful condition class name should be "Log" + name + "State".
class LogEveryNState final {
 public:
  bool ShouldLog(int n);
  uint32_t counter() { return counter_.load(std::memory_order_relaxed); }

 private:
  std::atomic<uint32_t> counter_{0};
};

class LogFirstNState final {
 public:
  bool ShouldLog(int n);
  uint32_t counter() { return counter_.load(std::memory_order_relaxed); }

 private:
  std::atomic<uint32_t> counter_{0};
};

class LogEveryPow2State final {
 public:
  bool ShouldLog();
  uint32_t counter() { return counter_.load(std::memory_order_relaxed); }

 private:
  std::atomic<uint32_t> counter_{0};
};

class LogEveryNSecState final {
 public:
  bool ShouldLog(double seconds);
  uint32_t counter() { return counter_.load(std::memory_order_relaxed); }

 private:
  std::atomic<uint32_t> counter_{0};
  // Cycle count according to CycleClock that we should next log at.
  std::atomic<int64_t> next_log_time_cycles_{0};
};

// Helper routines to abort the application quietly

[[noreturn]] inline void AbortQuietly() { abort(); }
[[noreturn]] inline void ExitQuietly() { _exit(1); }
}  // namespace log_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_LOG_INTERNAL_CONDITIONS_H_
*ÿ
osoong/.intermediates/external/abseil-cpp/absl_strings_hdrs/gen/my_include_dir/absl/strings/has_absl_stringify.h‹// 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.

#ifndef ABSL_STRINGS_HAS_ABSL_STRINGIFY_H_
#define ABSL_STRINGS_HAS_ABSL_STRINGIFY_H_

#include <type_traits>
#include <utility>

#include "absl/base/config.h"
#include "absl/strings/string_view.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

namespace strings_internal {

// This is an empty class not intended to be used. It exists so that
// `HasAbslStringify` can reference a universal class rather than needing to be
// copied for each new sink.
class UnimplementedSink {
 public:
  void Append(size_t count, char ch);

  void Append(string_view v);

  // Support `absl::Format(&sink, format, args...)`.
  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 {};

template <typename T>
struct HasAbslStringify<
    T, std::enable_if_t<std::is_void<decltype(AbslStringify(
           std::declval<strings_internal::UnimplementedSink&>(),
           std::declval<const T&>()))>::value>> : std::true_type {};

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_HAS_ABSL_STRINGIFY_H_
*®›
“soong/.intermediates/external/abseil-cpp/absl_time_internal_cctz_time_zone_hdrs/gen/my_include_dir/absl/time/internal/cctz/include/cctz/time_zone.h”š// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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.

// A library for translating between absolute times (represented by
// std::chrono::time_points of the std::chrono::system_clock) and civil
// times (represented by cctz::civil_second) using the rules defined by
// a time zone (cctz::time_zone).

#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_H_
#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_H_

#include <chrono>
#include <cstdint>
#include <limits>
#include <ratio>  // NOLINT: We use std::ratio in this header
#include <string>
#include <utility>

#include "absl/base/config.h"
#include "absl/time/internal/cctz/include/cctz/civil_time.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace time_internal {
namespace cctz {

// Convenience aliases. Not intended as public API points.
template <typename D>
using time_point = std::chrono::time_point<std::chrono::system_clock, D>;
using seconds = std::chrono::duration<std::int_fast64_t>;
using sys_seconds = seconds;  // Deprecated.  Use cctz::seconds instead.

namespace detail {
template <typename D>
std::pair<time_point<seconds>, D> split_seconds(const time_point<D>& tp);
std::pair<time_point<seconds>, seconds> split_seconds(
    const time_point<seconds>& tp);
}  // namespace detail

// cctz::time_zone is an opaque, small, value-type class representing a
// geo-political region within which particular rules are used for mapping
// between absolute and civil times. Time zones are named using the TZ
// identifiers from the IANA Time Zone Database, such as "America/Los_Angeles"
// or "Australia/Sydney". Time zones are created from factory functions such
// as load_time_zone(). Note: strings like "PST" and "EDT" are not valid TZ
// identifiers.
//
// Example:
//   cctz::time_zone utc = cctz::utc_time_zone();
//   cctz::time_zone pst = cctz::fixed_time_zone(std::chrono::hours(-8));
//   cctz::time_zone loc = cctz::local_time_zone();
//   cctz::time_zone lax;
//   if (!cctz::load_time_zone("America/Los_Angeles", &lax)) { ... }
//
// See also:
// - http://www.iana.org/time-zones
// - https://en.wikipedia.org/wiki/Zoneinfo
class time_zone {
 public:
  time_zone() : time_zone(nullptr) {}  // Equivalent to UTC
  time_zone(const time_zone&) = default;
  time_zone& operator=(const time_zone&) = default;

  std::string name() const;

  // An absolute_lookup represents the civil time (cctz::civil_second) within
  // this time_zone at the given absolute time (time_point). There are
  // additionally a few other fields that may be useful when working with
  // older APIs, such as std::tm.
  //
  // Example:
  //   const cctz::time_zone tz = ...
  //   const auto tp = std::chrono::system_clock::now();
  //   const cctz::time_zone::absolute_lookup al = tz.lookup(tp);
  struct absolute_lookup {
    civil_second cs;
    // Note: The following fields exist for backward compatibility with older
    // APIs. Accessing these fields directly is a sign of imprudent logic in
    // the calling code. Modern time-related code should only access this data
    // indirectly by way of cctz::format().
    int offset;        // civil seconds east of UTC
    bool is_dst;       // is offset non-standard?
    const char* abbr;  // time-zone abbreviation (e.g., "PST")
  };
  absolute_lookup lookup(const time_point<seconds>& tp) const;
  template <typename D>
  absolute_lookup lookup(const time_point<D>& tp) const {
    return lookup(detail::split_seconds(tp).first);
  }

  // A civil_lookup represents the absolute time(s) (time_point) that
  // correspond to the given civil time (cctz::civil_second) within this
  // time_zone. Usually the given civil time represents a unique instant
  // in time, in which case the conversion is unambiguous. However,
  // within this time zone, the given civil time may be skipped (e.g.,
  // during a positive UTC offset shift), or repeated (e.g., during a
  // negative UTC offset shift). To account for these possibilities,
  // civil_lookup is richer than just a single time_point.
  //
  // In all cases the civil_lookup::kind enum will indicate the nature
  // of the given civil-time argument, and the pre, trans, and post
  // members will give the absolute time answers using the pre-transition
  // offset, the transition point itself, and the post-transition offset,
  // respectively (all three times are equal if kind == UNIQUE). If any
  // of these three absolute times is outside the representable range of a
  // time_point<seconds> the field is set to its maximum/minimum value.
  //
  // Example:
  //   cctz::time_zone lax;
  //   if (!cctz::load_time_zone("America/Los_Angeles", &lax)) { ... }
  //
  //   // A unique civil time.
  //   auto jan01 = lax.lookup(cctz::civil_second(2011, 1, 1, 0, 0, 0));
  //   // jan01.kind == cctz::time_zone::civil_lookup::UNIQUE
  //   // jan01.pre    is 2011/01/01 00:00:00 -0800
  //   // jan01.trans  is 2011/01/01 00:00:00 -0800
  //   // jan01.post   is 2011/01/01 00:00:00 -0800
  //
  //   // A Spring DST transition, when there is a gap in civil time.
  //   auto mar13 = lax.lookup(cctz::civil_second(2011, 3, 13, 2, 15, 0));
  //   // mar13.kind == cctz::time_zone::civil_lookup::SKIPPED
  //   // mar13.pre   is 2011/03/13 03:15:00 -0700
  //   // mar13.trans is 2011/03/13 03:00:00 -0700
  //   // mar13.post  is 2011/03/13 01:15:00 -0800
  //
  //   // A Fall DST transition, when civil times are repeated.
  //   auto nov06 = lax.lookup(cctz::civil_second(2011, 11, 6, 1, 15, 0));
  //   // nov06.kind == cctz::time_zone::civil_lookup::REPEATED
  //   // nov06.pre   is 2011/11/06 01:15:00 -0700
  //   // nov06.trans is 2011/11/06 01:00:00 -0800
  //   // nov06.post  is 2011/11/06 01:15:00 -0800
  struct civil_lookup {
    enum civil_kind {
      UNIQUE,    // the civil time was singular (pre == trans == post)
      SKIPPED,   // the civil time did not exist (pre >= trans > post)
      REPEATED,  // the civil time was ambiguous (pre < trans <= post)
    } kind;
    time_point<seconds> pre;    // uses the pre-transition offset
    time_point<seconds> trans;  // instant of civil-offset change
    time_point<seconds> post;   // uses the post-transition offset
  };
  civil_lookup lookup(const civil_second& cs) const;

  // Finds the time of the next/previous offset change in this time zone.
  //
  // By definition, next_transition(tp, &trans) returns false when tp has
  // its maximum value, and prev_transition(tp, &trans) returns false
  // when tp has its minimum value. If the zone has no transitions, the
  // result will also be false no matter what the argument.
  //
  // Otherwise, when tp has its minimum value, next_transition(tp, &trans)
  // returns true and sets trans to the first recorded transition. Chains
  // of calls to next_transition()/prev_transition() will eventually return
  // false, but it is unspecified exactly when next_transition(tp, &trans)
  // jumps to false, or what time is set by prev_transition(tp, &trans) for
  // a very distant tp.
  //
  // Note: Enumeration of time-zone transitions is for informational purposes
  // only. Modern time-related code should not care about when offset changes
  // occur.
  //
  // Example:
  //   cctz::time_zone nyc;
  //   if (!cctz::load_time_zone("America/New_York", &nyc)) { ... }
  //   const auto now = std::chrono::system_clock::now();
  //   auto tp = cctz::time_point<cctz::seconds>::min();
  //   cctz::time_zone::civil_transition trans;
  //   while (tp <= now && nyc.next_transition(tp, &trans)) {
  //     // transition: trans.from -> trans.to
  //     tp = nyc.lookup(trans.to).trans;
  //   }
  struct civil_transition {
    civil_second from;  // the civil time we jump from
    civil_second to;    // the civil time we jump to
  };
  bool next_transition(const time_point<seconds>& tp,
                       civil_transition* trans) const;
  template <typename D>
  bool next_transition(const time_point<D>& tp, civil_transition* trans) const {
    return next_transition(detail::split_seconds(tp).first, trans);
  }
  bool prev_transition(const time_point<seconds>& tp,
                       civil_transition* trans) const;
  template <typename D>
  bool prev_transition(const time_point<D>& tp, civil_transition* trans) const {
    return prev_transition(detail::split_seconds(tp).first, trans);
  }

  // version() and description() provide additional information about the
  // time zone. The content of each of the returned strings is unspecified,
  // however, when the IANA Time Zone Database is the underlying data source
  // the version() string will be in the familiar form (e.g, "2018e") or
  // empty when unavailable.
  //
  // Note: These functions are for informational or testing purposes only.
  std::string version() const;  // empty when unknown
  std::string description() const;

  // Relational operators.
  friend bool operator==(time_zone lhs, time_zone rhs) {
    return &lhs.effective_impl() == &rhs.effective_impl();
  }
  friend bool operator!=(time_zone lhs, time_zone rhs) { return !(lhs == rhs); }

  template <typename H>
  friend H AbslHashValue(H h, time_zone tz) {
    return H::combine(std::move(h), &tz.effective_impl());
  }

  class Impl;

 private:
  explicit time_zone(const Impl* impl) : impl_(impl) {}
  const Impl& effective_impl() const;  // handles implicit UTC
  const Impl* impl_;
};

// Loads the named time zone. May perform I/O on the initial load.
// If the name is invalid, or some other kind of error occurs, returns
// false and "*tz" is set to the UTC time zone.
bool load_time_zone(const std::string& name, time_zone* tz);

// Returns a time_zone representing UTC. Cannot fail.
time_zone utc_time_zone();

// Returns a time zone that is a fixed offset (seconds east) from UTC.
// Note: If the absolute value of the offset is greater than 24 hours
// you'll get UTC (i.e., zero offset) instead.
time_zone fixed_time_zone(const seconds& offset);

// Returns a time zone representing the local time zone. Falls back to UTC.
// Note: local_time_zone.name() may only be something like "localtime".
time_zone local_time_zone();

// Returns the civil time (cctz::civil_second) within the given time zone at
// the given absolute time (time_point). Since the additional fields provided
// by the time_zone::absolute_lookup struct should rarely be needed in modern
// code, this convert() function is simpler and should be preferred.
template <typename D>
inline civil_second convert(const time_point<D>& tp, const time_zone& tz) {
  return tz.lookup(tp).cs;
}

// Returns the absolute time (time_point) that corresponds to the given civil
// time within the given time zone. If the civil time is not unique (i.e., if
// it was either repeated or non-existent), then the returned time_point is
// the best estimate that preserves relative order. That is, this function
// guarantees that if cs1 < cs2, then convert(cs1, tz) <= convert(cs2, tz).
inline time_point<seconds> convert(const civil_second& cs,
                                   const time_zone& tz) {
  const time_zone::civil_lookup cl = tz.lookup(cs);
  if (cl.kind == time_zone::civil_lookup::SKIPPED) return cl.trans;
  return cl.pre;
}

namespace detail {
using femtoseconds = std::chrono::duration<std::int_fast64_t, std::femto>;
std::string format(const std::string&, const time_point<seconds>&,
                   const femtoseconds&, const time_zone&);
bool parse(const std::string&, const std::string&, const time_zone&,
           time_point<seconds>*, femtoseconds*, std::string* err = nullptr);
template <typename Rep, std::intmax_t Denom>
bool join_seconds(
    const time_point<seconds>& sec, const femtoseconds& fs,
    time_point<std::chrono::duration<Rep, std::ratio<1, Denom>>>* tpp);
template <typename Rep, std::intmax_t Num>
bool join_seconds(
    const time_point<seconds>& sec, const femtoseconds& fs,
    time_point<std::chrono::duration<Rep, std::ratio<Num, 1>>>* tpp);
template <typename Rep>
bool join_seconds(
    const time_point<seconds>& sec, const femtoseconds& fs,
    time_point<std::chrono::duration<Rep, std::ratio<1, 1>>>* tpp);
bool join_seconds(const time_point<seconds>& sec, const femtoseconds&,
                  time_point<seconds>* tpp);
}  // namespace detail

// Formats the given time_point in the given cctz::time_zone according to
// the provided format string. Uses strftime()-like formatting options,
// with the following extensions:
//
//   - %Ez  - RFC3339-compatible numeric UTC offset (+hh:mm or -hh:mm)
//   - %E*z - Full-resolution numeric UTC offset (+hh:mm:ss or -hh:mm:ss)
//   - %E#S - Seconds with # digits of fractional precision
//   - %E*S - Seconds with full fractional precision (a literal '*')
//   - %E#f - Fractional seconds with # digits of precision
//   - %E*f - Fractional seconds with full precision (a literal '*')
//   - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999)
//   - %ET  - The RFC3339 "date-time" separator "T"
//
// Note that %E0S behaves like %S, and %E0f produces no characters. In
// contrast %E*f always produces at least one digit, which may be '0'.
//
// Note that %Y produces as many characters as it takes to fully render the
// year. A year outside of [-999:9999] when formatted with %E4Y will produce
// more than four characters, just like %Y.
//
// Tip: Format strings should include the UTC offset (e.g., %z, %Ez, or %E*z)
// so that the resulting string uniquely identifies an absolute time.
//
// Example:
//   cctz::time_zone lax;
//   if (!cctz::load_time_zone("America/Los_Angeles", &lax)) { ... }
//   auto tp = cctz::convert(cctz::civil_second(2013, 1, 2, 3, 4, 5), lax);
//   std::string f = cctz::format("%H:%M:%S", tp, lax);  // "03:04:05"
//   f = cctz::format("%H:%M:%E3S", tp, lax);            // "03:04:05.000"
template <typename D>
inline std::string format(const std::string& fmt, const time_point<D>& tp,
                          const time_zone& tz) {
  const auto p = detail::split_seconds(tp);
  const auto n = std::chrono::duration_cast<detail::femtoseconds>(p.second);
  return detail::format(fmt, p.first, n, tz);
}

// Parses an input string according to the provided format string and
// returns the corresponding time_point. Uses strftime()-like formatting
// options, with the same extensions as cctz::format(), but with the
// exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f. %Ez
// and %E*z also accept the same inputs, which (along with %z) includes
// 'z' and 'Z' as synonyms for +00:00.  %ET accepts either 'T' or 't'.
//
// %Y consumes as many numeric characters as it can, so the matching data
// should always be terminated with a non-numeric. %E4Y always consumes
// exactly four characters, including any sign.
//
// Unspecified fields are taken from the default date and time of ...
//
//   "1970-01-01 00:00:00.0 +0000"
//
// For example, parsing a string of "15:45" (%H:%M) will return a time_point
// that represents "1970-01-01 15:45:00.0 +0000".
//
// Note that parse() returns time instants, so it makes most sense to parse
// fully-specified date/time strings that include a UTC offset (%z, %Ez, or
// %E*z).
//
// Note also that parse() only heeds the fields year, month, day, hour,
// minute, (fractional) second, and UTC offset. Other fields, like weekday (%a
// or %A), while parsed for syntactic validity, are ignored in the conversion.
//
// Date and time fields that are out-of-range will be treated as errors rather
// than normalizing them like cctz::civil_second() would do. For example, it
// is an error to parse the date "Oct 32, 2013" because 32 is out of range.
//
// A second of ":60" is normalized to ":00" of the following minute with
// fractional seconds discarded. The following table shows how the given
// seconds and subseconds will be parsed:
//
//   "59.x" -> 59.x  // exact
//   "60.x" -> 00.0  // normalized
//   "00.x" -> 00.x  // exact
//
// Errors are indicated by returning false.
//
// Example:
//   const cctz::time_zone tz = ...
//   std::chrono::system_clock::time_point tp;
//   if (cctz::parse("%Y-%m-%d", "2015-10-09", tz, &tp)) {
//     ...
//   }
template <typename D>
inline bool parse(const std::string& fmt, const std::string& input,
                  const time_zone& tz, time_point<D>* tpp) {
  time_point<seconds> sec;
  detail::femtoseconds fs;
  return detail::parse(fmt, input, tz, &sec, &fs) &&
         detail::join_seconds(sec, fs, tpp);
}

namespace detail {

// Split a time_point<D> into a time_point<seconds> and a D subseconds.
// Undefined behavior if time_point<seconds> is not of sufficient range.
// Note that this means it is UB to call cctz::time_zone::lookup(tp) or
// cctz::format(fmt, tp, tz) with a time_point that is outside the range
// of a 64-bit std::time_t.
template <typename D>
std::pair<time_point<seconds>, D> split_seconds(const time_point<D>& tp) {
  auto sec = std::chrono::time_point_cast<seconds>(tp);
  auto sub = tp - sec;
  if (sub.count() < 0) {
    sec -= seconds(1);
    sub += seconds(1);
  }
  return {sec, std::chrono::duration_cast<D>(sub)};
}

inline std::pair<time_point<seconds>, seconds> split_seconds(
    const time_point<seconds>& tp) {
  return {tp, seconds::zero()};
}

// Join a time_point<seconds> and femto subseconds into a time_point<D>.
// Floors to the resolution of time_point<D>. Returns false if time_point<D>
// is not of sufficient range.
template <typename Rep, std::intmax_t Denom>
bool join_seconds(
    const time_point<seconds>& sec, const femtoseconds& fs,
    time_point<std::chrono::duration<Rep, std::ratio<1, Denom>>>* tpp) {
  using D = std::chrono::duration<Rep, std::ratio<1, Denom>>;
  // TODO(#199): Return false if result unrepresentable as a time_point<D>.
  *tpp = std::chrono::time_point_cast<D>(sec);
  *tpp += std::chrono::duration_cast<D>(fs);
  return true;
}

template <typename Rep, std::intmax_t Num>
bool join_seconds(
    const time_point<seconds>& sec, const femtoseconds&,
    time_point<std::chrono::duration<Rep, std::ratio<Num, 1>>>* tpp) {
  using D = std::chrono::duration<Rep, std::ratio<Num, 1>>;
  auto count = sec.time_since_epoch().count();
  if (count >= 0 || count % Num == 0) {
    count /= Num;
  } else {
    count /= Num;
    count -= 1;
  }
  if (count > (std::numeric_limits<Rep>::max)()) return false;
  if (count < (std::numeric_limits<Rep>::min)()) return false;
  *tpp = time_point<D>() + D{static_cast<Rep>(count)};
  return true;
}

template <typename Rep>
bool join_seconds(
    const time_point<seconds>& sec, const femtoseconds&,
    time_point<std::chrono::duration<Rep, std::ratio<1, 1>>>* tpp) {
  using D = std::chrono::duration<Rep, std::ratio<1, 1>>;
  auto count = sec.time_since_epoch().count();
  if (count > (std::numeric_limits<Rep>::max)()) return false;
  if (count < (std::numeric_limits<Rep>::min)()) return false;
  *tpp = time_point<D>() + D{static_cast<Rep>(count)};
  return true;
}

inline bool join_seconds(const time_point<seconds>& sec, const femtoseconds&,
                         time_point<seconds>* tpp) {
  *tpp = sec;
  return true;
}

}  // namespace detail
}  // namespace cctz
}  // namespace time_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_H_
*Ëk
•soong/.intermediates/external/abseil-cpp/absl_time_internal_cctz_civil_time_hdrs/gen/my_include_dir/absl/time/internal/cctz/include/cctz/civil_time.h°j// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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_TIME_INTERNAL_CCTZ_CIVIL_TIME_H_
#define ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_H_

#include "absl/base/config.h"
#include "absl/time/internal/cctz/include/cctz/civil_time_detail.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace time_internal {
namespace cctz {

// The term "civil time" refers to the legally recognized human-scale time
// that is represented by the six fields YYYY-MM-DD hh:mm:ss. Modern-day civil
// time follows the Gregorian Calendar and is a time-zone-independent concept.
// A "date" is perhaps the most common example of a civil time (represented in
// this library as cctz::civil_day). This library provides six classes and a
// handful of functions that help with rounding, iterating, and arithmetic on
// civil times while avoiding complications like daylight-saving time (DST).
//
// The following six classes form the core of this civil-time library:
//
//   * civil_second
//   * civil_minute
//   * civil_hour
//   * civil_day
//   * civil_month
//   * civil_year
//
// Each class is a simple value type with the same interface for construction
// and the same six accessors for each of the civil fields (year, month, day,
// hour, minute, and second, aka YMDHMS). These classes differ only in their
// alignment, which is indicated by the type name and specifies the field on
// which arithmetic operates.
//
// Each class can be constructed by passing up to six optional integer
// arguments representing the YMDHMS fields (in that order) to the
// constructor. Omitted fields are assigned their minimum valid value. Hours,
// minutes, and seconds will be set to 0, month and day will be set to 1, and
// since there is no minimum valid year, it will be set to 1970. So, a
// default-constructed civil-time object will have YMDHMS fields representing
// "1970-01-01 00:00:00". Fields that are out-of-range are normalized (e.g.,
// October 32 -> November 1) so that all civil-time objects represent valid
// values.
//
// Each civil-time class is aligned to the civil-time field indicated in the
// class's name after normalization. Alignment is performed by setting all the
// inferior fields to their minimum valid value (as described above). The
// following are examples of how each of the six types would align the fields
// representing November 22, 2015 at 12:34:56 in the afternoon. (Note: the
// string format used here is not important; it's just a shorthand way of
// showing the six YMDHMS fields.)
//
//   civil_second  2015-11-22 12:34:56
//   civil_minute  2015-11-22 12:34:00
//   civil_hour    2015-11-22 12:00:00
//   civil_day     2015-11-22 00:00:00
//   civil_month   2015-11-01 00:00:00
//   civil_year    2015-01-01 00:00:00
//
// Each civil-time type performs arithmetic on the field to which it is
// aligned. This means that adding 1 to a civil_day increments the day field
// (normalizing as necessary), and subtracting 7 from a civil_month operates
// on the month field (normalizing as necessary). All arithmetic produces a
// valid civil time. Difference requires two similarly aligned civil-time
// objects and returns the scalar answer in units of the objects' alignment.
// For example, the difference between two civil_hour objects will give an
// answer in units of civil hours.
//
// In addition to the six civil-time types just described, there are
// a handful of helper functions and algorithms for performing common
// calculations. These are described below.
//
// Note: In C++14 and later, this library is usable in a constexpr context.
//
// CONSTRUCTION:
//
// Each of the civil-time types can be constructed in two ways: by directly
// passing to the constructor up to six (optional) integers representing the
// YMDHMS fields, or by copying the YMDHMS fields from a differently aligned
// civil-time type.
//
//   civil_day default_value;  // 1970-01-01 00:00:00
//
//   civil_day a(2015, 2, 3);           // 2015-02-03 00:00:00
//   civil_day b(2015, 2, 3, 4, 5, 6);  // 2015-02-03 00:00:00
//   civil_day c(2015);                 // 2015-01-01 00:00:00
//
//   civil_second ss(2015, 2, 3, 4, 5, 6);  // 2015-02-03 04:05:06
//   civil_minute mm(ss);                   // 2015-02-03 04:05:00
//   civil_hour hh(mm);                     // 2015-02-03 04:00:00
//   civil_day d(hh);                       // 2015-02-03 00:00:00
//   civil_month m(d);                      // 2015-02-01 00:00:00
//   civil_year y(m);                       // 2015-01-01 00:00:00
//
//   m = civil_month(y);     // 2015-01-01 00:00:00
//   d = civil_day(m);       // 2015-01-01 00:00:00
//   hh = civil_hour(d);     // 2015-01-01 00:00:00
//   mm = civil_minute(hh);  // 2015-01-01 00:00:00
//   ss = civil_second(mm);  // 2015-01-01 00:00:00
//
// ALIGNMENT CONVERSION:
//
// The alignment of a civil-time object cannot change, but the object may be
// used to construct a new object with a different alignment. This is referred
// to as "realigning". When realigning to a type with the same or more
// precision (e.g., civil_day -> civil_second), the conversion may be
// performed implicitly since no information is lost. However, if information
// could be discarded (e.g., civil_second -> civil_day), the conversion must
// be explicit at the call site.
//
//   void fun(const civil_day& day);
//
//   civil_second cs;
//   fun(cs);  // Won't compile because data may be discarded
//   fun(civil_day(cs));  // OK: explicit conversion
//
//   civil_day cd;
//   fun(cd);  // OK: no conversion needed
//
//   civil_month cm;
//   fun(cm);  // OK: implicit conversion to civil_day
//
// NORMALIZATION:
//
// Integer arguments passed to the constructor may be out-of-range, in which
// case they are normalized to produce a valid civil-time object. This enables
// natural arithmetic on constructor arguments without worrying about the
// field's range. Normalization guarantees that there are no invalid
// civil-time objects.
//
//   civil_day d(2016, 10, 32);  // Out-of-range day; normalized to 2016-11-01
//
// Note: If normalization is undesired, you can signal an error by comparing
// the constructor arguments to the normalized values returned by the YMDHMS
// properties.
//
// PROPERTIES:
//
// All civil-time types have accessors for all six of the civil-time fields:
// year, month, day, hour, minute, and second. Recall that fields inferior to
// the type's alignment will be set to their minimum valid value.
//
//   civil_day d(2015, 6, 28);
//   // d.year() == 2015
//   // d.month() == 6
//   // d.day() == 28
//   // d.hour() == 0
//   // d.minute() == 0
//   // d.second() == 0
//
// COMPARISON:
//
// Comparison always considers all six YMDHMS fields, regardless of the type's
// alignment. Comparison between differently aligned civil-time types is
// allowed.
//
//   civil_day feb_3(2015, 2, 3);  // 2015-02-03 00:00:00
//   civil_day mar_4(2015, 3, 4);  // 2015-03-04 00:00:00
//   // feb_3 < mar_4
//   // civil_year(feb_3) == civil_year(mar_4)
//
//   civil_second feb_3_noon(2015, 2, 3, 12, 0, 0);  // 2015-02-03 12:00:00
//   // feb_3 < feb_3_noon
//   // feb_3 == civil_day(feb_3_noon)
//
//   // Iterates all the days of February 2015.
//   for (civil_day d(2015, 2, 1); d < civil_month(2015, 3); ++d) {
//     // ...
//   }
//
// STREAMING:
//
// Each civil-time type may be sent to an output stream using operator<<().
// The output format follows the pattern "YYYY-MM-DDThh:mm:ss" where fields
// inferior to the type's alignment are omitted.
//
//   civil_second cs(2015, 2, 3, 4, 5, 6);
//   std::cout << cs << "\n";  // Outputs: 2015-02-03T04:05:06
//
//   civil_day cd(cs);
//   std::cout << cd << "\n";  // Outputs: 2015-02-03
//
//   civil_year cy(cs);
//   std::cout << cy << "\n";  // Outputs: 2015
//
// ARITHMETIC:
//
// Civil-time types support natural arithmetic operators such as addition,
// subtraction, and difference. Arithmetic operates on the civil-time field
// indicated in the type's name. Difference requires arguments with the same
// alignment and returns the answer in units of the alignment.
//
//   civil_day a(2015, 2, 3);
//   ++a;                         // 2015-02-04 00:00:00
//   --a;                         // 2015-02-03 00:00:00
//   civil_day b = a + 1;         // 2015-02-04 00:00:00
//   civil_day c = 1 + b;         // 2015-02-05 00:00:00
//   int n = c - a;               // n = 2 (civil days)
//   int m = c - civil_month(c);  // Won't compile: different types.
//
// EXAMPLE: Adding a month to January 31.
//
// One of the classic questions that arises when considering a civil-time
// library (or a date library or a date/time library) is this: "What happens
// when you add a month to January 31?" This is an interesting question
// because there could be a number of possible answers:
//
//   1. March 3 (or 2 if a leap year). This may make sense if the operation
//      wants the equivalent of February 31.
//   2. February 28 (or 29 if a leap year). This may make sense if the operation
//      wants the last day of January to go to the last day of February.
//   3. Error. The caller may get some error, an exception, an invalid date
//      object, or maybe false is returned. This may make sense because there is
//      no single unambiguously correct answer to the question.
//
// Practically speaking, any answer that is not what the programmer intended
// is the wrong answer.
//
// This civil-time library avoids the problem by making it impossible to ask
// ambiguous questions. All civil-time objects are aligned to a particular
// civil-field boundary (such as aligned to a year, month, day, hour, minute,
// or second), and arithmetic operates on the field to which the object is
// aligned. This means that in order to "add a month" the object must first be
// aligned to a month boundary, which is equivalent to the first day of that
// month.
//
// Of course, there are ways to compute an answer the question at hand using
// this civil-time library, but they require the programmer to be explicit
// about the answer they expect. To illustrate, let's see how to compute all
// three of the above possible answers to the question of "Jan 31 plus 1
// month":
//
//   const civil_day d(2015, 1, 31);
//
//   // Answer 1:
//   // Add 1 to the month field in the constructor, and rely on normalization.
//   const auto ans_normalized = civil_day(d.year(), d.month() + 1, d.day());
//   // ans_normalized == 2015-03-03 (aka Feb 31)
//
//   // Answer 2:
//   // Add 1 to month field, capping to the end of next month.
//   const auto next_month = civil_month(d) + 1;
//   const auto last_day_of_next_month = civil_day(next_month + 1) - 1;
//   const auto ans_capped = std::min(ans_normalized, last_day_of_next_month);
//   // ans_capped == 2015-02-28
//
//   // Answer 3:
//   // Signal an error if the normalized answer is not in next month.
//   if (civil_month(ans_normalized) != next_month) {
//     // error, month overflow
//   }
//
using civil_year = detail::civil_year;
using civil_month = detail::civil_month;
using civil_day = detail::civil_day;
using civil_hour = detail::civil_hour;
using civil_minute = detail::civil_minute;
using civil_second = detail::civil_second;

// An enum class with members monday, tuesday, wednesday, thursday, friday,
// saturday, and sunday. These enum values may be sent to an output stream
// using operator<<(). The result is the full weekday name in English with a
// leading capital letter.
//
//   weekday wd = weekday::thursday;
//   std::cout << wd << "\n";  // Outputs: Thursday
//
using detail::weekday;

// Returns the weekday for the given civil-time value.
//
//   civil_day a(2015, 8, 13);
//   weekday wd = get_weekday(a);  // wd == weekday::thursday
//
using detail::get_weekday;

// Returns the civil_day that strictly follows or precedes the given
// civil_day, and that falls on the given weekday.
//
// For example, given:
//
//     August 2015
// Su Mo Tu We Th Fr Sa
//                    1
//  2  3  4  5  6  7  8
//  9 10 11 12 13 14 15
// 16 17 18 19 20 21 22
// 23 24 25 26 27 28 29
// 30 31
//
//   civil_day a(2015, 8, 13);  // get_weekday(a) == weekday::thursday
//   civil_day b = next_weekday(a, weekday::thursday);  // b = 2015-08-20
//   civil_day c = prev_weekday(a, weekday::thursday);  // c = 2015-08-06
//
//   civil_day d = ...
//   // Gets the following Thursday if d is not already Thursday
//   civil_day thurs1 = next_weekday(d - 1, weekday::thursday);
//   // Gets the previous Thursday if d is not already Thursday
//   civil_day thurs2 = prev_weekday(d + 1, weekday::thursday);
//
using detail::next_weekday;
using detail::prev_weekday;

// Returns the day-of-year for the given civil-time value.
//
//   civil_day a(2015, 1, 1);
//   int yd_jan_1 = get_yearday(a);   // yd_jan_1 = 1
//   civil_day b(2015, 12, 31);
//   int yd_dec_31 = get_yearday(b);  // yd_dec_31 = 365
//
using detail::get_yearday;

}  // namespace cctz
}  // namespace time_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_H_
*·²
asoong/.intermediates/external/abseil-cpp/absl_time_hdrs/gen/my_include_dir/absl/time/civil_time.hÐ±// Copyright 2018 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// File: civil_time.h
// -----------------------------------------------------------------------------
//
// This header file defines abstractions for computing with "civil time".
// The term "civil time" refers to the legally recognized human-scale time
// that is represented by the six fields `YYYY-MM-DD hh:mm:ss`. A "date"
// is perhaps the most common example of a civil time (represented here as
// an `absl::CivilDay`).
//
// Modern-day civil time follows the Gregorian Calendar and is a
// time-zone-independent concept: a civil time of "2015-06-01 12:00:00", for
// example, is not tied to a time zone. Put another way, a civil time does not
// map to a unique point in time; a civil time must be mapped to an absolute
// time *through* a time zone.
//
// Because a civil time is what most people think of as "time," it is common to
// map absolute times to civil times to present to users.
//
// Time zones define the relationship between absolute and civil times. Given an
// absolute or civil time and a time zone, you can compute the other time:
//
//   Civil Time = F(Absolute Time, Time Zone)
//   Absolute Time = G(Civil Time, Time Zone)
//
// The Abseil time library allows you to construct such civil times from
// absolute times; consult time.h for such functionality.
//
// This library provides six classes for constructing civil-time objects, and
// provides several helper functions for rounding, iterating, and performing
// arithmetic on civil-time objects, while avoiding complications like
// daylight-saving time (DST):
//
//   * `absl::CivilSecond`
//   * `absl::CivilMinute`
//   * `absl::CivilHour`
//   * `absl::CivilDay`
//   * `absl::CivilMonth`
//   * `absl::CivilYear`
//
// Example:
//
//   // Construct a civil-time object for a specific day
//   const absl::CivilDay cd(1969, 7, 20);
//
//   // Construct a civil-time object for a specific second
//   const absl::CivilSecond cd(2018, 8, 1, 12, 0, 1);
//
// Note: In C++14 and later, this library is usable in a constexpr context.
//
// Example:
//
//   // Valid in C++14
//   constexpr absl::CivilDay cd(1969, 7, 20);

#ifndef ABSL_TIME_CIVIL_TIME_H_
#define ABSL_TIME_CIVIL_TIME_H_

#include <iosfwd>
#include <string>

#include "absl/base/config.h"
#include "absl/strings/string_view.h"
#include "absl/time/internal/cctz/include/cctz/civil_time.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

namespace time_internal {
struct second_tag : cctz::detail::second_tag {};
struct minute_tag : second_tag, cctz::detail::minute_tag {};
struct hour_tag : minute_tag, cctz::detail::hour_tag {};
struct day_tag : hour_tag, cctz::detail::day_tag {};
struct month_tag : day_tag, cctz::detail::month_tag {};
struct year_tag : month_tag, cctz::detail::year_tag {};
}  // namespace time_internal

// -----------------------------------------------------------------------------
// CivilSecond, CivilMinute, CivilHour, CivilDay, CivilMonth, CivilYear
// -----------------------------------------------------------------------------
//
// Each of these civil-time types is a simple value type with the same
// interface for construction and the same six accessors for each of the civil
// time fields (year, month, day, hour, minute, and second, aka YMDHMS). These
// classes differ only in their alignment, which is indicated by the type name
// and specifies the field on which arithmetic operates.
//
// CONSTRUCTION
//
// Each of the civil-time types can be constructed in two ways: by directly
// passing to the constructor up to six integers representing the YMDHMS fields,
// or by copying the YMDHMS fields from a differently aligned civil-time type.
// Omitted fields are assigned their minimum valid value. Hours, minutes, and
// seconds will be set to 0, month and day will be set to 1. Since there is no
// minimum year, the default is 1970.
//
// Examples:
//
//   absl::CivilDay default_value;               // 1970-01-01 00:00:00
//
//   absl::CivilDay a(2015, 2, 3);               // 2015-02-03 00:00:00
//   absl::CivilDay b(2015, 2, 3, 4, 5, 6);      // 2015-02-03 00:00:00
//   absl::CivilDay c(2015);                     // 2015-01-01 00:00:00
//
//   absl::CivilSecond ss(2015, 2, 3, 4, 5, 6);  // 2015-02-03 04:05:06
//   absl::CivilMinute mm(ss);                   // 2015-02-03 04:05:00
//   absl::CivilHour hh(mm);                     // 2015-02-03 04:00:00
//   absl::CivilDay d(hh);                       // 2015-02-03 00:00:00
//   absl::CivilMonth m(d);                      // 2015-02-01 00:00:00
//   absl::CivilYear y(m);                       // 2015-01-01 00:00:00
//
//   m = absl::CivilMonth(y);                    // 2015-01-01 00:00:00
//   d = absl::CivilDay(m);                      // 2015-01-01 00:00:00
//   hh = absl::CivilHour(d);                    // 2015-01-01 00:00:00
//   mm = absl::CivilMinute(hh);                 // 2015-01-01 00:00:00
//   ss = absl::CivilSecond(mm);                 // 2015-01-01 00:00:00
//
// Each civil-time class is aligned to the civil-time field indicated in the
// class's name after normalization. Alignment is performed by setting all the
// inferior fields to their minimum valid value (as described above). The
// following are examples of how each of the six types would align the fields
// representing November 22, 2015 at 12:34:56 in the afternoon. (Note: the
// string format used here is not important; it's just a shorthand way of
// showing the six YMDHMS fields.)
//
//   absl::CivilSecond   : 2015-11-22 12:34:56
//   absl::CivilMinute   : 2015-11-22 12:34:00
//   absl::CivilHour     : 2015-11-22 12:00:00
//   absl::CivilDay      : 2015-11-22 00:00:00
//   absl::CivilMonth    : 2015-11-01 00:00:00
//   absl::CivilYear     : 2015-01-01 00:00:00
//
// Each civil-time type performs arithmetic on the field to which it is
// aligned. This means that adding 1 to an absl::CivilDay increments the day
// field (normalizing as necessary), and subtracting 7 from an absl::CivilMonth
// operates on the month field (normalizing as necessary). All arithmetic
// produces a valid civil time. Difference requires two similarly aligned
// civil-time objects and returns the scalar answer in units of the objects'
// alignment. For example, the difference between two absl::CivilHour objects
// will give an answer in units of civil hours.
//
// ALIGNMENT CONVERSION
//
// The alignment of a civil-time object cannot change, but the object may be
// used to construct a new object with a different alignment. This is referred
// to as "realigning". When realigning to a type with the same or more
// precision (e.g., absl::CivilDay -> absl::CivilSecond), the conversion may be
// performed implicitly since no information is lost. However, if information
// could be discarded (e.g., CivilSecond -> CivilDay), the conversion must
// be explicit at the call site.
//
// Examples:
//
//   void UseDay(absl::CivilDay day);
//
//   absl::CivilSecond cs;
//   UseDay(cs);                  // Won't compile because data may be discarded
//   UseDay(absl::CivilDay(cs));  // OK: explicit conversion
//
//   absl::CivilDay cd;
//   UseDay(cd);                  // OK: no conversion needed
//
//   absl::CivilMonth cm;
//   UseDay(cm);                  // OK: implicit conversion to absl::CivilDay
//
// NORMALIZATION
//
// Normalization takes invalid values and adjusts them to produce valid values.
// Within the civil-time library, integer arguments passed to the Civil*
// constructors may be out-of-range, in which case they are normalized by
// carrying overflow into a field of courser granularity to produce valid
// civil-time objects. This normalization enables natural arithmetic on
// constructor arguments without worrying about the field's range.
//
// Examples:
//
//   // Out-of-range; normalized to 2016-11-01
//   absl::CivilDay d(2016, 10, 32);
//   // Out-of-range, negative: normalized to 2016-10-30T23
//   absl::CivilHour h1(2016, 10, 31, -1);
//   // Normalization is cumulative: normalized to 2016-10-30T23
//   absl::CivilHour h2(2016, 10, 32, -25);
//
// Note: If normalization is undesired, you can signal an error by comparing
// the constructor arguments to the normalized values returned by the YMDHMS
// properties.
//
// COMPARISON
//
// Comparison between civil-time objects considers all six YMDHMS fields,
// regardless of the type's alignment. Comparison between differently aligned
// civil-time types is allowed.
//
// Examples:
//
//   absl::CivilDay feb_3(2015, 2, 3);  // 2015-02-03 00:00:00
//   absl::CivilDay mar_4(2015, 3, 4);  // 2015-03-04 00:00:00
//   // feb_3 < mar_4
//   // absl::CivilYear(feb_3) == absl::CivilYear(mar_4)
//
//   absl::CivilSecond feb_3_noon(2015, 2, 3, 12, 0, 0);  // 2015-02-03 12:00:00
//   // feb_3 < feb_3_noon
//   // feb_3 == absl::CivilDay(feb_3_noon)
//
//   // Iterates all the days of February 2015.
//   for (absl::CivilDay d(2015, 2, 1); d < absl::CivilMonth(2015, 3); ++d) {
//     // ...
//   }
//
// ARITHMETIC
//
// Civil-time types support natural arithmetic operators such as addition,
// subtraction, and difference. Arithmetic operates on the civil-time field
// indicated in the type's name. Difference operators require arguments with
// the same alignment and return the answer in units of the alignment.
//
// Example:
//
//   absl::CivilDay a(2015, 2, 3);
//   ++a;                              // 2015-02-04 00:00:00
//   --a;                              // 2015-02-03 00:00:00
//   absl::CivilDay b = a + 1;         // 2015-02-04 00:00:00
//   absl::CivilDay c = 1 + b;         // 2015-02-05 00:00:00
//   int n = c - a;                    // n = 2 (civil days)
//   int m = c - absl::CivilMonth(c);  // Won't compile: different types.
//
// ACCESSORS
//
// Each civil-time type has accessors for all six of the civil-time fields:
// year, month, day, hour, minute, and second.
//
// civil_year_t year()
// int          month()
// int          day()
// int          hour()
// int          minute()
// int          second()
//
// Recall that fields inferior to the type's alignment will be set to their
// minimum valid value.
//
// Example:
//
//   absl::CivilDay d(2015, 6, 28);
//   // d.year() == 2015
//   // d.month() == 6
//   // d.day() == 28
//   // d.hour() == 0
//   // d.minute() == 0
//   // d.second() == 0
//
// CASE STUDY: Adding a month to January 31.
//
// One of the classic questions that arises when considering a civil time
// library (or a date library or a date/time library) is this:
//   "What is the result of adding a month to January 31?"
// This is an interesting question because it is unclear what is meant by a
// "month", and several different answers are possible, depending on context:
//
//   1. March 3 (or 2 if a leap year), if "add a month" means to add a month to
//      the current month, and adjust the date to overflow the extra days into
//      March. In this case the result of "February 31" would be normalized as
//      within the civil-time library.
//   2. February 28 (or 29 if a leap year), if "add a month" means to add a
//      month, and adjust the date while holding the resulting month constant.
//      In this case, the result of "February 31" would be truncated to the last
//      day in February.
//   3. An error. The caller may get some error, an exception, an invalid date
//      object, or perhaps return `false`. This may make sense because there is
//      no single unambiguously correct answer to the question.
//
// Practically speaking, any answer that is not what the programmer intended
// is the wrong answer.
//
// The Abseil time library avoids this problem by making it impossible to
// ask ambiguous questions. All civil-time objects are aligned to a particular
// civil-field boundary (such as aligned to a year, month, day, hour, minute,
// or second), and arithmetic operates on the field to which the object is
// aligned. This means that in order to "add a month" the object must first be
// aligned to a month boundary, which is equivalent to the first day of that
// month.
//
// Of course, there are ways to compute an answer the question at hand using
// this Abseil time library, but they require the programmer to be explicit
// about the answer they expect. To illustrate, let's see how to compute all
// three of the above possible answers to the question of "Jan 31 plus 1
// month":
//
// Example:
//
//   const absl::CivilDay d(2015, 1, 31);
//
//   // Answer 1:
//   // Add 1 to the month field in the constructor, and rely on normalization.
//   const auto normalized = absl::CivilDay(d.year(), d.month() + 1, d.day());
//   // normalized == 2015-03-03 (aka Feb 31)
//
//   // Answer 2:
//   // Add 1 to month field, capping to the end of next month.
//   const auto next_month = absl::CivilMonth(d) + 1;
//   const auto last_day_of_next_month = absl::CivilDay(next_month + 1) - 1;
//   const auto capped = std::min(normalized, last_day_of_next_month);
//   // capped == 2015-02-28
//
//   // Answer 3:
//   // Signal an error if the normalized answer is not in next month.
//   if (absl::CivilMonth(normalized) != next_month) {
//     // error, month overflow
//   }
//
using CivilSecond =
    time_internal::cctz::detail::civil_time<time_internal::second_tag>;
using CivilMinute =
    time_internal::cctz::detail::civil_time<time_internal::minute_tag>;
using CivilHour =
    time_internal::cctz::detail::civil_time<time_internal::hour_tag>;
using CivilDay =
    time_internal::cctz::detail::civil_time<time_internal::day_tag>;
using CivilMonth =
    time_internal::cctz::detail::civil_time<time_internal::month_tag>;
using CivilYear =
    time_internal::cctz::detail::civil_time<time_internal::year_tag>;

// civil_year_t
//
// Type alias of a civil-time year value. This type is guaranteed to (at least)
// support any year value supported by `time_t`.
//
// Example:
//
//   absl::CivilSecond cs = ...;
//   absl::civil_year_t y = cs.year();
//   cs = absl::CivilSecond(y, 1, 1, 0, 0, 0);  // CivilSecond(CivilYear(cs))
//
using civil_year_t = time_internal::cctz::year_t;

// civil_diff_t
//
// Type alias of the difference between two civil-time values.
// This type is used to indicate arguments that are not
// normalized (such as parameters to the civil-time constructors), the results
// of civil-time subtraction, or the operand to civil-time addition.
//
// Example:
//
//   absl::civil_diff_t n_sec = cs1 - cs2;             // cs1 == cs2 + n_sec;
//
using civil_diff_t = time_internal::cctz::diff_t;

// Weekday::monday, Weekday::tuesday, Weekday::wednesday, Weekday::thursday,
// Weekday::friday, Weekday::saturday, Weekday::sunday
//
// The Weekday enum class represents the civil-time concept of a "weekday" with
// members for all days of the week.
//
//   absl::Weekday wd = absl::Weekday::thursday;
//
using Weekday = time_internal::cctz::weekday;

// GetWeekday()
//
// Returns the absl::Weekday for the given (realigned) civil-time value.
//
// Example:
//
//   absl::CivilDay a(2015, 8, 13);
//   absl::Weekday wd = absl::GetWeekday(a);  // wd == absl::Weekday::thursday
//
inline Weekday GetWeekday(CivilSecond cs) {
  return time_internal::cctz::get_weekday(cs);
}

// NextWeekday()
// PrevWeekday()
//
// Returns the absl::CivilDay that strictly follows or precedes a given
// absl::CivilDay, and that falls on the given absl::Weekday.
//
// Example, given the following month:
//
//       August 2015
//   Su Mo Tu We Th Fr Sa
//                      1
//    2  3  4  5  6  7  8
//    9 10 11 12 13 14 15
//   16 17 18 19 20 21 22
//   23 24 25 26 27 28 29
//   30 31
//
//   absl::CivilDay a(2015, 8, 13);
//   // absl::GetWeekday(a) == absl::Weekday::thursday
//   absl::CivilDay b = absl::NextWeekday(a, absl::Weekday::thursday);
//   // b = 2015-08-20
//   absl::CivilDay c = absl::PrevWeekday(a, absl::Weekday::thursday);
//   // c = 2015-08-06
//
//   absl::CivilDay d = ...
//   // Gets the following Thursday if d is not already Thursday
//   absl::CivilDay thurs1 = absl::NextWeekday(d - 1, absl::Weekday::thursday);
//   // Gets the previous Thursday if d is not already Thursday
//   absl::CivilDay thurs2 = absl::PrevWeekday(d + 1, absl::Weekday::thursday);
//
inline CivilDay NextWeekday(CivilDay cd, Weekday wd) {
  return CivilDay(time_internal::cctz::next_weekday(cd, wd));
}
inline CivilDay PrevWeekday(CivilDay cd, Weekday wd) {
  return CivilDay(time_internal::cctz::prev_weekday(cd, wd));
}

// GetYearDay()
//
// Returns the day-of-year for the given (realigned) civil-time value.
//
// Example:
//
//   absl::CivilDay a(2015, 1, 1);
//   int yd_jan_1 = absl::GetYearDay(a);   // yd_jan_1 = 1
//   absl::CivilDay b(2015, 12, 31);
//   int yd_dec_31 = absl::GetYearDay(b);  // yd_dec_31 = 365
//
inline int GetYearDay(CivilSecond cs) {
  return time_internal::cctz::get_yearday(cs);
}

// FormatCivilTime()
//
// Formats the given civil-time value into a string value of the following
// format:
//
//  Type        | Format
//  ---------------------------------
//  CivilSecond | YYYY-MM-DDTHH:MM:SS
//  CivilMinute | YYYY-MM-DDTHH:MM
//  CivilHour   | YYYY-MM-DDTHH
//  CivilDay    | YYYY-MM-DD
//  CivilMonth  | YYYY-MM
//  CivilYear   | YYYY
//
// Example:
//
//   absl::CivilDay d = absl::CivilDay(1969, 7, 20);
//   std::string day_string = absl::FormatCivilTime(d);  // "1969-07-20"
//
std::string FormatCivilTime(CivilSecond c);
std::string FormatCivilTime(CivilMinute c);
std::string FormatCivilTime(CivilHour c);
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
// passed output parameter. Returns `true` upon successful parsing.
//
// The expected form of the input string is as follows:
//
//  Type        | Format
//  ---------------------------------
//  CivilSecond | YYYY-MM-DDTHH:MM:SS
//  CivilMinute | YYYY-MM-DDTHH:MM
//  CivilHour   | YYYY-MM-DDTHH
//  CivilDay    | YYYY-MM-DD
//  CivilMonth  | YYYY-MM
//  CivilYear   | YYYY
//
// Example:
//
//   absl::CivilDay d;
//   bool ok = absl::ParseCivilTime("2018-01-02", &d); // OK
//
// Note that parsing will fail if the string's format does not match the
// expected type exactly. `ParseLenientCivilTime()` below is more lenient.
//
bool ParseCivilTime(absl::string_view s, CivilSecond* c);
bool ParseCivilTime(absl::string_view s, CivilMinute* c);
bool ParseCivilTime(absl::string_view s, CivilHour* c);
bool ParseCivilTime(absl::string_view s, CivilDay* c);
bool ParseCivilTime(absl::string_view s, CivilMonth* c);
bool ParseCivilTime(absl::string_view s, CivilYear* c);

// ParseLenientCivilTime()
//
// Parses any of the formats accepted by `absl::ParseCivilTime()`, but is more
// lenient if the format of the string does not exactly match the associated
// type.
//
// Example:
//
//   absl::CivilDay d;
//   bool ok = absl::ParseLenientCivilTime("1969-07-20", &d); // OK
//   ok = absl::ParseLenientCivilTime("1969-07-20T10", &d);   // OK: T10 floored
//   ok = absl::ParseLenientCivilTime("1969-07", &d);   // OK: day defaults to 1
//
bool ParseLenientCivilTime(absl::string_view s, CivilSecond* c);
bool ParseLenientCivilTime(absl::string_view s, CivilMinute* c);
bool ParseLenientCivilTime(absl::string_view s, CivilHour* c);
bool ParseLenientCivilTime(absl::string_view s, CivilDay* c);
bool ParseLenientCivilTime(absl::string_view s, CivilMonth* c);
bool ParseLenientCivilTime(absl::string_view s, CivilYear* c);

namespace time_internal {  // For functions found via ADL on civil-time tags.

// Streaming Operators
//
// Each civil-time type may be sent to an output stream using operator<<().
// The result matches the string produced by `FormatCivilTime()`.
//
// Example:
//
//   absl::CivilDay d = absl::CivilDay(1969, 7, 20);
//   std::cout << "Date is: " << d << "\n";
//
std::ostream& operator<<(std::ostream& os, CivilYear y);
std::ostream& operator<<(std::ostream& os, CivilMonth m);
std::ostream& operator<<(std::ostream& os, CivilDay d);
std::ostream& operator<<(std::ostream& os, CivilHour h);
std::ostream& operator<<(std::ostream& os, CivilMinute m);
std::ostream& operator<<(std::ostream& os, CivilSecond s);

// AbslParseFlag()
//
// Parses the command-line flag string representation `s` into a civil-time
// value. Flags must be specified in a format that is valid for
// `absl::ParseLenientCivilTime()`.
bool AbslParseFlag(absl::string_view s, CivilSecond* c, std::string* error);
bool AbslParseFlag(absl::string_view s, CivilMinute* c, std::string* error);
bool AbslParseFlag(absl::string_view s, CivilHour* c, std::string* error);
bool AbslParseFlag(absl::string_view s, CivilDay* c, std::string* error);
bool AbslParseFlag(absl::string_view s, CivilMonth* c, std::string* error);
bool AbslParseFlag(absl::string_view s, CivilYear* c, std::string* error);

// AbslUnparseFlag()
//
// Unparses a civil-time value into a command-line string representation using
// the format specified by `absl::ParseCivilTime()`.
std::string AbslUnparseFlag(CivilSecond c);
std::string AbslUnparseFlag(CivilMinute c);
std::string AbslUnparseFlag(CivilHour c);
std::string AbslUnparseFlag(CivilDay c);
std::string AbslUnparseFlag(CivilMonth c);
std::string AbslUnparseFlag(CivilYear c);

}  // namespace time_internal

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_TIME_CIVIL_TIME_H_
*Å
dsoong/.intermediates/external/abseil-cpp/absl_utility_hdrs/gen/my_include_dir/absl/utility/utility.hÜ// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_UTILITY_UTILITY_H_
#define ABSL_UTILITY_UTILITY_H_

#include <cstddef>
#include <cstdlib>
#include <tuple>
#include <utility>

#include "absl/base/config.h"

// TODO(b/290784225): Include what you use cleanup required.
#include "absl/meta/type_traits.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

// 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::apply;
using std::exchange;
using std::forward;
using std::in_place;
using std::in_place_index;
using std::in_place_index_t;
using std::in_place_t;
using std::in_place_type;
using std::in_place_type_t;
using std::index_sequence;
using std::index_sequence_for;
using std::integer_sequence;
using std::make_from_tuple;
using std::make_index_sequence;
using std::make_integer_sequence;
using std::move;

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_UTILITY_UTILITY_H_
*“
jsoong/.intermediates/external/abseil-cpp/absl_algorithm_hdrs/gen/my_include_dir/absl/algorithm/algorithm.h¤// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// File: algorithm.h
// -----------------------------------------------------------------------------
//
// This header file contains Google extensions to the standard <algorithm> C++
// header.

#ifndef ABSL_ALGORITHM_ALGORITHM_H_
#define ABSL_ALGORITHM_ALGORITHM_H_

#include <algorithm>
#include <iterator>
#include <type_traits>

#include "absl/base/config.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

// equal()
// rotate()
//
// 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.
//
// 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()
//
// Performs a linear search for `value` using the iterator `first` up to
// but not including `last`, returning true if [`first`, `last`) contains an
// element equal to `value`.
//
// A linear search is of O(n) complexity which is guaranteed to make at most
// n = (`last` - `first`) comparisons. A linear search over short containers
// may be faster than a binary search, even when the container is sorted.
template <typename InputIterator, typename EqualityComparable>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool linear_search(
    InputIterator first, InputIterator last, const EqualityComparable& value) {
  return std::find(first, last, value) != last;
}

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_ALGORITHM_ALGORITHM_H_
*¡
‰soong/.intermediates/external/abseil-cpp/absl_hash_weakly_mixed_integer_hdrs/gen/my_include_dir/absl/hash/internal/weakly_mixed_integer.h’
// Copyright 2025 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_HASH_INTERNAL_WEAKLY_MIXED_INTEGER_H_
#define ABSL_HASH_INTERNAL_WEAKLY_MIXED_INTEGER_H_

#include <cstddef>

#include "absl/base/config.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace hash_internal {

// Contains an integer that will be mixed into a hash state more weakly than
// regular integers. It is useful for cases in which an integer is a part of a
// larger object and needs to be mixed as a supplement. E.g., absl::string_view
// and absl::Span are mixing their size wrapped with WeaklyMixedInteger.
struct WeaklyMixedInteger {
  size_t value;
};

}  // namespace hash_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_HASH_INTERNAL_WEAKLY_MIXED_INTEGER_H_
*Êì
bsoong/.intermediates/external/abseil-cpp/absl_types_span_hdrs/gen/my_include_dir/absl/types/span.hâë//
// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// span.h
// -----------------------------------------------------------------------------
//
// This header file defines a `Span<T>` type for holding a reference to existing
// array data. The `Span` object, much like the `absl::string_view` object,
// does not own such data itself, and the data being referenced by the span must
// outlive the span itself. Unlike `view` type references, a span can hold a
// reference to mutable data (and can mutate it for underlying types of
// non-const T.) A span provides a lightweight way to pass a reference to such
// data.
//
// Additionally, this header file defines `MakeSpan()` and `MakeConstSpan()`
// factory functions, for clearly creating spans of type `Span<T>` or read-only
// `Span<const T>` when such types may be difficult to identify due to issues
// with implicit conversion.
//
// The C++20 draft standard includes a `std::span` type. As of June 2020, the
// differences between `absl::Span` and `std::span` are:
//    * `absl::Span` has `operator==` (which is likely a design bug,
//       per https://abseil.io/blog/20180531-regular-types)
//    * `absl::Span` has the factory functions `MakeSpan()` and
//      `MakeConstSpan()`
//    * bounds-checked access to `absl::Span` is accomplished with `at()`
//    * `absl::Span` has compiler-provided move and copy constructors and
//      assignment. This is due to them being specified as `constexpr`, but that
//      implies const in C++11.
//    * A read-only `absl::Span<const T>` can be implicitly constructed from an
//      initializer list.
//    * `absl::Span` has no `bytes()`, `size_bytes()`, `as_bytes()`, or
//      `as_writable_bytes()` methods
//    * `absl::Span` has no static extent template parameter, nor constructors
//      which exist only because of the static extent parameter.
//    * `absl::Span` has an explicit mutable-reference constructor
//
// For more information, see the class comments below.
#ifndef ABSL_TYPES_SPAN_H_
#define ABSL_TYPES_SPAN_H_

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <initializer_list>
#include <iterator>
#include <type_traits>
#include <utility>

#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/throw_delegate.h"
#include "absl/base/macros.h"
#include "absl/base/nullability.h"
#include "absl/base/optimization.h"
#include "absl/base/port.h"  // TODO(strel): remove this include
#include "absl/hash/internal/weakly_mixed_integer.h"
#include "absl/meta/type_traits.h"
#include "absl/types/internal/span.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

template <typename T>
class Span;

ABSL_NAMESPACE_END
}  // namespace absl

// Android local modification: some security tests use "#define private public"
// to access private implementation details. libc++'s <ranges> is currently not
// compatible with that.
#if !defined(private)

// If std::ranges is available, mark Span as satisfying the `view` and
// `borrowed_range` concepts, just like std::span.
#if !defined(__has_include)
#define __has_include(header) 0
#endif
#if __has_include(<version>)
#include <version>  // NOLINT(misc-include-cleaner)
#endif
#if defined(__cpp_lib_ranges) && __cpp_lib_ranges >= 201911L
#include <ranges>  // NOLINT(build/c++20)
template <typename T>
 // NOLINTNEXTLINE(build/c++20)
inline constexpr bool std::ranges::enable_view<absl::Span<T>> = true;
template <typename T>
 // NOLINTNEXTLINE(build/c++20)
inline constexpr bool std::ranges::enable_borrowed_range<absl::Span<T>> = true;
#endif

#endif // !defined(private)

namespace absl {
ABSL_NAMESPACE_BEGIN

//------------------------------------------------------------------------------
// Span
//------------------------------------------------------------------------------
//
// A `Span` is an "array reference" type for holding a reference of contiguous
// array data; the `Span` object does not and cannot own such data itself. A
// span provides an easy way to provide overloads for anything operating on
// contiguous sequences without needing to manage pointers and array lengths
// manually.

// A span is conceptually a pointer (ptr) and a length (size) into an already
// existing array of contiguous memory; the array it represents references the
// elements "ptr[0] .. ptr[size-1]". Passing a properly-constructed `Span`
// instead of raw pointers avoids many issues related to index out of bounds
// errors.
//
// Spans may also be constructed from containers holding contiguous sequences.
// Such containers must supply `data()` and `size() const` methods (e.g
// `std::vector<T>`, `absl::InlinedVector<T, N>`). All implicit conversions to
// `absl::Span` from such containers will create spans of type `const T`;
// spans which can mutate their values (of type `T`) must use explicit
// constructors.
//
// A `Span<T>` is somewhat analogous to an `absl::string_view`, but for an array
// of elements of type `T`, and unlike an `absl::string_view`, a span can hold a
// reference to mutable data. A user of `Span` must ensure that the data being
// pointed to outlives the `Span` itself.
//
// You can construct a `Span<T>` in several ways:
//
//   * Explicitly from a reference to a container type
//   * Explicitly from a pointer and size
//   * Implicitly from a container type (but only for spans of type `const T`)
//   * Using the `MakeSpan()` or `MakeConstSpan()` factory functions.
//
// Examples:
//
//   // Construct a Span explicitly from a container:
//   std::vector<int> v = {1, 2, 3, 4, 5};
//   auto span = absl::Span<const int>(v);
//
//   // Construct a Span explicitly from a C-style array:
//   int a[5] =  {1, 2, 3, 4, 5};
//   auto span = absl::Span<const int>(a);
//
//   // Construct a Span implicitly from a container
//   void MyRoutine(absl::Span<const int> a) {
//     ...
//   }
//   std::vector v = {1,2,3,4,5};
//   MyRoutine(v)                     // convert to Span<const T>
//
// Note that `Span` objects, in addition to requiring that the memory they
// point to remains alive, must also ensure that such memory does not get
// reallocated. Therefore, to avoid undefined behavior, containers with
// associated spans should not invoke operations that may reallocate memory
// (such as resizing) or invalidate iterators into the container.
//
// One common use for a `Span` is when passing arguments to a routine that can
// accept a variety of array types (e.g. a `std::vector`, `absl::InlinedVector`,
// a C-style array, etc.). Instead of creating overloads for each case, you
// can simply specify a `Span` as the argument to such a routine.
//
// Example:
//
//   void MyRoutine(absl::Span<const int> a) {
//     ...
//   }
//
//   std::vector v = {1,2,3,4,5};
//   MyRoutine(v);
//
//   absl::InlinedVector<int, 4> my_inline_vector;
//   MyRoutine(my_inline_vector);
//
//   // Explicit constructor from pointer,size
//   int* my_array = new int[10];
//   MyRoutine(absl::Span<const int>(my_array, 10));
template <typename T>
class ABSL_ATTRIBUTE_VIEW Span {
 private:
  // Used to determine whether a Span can be constructed from a container of
  // type C.
  template <typename C>
  using EnableIfConvertibleFrom =
      typename std::enable_if<span_internal::HasData<T, C>::value &&
                              span_internal::HasSize<C>::value>::type;

  // Used to SFINAE-enable a function when the slice elements are const.
  template <typename U>
  using EnableIfValueIsConst =
      typename std::enable_if<std::is_const<T>::value, U>::type;

  // Used to SFINAE-enable a function when the slice elements are mutable.
  template <typename U>
  using EnableIfValueIsMutable =
      typename std::enable_if<!std::is_const<T>::value, U>::type;

 public:
  using element_type = T;
  using value_type = absl::remove_cv_t<T>;
  // TODO(b/316099902) - pointer should be absl_nullable, but this makes it hard
  // to recognize foreach loops as safe. absl_nullability_unknown is currently
  // used to suppress -Wnullability-completeness warnings.
  using pointer = T* absl_nullability_unknown;
  using const_pointer = const T* absl_nullability_unknown;
  using reference = T&;
  using const_reference = const T&;
  using iterator = pointer;
  using const_iterator = const_pointer;
  using reverse_iterator = std::reverse_iterator<iterator>;
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  using size_type = size_t;
  using difference_type = ptrdiff_t;
  using absl_internal_is_view = std::true_type;

  // NOLINTNEXTLINE
  static const size_type npos = ~(size_type(0));

  constexpr Span() noexcept : Span(nullptr, 0) {}
  constexpr Span(pointer array ABSL_ATTRIBUTE_LIFETIME_BOUND,
                 size_type length) noexcept
      : ptr_(array), len_(length) {}

  // Implicit conversion constructors
  template <size_t N>
  constexpr Span(T(  // NOLINT(google-explicit-constructor)
      &a ABSL_ATTRIBUTE_LIFETIME_BOUND)[N]) noexcept
      : Span(a, N) {}

  // Explicit reference constructor for a mutable `Span<T>` type. Can be
  // replaced with MakeSpan() to infer the type parameter.
  template <typename V, typename = EnableIfConvertibleFrom<V>,
            typename = EnableIfValueIsMutable<V>,
            typename = span_internal::EnableIfNotIsView<V>>
  explicit Span(
      V& v
          ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept  // NOLINT(runtime/references)
      : Span(span_internal::GetData(v), v.size()) {}

  // Implicit reference constructor for a read-only `Span<const T>` type
  template <typename V, typename = EnableIfConvertibleFrom<V>,
            typename = EnableIfValueIsConst<V>,
            typename = span_internal::EnableIfNotIsView<V>>
  // NOLINTNEXTLINE(google-explicit-constructor)
  constexpr Span(const V& v ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept
      : Span(span_internal::GetData(v), v.size()) {}

  // Overloads of the above two functions that are only enabled for view types.
  // This is so we can drop the ABSL_ATTRIBUTE_LIFETIME_BOUND annotation. These
  // overloads must be made unique by using a different template parameter list
  // (hence the = 0 for the IsView enabler).
  template <typename V, typename = EnableIfConvertibleFrom<V>,
            typename = EnableIfValueIsMutable<V>,
            span_internal::EnableIfIsView<V> = 0>
  explicit Span(V& v) noexcept  // NOLINT(runtime/references)
      : Span(span_internal::GetData(v), v.size()) {}
  template <typename V, typename = EnableIfConvertibleFrom<V>,
            typename = EnableIfValueIsConst<V>,
            span_internal::EnableIfIsView<V> = 0>
  constexpr Span(const V& v) noexcept  // NOLINT(google-explicit-constructor)
      : Span(span_internal::GetData(v), v.size()) {}

  // Implicit constructor from an initializer list, making it possible to pass a
  // brace-enclosed initializer list to a function expecting a `Span`. Such
  // spans constructed from an initializer list must be of type `Span<const T>`.
  //
  //   void Process(absl::Span<const int> x);
  //   Process({1, 2, 3});
  //
  // Note that as always the array referenced by the span must outlive the span.
  // Since an initializer list constructor acts as if it is fed a temporary
  // array (cf. C++ standard [dcl.init.list]/5), it's safe to use this
  // constructor only when the `std::initializer_list` itself outlives the span.
  // In order to meet this requirement it's sufficient to ensure that neither
  // the span nor a copy of it is used outside of the expression in which it's
  // created:
  //
  //   // Assume that this function uses the array directly, not retaining any
  //   // copy of the span or pointer to any of its elements.
  //   void Process(absl::Span<const int> ints);
  //
  //   // Okay: the std::initializer_list<int> will reference a temporary array
  //   // that isn't destroyed until after the call to Process returns.
  //   Process({ 17, 19 });
  //
  //   // Not okay: the storage used by the std::initializer_list<int> is not
  //   // allowed to be referenced after the first line.
  //   absl::Span<const int> ints = { 17, 19 };
  //   Process(ints);
  //
  //   // Not okay for the same reason as above: even when the elements of the
  //   // initializer list expression are not temporaries the underlying array
  //   // is, so the initializer list must still outlive the span.
  //   const int foo = 17;
  //   absl::Span<const int> ints = { foo };
  //   Process(ints);
  //
  template <typename LazyT = T,
            typename = EnableIfValueIsConst<LazyT>>
  Span(std::initializer_list<value_type> v
           ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept  // NOLINT(runtime/explicit)
      : Span(v.begin(), v.size()) {}

  // Accessors

  // Span::data()
  //
  // Returns a pointer to the span's underlying array of data (which is held
  // outside the span).
  constexpr pointer data() const noexcept { return ptr_; }

  // Span::size()
  //
  // Returns the size of this span.
  constexpr size_type size() const noexcept { return len_; }

  // Span::length()
  //
  // Returns the length (size) of this span.
  constexpr size_type length() const noexcept { return size(); }

  // Span::empty()
  //
  // Returns a boolean indicating whether or not this span is considered empty.
  constexpr bool empty() const noexcept { return size() == 0; }

  // Span::operator[]
  //
  // Returns a reference to the i'th element of this span.
  constexpr reference operator[](size_type i) const noexcept {
    ABSL_HARDENING_ASSERT(i < size());
    return ptr_[i];
  }

  // Span::at()
  //
  // Returns a reference to the i'th element of this span.
  constexpr reference at(size_type i) const {
    return ABSL_PREDICT_TRUE(i < size())  //
               ? *(data() + i)
               : (base_internal::ThrowStdOutOfRange(
                      "Span::at failed bounds check"),
                  *(data() + i));
  }

  // Span::front()
  //
  // Returns a reference to the first element of this span. The span must not
  // be empty.
  constexpr reference front() const noexcept {
    ABSL_HARDENING_ASSERT(size() > 0);
    return *data();
  }

  // Span::back()
  //
  // Returns a reference to the last element of this span. The span must not
  // be empty.
  constexpr reference back() const noexcept {
    ABSL_HARDENING_ASSERT(size() > 0);
    return *(data() + size() - 1);
  }

  // Span::begin()
  //
  // Returns an iterator pointing to the first element of this span, or `end()`
  // if the span is empty.
  constexpr iterator begin() const noexcept { return data(); }

  // Span::cbegin()
  //
  // Returns a const iterator pointing to the first element of this span, or
  // `end()` if the span is empty.
  constexpr const_iterator cbegin() const noexcept { return begin(); }

  // Span::end()
  //
  // Returns an iterator pointing just beyond the last element at the
  // end of this span. This iterator acts as a placeholder; attempting to
  // access it results in undefined behavior.
  constexpr iterator end() const noexcept { return data() + size(); }

  // Span::cend()
  //
  // Returns a const iterator pointing just beyond the last element at the
  // end of this span. This iterator acts as a placeholder; attempting to
  // access it results in undefined behavior.
  constexpr const_iterator cend() const noexcept { return end(); }

  // Span::rbegin()
  //
  // Returns a reverse iterator pointing to the last element at the end of this
  // span, or `rend()` if the span is empty.
  constexpr reverse_iterator rbegin() const noexcept {
    return reverse_iterator(end());
  }

  // Span::crbegin()
  //
  // Returns a const reverse iterator pointing to the last element at the end of
  // this span, or `crend()` if the span is empty.
  constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); }

  // Span::rend()
  //
  // Returns a reverse iterator pointing just before the first element
  // at the beginning of this span. This pointer acts as a placeholder;
  // attempting to access its element results in undefined behavior.
  constexpr reverse_iterator rend() const noexcept {
    return reverse_iterator(begin());
  }

  // Span::crend()
  //
  // Returns a reverse const iterator pointing just before the first element
  // at the beginning of this span. This pointer acts as a placeholder;
  // attempting to access its element results in undefined behavior.
  constexpr const_reverse_iterator crend() const noexcept { return rend(); }

  // Span mutations

  // Span::remove_prefix()
  //
  // Removes the first `n` elements from the span.
  void remove_prefix(size_type n) noexcept {
    ABSL_HARDENING_ASSERT(size() >= n);
    ptr_ += n;
    len_ -= n;
  }

  // Span::remove_suffix()
  //
  // Removes the last `n` elements from the span.
  void remove_suffix(size_type n) noexcept {
    ABSL_HARDENING_ASSERT(size() >= n);
    len_ -= n;
  }

  // Span::subspan()
  //
  // Returns a `Span` starting at element `pos` and of length `len`. Both `pos`
  // and `len` are of type `size_type` and thus non-negative. Parameter `pos`
  // must be <= size(). Any `len` value that points past the end of the span
  // will be trimmed to at most size() - `pos`. A default `len` value of `npos`
  // ensures the returned subspan continues until the end of the span.
  //
  // Examples:
  //
  //   std::vector<int> vec = {10, 11, 12, 13};
  //   absl::MakeSpan(vec).subspan(1, 2);  // {11, 12}
  //   absl::MakeSpan(vec).subspan(2, 8);  // {12, 13}
  //   absl::MakeSpan(vec).subspan(1);     // {11, 12, 13}
  //   absl::MakeSpan(vec).subspan(4);     // {}
  //   absl::MakeSpan(vec).subspan(5);     // throws std::out_of_range
  constexpr Span subspan(size_type pos = 0, size_type len = npos) const {
    return (pos <= size())
               ? Span(data() + pos, (std::min)(size() - pos, len))
               : (base_internal::ThrowStdOutOfRange("pos > size()"), Span());
  }

  // Span::first()
  //
  // Returns a `Span` containing first `len` elements. Parameter `len` is of
  // type `size_type` and thus non-negative. `len` value must be <= size().
  //
  // Examples:
  //
  //   std::vector<int> vec = {10, 11, 12, 13};
  //   absl::MakeSpan(vec).first(1);  // {10}
  //   absl::MakeSpan(vec).first(3);  // {10, 11, 12}
  //   absl::MakeSpan(vec).first(5);  // throws std::out_of_range
  constexpr Span first(size_type len) const {
    return (len <= size())
               ? Span(data(), len)
               : (base_internal::ThrowStdOutOfRange("len > size()"), Span());
  }

  // Span::last()
  //
  // Returns a `Span` containing last `len` elements. Parameter `len` is of
  // type `size_type` and thus non-negative. `len` value must be <= size().
  //
  // Examples:
  //
  //   std::vector<int> vec = {10, 11, 12, 13};
  //   absl::MakeSpan(vec).last(1);  // {13}
  //   absl::MakeSpan(vec).last(3);  // {11, 12, 13}
  //   absl::MakeSpan(vec).last(5);  // throws std::out_of_range
  constexpr Span last(size_type len) const {
    return (len <= size())
               ? Span(size() - len + data(), len)
               : (base_internal::ThrowStdOutOfRange("len > size()"), Span());
  }

  // Support for absl::Hash.
  template <typename H>
  friend H AbslHashValue(H h, Span v) {
    return H::combine(H::combine_contiguous(std::move(h), v.data(), v.size()),
                      hash_internal::WeaklyMixedInteger{v.size()});
  }

 private:
  pointer ptr_;
  size_type len_;
};

template <typename T>
const typename Span<T>::size_type Span<T>::npos;

// Span relationals

// Equality is compared element-by-element, while ordering is lexicographical.
// We provide three overloads for each operator to cover any combination on the
// left or right hand side of mutable Span<T>, read-only Span<const T>, and
// convertible-to-read-only Span<T>.
// TODO(zhangxy): Due to MSVC overload resolution bug with partial ordering
// template functions, 5 overloads per operator is needed as a workaround. We
// should update them to 3 overloads per operator using non-deduced context like
// string_view, i.e.
// - (Span<T>, Span<T>)
// - (Span<T>, non_deduced<Span<const T>>)
// - (non_deduced<Span<const T>>, Span<T>)

// operator==
template <typename T>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator==(Span<T> a, Span<T> b) {
  return span_internal::EqualImpl<Span, const T>(a, b);
}
template <typename T>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator==(Span<const T> a,
                                                    Span<T> b) {
  return span_internal::EqualImpl<Span, const T>(a, b);
}
template <typename T>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator==(Span<T> a,
                                                    Span<const T> b) {
  return span_internal::EqualImpl<Span, const T>(a, b);
}
template <
    typename T, typename U,
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator==(const U& a, Span<T> b) {
  return span_internal::EqualImpl<Span, const T>(a, b);
}
template <
    typename T, typename U,
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator==(Span<T> a, const U& b) {
  return span_internal::EqualImpl<Span, const T>(a, b);
}

// operator!=
template <typename T>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator!=(Span<T> a, Span<T> b) {
  return !(a == b);
}
template <typename T>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator!=(Span<const T> a,
                                                    Span<T> b) {
  return !(a == b);
}
template <typename T>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator!=(Span<T> a,
                                                    Span<const T> b) {
  return !(a == b);
}
template <
    typename T, typename U,
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator!=(const U& a, Span<T> b) {
  return !(a == b);
}
template <
    typename T, typename U,
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator!=(Span<T> a, const U& b) {
  return !(a == b);
}

// operator<
template <typename T>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<(Span<T> a, Span<T> b) {
  return span_internal::LessThanImpl<Span, const T>(a, b);
}
template <typename T>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<(Span<const T> a, Span<T> b) {
  return span_internal::LessThanImpl<Span, const T>(a, b);
}
template <typename T>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<(Span<T> a, Span<const T> b) {
  return span_internal::LessThanImpl<Span, const T>(a, b);
}
template <
    typename T, typename U,
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<(const U& a, Span<T> b) {
  return span_internal::LessThanImpl<Span, const T>(a, b);
}
template <
    typename T, typename U,
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<(Span<T> a, const U& b) {
  return span_internal::LessThanImpl<Span, const T>(a, b);
}

// operator>
template <typename T>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>(Span<T> a, Span<T> b) {
  return b < a;
}
template <typename T>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>(Span<const T> a, Span<T> b) {
  return b < a;
}
template <typename T>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>(Span<T> a, Span<const T> b) {
  return b < a;
}
template <
    typename T, typename U,
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>(const U& a, Span<T> b) {
  return b < a;
}
template <
    typename T, typename U,
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>(Span<T> a, const U& b) {
  return b < a;
}

// operator<=
template <typename T>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<=(Span<T> a, Span<T> b) {
  return !(b < a);
}
template <typename T>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<=(Span<const T> a,
                                                    Span<T> b) {
  return !(b < a);
}
template <typename T>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<=(Span<T> a,
                                                    Span<const T> b) {
  return !(b < a);
}
template <
    typename T, typename U,
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<=(const U& a, Span<T> b) {
  return !(b < a);
}
template <
    typename T, typename U,
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator<=(Span<T> a, const U& b) {
  return !(b < a);
}

// operator>=
template <typename T>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>=(Span<T> a, Span<T> b) {
  return !(a < b);
}
template <typename T>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>=(Span<const T> a,
                                                    Span<T> b) {
  return !(a < b);
}
template <typename T>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>=(Span<T> a,
                                                    Span<const T> b) {
  return !(a < b);
}
template <
    typename T, typename U,
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>=(const U& a, Span<T> b) {
  return !(a < b);
}
template <
    typename T, typename U,
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool operator>=(Span<T> a, const U& b) {
  return !(a < b);
}

// MakeSpan()
//
// Constructs a mutable `Span<T>`, deducing `T` automatically from either a
// container or pointer+size.
//
// Because a read-only `Span<const T>` is implicitly constructed from container
// types regardless of whether the container itself is a const container,
// constructing mutable spans of type `Span<T>` from containers requires
// explicit constructors. The container-accepting version of `MakeSpan()`
// deduces the type of `T` by the constness of the pointer received from the
// container's `data()` member. Similarly, the pointer-accepting version returns
// a `Span<const T>` if `T` is `const`, and a `Span<T>` otherwise.
//
// Examples:
//
//   void MyRoutine(absl::Span<MyComplicatedType> a) {
//     ...
//   };
//   // my_vector is a container of non-const types
//   std::vector<MyComplicatedType> my_vector;
//
//   // Constructing a Span implicitly attempts to create a Span of type
//   // `Span<const T>`
//   MyRoutine(my_vector);                // error, type mismatch
//
//   // Explicitly constructing the Span is verbose
//   MyRoutine(absl::Span<MyComplicatedType>(my_vector));
//
//   // Use MakeSpan() to make an absl::Span<T>
//   MyRoutine(absl::MakeSpan(my_vector));
//
//   // Construct a span from an array ptr+size
//   absl::Span<T> my_span() {
//     return absl::MakeSpan(&array[0], num_elements_);
//   }
//
template <int&... ExplicitArgumentBarrier, typename T>
constexpr Span<T> MakeSpan(T* absl_nullable ptr, size_t size) noexcept {
  return Span<T>(ptr, size);
}

template <int&... ExplicitArgumentBarrier, typename T>
Span<T> MakeSpan(T* absl_nullable begin, T* absl_nullable end) noexcept {
  ABSL_HARDENING_ASSERT(begin <= end);
  return Span<T>(begin, static_cast<size_t>(end - begin));
}

template <int&... ExplicitArgumentBarrier, typename C>
constexpr auto MakeSpan(C& c) noexcept  // NOLINT(runtime/references)
    -> decltype(absl::MakeSpan(span_internal::GetData(c), c.size())) {
  return MakeSpan(span_internal::GetData(c), c.size());
}

template <int&... ExplicitArgumentBarrier, typename T, size_t N>
constexpr Span<T> MakeSpan(T (&array)[N]) noexcept {
  return Span<T>(array, N);
}

// MakeConstSpan()
//
// Constructs a `Span<const T>` as with `MakeSpan`, deducing `T` automatically,
// but always returning a `Span<const T>`.
//
// Examples:
//
//   void ProcessInts(absl::Span<const int> some_ints);
//
//   // Call with a pointer and size.
//   int array[3] = { 0, 0, 0 };
//   ProcessInts(absl::MakeConstSpan(&array[0], 3));
//
//   // Call with a [begin, end) pair.
//   ProcessInts(absl::MakeConstSpan(&array[0], &array[3]));
//
//   // Call directly with an array.
//   ProcessInts(absl::MakeConstSpan(array));
//
//   // Call with a contiguous container.
//   std::vector<int> some_ints = ...;
//   ProcessInts(absl::MakeConstSpan(some_ints));
//   ProcessInts(absl::MakeConstSpan(std::vector<int>{ 0, 0, 0 }));
//
template <int&... ExplicitArgumentBarrier, typename T>
constexpr Span<const T> MakeConstSpan(T* absl_nullable ptr,
                                      size_t size) noexcept {
  return Span<const T>(ptr, size);
}

template <int&... ExplicitArgumentBarrier, typename T>
Span<const T> MakeConstSpan(T* absl_nullable begin,
                            T* absl_nullable end) noexcept {
  ABSL_HARDENING_ASSERT(begin <= end);
  return Span<const T>(begin, end - begin);
}

template <int&... ExplicitArgumentBarrier, typename C>
constexpr auto MakeConstSpan(const C& c) noexcept -> decltype(MakeSpan(c)) {
  return MakeSpan(c);
}

template <int&... ExplicitArgumentBarrier, typename T, size_t N>
constexpr Span<const T> MakeConstSpan(const T (&array)[N]) noexcept {
  return Span<const T>(array, N);
}
ABSL_NAMESPACE_END
}  // namespace absl
#endif  // ABSL_TYPES_SPAN_H_
*Àh
rsoong/.intermediates/external/abseil-cpp/absl_log_internal_proto_hdrs/gen/my_include_dir/absl/log/internal/proto.hÉg// 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.

// -----------------------------------------------------------------------------
// File: internal/proto.h
// -----------------------------------------------------------------------------
//
// Declares functions for serializing and deserializing data to and from memory
// buffers in protocol buffer wire format.  This library takes no steps to
// ensure that the encoded data matches with any message specification.

#ifndef ABSL_LOG_INTERNAL_PROTO_H_
#define ABSL_LOG_INTERNAL_PROTO_H_

#include <cstddef>
#include <cstdint>
#include <limits>

#include "absl/base/attributes.h"
#include "absl/base/casts.h"
#include "absl/base/config.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace log_internal {

// absl::Span<char> represents a view into the available space in a mutable
// buffer during encoding.  Encoding functions shrink the span as they go so
// that the same view can be passed to a series of Encode functions.  If the
// data do not fit, nothing is encoded, the view is set to size zero (so that
// all subsequent encode calls fail), and false is returned.  Otherwise true is
// returned.

// In particular, attempting to encode a series of data into an insufficient
// buffer has consistent and efficient behavior without any caller-side error
// checking.  Individual values will be encoded in their entirety or not at all
// (unless one of the `Truncate` functions is used).  Once a value is omitted
// because it does not fit, no subsequent values will be encoded to preserve
// ordering; the decoded sequence will be a prefix of the original sequence.

// There are two ways to encode a message-typed field:
//
// * Construct its contents in a separate buffer and use `EncodeBytes` to copy
//   it into the primary buffer with type, tag, and length.
// * Use `EncodeMessageStart` to write type and tag fields and reserve space for
//   the length field, then encode the contents directly into the buffer, then
//   use `EncodeMessageLength` to write the actual length into the reserved
//   bytes.  This works fine if the actual length takes fewer bytes to encode
//   than were reserved, although you don't get your extra bytes back.
//   This approach will always produce a valid encoding, but your protocol may
//   require that the whole message field by omitted if the buffer is too small
//   to contain all desired subfields.  In this case, operate on a copy of the
//   buffer view and assign back only if everything fit, i.e. if the last
//   `Encode` call returned true.

// Encodes the specified integer as a varint field and returns true if it fits.
// Used for int32_t, int64_t, uint32_t, uint64_t, bool, and enum field types.
// Consumes up to kMaxVarintSize * 2 bytes (20).
bool EncodeVarint(uint64_t tag, uint64_t value, absl::Span<char> *buf);
inline bool EncodeVarint(uint64_t tag, int64_t value, absl::Span<char> *buf) {
  return EncodeVarint(tag, static_cast<uint64_t>(value), buf);
}
inline bool EncodeVarint(uint64_t tag, uint32_t value, absl::Span<char> *buf) {
  return EncodeVarint(tag, static_cast<uint64_t>(value), buf);
}
inline bool EncodeVarint(uint64_t tag, int32_t value, absl::Span<char> *buf) {
  return EncodeVarint(tag, static_cast<uint64_t>(value), buf);
}

// Encodes the specified integer as a varint field using ZigZag encoding and
// returns true if it fits.
// Used for sint32 and sint64 field types.
// Consumes up to kMaxVarintSize * 2 bytes (20).
inline bool EncodeVarintZigZag(uint64_t tag, int64_t value,
                               absl::Span<char> *buf) {
  if (value < 0)
    return EncodeVarint(tag, 2 * static_cast<uint64_t>(-(value + 1)) + 1, buf);
  return EncodeVarint(tag, 2 * static_cast<uint64_t>(value), buf);
}

// Encodes the specified integer as a 64-bit field and returns true if it fits.
// Used for fixed64 and sfixed64 field types.
// Consumes up to kMaxVarintSize + 8 bytes (18).
bool Encode64Bit(uint64_t tag, uint64_t value, absl::Span<char> *buf);
inline bool Encode64Bit(uint64_t tag, int64_t value, absl::Span<char> *buf) {
  return Encode64Bit(tag, static_cast<uint64_t>(value), buf);
}
inline bool Encode64Bit(uint64_t tag, uint32_t value, absl::Span<char> *buf) {
  return Encode64Bit(tag, static_cast<uint64_t>(value), buf);
}
inline bool Encode64Bit(uint64_t tag, int32_t value, absl::Span<char> *buf) {
  return Encode64Bit(tag, static_cast<uint64_t>(value), buf);
}

// Encodes the specified double as a 64-bit field and returns true if it fits.
// Used for double field type.
// Consumes up to kMaxVarintSize + 8 bytes (18).
inline bool EncodeDouble(uint64_t tag, double value, absl::Span<char> *buf) {
  return Encode64Bit(tag, absl::bit_cast<uint64_t>(value), buf);
}

// Encodes the specified integer as a 32-bit field and returns true if it fits.
// Used for fixed32 and sfixed32 field types.
// Consumes up to kMaxVarintSize + 4 bytes (14).
bool Encode32Bit(uint64_t tag, uint32_t value, absl::Span<char> *buf);
inline bool Encode32Bit(uint64_t tag, int32_t value, absl::Span<char> *buf) {
  return Encode32Bit(tag, static_cast<uint32_t>(value), buf);
}

// Encodes the specified float as a 32-bit field and returns true if it fits.
// Used for float field type.
// Consumes up to kMaxVarintSize + 4 bytes (14).
inline bool EncodeFloat(uint64_t tag, float value, absl::Span<char> *buf) {
  return Encode32Bit(tag, absl::bit_cast<uint32_t>(value), buf);
}

// Encodes the specified bytes as a length-delimited field and returns true if
// they fit.
// Used for string, bytes, message, and packed-repeated field type.
// Consumes up to kMaxVarintSize * 2 + value.size() bytes (20 + value.size()).
bool EncodeBytes(uint64_t tag, absl::Span<const char> value,
                 absl::Span<char> *buf);

// Encodes as many of the specified bytes as will fit as a length-delimited
// field and returns true as long as the field header (`tag_type` and `length`)
// fits.
// Used for string, bytes, message, and packed-repeated field type.
// Consumes up to kMaxVarintSize * 2 + value.size() bytes (20 + value.size()).
bool EncodeBytesTruncate(uint64_t tag, absl::Span<const char> value,
                         absl::Span<char> *buf);

// Encodes the specified string as a length-delimited field and returns true if
// it fits.
// Used for string, bytes, message, and packed-repeated field type.
// Consumes up to kMaxVarintSize * 2 + value.size() bytes (20 + value.size()).
inline bool EncodeString(uint64_t tag, absl::string_view value,
                         absl::Span<char> *buf) {
  return EncodeBytes(tag, value, buf);
}

// Encodes as much of the specified string as will fit as a length-delimited
// field and returns true as long as the field header (`tag_type` and `length`)
// fits.
// Used for string, bytes, message, and packed-repeated field type.
// Consumes up to kMaxVarintSize * 2 + value.size() bytes (20 + value.size()).
inline bool EncodeStringTruncate(uint64_t tag, absl::string_view value,
                                 absl::Span<char> *buf) {
  return EncodeBytesTruncate(tag, value, buf);
}

// Encodes the header for a length-delimited field containing up to `max_size`
// bytes or the number remaining in the buffer, whichever is less.  If the
// header fits, a non-nullptr `Span` is returned; this must be passed to
// `EncodeMessageLength` after all contents are encoded to finalize the length
// field.  If the header does not fit, a nullptr `Span` is returned which is
// safe to pass to `EncodeMessageLength` but need not be.
// Used for string, bytes, message, and packed-repeated field type.
// Consumes up to kMaxVarintSize * 2 bytes (20).
[[nodiscard]] absl::Span<char> EncodeMessageStart(uint64_t tag,
                                                  uint64_t max_size,
                                                  absl::Span<char> *buf);

// Finalizes the length field in `msg` so that it encompasses all data encoded
// since the call to `EncodeMessageStart` which returned `msg`.  Does nothing if
// `msg` is a `nullptr` `Span`.
void EncodeMessageLength(absl::Span<char> msg, const absl::Span<char> *buf);

enum class WireType : uint64_t {
  kVarint = 0,
  k64Bit = 1,
  kLengthDelimited = 2,
  k32Bit = 5,
};

constexpr size_t VarintSize(uint64_t value) {
  return value < 128 ? 1 : 1 + VarintSize(value >> 7);
}
constexpr size_t MinVarintSize() {
  return VarintSize((std::numeric_limits<uint64_t>::min)());
}
constexpr size_t MaxVarintSize() {
  return VarintSize((std::numeric_limits<uint64_t>::max)());
}

constexpr uint64_t MaxVarintForSize(size_t size) {
  return size >= 10 ? (std::numeric_limits<uint64_t>::max)()
                    : (static_cast<uint64_t>(1) << size * 7) - 1;
}
constexpr uint64_t MakeTagType(uint64_t tag, WireType type) {
  return tag << 3 | static_cast<uint64_t>(type);
}

// `BufferSizeFor` returns a number of bytes guaranteed to be sufficient to
// store encoded fields as `(tag, WireType)`, regardless of data values.  This
// only makes sense for `WireType::kLengthDelimited` if you add in the length of
// the contents yourself, e.g. for string and bytes fields by adding the lengths
// of any encoded strings to the return value or for submessage fields by
// enumerating the fields you may encode into their contents.
constexpr size_t BufferSizeFor(uint64_t tag, WireType type) {
  size_t buffer_size = VarintSize(MakeTagType(tag, type));
  switch (type) {
    case WireType::kVarint:
      buffer_size += MaxVarintSize();
      break;
    case WireType::k64Bit:
      buffer_size += size_t{8};
      break;
    case WireType::kLengthDelimited:
      buffer_size += MaxVarintSize();
      break;
    case WireType::k32Bit:
      buffer_size += size_t{4};
      break;
  }
  return buffer_size;
}

// absl::Span<const char> represents a view into the un-processed space in a
// buffer during decoding.  Decoding functions shrink the span as they go so
// that the same view can be decoded iteratively until all data are processed.
// In general, if the buffer is exhausted but additional bytes are expected by
// the decoder, it will return values as if the additional bytes were zeros.
// Length-delimited fields are an exception - if the encoded length field
// indicates more data bytes than are available in the buffer, the `bytes_value`
// and `string_value` accessors will return truncated views.

class ProtoField final {
 public:
  // Consumes bytes from `data` and returns true if there were any bytes to
  // decode.
  bool DecodeFrom(absl::Span<const char> *data);
  uint64_t tag() const { return tag_; }
  WireType type() const { return type_; }

  // These value accessors will return nonsense if the data were not encoded in
  // the corresponding wiretype from the corresponding C++ (or other language)
  // type.

  double double_value() const { return absl::bit_cast<double>(value_); }
  float float_value() const {
    return absl::bit_cast<float>(static_cast<uint32_t>(value_));
  }
  int32_t int32_value() const { return static_cast<int32_t>(value_); }
  int64_t int64_value() const { return static_cast<int64_t>(value_); }
  int32_t sint32_value() const {
    if (value_ % 2) return static_cast<int32_t>(0 - ((value_ - 1) / 2) - 1);
    return static_cast<int32_t>(value_ / 2);
  }
  int64_t sint64_value() const {
    if (value_ % 2) return 0 - ((value_ - 1) / 2) - 1;
    return value_ / 2;
  }
  uint32_t uint32_value() const { return static_cast<uint32_t>(value_); }
  uint64_t uint64_value() const { return value_; }
  bool bool_value() const { return value_ != 0; }
  // To decode an enum, call int32_value() and cast to the appropriate type.
  // Note that the official C++ proto compiler treats enum fields with values
  // that do not correspond to a defined enumerator as unknown fields.

  // To decode fields within a submessage field, call
  // `DecodeNextField(field.BytesValue())`.
  absl::Span<const char> bytes_value() const { return data_; }
  absl::string_view string_value() const {
    const auto data = bytes_value();
    return absl::string_view(data.data(), data.size());
  }
  // Returns the encoded length of a length-delimited field.  This equals
  // `bytes_value().size()` except when the latter has been truncated due to
  // buffer underrun.
  uint64_t encoded_length() const { return value_; }

 private:
  uint64_t tag_;
  WireType type_;
  // For `kTypeVarint`, `kType64Bit`, and `kType32Bit`, holds the decoded value.
  // For `kTypeLengthDelimited`, holds the decoded length.
  uint64_t value_;
  absl::Span<const char> data_;
};

}  // namespace log_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_LOG_INTERNAL_PROTO_H_
*³9
wsoong/.intermediates/external/abseil-cpp/absl_container_common_hdrs/gen/my_include_dir/absl/container/internal/common.h·8// 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.

#ifndef ABSL_CONTAINER_INTERNAL_COMMON_H_
#define ABSL_CONTAINER_INTERNAL_COMMON_H_

#include <cassert>
#include <type_traits>

#include "absl/meta/type_traits.h"
#include "absl/types/optional.h"

// TODO(b/402804213): Clean up these macros when no longer needed.
#define ABSL_INTERNAL_SINGLE_ARG(...) __VA_ARGS__

#define ABSL_INTERNAL_IF_true(if_satisfied, ...) if_satisfied
#define ABSL_INTERNAL_IF_false(if_satisfied, ...) __VA_ARGS__

#define ABSL_INTERNAL_IF_true_AND_true ABSL_INTERNAL_IF_true
#define ABSL_INTERNAL_IF_false_AND_false ABSL_INTERNAL_IF_false
#define ABSL_INTERNAL_IF_true_AND_false ABSL_INTERNAL_IF_false_AND_false
#define ABSL_INTERNAL_IF_false_AND_true ABSL_INTERNAL_IF_false_AND_false

#define ABSL_INTERNAL_IF_true_OR_true ABSL_INTERNAL_IF_true
#define ABSL_INTERNAL_IF_false_OR_false ABSL_INTERNAL_IF_false
#define ABSL_INTERNAL_IF_true_OR_false ABSL_INTERNAL_IF_true_OR_true
#define ABSL_INTERNAL_IF_false_OR_true ABSL_INTERNAL_IF_true_OR_true

#define ABSL_INTERNAL_IF_true_NOR_true ABSL_INTERNAL_IF_false_AND_false
#define ABSL_INTERNAL_IF_false_NOR_false ABSL_INTERNAL_IF_true_AND_true
#define ABSL_INTERNAL_IF_true_NOR_false ABSL_INTERNAL_IF_false_AND_true
#define ABSL_INTERNAL_IF_false_NOR_true ABSL_INTERNAL_IF_true_AND_false

#define ABSL_INTERNAL_COMMA ,

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace container_internal {

// TODO(b/402804213): Clean up these traits when no longer needed or
// deduplicate them with absl::functional_internal::EnableIf.
template <class Cond>
using EnableIf = std::enable_if_t<Cond::value, int>;

template <bool Value, class T>
using HasValue = std::conditional_t<Value, T, absl::negation<T>>;

template <class T>
struct IfRRef {
  template <class Other>
  using AddPtr = Other;
};

template <class T>
struct IfRRef<T&&> {
  template <class Other>
  using AddPtr = Other*;
};

template <class, class = void>
struct IsTransparent : std::false_type {};
template <class T>
struct IsTransparent<T, absl::void_t<typename T::is_transparent>>
    : std::true_type {};

template <bool is_transparent>
struct KeyArg {
  // Transparent. Forward `K`.
  template <typename K, typename key_type>
  using type = K;
};

template <>
struct KeyArg<false> {
  // Not transparent. Always use `key_type`.
  template <typename K, typename key_type>
  using type = key_type;
};

// The node_handle concept from C++17.
// We specialize node_handle for sets and maps. node_handle_base holds the
// common API of both.
template <typename PolicyTraits, typename Alloc>
class node_handle_base {
 protected:
  using slot_type = typename PolicyTraits::slot_type;

 public:
  using allocator_type = Alloc;

  constexpr node_handle_base() = default;
  node_handle_base(node_handle_base&& other) noexcept {
    *this = std::move(other);
  }
  ~node_handle_base() { destroy(); }
  node_handle_base& operator=(node_handle_base&& other) noexcept {
    destroy();
    if (!other.empty()) {
      alloc_ = other.alloc_;
      PolicyTraits::transfer(alloc(), slot(), other.slot());
      other.reset();
    }
    return *this;
  }

  bool empty() const noexcept { return !alloc_; }
  explicit operator bool() const noexcept { return !empty(); }
  allocator_type get_allocator() const { return *alloc_; }

 protected:
  friend struct CommonAccess;

  struct transfer_tag_t {};
  node_handle_base(transfer_tag_t, const allocator_type& a, slot_type* s)
      : alloc_(a) {
    PolicyTraits::transfer(alloc(), slot(), s);
  }

  struct construct_tag_t {};
  template <typename... Args>
  node_handle_base(construct_tag_t, const allocator_type& a, Args&&... args)
      : alloc_(a) {
    PolicyTraits::construct(alloc(), slot(), std::forward<Args>(args)...);
  }

  void destroy() {
    if (!empty()) {
      PolicyTraits::destroy(alloc(), slot());
      reset();
    }
  }

  void reset() {
    assert(alloc_.has_value());
    alloc_ = absl::nullopt;
  }

  slot_type* slot() const {
    assert(!empty());
    return reinterpret_cast<slot_type*>(std::addressof(slot_space_));
  }
  allocator_type* alloc() { return std::addressof(*alloc_); }

 private:
  absl::optional<allocator_type> alloc_ = {};
  alignas(slot_type) mutable unsigned char slot_space_[sizeof(slot_type)] = {};
};

// For sets.
template <typename Policy, typename PolicyTraits, typename Alloc,
          typename = void>
class node_handle : public node_handle_base<PolicyTraits, Alloc> {
  using Base = node_handle_base<PolicyTraits, Alloc>;

 public:
  using value_type = typename PolicyTraits::value_type;

  constexpr node_handle() {}

  value_type& value() const { return PolicyTraits::element(this->slot()); }

 private:
  friend struct CommonAccess;

  using Base::Base;
};

// For maps.
template <typename Policy, typename PolicyTraits, typename Alloc>
class node_handle<Policy, PolicyTraits, Alloc,
                  absl::void_t<typename Policy::mapped_type>>
    : public node_handle_base<PolicyTraits, Alloc> {
  using Base = node_handle_base<PolicyTraits, Alloc>;
  using slot_type = typename PolicyTraits::slot_type;

 public:
  using key_type = typename Policy::key_type;
  using mapped_type = typename Policy::mapped_type;

  constexpr node_handle() {}

  // When C++17 is available, we can use std::launder to provide mutable
  // access to the key. Otherwise, we provide const access.
  auto key() const
      -> decltype(PolicyTraits::mutable_key(std::declval<slot_type*>())) {
    return PolicyTraits::mutable_key(this->slot());
  }

  mapped_type& mapped() const {
    return PolicyTraits::value(&PolicyTraits::element(this->slot()));
  }

 private:
  friend struct CommonAccess;

  using Base::Base;
};

// Provide access to non-public node-handle functions.
struct CommonAccess {
  template <typename Node>
  static auto GetSlot(const Node& node) -> decltype(node.slot()) {
    return node.slot();
  }

  template <typename Node>
  static void Destroy(Node* node) {
    node->destroy();
  }

  template <typename Node>
  static void Reset(Node* node) {
    node->reset();
  }

  template <typename T, typename... Args>
  static T Transfer(Args&&... args) {
    return T(typename T::transfer_tag_t{}, std::forward<Args>(args)...);
  }

  template <typename T, typename... Args>
  static T Construct(Args&&... args) {
    return T(typename T::construct_tag_t{}, std::forward<Args>(args)...);
  }
};

// Implement the insert_return_type<> concept of C++17.
template <class Iterator, class NodeType>
struct InsertReturnType {
  Iterator position;
  bool inserted;
  NodeType node;
};

}  // namespace container_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_CONTAINER_INTERNAL_COMMON_H_
*Ÿ
ˆsoong/.intermediates/external/abseil-cpp/absl_log_internal_structured_proto_hdrs/gen/my_include_dir/absl/log/internal/structured_proto.h‘// Copyright 2024 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// File: log/internal/structured_proto.h
// -----------------------------------------------------------------------------

#ifndef ABSL_LOG_INTERNAL_STRUCTURED_PROTO_H_
#define ABSL_LOG_INTERNAL_STRUCTURED_PROTO_H_

#include <cstddef>
#include <cstdint>

#include "absl/base/config.h"
#include "absl/log/internal/proto.h"
#include "absl/types/span.h"
#include "absl/types/variant.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace log_internal {

// Sum type holding a single valid protobuf field suitable for encoding.
struct StructuredProtoField final {
  // Numeric type encoded with varint encoding:
  // https://protobuf.dev/programming-guides/encoding/#varints
  using Varint = absl::variant<uint64_t, int64_t, uint32_t, int32_t, bool>;

  // Fixed-length 64-bit integer encoding:
  // https://protobuf.dev/programming-guides/encoding/#non-varints
  using I64 = absl::variant<uint64_t, int64_t, double>;

  // Length-delimited record type (string, sub-message):
  // https://protobuf.dev/programming-guides/encoding/#length-types
  using LengthDelimited = absl::Span<const char>;

  // Fixed-length 32-bit integer encoding:
  // https://protobuf.dev/programming-guides/encoding/#non-varints
  using I32 = absl::variant<uint32_t, int32_t, float>;

  // Valid record type:
  // https://protobuf.dev/programming-guides/encoding/#structure
  using Value = absl::variant<Varint, I64, LengthDelimited, I32>;

  // Field number for the protobuf value.
  uint64_t field_number;

  // Value to encode.
  Value value;
};

// Estimates the number of bytes needed to encode `field` using
// protobuf encoding.
//
// The returned value might be larger than the actual number of bytes needed.
inline size_t BufferSizeForStructuredProtoField(StructuredProtoField field) {
  // Visitor to estimate the number of bytes of one of the types contained
  // inside `StructuredProtoField`.
  struct BufferSizeVisitor final {
    size_t operator()(StructuredProtoField::Varint /*unused*/) {
      return BufferSizeFor(field_number, WireType::kVarint);
    }

    size_t operator()(StructuredProtoField::I64 /*unused*/) {
      return BufferSizeFor(field_number, WireType::k64Bit);
    }

    size_t operator()(StructuredProtoField::LengthDelimited length_delimited) {
      return BufferSizeFor(field_number, WireType::kLengthDelimited) +
             length_delimited.size();
    }

    size_t operator()(StructuredProtoField::I32 /*unused*/) {
      return BufferSizeFor(field_number, WireType::k32Bit);
    }

    uint64_t field_number;
  };

  return absl::visit(BufferSizeVisitor{field.field_number}, field.value);
}

// Encodes `field` into `buf` using protobuf encoding.
//
// On success, returns `true` and advances `buf` to the end of
// the bytes consumed.
//
// On failure (if `buf` was too small), returns `false`.
bool EncodeStructuredProtoField(StructuredProtoField field,
                                absl::Span<char>& buf);

}  // namespace log_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_LOG_INTERNAL_STRUCTURED_PROTO_H_
*©‘
~soong/.intermediates/external/abseil-cpp/absl_log_internal_log_message_hdrs/gen/my_include_dir/absl/log/internal/log_message.h¥�// 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/internal/log_message.h
// -----------------------------------------------------------------------------
//
// This file declares `class absl::log_internal::LogMessage`. This class more or
// less represents a particular log message. LOG/CHECK macros create a temporary
// instance of `LogMessage` and then stream values to it.  At the end of the
// LOG/CHECK statement, the LogMessage is voidified by operator&&, and `Flush()`
// directs the message to the registered log sinks.  Heap-allocation of
// `LogMessage` is unsupported.  Construction outside of a `LOG` macro is
// unsupported.

#ifndef ABSL_LOG_INTERNAL_LOG_MESSAGE_H_
#define ABSL_LOG_INTERNAL_LOG_MESSAGE_H_

#include <wchar.h>

#include <cstddef>
#include <ios>
#include <memory>
#include <ostream>
#include <streambuf>
#include <string>
#include <string_view>
#include <type_traits>

#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/errno_saver.h"
#include "absl/base/log_severity.h"
#include "absl/base/nullability.h"
#include "absl/log/internal/nullguard.h"
#include "absl/log/internal/structured_proto.h"
#include "absl/log/log_entry.h"
#include "absl/log/log_sink.h"
#include "absl/strings/has_absl_stringify.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace log_internal {
constexpr int kLogMessageBufferSize = 15000;

enum class StructuredStringType;

class LogMessage {
 public:
  struct InfoTag {};
  struct WarningTag {};
  struct ErrorTag {};

  // Used for `LOG`.
  LogMessage(const char* absl_nonnull file, int line,
             absl::LogSeverity severity) ABSL_ATTRIBUTE_COLD;
  // These constructors are slightly smaller/faster to call; the severity is
  // curried into the function pointer.
  LogMessage(const char* absl_nonnull file, int line,
             InfoTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE;
  LogMessage(const char* absl_nonnull file, int line,
             WarningTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE;
  LogMessage(const char* absl_nonnull file, int line,
             ErrorTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE;
  LogMessage(const LogMessage&) = delete;
  LogMessage& operator=(const LogMessage&) = delete;
  ~LogMessage() ABSL_ATTRIBUTE_COLD;

  // Overrides the location inferred from the callsite.  The string pointed to
  // by `file` must be valid until the end of the statement.
  LogMessage& AtLocation(absl::string_view file, int line);
  // Omits the prefix from this line.  The prefix includes metadata about the
  // logged data such as source code location and timestamp.
  LogMessage& NoPrefix();
  // 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 `absl::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.
  LogMessage& WithVerbosity(int verbose_level);
  // Uses the specified timestamp instead of one collected in the constructor.
  LogMessage& WithTimestamp(absl::Time timestamp);
  // Uses the specified thread ID instead of one collected in the constructor.
  LogMessage& WithThreadID(absl::LogEntry::tid_t tid);
  // Copies all metadata (but no data) from the specified `absl::LogEntry`.
  LogMessage& WithMetadataFrom(const absl::LogEntry& entry);
  // Appends to the logged message a colon, a space, a textual description of
  // the current value of `errno` (as by strerror(3)), and the numerical value
  // of `errno`.
  LogMessage& WithPerror();
  // Sends this message to `*sink` in addition to whatever other sinks it would
  // otherwise have been sent to.
  LogMessage& ToSinkAlso(absl::LogSink* absl_nonnull sink);
  // Sends this message to `*sink` and no others.
  LogMessage& ToSinkOnly(absl::LogSink* absl_nonnull sink);

  // Don't call this method from outside this library.
  LogMessage& InternalStream() { return *this; }

  // By-value overloads for small, common types let us overlook common failures
  // to define globals and static data members (i.e. in a .cc file).
  // NOLINTBEGIN(runtime/int)
  // NOLINTBEGIN(google-runtime-int)
  // clang-format off:  The CUDA toolchain cannot handle these <<<'s
  LogMessage& operator<<(char v) { return operator<< <char>(v); }
  LogMessage& operator<<(signed char v) { return operator<< <signed char>(v); }
  LogMessage& operator<<(unsigned char v) {
    return operator<< <unsigned char>(v);
  }
  LogMessage& operator<<(signed short v) {
    return operator<< <signed short>(v);
  }
  LogMessage& operator<<(signed int v) { return operator<< <signed int>(v); }
  LogMessage& operator<<(signed long v) {
    return operator<< <signed long>(v);
  }
  LogMessage& operator<<(signed long long v) {
    return operator<< <signed long long>(v);
  }
  LogMessage& operator<<(unsigned short v) {
    return operator<< <unsigned short>(v);
  }
  LogMessage& operator<<(unsigned int v) {
    return operator<< <unsigned int>(v);
  }
  LogMessage& operator<<(unsigned long v) {
    return operator<< <unsigned long>(v);
  }
  LogMessage& operator<<(unsigned long long v) {
    return operator<< <unsigned long long>(v);
  }
  LogMessage& operator<<(void* absl_nullable  v) {
    return operator<< <void*>(v);
  }
  LogMessage& operator<<(const void* absl_nullable  v) {
    return operator<< <const void*>(v);
  }
  LogMessage& operator<<(float v) { return operator<< <float>(v); }
  LogMessage& operator<<(double v) { return operator<< <double>(v); }
  LogMessage& operator<<(bool v) { return operator<< <bool>(v); }
  // clang-format on
  // NOLINTEND(google-runtime-int)
  // NOLINTEND(runtime/int)

  // These overloads are more efficient since no `ostream` is involved.
  LogMessage& operator<<(const std::string& v);
  LogMessage& operator<<(absl::string_view v);

  // Wide string overloads (since std::ostream does not provide them).
  LogMessage& operator<<(const std::wstring& v);
  LogMessage& operator<<(std::wstring_view v);
  // `const wchar_t*` is handled by `operator<< <const wchar_t*>`.
  LogMessage& operator<<(wchar_t* absl_nullable v);
  LogMessage& operator<<(wchar_t v);

  // Handle stream manipulators e.g. std::endl.
  LogMessage& operator<<(std::ostream& (*absl_nonnull m)(std::ostream& os));
  LogMessage& operator<<(std::ios_base& (*absl_nonnull m)(std::ios_base& os));

  // Literal strings.  This allows us to record C string literals as literals in
  // the logging.proto.Value.
  //
  // Allow this overload to be inlined to prevent generating instantiations of
  // this template for every value of `SIZE` encountered in each source code
  // file. That significantly increases linker input sizes. Inlining is cheap
  // because the argument to this overload is almost always a string literal so
  // the call to `strlen` can be replaced at compile time. The overloads for
  // `char[]`/`wchar_t[]` below should not be inlined. The compiler typically
  // does not have the string at compile time and cannot replace the call to
  // `strlen` so inlining it increases the binary size. See the discussion on
  // cl/107527369.
  template <int SIZE>
  LogMessage& operator<<(const char (&buf)[SIZE]);
  template <int SIZE>
  LogMessage& operator<<(const wchar_t (&buf)[SIZE]);

  // This prevents non-const `char[]` arrays from looking like literals.
  template <int SIZE>
  LogMessage& operator<<(char (&buf)[SIZE]) ABSL_ATTRIBUTE_NOINLINE;
  // `wchar_t[SIZE]` is handled by `operator<< <const wchar_t*>`.

  // Types that support `AbslStringify()` are serialized that way.
  // Types that don't support `AbslStringify()` but do support streaming into a
  // `std::ostream&` are serialized that way.
  template <typename T>
  LogMessage& operator<<(const T& v) ABSL_ATTRIBUTE_NOINLINE;

  // Dispatches the completed `absl::LogEntry` to applicable `absl::LogSink`s.
  void Flush();

  // Note: We explicitly do not support `operator<<` for non-const references
  // because it breaks logging of non-integer bitfield types (i.e., enums).

 protected:
  // Call `abort()` or similar to perform `LOG(FATAL)` crash.  It is assumed
  // that the caller has already generated and written the trace as appropriate.
  [[noreturn]] static void FailWithoutStackTrace();

  // Similar to `FailWithoutStackTrace()`, but without `abort()`.  Terminates
  // the process with an error exit code.
  [[noreturn]] static void FailQuietly();

  // After this is called, failures are done as quiet as possible for this log
  // message.
  void SetFailQuietly();

 private:
  struct LogMessageData;  // Opaque type containing message state
  friend class AsLiteralImpl;
  friend class StringifySink;
  template <StructuredStringType str_type>
  friend class AsStructuredStringTypeImpl;
  template <typename T>
  friend class AsStructuredValueImpl;

  // This streambuf writes directly into the structured logging buffer so that
  // arbitrary types can be encoded as string data (using
  // `operator<<(std::ostream &, ...)` without any extra allocation or copying.
  // Space is reserved before the data to store the length field, which is
  // filled in by `~OstreamView`.
  class OstreamView final : public std::streambuf {
   public:
    explicit OstreamView(LogMessageData& message_data);
    ~OstreamView() override;
    OstreamView(const OstreamView&) = delete;
    OstreamView& operator=(const OstreamView&) = delete;
    std::ostream& stream();

   private:
    LogMessageData& data_;
    absl::Span<char> encoded_remaining_copy_;
    absl::Span<char> message_start_;
    absl::Span<char> string_start_;
  };

  enum class StringType {
    kLiteral,
    kNotLiteral,
  };
  template <StringType str_type>
  void CopyToEncodedBuffer(absl::string_view str) ABSL_ATTRIBUTE_NOINLINE;
  template <StringType str_type>
  void CopyToEncodedBuffer(char ch, size_t num) ABSL_ATTRIBUTE_NOINLINE;
  template <StringType str_type>
  void CopyToEncodedBuffer(std::wstring_view str) ABSL_ATTRIBUTE_NOINLINE;

  // Copies `field` to the encoded buffer, then appends `str` after it
  // (truncating `str` if necessary to fit).
  template <StringType str_type>
  void CopyToEncodedBufferWithStructuredProtoField(StructuredProtoField field,
                                                   absl::string_view str)
      ABSL_ATTRIBUTE_NOINLINE;

  // Returns `true` if the message is fatal or enabled debug-fatal.
  bool IsFatal() const;

  // Records some tombstone-type data in anticipation of `Die`.
  void PrepareToDie();
  void Die();

  void SendToLog();

  // Checks `FLAGS_log_backtrace_at` and appends a backtrace if appropriate.
  void LogBacktraceIfNeeded();

  // This should be the first data member so that its initializer captures errno
  // before any other initializers alter it (e.g. with calls to new) and so that
  // no other destructors run afterward an alter it (e.g. with calls to delete).
  absl::base_internal::ErrnoSaver errno_saver_;

  // We keep the data in a separate struct so that each instance of `LogMessage`
  // uses less stack space.
  absl_nonnull std::unique_ptr<LogMessageData> data_;
};

// Explicitly specializes the generic operator<< for `const wchar_t*`
// arguments.
//
// This method is used instead of a non-template `const wchar_t*` overload,
// as the latter was found to take precedence over the array template
// (`operator<<(const wchar_t(&)[SIZE])`) when handling string literals.
// This specialization ensures the array template now correctly processes
// literals.
template <>
LogMessage& LogMessage::operator<< <const wchar_t*>(
    const wchar_t* absl_nullable const& v);

inline LogMessage& LogMessage::operator<<(wchar_t* absl_nullable v) {
  return operator<<(const_cast<const wchar_t*>(v));
}

// Helper class so that `AbslStringify()` can modify the LogMessage.
class StringifySink final {
 public:
  explicit StringifySink(LogMessage& message) : message_(message) {}

  void Append(size_t count, char ch) {
    message_.CopyToEncodedBuffer<LogMessage::StringType::kNotLiteral>(ch,
                                                                      count);
  }

  void Append(absl::string_view v) {
    message_.CopyToEncodedBuffer<LogMessage::StringType::kNotLiteral>(v);
  }

  // For types that implement `AbslStringify` using `absl::Format()`.
  friend void AbslFormatFlush(StringifySink* absl_nonnull sink,
                              absl::string_view v) {
    sink->Append(v);
  }

 private:
  LogMessage& message_;
};

// Note: the following is declared `ABSL_ATTRIBUTE_NOINLINE`
template <typename T>
LogMessage& LogMessage::operator<<(const T& v) {
  if constexpr (absl::HasAbslStringify<T>::value) {
    StringifySink sink(*this);
    // Replace with public API.
    AbslStringify(sink, v);
  } else {
    OstreamView view(*data_);
    view.stream() << log_internal::NullGuard<T>().Guard(v);
  }
  return *this;
}

template <int SIZE>
LogMessage& LogMessage::operator<<(const char (&buf)[SIZE]) {
  CopyToEncodedBuffer<StringType::kLiteral>(buf);
  return *this;
}

template <int SIZE>
LogMessage& LogMessage::operator<<(const wchar_t (&buf)[SIZE]) {
  CopyToEncodedBuffer<StringType::kLiteral>(buf);
  return *this;
}

// Note: the following is declared `ABSL_ATTRIBUTE_NOINLINE`
template <int SIZE>
LogMessage& LogMessage::operator<<(char (&buf)[SIZE]) {
  CopyToEncodedBuffer<StringType::kNotLiteral>(buf);
  return *this;
}
// We instantiate these specializations in the library's TU to save space in
// other TUs.  Since the template is marked `ABSL_ATTRIBUTE_NOINLINE` we will be
// emitting a function call either way.
// NOLINTBEGIN(runtime/int)
// NOLINTBEGIN(google-runtime-int)
extern template LogMessage& LogMessage::operator<<(const char& v);
extern template LogMessage& LogMessage::operator<<(const signed char& v);
extern template LogMessage& LogMessage::operator<<(const unsigned char& v);
extern template LogMessage& LogMessage::operator<<(const short& v);
extern template LogMessage& LogMessage::operator<<(const unsigned short& v);
extern template LogMessage& LogMessage::operator<<(const int& v);
extern template LogMessage& LogMessage::operator<<(const unsigned int& v);
extern template LogMessage& LogMessage::operator<<(const long& v);
extern template LogMessage& LogMessage::operator<<(const unsigned long& v);
extern template LogMessage& LogMessage::operator<<(const long long& v);
extern template LogMessage& LogMessage::operator<<(const unsigned long long& v);
extern template LogMessage& LogMessage::operator<<(
    void* absl_nullable const& v);
extern template LogMessage& LogMessage::operator<<(
    const void* absl_nullable const& v);
extern template LogMessage& LogMessage::operator<<(const float& v);
extern template LogMessage& LogMessage::operator<<(const double& v);
extern template LogMessage& LogMessage::operator<<(const bool& v);
// NOLINTEND(google-runtime-int)
// NOLINTEND(runtime/int)

extern template void LogMessage::CopyToEncodedBuffer<
    LogMessage::StringType::kLiteral>(absl::string_view str);
extern template void LogMessage::CopyToEncodedBuffer<
    LogMessage::StringType::kNotLiteral>(absl::string_view str);
extern template void
LogMessage::CopyToEncodedBuffer<LogMessage::StringType::kLiteral>(char ch,
                                                                  size_t num);
extern template void LogMessage::CopyToEncodedBuffer<
    LogMessage::StringType::kNotLiteral>(char ch, size_t num);
extern template void LogMessage::CopyToEncodedBuffer<
    LogMessage::StringType::kLiteral>(std::wstring_view str);
extern template void LogMessage::CopyToEncodedBuffer<
    LogMessage::StringType::kNotLiteral>(std::wstring_view str);

// `LogMessageFatal` ensures the process will exit in failure after logging this
// message.
class LogMessageFatal final : public LogMessage {
 public:
  LogMessageFatal(const char* absl_nonnull file, int line) ABSL_ATTRIBUTE_COLD;
  LogMessageFatal(const char* absl_nonnull file, int line,
                  const char* absl_nonnull failure_msg) ABSL_ATTRIBUTE_COLD;
  [[noreturn]] ~LogMessageFatal();
};

// `LogMessageDebugFatal` ensures the process will exit in failure after logging
// this message. It matches LogMessageFatal but is not [[noreturn]] as it's used
// for DLOG(FATAL) variants.
class LogMessageDebugFatal final : public LogMessage {
 public:
  LogMessageDebugFatal(const char* absl_nonnull file,
                       int line) ABSL_ATTRIBUTE_COLD;
  ~LogMessageDebugFatal();
};

class LogMessageQuietlyDebugFatal final : public LogMessage {
 public:
  // DLOG(QFATAL) calls this instead of LogMessageQuietlyFatal to make sure the
  // destructor is not [[noreturn]] even if this is always FATAL as this is only
  // invoked when DLOG() is enabled.
  LogMessageQuietlyDebugFatal(const char* absl_nonnull file,
                              int line) ABSL_ATTRIBUTE_COLD;
  ~LogMessageQuietlyDebugFatal();
};

// Used for LOG(QFATAL) to make sure it's properly understood as [[noreturn]].
class LogMessageQuietlyFatal final : public LogMessage {
 public:
  LogMessageQuietlyFatal(const char* absl_nonnull file,
                         int line) ABSL_ATTRIBUTE_COLD;
  LogMessageQuietlyFatal(const char* absl_nonnull file, int line,
                         const char* absl_nonnull failure_msg)
      ABSL_ATTRIBUTE_COLD;
  [[noreturn]] ~LogMessageQuietlyFatal();
};

}  // namespace log_internal
ABSL_NAMESPACE_END
}  // namespace absl

extern "C" ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(
    AbslInternalOnFatalLogMessage)(const absl::LogEntry&);

#endif  // ABSL_LOG_INTERNAL_LOG_MESSAGE_H_
*Ô'
rsoong/.intermediates/external/abseil-cpp/absl_log_internal_strip_hdrs/gen/my_include_dir/absl/log/internal/strip.hÝ&// 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/internal/strip.h
// -----------------------------------------------------------------------------

// SKIP_ABSL_INLINE_NAMESPACE_CHECK

#ifndef ABSL_LOG_INTERNAL_STRIP_H_
#define ABSL_LOG_INTERNAL_STRIP_H_

#include "absl/base/attributes.h"  // IWYU pragma: keep
#include "absl/base/log_severity.h"
#include "absl/log/internal/log_message.h"
#include "absl/log/internal/nullstream.h"

// `ABSL_LOGGING_INTERNAL_LOG_*` evaluates to a temporary `LogMessage` object or
// to a related object with a compatible API but different behavior.  This set
// of defines comes in three flavors: vanilla, plus two variants that strip some
// logging in subtly different ways for subtly different reasons (see below).
#if defined(STRIP_LOG) && STRIP_LOG

#define ABSL_LOGGING_INTERNAL_LOG_INFO ::absl::log_internal::NullStream()
#define ABSL_LOGGING_INTERNAL_LOG_WARNING ::absl::log_internal::NullStream()
#define ABSL_LOGGING_INTERNAL_LOG_ERROR ::absl::log_internal::NullStream()
#define ABSL_LOGGING_INTERNAL_LOG_FATAL ::absl::log_internal::NullStreamFatal()
#define ABSL_LOGGING_INTERNAL_LOG_QFATAL ::absl::log_internal::NullStreamFatal()
#define ABSL_LOGGING_INTERNAL_LOG_DFATAL \
  ::absl::log_internal::NullStreamMaybeFatal(::absl::kLogDebugFatal)
#define ABSL_LOGGING_INTERNAL_LOG_LEVEL(severity) \
  ::absl::log_internal::NullStreamMaybeFatal(absl_log_internal_severity)

// Fatal `DLOG`s expand a little differently to avoid being `[[noreturn]]`.
#define ABSL_LOGGING_INTERNAL_DLOG_FATAL \
  ::absl::log_internal::NullStreamMaybeFatal(::absl::LogSeverity::kFatal)
#define ABSL_LOGGING_INTERNAL_DLOG_QFATAL \
  ::absl::log_internal::NullStreamMaybeFatal(::absl::LogSeverity::kFatal)

#define ABSL_LOG_INTERNAL_CHECK(failure_message) ABSL_LOGGING_INTERNAL_LOG_FATAL
#define ABSL_LOG_INTERNAL_QCHECK(failure_message) \
  ABSL_LOGGING_INTERNAL_LOG_QFATAL

#else  // !defined(STRIP_LOG) || !STRIP_LOG

#define ABSL_LOGGING_INTERNAL_LOG_INFO \
  ::absl::log_internal::LogMessage(    \
      __FILE__, __LINE__, ::absl::log_internal::LogMessage::InfoTag{})
#define ABSL_LOGGING_INTERNAL_LOG_WARNING \
  ::absl::log_internal::LogMessage(       \
      __FILE__, __LINE__, ::absl::log_internal::LogMessage::WarningTag{})
#define ABSL_LOGGING_INTERNAL_LOG_ERROR \
  ::absl::log_internal::LogMessage(     \
      __FILE__, __LINE__, ::absl::log_internal::LogMessage::ErrorTag{})
#define ABSL_LOGGING_INTERNAL_LOG_FATAL \
  ::absl::log_internal::LogMessageFatal(__FILE__, __LINE__)
#define ABSL_LOGGING_INTERNAL_LOG_QFATAL \
  ::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__, \
                                   absl_log_internal_severity)

// Fatal `DLOG`s expand a little differently to avoid being `[[noreturn]]`.
#define ABSL_LOGGING_INTERNAL_DLOG_FATAL \
  ::absl::log_internal::LogMessageDebugFatal(__FILE__, __LINE__)
#define ABSL_LOGGING_INTERNAL_DLOG_QFATAL \
  ::absl::log_internal::LogMessageQuietlyDebugFatal(__FILE__, __LINE__)

// 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) \
  ::absl::log_internal::LogMessageFatal(__FILE__, __LINE__, failure_message)
#define ABSL_LOG_INTERNAL_QCHECK(failure_message)                  \
  ::absl::log_internal::LogMessageQuietlyFatal(__FILE__, __LINE__, \
                                               failure_message)
#endif  // !defined(STRIP_LOG) || !STRIP_LOG

// This part of a non-fatal `DLOG`s expands the same as `LOG`.
#define ABSL_LOGGING_INTERNAL_DLOG_INFO ABSL_LOGGING_INTERNAL_LOG_INFO
#define ABSL_LOGGING_INTERNAL_DLOG_WARNING ABSL_LOGGING_INTERNAL_LOG_WARNING
#define ABSL_LOGGING_INTERNAL_DLOG_ERROR ABSL_LOGGING_INTERNAL_LOG_ERROR
#define ABSL_LOGGING_INTERNAL_DLOG_DFATAL ABSL_LOGGING_INTERNAL_LOG_DFATAL
#define ABSL_LOGGING_INTERNAL_DLOG_LEVEL ABSL_LOGGING_INTERNAL_LOG_LEVEL

#define ABSL_LOGGING_INTERNAL_LOG_DO_NOT_SUBMIT ABSL_LOGGING_INTERNAL_LOG_ERROR

#endif  // ABSL_LOG_INTERNAL_STRIP_H_
*· 
|soong/.intermediates/external/abseil-cpp/absl_log_internal_nullstream_hdrs/gen/my_include_dir/absl/log/internal/nullstream.h¶// 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/internal/nullstream.h
// -----------------------------------------------------------------------------
//
// Classes `NullStream`, `NullStreamMaybeFatal ` and `NullStreamFatal`
// implement a subset of the `LogMessage` API and are used instead when logging
// of messages has been disabled.

#ifndef ABSL_LOG_INTERNAL_NULLSTREAM_H_
#define ABSL_LOG_INTERNAL_NULLSTREAM_H_

#ifdef _WIN32
#include <cstdlib>
#else
#include <unistd.h>
#endif
#include <ios>
#include <ostream>

#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/log_severity.h"
#include "absl/strings/string_view.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace log_internal {

// A `NullStream` implements the API of `LogMessage` (a few methods and
// `operator<<`) but does nothing.  All methods are defined inline so the
// compiler can eliminate the whole instance and discard anything that's
// streamed in.
class NullStream {
 public:
  NullStream& AtLocation(absl::string_view, int) { return *this; }
  template <typename SourceLocationType>
  NullStream& AtLocation(SourceLocationType) {
    return *this;
  }
  NullStream& NoPrefix() { return *this; }
  NullStream& WithVerbosity(int) { return *this; }
  template <typename TimeType>
  NullStream& WithTimestamp(TimeType) {
    return *this;
  }
  template <typename Tid>
  NullStream& WithThreadID(Tid) {
    return *this;
  }
  template <typename LogEntryType>
  NullStream& WithMetadataFrom(const LogEntryType&) {
    return *this;
  }
  NullStream& WithPerror() { return *this; }
  template <typename LogSinkType>
  NullStream& ToSinkAlso(LogSinkType*) {
    return *this;
  }
  template <typename LogSinkType>
  NullStream& ToSinkOnly(LogSinkType*) {
    return *this;
  }
  template <typename LogSinkType>
  NullStream& OutputToSink(LogSinkType*, bool) {
    return *this;
  }
  NullStream& InternalStream() { return *this; }
  void Flush() {}
};
template <typename T>
inline NullStream& operator<<(NullStream& str, const T&) {
  return str;
}
inline NullStream& operator<<(NullStream& str,
                              std::ostream& (*)(std::ostream& os)) {
  return str;
}
inline NullStream& operator<<(NullStream& str,
                              std::ios_base& (*)(std::ios_base& os)) {
  return str;
}

// `NullStreamMaybeFatal` implements the process termination semantics of
// `LogMessage`, which is used for `DFATAL` severity and expression-defined
// severity e.g. `LOG(LEVEL(HowBadIsIt()))`.  Like `LogMessage`, it terminates
// the process when destroyed if the passed-in severity equals `FATAL`.
class NullStreamMaybeFatal final : public NullStream {
 public:
  explicit NullStreamMaybeFatal(absl::LogSeverity severity)
      : fatal_(severity == absl::LogSeverity::kFatal) {}
  ~NullStreamMaybeFatal() {
    if (fatal_) {
      _exit(1);
    }
  }

 private:
  bool fatal_;
};

// `NullStreamFatal` implements the process termination semantics of
// `LogMessageFatal`, which means it always terminates the process.  `DFATAL`
// and expression-defined severity use `NullStreamMaybeFatal` above.
class NullStreamFatal final : public NullStream {
 public:
  NullStreamFatal() = default;
  [[noreturn]] ~NullStreamFatal() { _exit(1); }
};

}  // namespace log_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_LOG_INTERNAL_GLOBALS_H_
*�
zsoong/.intermediates/external/abseil-cpp/absl_log_internal_nullguard_hdrs/gen/my_include_dir/absl/log/internal/nullguard.hž// 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/internal/nullguard.h
// -----------------------------------------------------------------------------
//
// NullGuard exists such that NullGuard<T>::Guard(v) returns v, unless passed a
// nullptr_t, or a null char* or const char*, in which case it returns "(null)".
// This allows streaming NullGuard<T>::Guard(v) to an output stream without
// hitting undefined behavior for null values.

#ifndef ABSL_LOG_INTERNAL_NULLGUARD_H_
#define ABSL_LOG_INTERNAL_NULLGUARD_H_

#include <array>
#include <cstddef>

#include "absl/base/attributes.h"
#include "absl/base/config.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace log_internal {

ABSL_CONST_INIT ABSL_DLL extern const std::array<char, 7> kCharNull;
ABSL_CONST_INIT ABSL_DLL extern const std::array<signed char, 7>
    kSignedCharNull;
ABSL_CONST_INIT ABSL_DLL extern const std::array<unsigned char, 7>
    kUnsignedCharNull;

template <typename T>
struct NullGuard final {
  static const T& Guard(const T& v) { return v; }
};
template <>
struct NullGuard<char*> final {
  static const char* Guard(const char* v) { return v ? v : kCharNull.data(); }
};
template <>
struct NullGuard<const char*> final {
  static const char* Guard(const char* v) { return v ? v : kCharNull.data(); }
};
template <>
struct NullGuard<signed char*> final {
  static const signed char* Guard(const signed char* v) {
    return v ? v : kSignedCharNull.data();
  }
};
template <>
struct NullGuard<const signed char*> final {
  static const signed char* Guard(const signed char* v) {
    return v ? v : kSignedCharNull.data();
  }
};
template <>
struct NullGuard<unsigned char*> final {
  static const unsigned char* Guard(const unsigned char* v) {
    return v ? v : kUnsignedCharNull.data();
  }
};
template <>
struct NullGuard<const unsigned char*> final {
  static const unsigned char* Guard(const unsigned char* v) {
    return v ? v : kUnsignedCharNull.data();
  }
};
template <>
struct NullGuard<std::nullptr_t> final {
  static const char* Guard(const std::nullptr_t&) { return kCharNull.data(); }
};

}  // namespace log_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_LOG_INTERNAL_NULLGUARD_H_
*’8
\soong/.intermediates/external/abseil-cpp/absl_base_hdrs/gen/my_include_dir/absl/base/casts.h±7//
// 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.
//
// -----------------------------------------------------------------------------
// File: casts.h
// -----------------------------------------------------------------------------
//
// This header file defines casting templates to fit use cases not covered by
// the standard casts provided in the C++ standard. As with all cast operations,
// use these with caution and only if alternatives do not exist.

#ifndef ABSL_BASE_CASTS_H_
#define ABSL_BASE_CASTS_H_

#include <cstring>
#include <memory>
#include <type_traits>
#include <utility>

#if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L
#include <bit>  // For std::bit_cast.
#endif  // defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L

#include "absl/base/internal/identity.h"
#include "absl/base/macros.h"
#include "absl/meta/type_traits.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

// implicit_cast()
//
// Performs an implicit conversion between types following the language
// rules for implicit conversion; if an implicit conversion is otherwise
// allowed by the language in the given context, this function performs such an
// implicit conversion.
//
// Example:
//
//   // If the context allows implicit conversion:
//   From from;
//   To to = from;
//
//   // Such code can be replaced by:
//   implicit_cast<To>(from);
//
// An `implicit_cast()` may also be used to annotate numeric type conversions
// that, although safe, may produce compiler warnings (such as `long` to `int`).
// Additionally, an `implicit_cast()` is also useful within return statements to
// indicate a specific implicit conversion is being undertaken.
//
// Example:
//
//   return implicit_cast<double>(size_in_bytes) / capacity_;
//
// Annotating code with `implicit_cast()` allows you to explicitly select
// particular overloads and template instantiations, while providing a safer
// cast than `reinterpret_cast()` or `static_cast()`.
//
// Additionally, an `implicit_cast()` can be used to allow upcasting within a
// type hierarchy where incorrect use of `static_cast()` could accidentally
// allow downcasting.
//
// Finally, an `implicit_cast()` can be used to perform implicit conversions
// from unrelated types that otherwise couldn't be implicitly cast directly;
// C++ will normally only implicitly cast "one step" in such conversions.
//
// That is, if C is a type which can be implicitly converted to B, with B being
// a type that can be implicitly converted to A, an `implicit_cast()` can be
// used to convert C to B (which the compiler can then implicitly convert to A
// using language rules).
//
// Example:
//
//   // Assume an object C is convertible to B, which is implicitly convertible
//   // to A
//   A a = implicit_cast<B>(C);
//
// Such implicit cast chaining may be useful within template logic.
template <typename To>
constexpr To implicit_cast(typename absl::internal::type_identity_t<To> to) {
  return to;
}

// bit_cast()
//
// Creates a value of the new type `Dest` whose representation is the same as
// that of the argument, which is of (deduced) type `Source` (a "bitwise cast";
// every bit in the value representation of the result is equal to the
// corresponding bit in the object representation of the source). Source and
// destination types must be of the same size, and both types must be trivially
// copyable.
//
// As with most casts, use with caution. A `bit_cast()` might be needed when you
// need to treat a value as the value of some other type, for example, to access
// the individual bits of an object which are not normally accessible through
// the object's type, such as for working with the binary representation of a
// floating point value:
//
//   float f = 3.14159265358979;
//   int i = bit_cast<int>(f);
//   // i = 0x40490fdb
//
// Reinterpreting and accessing a value directly as a different type (as shown
// below) usually results in undefined behavior.
//
// Example:
//
//   // WRONG
//   float f = 3.14159265358979;
//   int i = reinterpret_cast<int&>(f);    // Wrong
//   int j = *reinterpret_cast<int*>(&f);  // Equally wrong
//   int k = *bit_cast<int*>(&f);          // Equally wrong
//
// Reinterpret-casting results in undefined behavior according to the ISO C++
// specification, section [basic.lval]. Roughly, this section says: if an object
// in memory has one type, and a program accesses it with a different type, the
// result is undefined behavior for most "different type".
//
// Using bit_cast on a pointer and then dereferencing it is no better than using
// reinterpret_cast. You should only use bit_cast on the value itself.
//
// Such casting results in type punning: holding an object in memory of one type
// and reading its bits back using a different type. A `bit_cast()` avoids this
// issue by copying the object representation to a new value, which avoids
// introducing this undefined behavior (since the original value is never
// accessed in the wrong way).
//
// The requirements of `absl::bit_cast` are more strict than that of
// `std::bit_cast` unless compiler support is available. Specifically, without
// compiler support, this implementation also requires `Dest` to be
// default-constructible. In C++20, `absl::bit_cast` is replaced by
// `std::bit_cast`.
#if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L

using std::bit_cast;

#else  // defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L

template <
    typename Dest, typename Source,
    typename std::enable_if<sizeof(Dest) == sizeof(Source) &&
                                std::is_trivially_copyable<Source>::value &&
                                std::is_trivially_copyable<Dest>::value
#if !ABSL_HAVE_BUILTIN(__builtin_bit_cast)
                                && std::is_default_constructible<Dest>::value
#endif  // !ABSL_HAVE_BUILTIN(__builtin_bit_cast)
                            ,
                            int>::type = 0>
#if ABSL_HAVE_BUILTIN(__builtin_bit_cast)
inline constexpr Dest bit_cast(const Source& source) {
  return __builtin_bit_cast(Dest, source);
}
#else  // ABSL_HAVE_BUILTIN(__builtin_bit_cast)
inline Dest bit_cast(const Source& source) {
  Dest dest;
  memcpy(static_cast<void*>(std::addressof(dest)),
         static_cast<const void*>(std::addressof(source)), sizeof(dest));
  return dest;
}
#endif  // ABSL_HAVE_BUILTIN(__builtin_bit_cast)

#endif  // defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_BASE_CASTS_H_
*¸A
|soong/.intermediates/external/abseil-cpp/absl_log_internal_check_impl_hdrs/gen/my_include_dir/absl/log/internal/check_impl.h·@// 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.

#ifndef ABSL_LOG_INTERNAL_CHECK_IMPL_H_
#define ABSL_LOG_INTERNAL_CHECK_IMPL_H_

#include "absl/base/optimization.h"
#include "absl/log/internal/check_op.h"
#include "absl/log/internal/conditions.h"
#include "absl/log/internal/log_message.h"
#include "absl/log/internal/strip.h"

// CHECK
#define ABSL_LOG_INTERNAL_CHECK_IMPL(condition, condition_text)       \
  ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS,                        \
                                    ABSL_PREDICT_FALSE(!(condition))) \
  ABSL_LOG_INTERNAL_CHECK(condition_text).InternalStream()

#define ABSL_LOG_INTERNAL_QCHECK_IMPL(condition, condition_text)       \
  ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS,                        \
                                     ABSL_PREDICT_FALSE(!(condition))) \
  ABSL_LOG_INTERNAL_QCHECK(condition_text).InternalStream()

#define ABSL_LOG_INTERNAL_PCHECK_IMPL(condition, condition_text) \
  ABSL_LOG_INTERNAL_CHECK_IMPL(condition, condition_text).WithPerror()

#ifndef NDEBUG
#define ABSL_LOG_INTERNAL_DCHECK_IMPL(condition, condition_text) \
  ABSL_LOG_INTERNAL_CHECK_IMPL(condition, condition_text)
#else
#define ABSL_LOG_INTERNAL_DCHECK_IMPL(condition, condition_text) \
  ABSL_LOG_INTERNAL_CHECK_IMPL(true || (condition), "true")
#endif

// CHECK_EQ
#define ABSL_LOG_INTERNAL_CHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_CHECK_OP(Check_EQ, ==, val1, val1_text, val2, val2_text)
#define ABSL_LOG_INTERNAL_CHECK_NE_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_CHECK_OP(Check_NE, !=, val1, val1_text, val2, val2_text)
#define ABSL_LOG_INTERNAL_CHECK_LE_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_CHECK_OP(Check_LE, <=, val1, val1_text, val2, val2_text)
#define ABSL_LOG_INTERNAL_CHECK_LT_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_CHECK_OP(Check_LT, <, val1, val1_text, val2, val2_text)
#define ABSL_LOG_INTERNAL_CHECK_GE_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_CHECK_OP(Check_GE, >=, val1, val1_text, val2, val2_text)
#define ABSL_LOG_INTERNAL_CHECK_GT_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_CHECK_OP(Check_GT, >, val1, val1_text, val2, val2_text)
#define ABSL_LOG_INTERNAL_QCHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_QCHECK_OP(Check_EQ, ==, val1, val1_text, val2, val2_text)
#define ABSL_LOG_INTERNAL_QCHECK_NE_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_QCHECK_OP(Check_NE, !=, val1, val1_text, val2, val2_text)
#define ABSL_LOG_INTERNAL_QCHECK_LE_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_QCHECK_OP(Check_LE, <=, val1, val1_text, val2, val2_text)
#define ABSL_LOG_INTERNAL_QCHECK_LT_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_QCHECK_OP(Check_LT, <, val1, val1_text, val2, val2_text)
#define ABSL_LOG_INTERNAL_QCHECK_GE_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_QCHECK_OP(Check_GE, >=, val1, val1_text, val2, val2_text)
#define ABSL_LOG_INTERNAL_QCHECK_GT_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_QCHECK_OP(Check_GT, >, val1, val1_text, val2, val2_text)
#ifndef NDEBUG
#define ABSL_LOG_INTERNAL_DCHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_CHECK_EQ_IMPL(val1, val1_text, val2, val2_text)
#define ABSL_LOG_INTERNAL_DCHECK_NE_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_CHECK_NE_IMPL(val1, val1_text, val2, val2_text)
#define ABSL_LOG_INTERNAL_DCHECK_LE_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_CHECK_LE_IMPL(val1, val1_text, val2, val2_text)
#define ABSL_LOG_INTERNAL_DCHECK_LT_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_CHECK_LT_IMPL(val1, val1_text, val2, val2_text)
#define ABSL_LOG_INTERNAL_DCHECK_GE_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_CHECK_GE_IMPL(val1, val1_text, val2, val2_text)
#define ABSL_LOG_INTERNAL_DCHECK_GT_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_CHECK_GT_IMPL(val1, val1_text, val2, val2_text)
#else  // ndef NDEBUG
#define ABSL_LOG_INTERNAL_DCHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2)
#define ABSL_LOG_INTERNAL_DCHECK_NE_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2)
#define ABSL_LOG_INTERNAL_DCHECK_LE_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2)
#define ABSL_LOG_INTERNAL_DCHECK_LT_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2)
#define ABSL_LOG_INTERNAL_DCHECK_GE_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2)
#define ABSL_LOG_INTERNAL_DCHECK_GT_IMPL(val1, val1_text, val2, val2_text) \
  ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2)
#endif  // def NDEBUG

// CHECK_OK
#define ABSL_LOG_INTERNAL_CHECK_OK_IMPL(status, status_text) \
  ABSL_LOG_INTERNAL_CHECK_OK(status, status_text)
#define ABSL_LOG_INTERNAL_QCHECK_OK_IMPL(status, status_text) \
  ABSL_LOG_INTERNAL_QCHECK_OK(status, status_text)
#ifndef NDEBUG
#define ABSL_LOG_INTERNAL_DCHECK_OK_IMPL(status, status_text) \
  ABSL_LOG_INTERNAL_CHECK_OK(status, status_text)
#else
#define ABSL_LOG_INTERNAL_DCHECK_OK_IMPL(status, status_text) \
  ABSL_LOG_INTERNAL_DCHECK_NOP(status, nullptr)
#endif

// CHECK_STREQ
#define ABSL_LOG_INTERNAL_CHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \
  ABSL_LOG_INTERNAL_CHECK_STROP(strcmp, ==, true, s1, s1_text, s2, s2_text)
#define ABSL_LOG_INTERNAL_CHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \
  ABSL_LOG_INTERNAL_CHECK_STROP(strcmp, !=, false, s1, s1_text, s2, s2_text)
#define ABSL_LOG_INTERNAL_CHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \
  ABSL_LOG_INTERNAL_CHECK_STROP(strcasecmp, ==, true, s1, s1_text, s2, s2_text)
#define ABSL_LOG_INTERNAL_CHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \
  ABSL_LOG_INTERNAL_CHECK_STROP(strcasecmp, !=, false, s1, s1_text, s2, s2_text)
#define ABSL_LOG_INTERNAL_QCHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \
  ABSL_LOG_INTERNAL_QCHECK_STROP(strcmp, ==, true, s1, s1_text, s2, s2_text)
#define ABSL_LOG_INTERNAL_QCHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \
  ABSL_LOG_INTERNAL_QCHECK_STROP(strcmp, !=, false, s1, s1_text, s2, s2_text)
#define ABSL_LOG_INTERNAL_QCHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \
  ABSL_LOG_INTERNAL_QCHECK_STROP(strcasecmp, ==, true, s1, s1_text, s2, s2_text)
#define ABSL_LOG_INTERNAL_QCHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \
  ABSL_LOG_INTERNAL_QCHECK_STROP(strcasecmp, !=, false, s1, s1_text, s2,  \
                                 s2_text)
#ifndef NDEBUG
#define ABSL_LOG_INTERNAL_DCHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \
  ABSL_LOG_INTERNAL_CHECK_STREQ_IMPL(s1, s1_text, s2, s2_text)
#define ABSL_LOG_INTERNAL_DCHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \
  ABSL_LOG_INTERNAL_CHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text)
#define ABSL_LOG_INTERNAL_DCHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \
  ABSL_LOG_INTERNAL_CHECK_STRNE_IMPL(s1, s1_text, s2, s2_text)
#define ABSL_LOG_INTERNAL_DCHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \
  ABSL_LOG_INTERNAL_CHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text)
#else  // ndef NDEBUG
#define ABSL_LOG_INTERNAL_DCHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \
  ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2)
#define ABSL_LOG_INTERNAL_DCHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \
  ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2)
#define ABSL_LOG_INTERNAL_DCHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \
  ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2)
#define ABSL_LOG_INTERNAL_DCHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \
  ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2)
#endif  // def NDEBUG

#endif  // ABSL_LOG_INTERNAL_CHECK_IMPL_H_
*Á+
jsoong/.intermediates/external/abseil-cpp/absl_log_absl_check_hdrs/gen/my_include_dir/absl/log/absl_check.hÒ*// 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_check.h
// -----------------------------------------------------------------------------
//
// This header declares a family of `ABSL_CHECK` macros as alternative spellings
// for `CHECK` macros in `check.h`.
//
// Except for those whose names begin with `ABSL_DCHECK`, these macros are not
// controlled by `NDEBUG` (cf. `assert`), so the check will be executed
// regardless of compilation mode. `ABSL_CHECK` and friends are thus useful for
// confirming invariants in situations where continuing to run would be worse
// than terminating, e.g., due to risk of data corruption or security
// compromise.  It is also more robust and portable to deliberately terminate
// at a particular place with a useful message and backtrace than to assume some
// ultimately unspecified and unreliable crashing behavior (such as a
// "segmentation fault").
//
// For full documentation of each macro, see comments in `check.h`, which has an
// identical set of macros without the ABSL_* prefix.

#ifndef ABSL_LOG_ABSL_CHECK_H_
#define ABSL_LOG_ABSL_CHECK_H_

#include "absl/log/internal/check_impl.h"

#define ABSL_CHECK(condition) \
  ABSL_LOG_INTERNAL_CHECK_IMPL((condition), #condition)
#define ABSL_QCHECK(condition) \
  ABSL_LOG_INTERNAL_QCHECK_IMPL((condition), #condition)
#define ABSL_PCHECK(condition) \
  ABSL_LOG_INTERNAL_PCHECK_IMPL((condition), #condition)
#define ABSL_DCHECK(condition) \
  ABSL_LOG_INTERNAL_DCHECK_IMPL((condition), #condition)

#define ABSL_CHECK_EQ(val1, val2) \
  ABSL_LOG_INTERNAL_CHECK_EQ_IMPL((val1), #val1, (val2), #val2)
#define ABSL_CHECK_NE(val1, val2) \
  ABSL_LOG_INTERNAL_CHECK_NE_IMPL((val1), #val1, (val2), #val2)
#define ABSL_CHECK_LE(val1, val2) \
  ABSL_LOG_INTERNAL_CHECK_LE_IMPL((val1), #val1, (val2), #val2)
#define ABSL_CHECK_LT(val1, val2) \
  ABSL_LOG_INTERNAL_CHECK_LT_IMPL((val1), #val1, (val2), #val2)
#define ABSL_CHECK_GE(val1, val2) \
  ABSL_LOG_INTERNAL_CHECK_GE_IMPL((val1), #val1, (val2), #val2)
#define ABSL_CHECK_GT(val1, val2) \
  ABSL_LOG_INTERNAL_CHECK_GT_IMPL((val1), #val1, (val2), #val2)
#define ABSL_QCHECK_EQ(val1, val2) \
  ABSL_LOG_INTERNAL_QCHECK_EQ_IMPL((val1), #val1, (val2), #val2)
#define ABSL_QCHECK_NE(val1, val2) \
  ABSL_LOG_INTERNAL_QCHECK_NE_IMPL((val1), #val1, (val2), #val2)
#define ABSL_QCHECK_LE(val1, val2) \
  ABSL_LOG_INTERNAL_QCHECK_LE_IMPL((val1), #val1, (val2), #val2)
#define ABSL_QCHECK_LT(val1, val2) \
  ABSL_LOG_INTERNAL_QCHECK_LT_IMPL((val1), #val1, (val2), #val2)
#define ABSL_QCHECK_GE(val1, val2) \
  ABSL_LOG_INTERNAL_QCHECK_GE_IMPL((val1), #val1, (val2), #val2)
#define ABSL_QCHECK_GT(val1, val2) \
  ABSL_LOG_INTERNAL_QCHECK_GT_IMPL((val1), #val1, (val2), #val2)
#define ABSL_DCHECK_EQ(val1, val2) \
  ABSL_LOG_INTERNAL_DCHECK_EQ_IMPL((val1), #val1, (val2), #val2)
#define ABSL_DCHECK_NE(val1, val2) \
  ABSL_LOG_INTERNAL_DCHECK_NE_IMPL((val1), #val1, (val2), #val2)
#define ABSL_DCHECK_LE(val1, val2) \
  ABSL_LOG_INTERNAL_DCHECK_LE_IMPL((val1), #val1, (val2), #val2)
#define ABSL_DCHECK_LT(val1, val2) \
  ABSL_LOG_INTERNAL_DCHECK_LT_IMPL((val1), #val1, (val2), #val2)
#define ABSL_DCHECK_GE(val1, val2) \
  ABSL_LOG_INTERNAL_DCHECK_GE_IMPL((val1), #val1, (val2), #val2)
#define ABSL_DCHECK_GT(val1, val2) \
  ABSL_LOG_INTERNAL_DCHECK_GT_IMPL((val1), #val1, (val2), #val2)

#define ABSL_CHECK_OK(status) ABSL_LOG_INTERNAL_CHECK_OK_IMPL((status), #status)
#define ABSL_QCHECK_OK(status) \
  ABSL_LOG_INTERNAL_QCHECK_OK_IMPL((status), #status)
#define ABSL_DCHECK_OK(status) \
  ABSL_LOG_INTERNAL_DCHECK_OK_IMPL((status), #status)

#define ABSL_CHECK_STREQ(s1, s2) \
  ABSL_LOG_INTERNAL_CHECK_STREQ_IMPL((s1), #s1, (s2), #s2)
#define ABSL_CHECK_STRNE(s1, s2) \
  ABSL_LOG_INTERNAL_CHECK_STRNE_IMPL((s1), #s1, (s2), #s2)
#define ABSL_CHECK_STRCASEEQ(s1, s2) \
  ABSL_LOG_INTERNAL_CHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2)
#define ABSL_CHECK_STRCASENE(s1, s2) \
  ABSL_LOG_INTERNAL_CHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2)
#define ABSL_QCHECK_STREQ(s1, s2) \
  ABSL_LOG_INTERNAL_QCHECK_STREQ_IMPL((s1), #s1, (s2), #s2)
#define ABSL_QCHECK_STRNE(s1, s2) \
  ABSL_LOG_INTERNAL_QCHECK_STRNE_IMPL((s1), #s1, (s2), #s2)
#define ABSL_QCHECK_STRCASEEQ(s1, s2) \
  ABSL_LOG_INTERNAL_QCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2)
#define ABSL_QCHECK_STRCASENE(s1, s2) \
  ABSL_LOG_INTERNAL_QCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2)
#define ABSL_DCHECK_STREQ(s1, s2) \
  ABSL_LOG_INTERNAL_DCHECK_STREQ_IMPL((s1), #s1, (s2), #s2)
#define ABSL_DCHECK_STRNE(s1, s2) \
  ABSL_LOG_INTERNAL_DCHECK_STRNE_IMPL((s1), #s1, (s2), #s2)
#define ABSL_DCHECK_STRCASEEQ(s1, s2) \
  ABSL_LOG_INTERNAL_DCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2)
#define ABSL_DCHECK_STRCASENE(s1, s2) \
  ABSL_LOG_INTERNAL_DCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2)

#endif  // ABSL_LOG_ABSL_CHECK_H_
*Õ`
psoong/.intermediates/external/abseil-cpp/absl_base_core_headers_hdrs/gen/my_include_dir/absl/base/optimization.hà_//
// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// File: optimization.h
// -----------------------------------------------------------------------------
//
// This header file defines portable macros for performance optimization.
//
// This header is included in both C++ code and legacy C code and thus must
// remain compatible with both C and C++. C compatibility will be removed if
// the legacy code is removed or converted to C++. Do not include this header in
// new code that requires C compatibility or assume C compatibility will remain
// indefinitely.

// SKIP_ABSL_INLINE_NAMESPACE_CHECK

#ifndef ABSL_BASE_OPTIMIZATION_H_
#define ABSL_BASE_OPTIMIZATION_H_

#include <assert.h>

#ifdef __cplusplus
// Included for std::unreachable()
#include <utility>
#endif  // __cplusplus

#include "absl/base/config.h"
#include "absl/base/options.h"

// ABSL_BLOCK_TAIL_CALL_OPTIMIZATION
//
// Instructs the compiler to avoid optimizing tail-call recursion. This macro is
// useful when you wish to preserve the existing function order within a stack
// trace for logging, debugging, or profiling purposes.
//
// Example:
//
//   int f() {
//     int result = g();
//     ABSL_BLOCK_TAIL_CALL_OPTIMIZATION();
//     return result;
//   }
#if defined(__pnacl__)
#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; }
#elif defined(__clang__)
// Clang will not tail call given inline volatile assembly.
#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("")
#elif defined(__GNUC__)
// GCC will not tail call given inline volatile assembly.
#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("")
#elif defined(_MSC_VER)
#include <intrin.h>
// The __nop() intrinsic blocks the optimisation.
#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __nop()
#else
#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; }
#endif

// ABSL_CACHELINE_SIZE
//
// Explicitly defines the size of the L1 cache for purposes of alignment.
// Setting the cacheline size allows you to specify that certain objects be
// aligned on a cacheline boundary with `ABSL_CACHELINE_ALIGNED` declarations.
// (See below.)
//
// NOTE: this macro should be replaced with the following C++17 features, when
// those are generally available:
//
//   * `std::hardware_constructive_interference_size`
//   * `std::hardware_destructive_interference_size`
//
// See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0154r1.html
// for more information.
#if defined(__GNUC__)
// Cache line alignment
#if defined(__i386__) || defined(__x86_64__)
#define ABSL_CACHELINE_SIZE 64
#elif defined(__powerpc64__)
#define ABSL_CACHELINE_SIZE 128
#elif defined(__aarch64__)
// We would need to read special register ctr_el0 to find out L1 dcache size.
// This value is a good estimate based on a real aarch64 machine.
#define ABSL_CACHELINE_SIZE 64
#elif defined(__arm__)
// Cache line sizes for ARM: These values are not strictly correct since
// cache line sizes depend on implementations, not architectures.  There
// are even implementations with cache line sizes configurable at boot
// time.
#if defined(__ARM_ARCH_5T__)
#define ABSL_CACHELINE_SIZE 32
#elif defined(__ARM_ARCH_7A__)
#define ABSL_CACHELINE_SIZE 64
#endif
#endif
#endif

#ifndef ABSL_CACHELINE_SIZE
// A reasonable default guess.  Note that overestimates tend to waste more
// space, while underestimates tend to waste more time.
#define ABSL_CACHELINE_SIZE 64
#endif

// ABSL_CACHELINE_ALIGNED
//
// Indicates that the declared object be cache aligned using
// `ABSL_CACHELINE_SIZE` (see above). Cacheline aligning objects allows you to
// load a set of related objects in the L1 cache for performance improvements.
// Cacheline aligning objects properly allows constructive memory sharing and
// prevents destructive (or "false") memory sharing.
//
// NOTE: callers should replace uses of this macro with `alignas()` using
// `std::hardware_constructive_interference_size` and/or
// `std::hardware_destructive_interference_size` when C++17 becomes available to
// them.
//
// See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0154r1.html
// for more information.
//
// On some compilers, `ABSL_CACHELINE_ALIGNED` expands to an `__attribute__`
// or `__declspec` attribute. For compilers where this is not known to work,
// the macro expands to nothing.
//
// No further guarantees are made here. The result of applying the macro
// to variables and types is always implementation-defined.
//
// WARNING: It is easy to use this attribute incorrectly, even to the point
// of causing bugs that are difficult to diagnose, crash, etc. It does not
// of itself guarantee that objects are aligned to a cache line.
//
// NOTE: Some compilers are picky about the locations of annotations such as
// this attribute, so prefer to put it at the beginning of your declaration.
// For example,
//
//   ABSL_CACHELINE_ALIGNED static Foo* foo = ...
//
//   class ABSL_CACHELINE_ALIGNED Bar { ...
//
// Recommendations:
//
// 1) Consult compiler documentation; this comment is not kept in sync as
//    toolchains evolve.
// 2) Verify your use has the intended effect. This often requires inspecting
//    the generated machine code.
// 3) Prefer applying this attribute to individual variables. Avoid
//    applying it to types. This tends to localize the effect.
#if defined(__clang__) || defined(__GNUC__)
#define ABSL_CACHELINE_ALIGNED __attribute__((aligned(ABSL_CACHELINE_SIZE)))
#elif defined(_MSC_VER)
#define ABSL_CACHELINE_ALIGNED __declspec(align(ABSL_CACHELINE_SIZE))
#else
#define ABSL_CACHELINE_ALIGNED
#endif

// ABSL_PREDICT_TRUE, ABSL_PREDICT_FALSE
//
// Enables the compiler to prioritize compilation using static analysis for
// likely paths within a boolean branch.
//
// Example:
//
//   if (ABSL_PREDICT_TRUE(expression)) {
//     return result;                        // Faster if more likely
//   } else {
//     return 0;
//   }
//
// Compilers can use the information that a certain branch is not likely to be
// taken (for instance, a CHECK failure) to optimize for the common case in
// the absence of better information (ie. compiling gcc with `-fprofile-arcs`).
//
// Recommendation: Modern CPUs dynamically predict branch execution paths,
// typically with accuracy greater than 97%. As a result, annotating every
// branch in a codebase is likely counterproductive; however, annotating
// specific branches that are both hot and consistently mispredicted is likely
// to yield performance improvements.
#if ABSL_HAVE_BUILTIN(__builtin_expect) || \
    (defined(__GNUC__) && !defined(__clang__))
#define ABSL_PREDICT_FALSE(x) (__builtin_expect(false || (x), false))
#define ABSL_PREDICT_TRUE(x) (__builtin_expect(false || (x), true))
#else
#define ABSL_PREDICT_FALSE(x) (x)
#define ABSL_PREDICT_TRUE(x) (x)
#endif

// `ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL()` aborts the program in the fastest
// possible way, with no attempt at logging. One use is to implement hardening
// aborts with ABSL_OPTION_HARDENED.  Since this is an internal symbol, it
// should not be used directly outside of Abseil.
#if ABSL_HAVE_BUILTIN(__builtin_trap) || \
    (defined(__GNUC__) && !defined(__clang__))
#define ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL() __builtin_trap()
#else
#define ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL() abort()
#endif

// `ABSL_INTERNAL_UNREACHABLE_IMPL()` is the platform specific directive to
// indicate that a statement is unreachable, and to allow the compiler to
// optimize accordingly. Clients should use `ABSL_UNREACHABLE()`, which is
// defined below.
#if defined(__cpp_lib_unreachable) && __cpp_lib_unreachable >= 202202L
#define ABSL_INTERNAL_UNREACHABLE_IMPL() std::unreachable()
#elif defined(__GNUC__) || ABSL_HAVE_BUILTIN(__builtin_unreachable)
#define ABSL_INTERNAL_UNREACHABLE_IMPL() __builtin_unreachable()
#elif ABSL_HAVE_BUILTIN(__builtin_assume)
#define ABSL_INTERNAL_UNREACHABLE_IMPL() __builtin_assume(false)
#elif defined(_MSC_VER)
#define ABSL_INTERNAL_UNREACHABLE_IMPL() __assume(false)
#else
#define ABSL_INTERNAL_UNREACHABLE_IMPL()
#endif

// `ABSL_UNREACHABLE()` is an unreachable statement.  A program which reaches
// one has undefined behavior, and the compiler may optimize accordingly.
#if ABSL_OPTION_HARDENED == 1 && defined(NDEBUG)
// Abort in hardened mode to avoid dangerous undefined behavior.
#define ABSL_UNREACHABLE()                \
  do {                                    \
    ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL(); \
    ABSL_INTERNAL_UNREACHABLE_IMPL();     \
  } while (false)
#else
// The assert only fires in debug mode to aid in debugging.
// When NDEBUG is defined, reaching ABSL_UNREACHABLE() is undefined behavior.
#define ABSL_UNREACHABLE()                       \
  do {                                           \
    /* NOLINTNEXTLINE: misc-static-assert */     \
    assert(false && "ABSL_UNREACHABLE reached"); \
    ABSL_INTERNAL_UNREACHABLE_IMPL();            \
  } while (false)
#endif

// ABSL_ASSUME(cond)
//
// Informs the compiler that a condition is always true and that it can assume
// it to be true for optimization purposes.
//
// WARNING: If the condition is false, the program can produce undefined and
// potentially dangerous behavior.
//
// In !NDEBUG mode, the condition is checked with an assert().
//
// NOTE: The expression must not have side effects, as it may only be evaluated
// in some compilation modes and not others. Some compilers may issue a warning
// if the compiler cannot prove the expression has no side effects. For example,
// the expression should not use a function call since the compiler cannot prove
// that a function call does not have side effects.
//
// Example:
//
//   int x = ...;
//   ABSL_ASSUME(x >= 0);
//   // The compiler can optimize the division to a simple right shift using the
//   // assumption specified above.
//   int y = x / 16;
//
#if !defined(NDEBUG)
#define ABSL_ASSUME(cond) assert(cond)
#elif ABSL_HAVE_BUILTIN(__builtin_assume)
#define ABSL_ASSUME(cond) __builtin_assume(cond)
#elif defined(_MSC_VER)
#define ABSL_ASSUME(cond) __assume(cond)
#elif defined(__cpp_lib_unreachable) && __cpp_lib_unreachable >= 202202L
#define ABSL_ASSUME(cond) ((cond) ? void() : std::unreachable())
#elif defined(__GNUC__) || ABSL_HAVE_BUILTIN(__builtin_unreachable)
#define ABSL_ASSUME(cond) ((cond) ? void() : __builtin_unreachable())
#elif ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
// Unimplemented. Uses the same definition as ABSL_ASSERT in the NDEBUG case.
#define ABSL_ASSUME(expr) (decltype((expr) ? void() : void())())
#else
#define ABSL_ASSUME(expr) (false ? ((expr) ? void() : void()) : void())
#endif

// ABSL_INTERNAL_UNIQUE_SMALL_NAME(cond)
// This macro forces small unique name on a static file level symbols like
// static local variables or static functions. This is intended to be used in
// macro definitions to optimize the cost of generated code. Do NOT use it on
// symbols exported from translation unit since it may cause a link time
// conflict.
//
// Example:
//
// #define MY_MACRO(txt)
// namespace {
//  char VeryVeryLongVarName[] ABSL_INTERNAL_UNIQUE_SMALL_NAME() = txt;
//  const char* VeryVeryLongFuncName() ABSL_INTERNAL_UNIQUE_SMALL_NAME();
//  const char* VeryVeryLongFuncName() { return txt; }
// }
//

#if defined(__GNUC__)
#define ABSL_INTERNAL_UNIQUE_SMALL_NAME2(x) #x
#define ABSL_INTERNAL_UNIQUE_SMALL_NAME1(x) ABSL_INTERNAL_UNIQUE_SMALL_NAME2(x)
#define ABSL_INTERNAL_UNIQUE_SMALL_NAME() \
  asm(ABSL_INTERNAL_UNIQUE_SMALL_NAME1(.absl.__COUNTER__))
#else
#define ABSL_INTERNAL_UNIQUE_SMALL_NAME()
#endif

#endif  // ABSL_BASE_OPTIMIZATION_H_
*þ
‚soong/.intermediates/external/abseil-cpp/absl_base_nullability_hdrs/gen/my_include_dir/absl/base/internal/nullability_deprecated.hö// 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_DEPRECATED_H_
#define ABSL_BASE_INTERNAL_NULLABILITY_DEPRECATED_H_

#include "absl/base/attributes.h"
#include "absl/base/config.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace nullability_internal {

template <typename T>
using NullableImpl
#if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate)
    [[clang::annotate("Nullable")]]
#endif
// Don't add the _Nullable attribute in Objective-C compiles. Many Objective-C
// projects enable the `-Wnullable-to-nonnull-conversion warning`, which is
// liable to produce false positives.
#if ABSL_HAVE_FEATURE(nullability_on_classes) && !defined(__OBJC__)
    = T _Nullable;
#else
    = T;
#endif

template <typename T>
using NonnullImpl
#if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate)
    [[clang::annotate("Nonnull")]]
#endif
#if ABSL_HAVE_FEATURE(nullability_on_classes) && !defined(__OBJC__)
    = T _Nonnull;
#else
    = T;
#endif

template <typename T>
using NullabilityUnknownImpl
#if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate)
    [[clang::annotate("Nullability_Unspecified")]]
#endif
#if ABSL_HAVE_FEATURE(nullability_on_classes) && !defined(__OBJC__)
    = T _Null_unspecified;
#else
    = T;
#endif

}  // namespace nullability_internal

// The following template aliases are deprecated forms of nullability
// annotations. They have some limitations, for example, an incompatibility with
// `auto*` pointers, as `auto` cannot be used in a template argument.
//
// 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*`.
//
// Prefer the macro style annotations in `absl/base/nullability.h` instead.

// absl::Nonnull, analogous to absl_nonnull
//
// Example:
// absl::Nonnull<int*> foo;
// Is equivalent to:
// int* absl_nonnull foo;
template <typename T>
using Nonnull [[deprecated("Use `absl_nonnull`.")]] =
    nullability_internal::NonnullImpl<T>;

// absl::Nullable, analogous to absl_nullable
//
// Example:
// absl::Nullable<int*> foo;
// Is equivalent to:
// int* absl_nullable foo;
template <typename T>
using Nullable [[deprecated("Use `absl_nullable`.")]] =
    nullability_internal::NullableImpl<T>;

// absl::NullabilityUnknown, analogous to absl_nullability_unknown
//
// Example:
// absl::NullabilityUnknown<int*> foo;
// Is equivalent to:
// int* absl_nullability_unknown foo;
template <typename T>
using NullabilityUnknown [[deprecated("Use `absl_nullability_unknown`.")]] =
    nullability_internal::NullabilityUnknownImpl<T>;

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_BASE_INTERNAL_NULLABILITY_DEPRECATED_H_
*øl
nsoong/.intermediates/external/abseil-cpp/absl_base_nullability_hdrs/gen/my_include_dir/absl/base/nullability.h…l// 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 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 `absl_nonnull`), indicating that it is
//    invalid for the given pointer to ever be null.
//  * "Nullable" (for pointers annotated `absl_nullable`), indicating that it is
//    valid for the given pointer to be null.
//  * "Unknown" (for pointers annotated `absl_nullability_unknown`), indicating
//    that the given pointer has not yet been classified as either nullable or
//    non-null. This is the default state of unannotated pointers.
//
// NOTE: Unannotated pointers implicitly bear the annotation
// `absl_nullability_unknown`; 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.
//
// -----------------------------------------------------------------------------
// Annotation Syntax
// -----------------------------------------------------------------------------
//
// The annotations should be positioned as a qualifier for the pointer type. For
// example, the position of `const` when declaring a const pointer (not a
// pointer to a const type) is the position you should also use for these
// annotations.
//
// Example:
//
// // A const non-null pointer to an `Employee`.
// Employee* absl_nonnull const e;
//
// // A non-null pointer to a const `Employee`.
// const Employee* absl_nonnull e;
//
// // A non-null pointer to a const nullable pointer to an `Employee`.
// Employee* absl_nullable const* absl_nonnull e = nullptr;
//
// // A non-null function pointer.
// void (*absl_nonnull func)(int, double);
//
// // A non-null array of `Employee`s as a parameter.
// void func(Employee employees[absl_nonnull]);
//
// // A non-null std::unique_ptr to an `Employee`.
// // As with `const`, it is possible to place the annotation on either side of
// // a named type not ending in `*`, but placing it before the type it
// // describes is preferred, unless inconsistent with surrounding code.
// absl_nonnull std::unique_ptr<Employee> employee;
//
// // Invalid annotation usage â€“ this attempts to declare a pointer to a
// // nullable `Employee`, which is meaningless.
// absl_nullable Employee* e;
//
// -----------------------------------------------------------------------------
// Using Nullability Annotations
// -----------------------------------------------------------------------------
//
// 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(Employee* absl_nonnull e) {
//   pay(e->salary);  // OK to dereference
// }
//
// // CompleteTransaction() guarantees the returned pointer to an `Account` to
// // be non-null.
// Account* absl_nonnull balance CompleteTransaction(double fee) {
// ...
// }
//
// // Note that specifying a nullability annotation does not prevent someone
// // from violating the contract:
//
// Employee* absl_nullable 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 adding the ABSL_NULLABILITY_COMPATIBLE attribute.
//
// // Example:
// struct ABSL_NULLABILITY_COMPATIBLE MyPtr {
//   ...
// };
//
// Note: Compilers that don't support the `nullability_on_classes` feature will
// allow nullability annotations to be applied to any type, not just ones
// marked with `ABSL_NULLABILITY_COMPATIBLE`.
//
// 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
// `absl_nonnull` is *not guaranteed* to be non-null, and the compiler won't
// alert or prevent assignment of a `T* absl_nullable` to a `T* absl_nonnull`.
// ===========================================================================
#ifndef ABSL_BASE_NULLABILITY_H_
#define ABSL_BASE_NULLABILITY_H_

#include "absl/base/config.h"
#include "absl/base/internal/nullability_deprecated.h"

// ABSL_POINTERS_DEFAULT_NONNULL
//
// This macro specifies that all unannotated pointer types within the given
// file are designated as nonnull (instead of the default "unknown"). This macro
// exists as a standalone statement and applies default nonnull behavior to all
// subsequent pointers; as a result, place this macro as the first non-comment,
// non-`#include` line in a file.
//
// Example:
//
//     #include "absl/base/nullability.h"
//
//     ABSL_POINTERS_DEFAULT_NONNULL
//
//     void FillMessage(Message *m);                  // implicitly non-null
//     T* absl_nullable GetNullablePtr();           // explicitly nullable
//     T* absl_nullability_unknown GetUnknownPtr();  // explicitly unknown
//
// The macro can be safely used in header files â€“ it will not affect any files
// that include it.
//
// In files with the macro, plain `T*` syntax means `T* absl_nonnull`, and the
// exceptions (`absl_nullable` and `absl_nullability_unknown`) must be marked
// explicitly. The same holds, correspondingly, for smart pointer types.
//
// For comparison, without the macro, all unannotated pointers would default to
// unknown, and otherwise require explicit annotations to change this behavior:
//
//     #include "absl/base/nullability.h"
//
//     void FillMessage(Message* absl_nonnull m);  // explicitly non-null
//     T* absl_nullable GetNullablePtr();          // explicitly nullable
//     T* GetUnknownPtr();                           // implicitly unknown
//
// No-op except for being a human readable signal.
#define ABSL_POINTERS_DEFAULT_NONNULL

#if defined(__clang__) && !defined(__OBJC__) && \
    ABSL_HAVE_FEATURE(nullability_on_classes)
// absl_nonnull (default with `ABSL_POINTERS_DEFAULT_NONNULL`)
//
// The indicated pointer is never null. It is the responsibility of the provider
// of this pointer across an API boundary to ensure that the pointer is never
// 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(Employee* absl_nonnull employee) {
//   pay(*employee);  // OK to dereference
// }
#define absl_nonnull _Nonnull

// 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(Employee* absl_nullable employee) {
//   if (employee != nullptr) {
//     Pay(*employee);  // OK to dereference
//   }
// }
#define absl_nullable _Nullable

// absl_nullability_unknown  (default without `ABSL_POINTERS_DEFAULT_NONNULL`)
//
// The indicated pointer has not yet been determined to be definitively
// "non-null" or "nullable." Providers of such pointers across API boundaries
// 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: `absl_nonnull` or
//  `absl_nullable`.
//
// NOTE: For files that do not specify `ABSL_POINTERS_DEFAULT_NONNULL`,
// because this annotation is the global default state, unannotated pointers are
// are assumed to have "unknown" semantics. This assumption is designed to
// minimize churn and reduce clutter within the codebase.
//
// Example:
//
// // `employee`s nullability state is unknown.
// void PaySalary(Employee* absl_nullability_unknown 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.
// }
#define absl_nullability_unknown _Null_unspecified
#else
// No-op for non-Clang compilers or Objective-C.
#define absl_nonnull
// No-op for non-Clang compilers or Objective-C.
#define absl_nullable
// No-op for non-Clang compilers or Objective-C.
#define absl_nullability_unknown
#endif

// ABSL_NULLABILITY_COMPATIBLE
//
// Indicates that a class is compatible with nullability annotations.
//
// For example:
//
// struct ABSL_NULLABILITY_COMPATIBLE MyPtr {
//   ...
// };
//
// Note: Compilers that don't support the `nullability_on_classes` feature will
// allow nullability annotations to be applied to any type, not just ones marked
// with `ABSL_NULLABILITY_COMPATIBLE`.
#if ABSL_HAVE_FEATURE(nullability_on_classes)
#define ABSL_NULLABILITY_COMPATIBLE _Nullable
#else
#define ABSL_NULLABILITY_COMPATIBLE
#endif

#endif  // ABSL_BASE_NULLABILITY_H_
*�I
esoong/.intermediates/external/abseil-cpp/absl_base_config_hdrs/gen/my_include_dir/absl/base/options.h¥H// Copyright 2019 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// File: options.h
// -----------------------------------------------------------------------------
//
// This file contains Abseil configuration options for setting specific
// implementations instead of letting Abseil determine which implementation to
// use at compile-time. Setting these options may be useful for package or build
// managers who wish to guarantee ABI stability within binary builds (which are
// otherwise difficult to enforce).
//
// *** IMPORTANT NOTICE FOR PACKAGE MANAGERS:  It is important that
// maintainers of package managers who wish to package Abseil read and
// understand this file! ***
//
// Abseil contains a number of possible configuration endpoints, based on
// parameters such as the detected platform, language version, or command-line
// flags used to invoke the underlying binary. As is the case with all
// libraries, binaries which contain Abseil code must ensure that separate
// packages use the same compiled copy of Abseil to avoid a diamond dependency
// problem, which can occur if two packages built with different Abseil
// configuration settings are linked together. Diamond dependency problems in
// C++ may manifest as violations to the One Definition Rule (ODR) (resulting in
// linker errors), or undefined behavior (resulting in crashes).
//
// Diamond dependency problems can be avoided if all packages utilize the same
// exact version of Abseil. Building from source code with the same compilation
// parameters is the easiest way to avoid such dependency problems. However, for
// package managers who cannot control such compilation parameters, we are
// providing the file to allow you to inject ABI (Application Binary Interface)
// stability across builds. Settings options in this file will neither change
// API nor ABI, providing a stable copy of Abseil between packages.
//
// Care must be taken to keep options within these configurations isolated
// from any other dynamic settings, such as command-line flags which could alter
// these options. This file is provided specifically to help build and package
// managers provide a stable copy of Abseil within their libraries and binaries;
// other developers should not have need to alter the contents of this file.
//
// -----------------------------------------------------------------------------
// Usage
// -----------------------------------------------------------------------------
//
// For any particular package release, set the appropriate definitions within
// this file to whatever value makes the most sense for your package(s). Note
// that, by default, most of these options, at the moment, affect the
// implementation of types; future options may affect other implementation
// details.
//
// NOTE: the defaults within this file all assume that Abseil can select the
// proper Abseil implementation at compile-time, which will not be sufficient
// to guarantee ABI stability to package managers.

// SKIP_ABSL_INLINE_NAMESPACE_CHECK

#ifndef ABSL_BASE_OPTIONS_H_
#define ABSL_BASE_OPTIONS_H_

// -----------------------------------------------------------------------------
// Type Compatibility Options
// -----------------------------------------------------------------------------

// ABSL_OPTION_USE_STD_STRING_VIEW
//
// This option controls whether absl::string_view is implemented as an alias to
// std::string_view, 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 an alias to std::string_view.  This requires that
// all code using Abseil is built in C++17 mode or later.
//
// A value of 2 means to detect the C++ version being used to compile Abseil,
// and use an alias only if a working std::string_view is 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, absl::string_view will name a
// different type, with a different mangled name 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
// absl::string_view is a typedef of std::string_view, use the feature macro
// ABSL_USES_STD_STRING_VIEW.

#define ABSL_OPTION_USE_STD_STRING_VIEW 1

// 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
//
// These options controls whether all entities in the absl namespace are
// contained within an inner inline namespace.  This does not affect the
// user-visible API of Abseil, but it changes the mangled names of all symbols.
//
// This can be useful as a version tag if you are distributing Abseil in
// precompiled form.  This will prevent a binary library build of Abseil with
// one inline namespace being used with headers configured with a different
// inline namespace name.  Binary packagers are reminded that Abseil does not
// guarantee any ABI stability in Abseil, so any update of Abseil or
// configuration change in such a binary package should be combined with a
// new, unique value for the inline namespace name.
//
// A value of 0 means not to use inline namespaces.
//
// A value of 1 means to use an inline namespace with the given name inside
// namespace absl.  If this is set, ABSL_OPTION_INLINE_NAMESPACE_NAME must also
// be changed to a new, unique identifier name.  In particular "head" is not
// allowed.

#define ABSL_OPTION_USE_INLINE_NAMESPACE 1
#ifdef ANDROID_DISABLE_TLS_FOR_LINKER
#define ABSL_OPTION_INLINE_NAMESPACE_NAME lts_20250512_notls
#else
#define ABSL_OPTION_INLINE_NAMESPACE_NAME lts_20250512
#endif

// ABSL_OPTION_HARDENED
//
// This option enables a "hardened" build in release mode (in this context,
// release mode is defined as a build where the `NDEBUG` macro is defined).
//
// A value of 0 means that "hardened" mode is not enabled.
//
// A value of 1 means that "hardened" mode is enabled with all checks.
//
// A value of 2 means that "hardened" mode is partially enabled, with
// only a subset of checks chosen to minimize performance impact.
//
// Hardened builds have additional security checks enabled when `NDEBUG` is
// defined. Defining `NDEBUG` is normally used to turn `assert()` macro into a
// no-op, as well as disabling other bespoke program consistency checks. By
// defining ABSL_OPTION_HARDENED to 1, a select set of checks remain enabled in
// release mode. These checks guard against programming errors that may lead to
// security vulnerabilities. In release mode, when one of these programming
// errors is encountered, the program will immediately abort, possibly without
// any attempt at logging.
//
// The checks enabled by this option are not free; they do incur runtime cost.
//
// The checks enabled by this option are always active when `NDEBUG` is not
// defined, even in the case when ABSL_OPTION_HARDENED is defined to 0. The
// checks enabled by this option may abort the program in a different way and
// log additional information when `NDEBUG` is not defined.

#define ABSL_OPTION_HARDENED 0

#endif  // ABSL_BASE_OPTIONS_H_
*¶å
tsoong/.intermediates/external/abseil-cpp/absl_strings_string_view_hdrs/gen/my_include_dir/absl/strings/string_view.h¼ä//
// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// File: string_view.h
// -----------------------------------------------------------------------------
//
// This file contains the definition of the `absl::string_view` class. A
// `string_view` points to a contiguous span of characters, often part or all of
// another `std::string`, double-quoted string literal, character array, or even
// another `string_view`.
//
// This `absl::string_view` abstraction is designed to be a drop-in
// replacement for the C++17 `std::string_view` abstraction.
#ifndef ABSL_STRINGS_STRING_VIEW_H_
#define ABSL_STRINGS_STRING_VIEW_H_

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstring>
#include <iosfwd>
#include <iterator>
#include <limits>
#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"
#include "absl/base/optimization.h"
#include "absl/base/port.h"

#ifdef ABSL_USES_STD_STRING_VIEW

#include <string_view>  // IWYU pragma: export

namespace absl {
ABSL_NAMESPACE_BEGIN
using string_view = std::string_view;
ABSL_NAMESPACE_END
}  // namespace absl

#else  // ABSL_USES_STD_STRING_VIEW

#if ABSL_HAVE_BUILTIN(__builtin_memcmp) ||        \
    (defined(__GNUC__) && !defined(__clang__)) || \
    (defined(_MSC_VER) && _MSC_VER >= 1928)
#define ABSL_INTERNAL_STRING_VIEW_MEMCMP __builtin_memcmp
#else  // ABSL_HAVE_BUILTIN(__builtin_memcmp)
#define ABSL_INTERNAL_STRING_VIEW_MEMCMP memcmp
#endif  // ABSL_HAVE_BUILTIN(__builtin_memcmp)

namespace absl {
ABSL_NAMESPACE_BEGIN

// absl::string_view
//
// A `string_view` provides a lightweight view into the string data provided by
// a `std::string`, double-quoted string literal, character array, or even
// another `string_view`. A `string_view` does *not* own the string to which it
// points, and that data cannot be modified through the view.
//
// You can use `string_view` as a function or method parameter anywhere a
// parameter can receive a double-quoted string literal, `const char*`,
// `std::string`, or another `absl::string_view` argument with no need to copy
// the string data. Systematic use of `string_view` within function arguments
// reduces data copies and `strlen()` calls.
//
// Because of its small size, prefer passing `string_view` by value:
//
//   void MyFunction(absl::string_view arg);
//
// If circumstances require, you may also pass one by const reference:
//
//   void MyFunction(const absl::string_view& arg);  // not preferred
//
// Passing by value generates slightly smaller code for many architectures.
//
// In either case, the source data of the `string_view` must outlive the
// `string_view` itself.
//
// A `string_view` is also suitable for local variables if you know that the
// lifetime of the underlying object is longer than the lifetime of your
// `string_view` variable. However, beware of binding a `string_view` to a
// temporary value:
//
//   // BAD use of string_view: lifetime problem
//   absl::string_view sv = obj.ReturnAString();
//
//   // GOOD use of string_view: str outlives sv
//   std::string str = obj.ReturnAString();
//   absl::string_view sv = str;
//
// Due to lifetime issues, a `string_view` is sometimes a poor choice for a
// return value and usually a poor choice for a data member. If you do use a
// `string_view` this way, it is your responsibility to ensure that the object
// pointed to by the `string_view` outlives the `string_view`.
//
// A `string_view` may represent a whole string or just part of a string. For
// example, when splitting a string, `std::vector<absl::string_view>` is a
// natural data type for the output.
//
// For another example, a Cord is a non-contiguous, potentially very
// long string-like object.  The Cord class has an interface that iteratively
// provides string_view objects that point to the successive pieces of a Cord
// object.
//
// When constructed from a source which is NUL-terminated, the `string_view`
// itself will not include the NUL-terminator unless a specific size (including
// the NUL) is passed to the constructor. As a result, common idioms that work
// on NUL-terminated strings do not work on `string_view` objects. If you write
// code that scans a `string_view`, you must check its length rather than test
// for nul, for example. Note, however, that nuls may still be embedded within
// a `string_view` explicitly.
//
// You may create a null `string_view` in two ways:
//
//   absl::string_view sv;
//   absl::string_view sv(nullptr, 0);
//
// For the above, `sv.data() == nullptr`, `sv.length() == 0`, and
// `sv.empty() == true`. Also, if you create a `string_view` with a non-null
// pointer then `sv.data() != nullptr`. Thus, you can use `string_view()` to
// signal an undefined value that is different from other `string_view` values
// in a similar fashion to how `const char* p1 = nullptr;` is different from
// `const char* p2 = "";`. However, in practice, it is not recommended to rely
// on this behavior.
//
// Be careful not to confuse a null `string_view` with an empty one. A null
// `string_view` is an empty `string_view`, but some empty `string_view`s are
// not null. Prefer checking for emptiness over checking for null.
//
// There are many ways to create an empty string_view:
//
//   const char* nullcp = nullptr;
//   // string_view.size() will return 0 in all cases.
//   absl::string_view();
//   absl::string_view(nullcp, 0);
//   absl::string_view("");
//   absl::string_view("", 0);
//   absl::string_view("abcdef", 0);
//   absl::string_view("abcdef" + 6, 0);
//
// All empty `string_view` objects whether null or not, are equal:
//
//   absl::string_view() == absl::string_view("", 0)
//   absl::string_view(nullptr, 0) == absl::string_view("abcdef"+6, 0)
class ABSL_ATTRIBUTE_VIEW string_view {
 public:
  using traits_type = std::char_traits<char>;
  using value_type = char;
  using pointer = char* absl_nullable;
  using const_pointer = const char* absl_nullable;
  using reference = char&;
  using const_reference = const char&;
  using const_iterator = const char* absl_nullable;
  using iterator = const_iterator;
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  using reverse_iterator = const_reverse_iterator;
  using size_type = size_t;
  using difference_type = std::ptrdiff_t;
  using absl_internal_is_view = std::true_type;

  static constexpr size_type npos = static_cast<size_type>(-1);

  // Null `string_view` constructor
  constexpr string_view() noexcept : ptr_(nullptr), length_(0) {}

  // Implicit constructors

  template <typename Allocator>
  string_view(  // NOLINT(runtime/explicit)
      const std::basic_string<char, std::char_traits<char>, Allocator>& str
          ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept
      // This is implemented in terms of `string_view(p, n)` so `str.size()`
      // doesn't need to be reevaluated after `ptr_` is set.
      // The length check is also skipped since it is unnecessary and causes
      // code bloat.
      : string_view(str.data(), str.size(), SkipCheckLengthTag{}) {}

  // Implicit constructor of a `string_view` from NUL-terminated `str`. When
  // accepting possibly null strings, use `absl::NullSafeStringView(str)`
  // instead (see below).
  // The length check is skipped since it is unnecessary and causes code bloat.
  constexpr string_view(  // NOLINT(runtime/explicit)
      const char* absl_nonnull str)
      : ptr_(str), length_(str ? StrlenInternal(str) : 0) {}

  // Constructor of a `string_view` from a `const char*` and length.
  constexpr string_view(const char* absl_nullable data, size_type len)
      : ptr_(data), length_(CheckLengthInternal(len)) {}

  constexpr string_view(const string_view&) noexcept = default;
  string_view& operator=(const string_view&) noexcept = default;

  // Iterators

  // string_view::begin()
  //
  // Returns an iterator pointing to the first character at the beginning of the
  // `string_view`, or `end()` if the `string_view` is empty.
  constexpr const_iterator begin() const noexcept { return ptr_; }

  // string_view::end()
  //
  // Returns an iterator pointing just beyond the last character at the end of
  // the `string_view`. This iterator acts as a placeholder; attempting to
  // access it results in undefined behavior.
  constexpr const_iterator end() const noexcept { return ptr_ + length_; }

  // string_view::cbegin()
  //
  // Returns a const iterator pointing to the first character at the beginning
  // of the `string_view`, or `end()` if the `string_view` is empty.
  constexpr const_iterator cbegin() const noexcept { return begin(); }

  // string_view::cend()
  //
  // Returns a const iterator pointing just beyond the last character at the end
  // of the `string_view`. This pointer acts as a placeholder; attempting to
  // access its element results in undefined behavior.
  constexpr const_iterator cend() const noexcept { return end(); }

  // string_view::rbegin()
  //
  // Returns a reverse iterator pointing to the last character at the end of the
  // `string_view`, or `rend()` if the `string_view` is empty.
  const_reverse_iterator rbegin() const noexcept {
    return const_reverse_iterator(end());
  }

  // string_view::rend()
  //
  // Returns a reverse iterator pointing just before the first character at the
  // beginning of the `string_view`. This pointer acts as a placeholder;
  // attempting to access its element results in undefined behavior.
  const_reverse_iterator rend() const noexcept {
    return const_reverse_iterator(begin());
  }

  // string_view::crbegin()
  //
  // Returns a const reverse iterator pointing to the last character at the end
  // of the `string_view`, or `crend()` if the `string_view` is empty.
  const_reverse_iterator crbegin() const noexcept { return rbegin(); }

  // string_view::crend()
  //
  // Returns a const reverse iterator pointing just before the first character
  // at the beginning of the `string_view`. This pointer acts as a placeholder;
  // attempting to access its element results in undefined behavior.
  const_reverse_iterator crend() const noexcept { return rend(); }

  // Capacity Utilities

  // string_view::size()
  //
  // Returns the number of characters in the `string_view`.
  constexpr size_type size() const noexcept { return length_; }

  // string_view::length()
  //
  // Returns the number of characters in the `string_view`. Alias for `size()`.
  constexpr size_type length() const noexcept { return size(); }

  // string_view::max_size()
  //
  // Returns the maximum number of characters the `string_view` can hold.
  constexpr size_type max_size() const noexcept { return kMaxSize; }

  // string_view::empty()
  //
  // Checks if the `string_view` is empty (refers to no characters).
  constexpr bool empty() const noexcept { return length_ == 0; }

  // string_view::operator[]
  //
  // Returns the ith element of the `string_view` using the array operator.
  // Note that this operator does not perform any bounds checking.
  constexpr const_reference operator[](size_type i) const {
    ABSL_HARDENING_ASSERT(i < size());
    return ptr_[i];
  }

  // string_view::at()
  //
  // Returns the ith element of the `string_view`. Bounds checking is performed,
  // and an exception of type `std::out_of_range` will be thrown on invalid
  // access.
  constexpr const_reference at(size_type i) const {
    if (ABSL_PREDICT_FALSE(i >= size())) {
      base_internal::ThrowStdOutOfRange("absl::string_view::at");
    }
    return ptr_[i];
  }

  // string_view::front()
  //
  // Returns the first element of a `string_view`.
  constexpr const_reference front() const {
    ABSL_HARDENING_ASSERT(!empty());
    return ptr_[0];
  }

  // string_view::back()
  //
  // Returns the last element of a `string_view`.
  constexpr const_reference back() const {
    ABSL_HARDENING_ASSERT(!empty());
    return ptr_[size() - 1];
  }

  // string_view::data()
  //
  // Returns a pointer to the underlying character array (which is of course
  // stored elsewhere). Note that `string_view::data()` may contain embedded nul
  // characters, but the returned buffer may or may not be NUL-terminated;
  // therefore, do not pass `data()` to a routine that expects a NUL-terminated
  // string.
  constexpr const_pointer data() const noexcept { return ptr_; }

  // Modifiers

  // string_view::remove_prefix()
  //
  // Removes the first `n` characters from the `string_view`. Note that the
  // underlying string is not changed, only the view.
  constexpr void remove_prefix(size_type n) {
    ABSL_HARDENING_ASSERT(n <= length_);
    ptr_ += n;
    length_ -= n;
  }

  // string_view::remove_suffix()
  //
  // Removes the last `n` characters from the `string_view`. Note that the
  // underlying string is not changed, only the view.
  constexpr void remove_suffix(size_type n) {
    ABSL_HARDENING_ASSERT(n <= length_);
    length_ -= n;
  }

  // string_view::swap()
  //
  // Swaps this `string_view` with another `string_view`.
  constexpr void swap(string_view& s) noexcept {
    auto t = *this;
    *this = s;
    s = t;
  }

  // Explicit conversion operators

  // Converts to `std::basic_string`.
  template <typename A>
  explicit operator std::basic_string<char, traits_type, A>() const {
    if (!data()) return {};
    return std::basic_string<char, traits_type, A>(data(), size());
  }

  // string_view::copy()
  //
  // Copies the contents of the `string_view` at offset `pos` and length `n`
  // into `buf`.
  size_type copy(char* buf, size_type n, size_type pos = 0) const {
    if (ABSL_PREDICT_FALSE(pos > length_)) {
      base_internal::ThrowStdOutOfRange("absl::string_view::copy");
    }
    size_type rlen = (std::min)(length_ - pos, n);
    if (rlen > 0) {
      const char* start = ptr_ + pos;
      traits_type::copy(buf, start, rlen);
    }
    return rlen;
  }

  // string_view::substr()
  //
  // Returns a "substring" of the `string_view` (at offset `pos` and length
  // `n`) as another string_view. This function throws `std::out_of_bounds` if
  // `pos > size`.
  // Use absl::ClippedSubstr if you need a truncating substr operation.
  constexpr string_view substr(size_type pos = 0, size_type n = npos) const {
    if (ABSL_PREDICT_FALSE(pos > length_)) {
      base_internal::ThrowStdOutOfRange("absl::string_view::substr");
    }
    return string_view(ptr_ + pos, (std::min)(n, length_ - pos));
  }

  // string_view::compare()
  //
  // Performs a lexicographical comparison between this `string_view` and
  // another `string_view` `x`, returning a negative value if `*this` is less
  // than `x`, 0 if `*this` is equal to `x`, and a positive value if `*this`
  // is greater than `x`.
  constexpr int compare(string_view x) const noexcept {
    return CompareImpl(length_, x.length_,
                       (std::min)(length_, x.length_) == 0
                           ? 0
                           : ABSL_INTERNAL_STRING_VIEW_MEMCMP(
                                 ptr_, x.ptr_, (std::min)(length_, x.length_)));
  }

  // Overload of `string_view::compare()` for comparing a substring of the
  // 'string_view` and another `absl::string_view`.
  constexpr int compare(size_type pos1, size_type count1, string_view v) const {
    return substr(pos1, count1).compare(v);
  }

  // Overload of `string_view::compare()` for comparing a substring of the
  // `string_view` and a substring of another `absl::string_view`.
  constexpr int compare(size_type pos1, size_type count1, string_view v,
                        size_type pos2, size_type count2) const {
    return substr(pos1, count1).compare(v.substr(pos2, count2));
  }

  // Overload of `string_view::compare()` for comparing a `string_view` and a
  // a different C-style string `s`.
  constexpr int compare(const char* absl_nonnull 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* absl_nonnull 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* absl_nonnull s, size_type count2) const {
    return substr(pos1, count1).compare(string_view(s, count2));
  }

  // Find Utilities

  // string_view::find()
  //
  // Finds the first occurrence of the substring `s` within the `string_view`,
  // returning the position of the first character's match, or `npos` if no
  // match was found.
  size_type find(string_view s, size_type pos = 0) const noexcept;

  // Overload of `string_view::find()` for finding the given character `c`
  // within the `string_view`.
  size_type find(char c, size_type pos = 0) const noexcept;

  // Overload of `string_view::find()` for finding a substring of a different
  // C-style string `s` within the `string_view`.
  size_type find(const char* absl_nonnull 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* absl_nonnull s, size_type pos = 0) const {
    return find(string_view(s), pos);
  }

  // string_view::rfind()
  //
  // Finds the last occurrence of a substring `s` within the `string_view`,
  // returning the position of the first character's match, or `npos` if no
  // match was found.
  size_type rfind(string_view s, size_type pos = npos) const noexcept;

  // Overload of `string_view::rfind()` for finding the last given character `c`
  // within the `string_view`.
  size_type rfind(char c, size_type pos = npos) const noexcept;

  // Overload of `string_view::rfind()` for finding a substring of a different
  // C-style string `s` within the `string_view`.
  size_type rfind(const char* absl_nonnull 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* absl_nonnull s, size_type pos = npos) const {
    return rfind(string_view(s), pos);
  }

  // string_view::find_first_of()
  //
  // Finds the first occurrence of any of the characters in `s` within the
  // `string_view`, returning the start position of the match, or `npos` if no
  // match was found.
  size_type find_first_of(string_view s, size_type pos = 0) const noexcept;

  // Overload of `string_view::find_first_of()` for finding a character `c`
  // within the `string_view`.
  size_type find_first_of(char c, size_type pos = 0) const noexcept {
    return find(c, pos);
  }

  // Overload of `string_view::find_first_of()` for finding a substring of a
  // different C-style string `s` within the `string_view`.
  size_type find_first_of(const char* absl_nonnull 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* absl_nonnull s, size_type pos = 0) const {
    return find_first_of(string_view(s), pos);
  }

  // string_view::find_last_of()
  //
  // Finds the last occurrence of any of the characters in `s` within the
  // `string_view`, returning the start position of the match, or `npos` if no
  // match was found.
  size_type find_last_of(string_view s, size_type pos = npos) const noexcept;

  // Overload of `string_view::find_last_of()` for finding a character `c`
  // within the `string_view`.
  size_type find_last_of(char c, size_type pos = npos) const noexcept {
    return rfind(c, pos);
  }

  // Overload of `string_view::find_last_of()` for finding a substring of a
  // different C-style string `s` within the `string_view`.
  size_type find_last_of(const char* absl_nonnull 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* absl_nonnull s,
                         size_type pos = npos) const {
    return find_last_of(string_view(s), pos);
  }

  // string_view::find_first_not_of()
  //
  // Finds the first occurrence of any of the characters not in `s` within the
  // `string_view`, returning the start position of the first non-match, or
  // `npos` if no non-match was found.
  size_type find_first_not_of(string_view s, size_type pos = 0) const noexcept;

  // Overload of `string_view::find_first_not_of()` for finding a character
  // that is not `c` within the `string_view`.
  size_type find_first_not_of(char c, size_type pos = 0) const noexcept;

  // Overload of `string_view::find_first_not_of()` for finding a substring of a
  // different C-style string `s` within the `string_view`.
  size_type find_first_not_of(const char* absl_nonnull 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* absl_nonnull s,
                              size_type pos = 0) const {
    return find_first_not_of(string_view(s), pos);
  }

  // string_view::find_last_not_of()
  //
  // Finds the last occurrence of any of the characters not in `s` within the
  // `string_view`, returning the start position of the last non-match, or
  // `npos` if no non-match was found.
  size_type find_last_not_of(string_view s,
                             size_type pos = npos) const noexcept;

  // Overload of `string_view::find_last_not_of()` for finding a character
  // that is not `c` within the `string_view`.
  size_type find_last_not_of(char c, size_type pos = npos) const noexcept;

  // Overload of `string_view::find_last_not_of()` for finding a substring of a
  // different C-style string `s` within the `string_view`.
  size_type find_last_not_of(const char* absl_nonnull 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* absl_nonnull 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* absl_nullable data, size_type len,
              SkipCheckLengthTag) noexcept
      : ptr_(data), length_(len) {}

  static constexpr size_type kMaxSize =
      (std::numeric_limits<difference_type>::max)();

  static constexpr size_type CheckLengthInternal(size_type len) {
    ABSL_HARDENING_ASSERT(len <= kMaxSize);
    return len;
  }

  static constexpr size_type StrlenInternal(const char* absl_nonnull str) {
#if defined(_MSC_VER) && !defined(__clang__)
    // MSVC 2017+ can evaluate this at compile-time.
    const char* begin = str;
    while (*str != '\0') ++str;
    return str - begin;
#elif ABSL_HAVE_BUILTIN(__builtin_strlen) || \
    (defined(__GNUC__) && !defined(__clang__))
    // GCC has __builtin_strlen according to
    // https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Other-Builtins.html, but
    // ABSL_HAVE_BUILTIN doesn't detect that, so we use the extra checks above.
    // __builtin_strlen is constexpr.
    return __builtin_strlen(str);
#else
    return str ? strlen(str) : 0;
#endif
  }

  static constexpr int CompareImpl(size_type length_a, size_type length_b,
                                   int compare_result) {
    return compare_result == 0 ? static_cast<int>(length_a > length_b) -
                                     static_cast<int>(length_a < length_b)
                               : (compare_result < 0 ? -1 : 1);
  }

  const char* absl_nullable ptr_;
  size_type length_;
};

// This large function is defined inline so that in a fairly common case where
// one of the arguments is a literal, the compiler can elide a lot of the
// following comparisons.
constexpr bool operator==(string_view x, string_view y) noexcept {
  return x.size() == y.size() &&
         (x.empty() ||
          ABSL_INTERNAL_STRING_VIEW_MEMCMP(x.data(), y.data(), x.size()) == 0);
}

constexpr bool operator!=(string_view x, string_view y) noexcept {
  return !(x == y);
}

constexpr bool operator<(string_view x, string_view y) noexcept {
  return x.compare(y) < 0;
}

constexpr bool operator>(string_view x, string_view y) noexcept {
  return y < x;
}

constexpr bool operator<=(string_view x, string_view y) noexcept {
  return !(y < x);
}

constexpr bool operator>=(string_view x, string_view y) noexcept {
  return !(x < y);
}

// IO Insertion Operator
std::ostream& operator<<(std::ostream& o, string_view piece);

ABSL_NAMESPACE_END
}  // namespace absl

#undef ABSL_INTERNAL_STRING_VIEW_MEMCMP

#endif  // ABSL_USES_STD_STRING_VIEW

namespace absl {
ABSL_NAMESPACE_BEGIN

// ClippedSubstr()
//
// Like `s.substr(pos, n)`, but clips `pos` to an upper bound of `s.size()`.
// Provided because std::string_view::substr throws if `pos > size()`
inline string_view ClippedSubstr(string_view s, size_t pos,
                                 size_t n = string_view::npos) {
  pos = (std::min)(pos, static_cast<size_t>(s.size()));
  return s.substr(pos, n);
}

// NullSafeStringView()
//
// 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* absl_nullable p) {
  return p ? string_view(p) : string_view();
}

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_STRING_VIEW_H_
*ñ.
{soong/.intermediates/external/abseil-cpp/absl_crc_crc_cord_state_hdrs/gen/my_include_dir/absl/crc/internal/crc_cord_state.hñ-// 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.

#ifndef ABSL_CRC_INTERNAL_CRC_CORD_STATE_H_
#define ABSL_CRC_INTERNAL_CRC_CORD_STATE_H_

#include <atomic>
#include <cstddef>
#include <deque>

#include "absl/base/config.h"
#include "absl/crc/crc32c.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace crc_internal {

// CrcCordState is a copy-on-write class that holds the chunked CRC32C data
// that allows CrcCord to perform efficient substring operations. CrcCordState
// is used as a member variable in CrcCord. When a CrcCord is converted to a
// Cord, the CrcCordState is shallow-copied into the root node of the Cord. If
// the converted Cord is modified outside of CrcCord, the CrcCordState is
// discarded from the Cord. If the Cord is converted back to a CrcCord, and the
// Cord is still carrying the CrcCordState in its root node, the CrcCord can
// re-use the CrcCordState, making the construction of the CrcCord cheap.
//
// CrcCordState does not try to encapsulate the CRC32C state (CrcCord requires
// knowledge of how CrcCordState represents the CRC32C state). It does
// encapsulate the copy-on-write nature of the state.
class CrcCordState {
 public:
  // Constructors.
  CrcCordState();
  CrcCordState(const CrcCordState&);
  CrcCordState(CrcCordState&&);

  // Destructor. Atomically unreferences the data.
  ~CrcCordState();

  // Copy and move operators.
  CrcCordState& operator=(const CrcCordState&);
  CrcCordState& operator=(CrcCordState&&);

  // A (length, crc) pair.
  struct PrefixCrc {
    PrefixCrc() = default;
    PrefixCrc(size_t length_arg, absl::crc32c_t crc_arg)
        : length(length_arg), crc(crc_arg) {}

    size_t length = 0;

    // TODO(absl-team): Memory stomping often zeros out memory. If this struct
    // gets overwritten, we could end up with {0, 0}, which is the correct CRC
    // for a string of length 0. Consider storing a scrambled value and
    // unscrambling it before verifying it.
    absl::crc32c_t crc = absl::crc32c_t{0};
  };

  // The representation of the chunked CRC32C data.
  struct Rep {
    // `removed_prefix` is the crc and length of any prefix that has been
    // removed from the Cord (for example, by calling
    // `CrcCord::RemovePrefix()`). To get the checksum of any prefix of the
    // cord, this value must be subtracted from `prefix_crc`. See `Checksum()`
    // for an example.
    //
    // CrcCordState is said to be "normalized" if removed_prefix.length == 0.
    PrefixCrc removed_prefix;

    // A deque of (length, crc) pairs, representing length and crc of a prefix
    // of the Cord, before removed_prefix has been subtracted. The lengths of
    // the prefixes are stored in increasing order. If the Cord is not empty,
    // the last value in deque is the contains the CRC32C of the entire Cord
    // when removed_prefix is subtracted from it.
    std::deque<PrefixCrc> prefix_crc;
  };

  // Returns a reference to the representation of the chunked CRC32C data.
  const Rep& rep() const { return refcounted_rep_->rep; }

  // Returns a mutable reference to the representation of the chunked CRC32C
  // data. Calling this function will copy the data if another instance also
  // holds a reference to the data, so it is important to call rep() instead if
  // the data may not be mutated.
  Rep* mutable_rep() {
    if (refcounted_rep_->count.load(std::memory_order_acquire) != 1) {
      RefcountedRep* copy = new RefcountedRep;
      copy->rep = refcounted_rep_->rep;
      Unref(refcounted_rep_);
      refcounted_rep_ = copy;
    }
    return &refcounted_rep_->rep;
  }

  // Returns the CRC32C of the entire Cord.
  absl::crc32c_t Checksum() const;

  // Returns true if the chunked CRC32C cached is normalized.
  bool IsNormalized() const { return rep().removed_prefix.length == 0; }

  // Normalizes the chunked CRC32C checksum cache by subtracting any removed
  // prefix from the chunks.
  void Normalize();

  // Returns the number of cached chunks.
  size_t NumChunks() const { return rep().prefix_crc.size(); }

  // Helper that returns the (length, crc) of the `n`-th cached chunked.
  PrefixCrc NormalizedPrefixCrcAtNthChunk(size_t n) const;

  // Poisons all chunks to so that Checksum() will likely be incorrect with high
  // probability.
  void Poison();

 private:
  struct RefcountedRep {
    std::atomic<int32_t> count{1};
    Rep rep;
  };

  // Adds a reference to the shared global empty `RefcountedRep`, and returns a
  // pointer to the `RefcountedRep`. This is an optimization to avoid unneeded
  // allocations when the allocation is unlikely to ever be used. The returned
  // pointer can be `Unref()`ed when it is no longer needed.  Since the returned
  // instance will always have a reference counter greater than 1, attempts to
  // modify it (by calling `mutable_rep()`) will create a new unshared copy.
  static RefcountedRep* RefSharedEmptyRep();

  static void Ref(RefcountedRep* r) {
    assert(r != nullptr);
    r->count.fetch_add(1, std::memory_order_relaxed);
  }

  static void Unref(RefcountedRep* r) {
    assert(r != nullptr);
    if (r->count.fetch_sub(1, std::memory_order_acq_rel) == 1) {
      delete r;
    }
  }

  RefcountedRep* refcounted_rep_;
};

}  // namespace crc_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_CRC_INTERNAL_CRC_CORD_STATE_H_
*ÑÑ
[soong/.intermediates/external/abseil-cpp/absl_time_hdrs/gen/my_include_dir/absl/time/time.hðÐ// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// File: time.h
// -----------------------------------------------------------------------------
//
// This header file defines abstractions for computing with absolute points
// in time, durations of time, and formatting and parsing time within a given
// time zone. The following abstractions are defined:
//
//  * `absl::Time` defines an absolute, specific instance in time
//  * `absl::Duration` defines a signed, fixed-length span of time
//  * `absl::TimeZone` defines geopolitical time zone regions (as collected
//     within the IANA Time Zone database (https://www.iana.org/time-zones)).
//
// Note: Absolute times are distinct from civil times, which refer to the
// human-scale time commonly represented by `YYYY-MM-DD hh:mm:ss`. The mapping
// between absolute and civil times can be specified by use of time zones
// (`absl::TimeZone` within this API). That is:
//
//   Civil Time = F(Absolute Time, Time Zone)
//   Absolute Time = G(Civil Time, Time Zone)
//
// See civil_time.h for abstractions related to constructing and manipulating
// civil time.
//
// Example:
//
//   absl::TimeZone nyc;
//   // LoadTimeZone() may fail so it's always better to check for success.
//   if (!absl::LoadTimeZone("America/New_York", &nyc)) {
//      // handle error case
//   }
//
//   // My flight leaves NYC on Jan 2, 2017 at 03:04:05
//   absl::CivilSecond cs(2017, 1, 2, 3, 4, 5);
//   absl::Time takeoff = absl::FromCivil(cs, nyc);
//
//   absl::Duration flight_duration = absl::Hours(21) + absl::Minutes(35);
//   absl::Time landing = takeoff + flight_duration;
//
//   absl::TimeZone syd;
//   if (!absl::LoadTimeZone("Australia/Sydney", &syd)) {
//      // handle error case
//   }
//   std::string s = absl::FormatTime(
//       "My flight will land in Sydney on %Y-%m-%d at %H:%M:%S",
//       landing, syd);

#ifndef ABSL_TIME_TIME_H_
#define ABSL_TIME_TIME_H_

#if !defined(_MSC_VER)
#include <sys/time.h>
#else
// We don't include `winsock2.h` because it drags in `windows.h` and friends,
// and they define conflicting macros like OPAQUE, ERROR, and more. This has the
// potential to break Abseil users.
//
// Instead we only forward declare `timeval` and require Windows users include
// `winsock2.h` themselves. This is both inconsistent and troublesome, but so is
// including 'windows.h' so we are picking the lesser of two evils here.
struct timeval;
#endif

#include "absl/base/config.h"

// For feature testing and determining which headers can be included.
#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
#include <version>
#endif

#include <chrono>  // NOLINT(build/c++11)
#include <cmath>
#ifdef __cpp_lib_three_way_comparison
#include <compare>
#endif  // __cpp_lib_three_way_comparison
#include <cstdint>
#include <ctime>
#include <limits>
#include <ostream>
#include <ratio>  // NOLINT(build/c++11)
#include <string>
#include <type_traits>
#include <utility>

#include "absl/base/attributes.h"
#include "absl/base/macros.h"
#include "absl/strings/string_view.h"
#include "absl/time/civil_time.h"
#include "absl/time/internal/cctz/include/cctz/time_zone.h"

#if defined(__cpp_impl_three_way_comparison) && \
    defined(__cpp_lib_three_way_comparison)
#define ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON 1
#endif

namespace absl {
ABSL_NAMESPACE_BEGIN

class Duration;  // Defined below
class Time;      // Defined below
class TimeZone;  // Defined below

namespace time_internal {
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromUnixDuration(Duration d);
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration ToUnixDuration(Time t);
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr int64_t GetRepHi(Duration d);
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr uint32_t GetRepLo(Duration d);
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration MakeDuration(int64_t hi,
                                                              uint32_t lo);
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration MakeDuration(int64_t hi,
                                                              int64_t lo);
ABSL_ATTRIBUTE_CONST_FUNCTION inline Duration MakePosDoubleDuration(double n);
constexpr int64_t kTicksPerNanosecond = 4;
constexpr int64_t kTicksPerSecond = 1000 * 1000 * 1000 * kTicksPerNanosecond;
template <std::intmax_t N>
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration FromInt64(int64_t v,
                                                           std::ratio<1, N>);
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration FromInt64(int64_t v,
                                                           std::ratio<60>);
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration FromInt64(int64_t v,
                                                           std::ratio<3600>);
template <typename T>
using EnableIfIntegral = typename std::enable_if<
    std::is_integral<T>::value || std::is_enum<T>::value, int>::type;
template <typename T>
using EnableIfFloat =
    typename std::enable_if<std::is_floating_point<T>::value, int>::type;
}  // namespace time_internal

// Duration
//
// The `absl::Duration` class represents a signed, fixed-length amount of time.
// A `Duration` is generated using a unit-specific factory function, or is
// the result of subtracting one `absl::Time` from another. Durations behave
// like unit-safe integers and they support all the natural integer-like
// arithmetic operations. Arithmetic overflows and saturates at +/- infinity.
// `Duration` is trivially destructible and should be passed by value rather
// than const reference.
//
// Factory functions `Nanoseconds()`, `Microseconds()`, `Milliseconds()`,
// `Seconds()`, `Minutes()`, `Hours()` and `InfiniteDuration()` allow for
// creation of constexpr `Duration` values
//
// Examples:
//
//   constexpr absl::Duration ten_ns = absl::Nanoseconds(10);
//   constexpr absl::Duration min = absl::Minutes(1);
//   constexpr absl::Duration hour = absl::Hours(1);
//   absl::Duration dur = 60 * min;  // dur == hour
//   absl::Duration half_sec = absl::Milliseconds(500);
//   absl::Duration quarter_sec = 0.25 * absl::Seconds(1);
//
// `Duration` values can be easily converted to an integral number of units
// using the division operator.
//
// Example:
//
//   constexpr absl::Duration dur = absl::Milliseconds(1500);
//   int64_t ns = dur / absl::Nanoseconds(1);   // ns == 1500000000
//   int64_t ms = dur / absl::Milliseconds(1);  // ms == 1500
//   int64_t sec = dur / absl::Seconds(1);    // sec == 1 (subseconds truncated)
//   int64_t min = dur / absl::Minutes(1);    // min == 0
//
// See the `IDivDuration()` and `FDivDuration()` functions below for details on
// how to access the fractional parts of the quotient.
//
// Alternatively, conversions can be performed using helpers such as
// `ToInt64Microseconds()` and `ToDoubleSeconds()`.
class Duration {
 public:
  // Value semantics.
  constexpr Duration() : rep_hi_(0), rep_lo_(0) {}  // zero-length duration

  // Copyable.
#if !defined(__clang__) && defined(_MSC_VER) && _MSC_VER < 1930
  // Explicitly defining the constexpr copy constructor avoids an MSVC bug.
  constexpr Duration(const Duration& d)
      : rep_hi_(d.rep_hi_), rep_lo_(d.rep_lo_) {}
#else
  constexpr Duration(const Duration& d) = default;
#endif
  Duration& operator=(const Duration& d) = default;

  // Compound assignment operators.
  Duration& operator+=(Duration d);
  Duration& operator-=(Duration d);
  Duration& operator*=(int64_t r);
  Duration& operator*=(double r);
  Duration& operator/=(int64_t r);
  Duration& operator/=(double r);
  Duration& operator%=(Duration rhs);

  // Overloads that forward to either the int64_t or double overloads above.
  // Integer operands must be representable as int64_t. Integer division is
  // truncating, so values less than the resolution will be returned as zero.
  // Floating-point multiplication and division is rounding (halfway cases
  // rounding away from zero), so values less than the resolution may be
  // returned as either the resolution or zero.  In particular, `d / 2.0`
  // can produce `d` when it is the resolution and "even".
  template <typename T, time_internal::EnableIfIntegral<T> = 0>
  Duration& operator*=(T r) {
    int64_t x = r;
    return *this *= x;
  }

  template <typename T, time_internal::EnableIfIntegral<T> = 0>
  Duration& operator/=(T r) {
    int64_t x = r;
    return *this /= x;
  }

  template <typename T, time_internal::EnableIfFloat<T> = 0>
  Duration& operator*=(T r) {
    double x = r;
    return *this *= x;
  }

  template <typename T, time_internal::EnableIfFloat<T> = 0>
  Duration& operator/=(T r) {
    double x = r;
    return *this /= x;
  }

  template <typename H>
  friend H AbslHashValue(H h, Duration d) {
    return H::combine(std::move(h), d.rep_hi_.Get(), d.rep_lo_);
  }

 private:
  friend constexpr int64_t time_internal::GetRepHi(Duration d);
  friend constexpr uint32_t time_internal::GetRepLo(Duration d);
  friend constexpr Duration time_internal::MakeDuration(int64_t hi,
                                                        uint32_t lo);
  constexpr Duration(int64_t hi, uint32_t lo) : rep_hi_(hi), rep_lo_(lo) {}

  // We store `rep_hi_` 4-byte rather than 8-byte aligned to avoid 4 bytes of
  // tail padding.
  class HiRep {
   public:
    // Default constructor default-initializes `hi_`, which has the same
    // semantics as default-initializing an `int64_t` (undetermined value).
    HiRep() = default;

    HiRep(const HiRep&) = default;
    HiRep& operator=(const HiRep&) = default;

    explicit constexpr HiRep(const int64_t value)
        :  // C++17 forbids default-initialization in constexpr contexts. We can
           // remove this in C++20.
#if defined(ABSL_IS_BIG_ENDIAN) && ABSL_IS_BIG_ENDIAN
          hi_(0),
          lo_(0)
#else
          lo_(0),
          hi_(0)
#endif
    {
      *this = value;
    }

    constexpr int64_t Get() const {
      const uint64_t unsigned_value =
          (static_cast<uint64_t>(hi_) << 32) | static_cast<uint64_t>(lo_);
      // `static_cast<int64_t>(unsigned_value)` is implementation-defined
      // before c++20. On all supported platforms the behaviour is that mandated
      // by c++20, i.e. "If the destination type is signed, [...] the result is
      // the unique value of the destination type equal to the source value
      // modulo 2^n, where n is the number of bits used to represent the
      // destination type."
      static_assert(
          (static_cast<int64_t>((std::numeric_limits<uint64_t>::max)()) ==
           int64_t{-1}) &&
              (static_cast<int64_t>(static_cast<uint64_t>(
                                        (std::numeric_limits<int64_t>::max)()) +
                                    1) ==
               (std::numeric_limits<int64_t>::min)()),
          "static_cast<int64_t>(uint64_t) does not have c++20 semantics");
      return static_cast<int64_t>(unsigned_value);
    }

    constexpr HiRep& operator=(const int64_t value) {
      // "If the destination type is unsigned, the resulting value is the
      // smallest unsigned value equal to the source value modulo 2^n
      // where `n` is the number of bits used to represent the destination
      // type".
      const auto unsigned_value = static_cast<uint64_t>(value);
      hi_ = static_cast<uint32_t>(unsigned_value >> 32);
      lo_ = static_cast<uint32_t>(unsigned_value);
      return *this;
    }

   private:
    // Notes:
    //  - Ideally we would use a `char[]` and `std::bitcast`, but the latter
    //    does not exist (and is not constexpr in `absl`) before c++20.
    //  - Order is optimized depending on endianness so that the compiler can
    //    turn `Get()` (resp. `operator=()`) into a single 8-byte load (resp.
    //    store).
#if defined(ABSL_IS_BIG_ENDIAN) && ABSL_IS_BIG_ENDIAN
    uint32_t hi_;
    uint32_t lo_;
#else
    uint32_t lo_;
    uint32_t hi_;
#endif
  };
  HiRep rep_hi_;
  uint32_t rep_lo_;
};

// Relational Operators

#ifdef ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON

ABSL_ATTRIBUTE_CONST_FUNCTION constexpr std::strong_ordering operator<=>(
    Duration lhs, Duration rhs);

#endif  // ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON

ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator<(Duration lhs,
                                                       Duration rhs);
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator>(Duration lhs,
                                                       Duration rhs) {
  return rhs < lhs;
}
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator>=(Duration lhs,
                                                        Duration rhs) {
  return !(lhs < rhs);
}
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator<=(Duration lhs,
                                                        Duration rhs) {
  return !(rhs < lhs);
}
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator==(Duration lhs,
                                                        Duration rhs);
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator!=(Duration lhs,
                                                        Duration rhs) {
  return !(lhs == rhs);
}

// Additive Operators
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration operator-(Duration d);
ABSL_ATTRIBUTE_CONST_FUNCTION inline Duration operator+(Duration lhs,
                                                        Duration rhs) {
  return lhs += rhs;
}
ABSL_ATTRIBUTE_CONST_FUNCTION inline Duration operator-(Duration lhs,
                                                        Duration rhs) {
  return lhs -= rhs;
}

// IDivDuration()
//
// Divides a numerator `Duration` by a denominator `Duration`, returning the
// quotient and remainder. The remainder always has the same sign as the
// numerator. The returned quotient and remainder respect the identity:
//
//   numerator = denominator * quotient + remainder
//
// Returned quotients are capped to the range of `int64_t`, with the difference
// spilling into the remainder to uphold the above identity. This means that the
// remainder returned could differ from the remainder returned by
// `Duration::operator%` for huge quotients.
//
// See also the notes on `InfiniteDuration()` below regarding the behavior of
// division involving zero and infinite durations.
//
// Example:
//
//   constexpr absl::Duration a =
//       absl::Seconds(std::numeric_limits<int64_t>::max());  // big
//   constexpr absl::Duration b = absl::Nanoseconds(1);       // small
//
//   absl::Duration rem = a % b;
//   // rem == absl::ZeroDuration()
//
//   // Here, q would overflow int64_t, so rem accounts for the difference.
//   int64_t q = absl::IDivDuration(a, b, &rem);
//   // q == std::numeric_limits<int64_t>::max(), rem == a - b * q
int64_t IDivDuration(Duration num, Duration den, Duration* rem);

// FDivDuration()
//
// Divides a `Duration` numerator into a fractional number of units of a
// `Duration` denominator.
//
// See also the notes on `InfiniteDuration()` below regarding the behavior of
// division involving zero and infinite durations.
//
// Example:
//
//   double d = absl::FDivDuration(absl::Milliseconds(1500), absl::Seconds(1));
//   // d == 1.5
ABSL_ATTRIBUTE_CONST_FUNCTION double FDivDuration(Duration num, Duration den);

// Multiplicative Operators
// Integer operands must be representable as int64_t.
template <typename T>
ABSL_ATTRIBUTE_CONST_FUNCTION Duration operator*(Duration lhs, T rhs) {
  return lhs *= rhs;
}
template <typename T>
ABSL_ATTRIBUTE_CONST_FUNCTION Duration operator*(T lhs, Duration rhs) {
  return rhs *= lhs;
}
template <typename T>
ABSL_ATTRIBUTE_CONST_FUNCTION Duration operator/(Duration lhs, T rhs) {
  return lhs /= rhs;
}
ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t operator/(Duration lhs,
                                                       Duration rhs) {
  return IDivDuration(lhs, rhs,
                      &lhs);  // trunc towards zero
}
ABSL_ATTRIBUTE_CONST_FUNCTION inline Duration operator%(Duration lhs,
                                                        Duration rhs) {
  return lhs %= rhs;
}

// ZeroDuration()
//
// Returns a zero-length duration. This function behaves just like the default
// constructor, but the name helps make the semantics clear at call sites.
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration ZeroDuration() {
  return Duration();
}

// AbsDuration()
//
// Returns the absolute value of a duration.
ABSL_ATTRIBUTE_CONST_FUNCTION inline Duration AbsDuration(Duration d) {
  return (d < ZeroDuration()) ? -d : d;
}

// Trunc()
//
// Truncates a duration (toward zero) to a multiple of a non-zero unit.
//
// Example:
//
//   absl::Duration d = absl::Nanoseconds(123456789);
//   absl::Duration a = absl::Trunc(d, absl::Microseconds(1));  // 123456us
ABSL_ATTRIBUTE_CONST_FUNCTION Duration Trunc(Duration d, Duration unit);

// Floor()
//
// Floors a duration using the passed duration unit to its largest value not
// greater than the duration.
//
// Example:
//
//   absl::Duration d = absl::Nanoseconds(123456789);
//   absl::Duration b = absl::Floor(d, absl::Microseconds(1));  // 123456us
ABSL_ATTRIBUTE_CONST_FUNCTION Duration Floor(Duration d, Duration unit);

// Ceil()
//
// Returns the ceiling of a duration using the passed duration unit to its
// smallest value not less than the duration.
//
// Example:
//
//   absl::Duration d = absl::Nanoseconds(123456789);
//   absl::Duration c = absl::Ceil(d, absl::Microseconds(1));   // 123457us
ABSL_ATTRIBUTE_CONST_FUNCTION Duration Ceil(Duration d, Duration unit);

// InfiniteDuration()
//
// Returns an infinite `Duration`.  To get a `Duration` representing negative
// infinity, use `-InfiniteDuration()`.
//
// Duration arithmetic overflows to +/- infinity and saturates. In general,
// arithmetic with `Duration` infinities is similar to IEEE 754 infinities
// except where IEEE 754 NaN would be involved, in which case +/-
// `InfiniteDuration()` is used in place of a "nan" Duration.
//
// Examples:
//
//   constexpr absl::Duration inf = absl::InfiniteDuration();
//   const absl::Duration d = ... any finite duration ...
//
//   inf == inf + inf
//   inf == inf + d
//   inf == inf - inf
//   -inf == d - inf
//
//   inf == d * 1e100
//   inf == inf / 2
//   0 == d / inf
//   INT64_MAX == inf / d
//
//   d < inf
//   -inf < d
//
//   // Division by zero returns infinity, or INT64_MIN/MAX where appropriate.
//   inf == d / 0
//   INT64_MAX == d / absl::ZeroDuration()
//
// The examples involving the `/` operator above also apply to `IDivDuration()`
// and `FDivDuration()`.
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration InfiniteDuration();

// Nanoseconds()
// Microseconds()
// Milliseconds()
// Seconds()
// Minutes()
// Hours()
//
// Factory functions for constructing `Duration` values from an integral number
// of the unit indicated by the factory function's name. The number must be
// representable as int64_t.
//
// NOTE: no "Days()" factory function exists because "a day" is ambiguous.
// Civil days are not always 24 hours long, and a 24-hour duration often does
// not correspond with a civil day. If a 24-hour duration is needed, use
// `absl::Hours(24)`. If you actually want a civil day, use absl::CivilDay
// from civil_time.h.
//
// Example:
//
//   absl::Duration a = absl::Seconds(60);
//   absl::Duration b = absl::Minutes(1);  // b == a
template <typename T, time_internal::EnableIfIntegral<T> = 0>
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration Nanoseconds(T n) {
  return time_internal::FromInt64(n, std::nano{});
}
template <typename T, time_internal::EnableIfIntegral<T> = 0>
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration Microseconds(T n) {
  return time_internal::FromInt64(n, std::micro{});
}
template <typename T, time_internal::EnableIfIntegral<T> = 0>
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration Milliseconds(T n) {
  return time_internal::FromInt64(n, std::milli{});
}
template <typename T, time_internal::EnableIfIntegral<T> = 0>
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration Seconds(T n) {
  return time_internal::FromInt64(n, std::ratio<1>{});
}
template <typename T, time_internal::EnableIfIntegral<T> = 0>
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration Minutes(T n) {
  return time_internal::FromInt64(n, std::ratio<60>{});
}
template <typename T, time_internal::EnableIfIntegral<T> = 0>
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration Hours(T n) {
  return time_internal::FromInt64(n, std::ratio<3600>{});
}

// Factory overloads for constructing `Duration` values from a floating-point
// number of the unit indicated by the factory function's name. These functions
// exist for convenience, but they are not as efficient as the integral
// factories, which should be preferred.
//
// Example:
//
//   auto a = absl::Seconds(1.5);        // OK
//   auto b = absl::Milliseconds(1500);  // BETTER
template <typename T, time_internal::EnableIfFloat<T> = 0>
ABSL_ATTRIBUTE_CONST_FUNCTION Duration Nanoseconds(T n) {
  return n * Nanoseconds(1);
}
template <typename T, time_internal::EnableIfFloat<T> = 0>
ABSL_ATTRIBUTE_CONST_FUNCTION Duration Microseconds(T n) {
  return n * Microseconds(1);
}
template <typename T, time_internal::EnableIfFloat<T> = 0>
ABSL_ATTRIBUTE_CONST_FUNCTION Duration Milliseconds(T n) {
  return n * Milliseconds(1);
}
template <typename T, time_internal::EnableIfFloat<T> = 0>
ABSL_ATTRIBUTE_CONST_FUNCTION Duration Seconds(T n) {
  if (n >= 0) {  // Note: `NaN >= 0` is false.
    if (n >= static_cast<T>((std::numeric_limits<int64_t>::max)())) {
      return InfiniteDuration();
    }
    return time_internal::MakePosDoubleDuration(n);
  } else {
    if (std::isnan(n))
      return std::signbit(n) ? -InfiniteDuration() : InfiniteDuration();
    if (n <= (std::numeric_limits<int64_t>::min)()) return -InfiniteDuration();
    return -time_internal::MakePosDoubleDuration(-n);
  }
}
template <typename T, time_internal::EnableIfFloat<T> = 0>
ABSL_ATTRIBUTE_CONST_FUNCTION Duration Minutes(T n) {
  return n * Minutes(1);
}
template <typename T, time_internal::EnableIfFloat<T> = 0>
ABSL_ATTRIBUTE_CONST_FUNCTION Duration Hours(T n) {
  return n * Hours(1);
}

// ToInt64Nanoseconds()
// ToInt64Microseconds()
// ToInt64Milliseconds()
// ToInt64Seconds()
// ToInt64Minutes()
// ToInt64Hours()
//
// Helper functions that convert a Duration to an integral count of the
// indicated unit. These return the same results as the `IDivDuration()`
// function, though they usually do so more efficiently; see the
// documentation of `IDivDuration()` for details about overflow, etc.
//
// Example:
//
//   absl::Duration d = absl::Milliseconds(1500);
//   int64_t isec = absl::ToInt64Seconds(d);  // isec == 1
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr int64_t ToInt64Nanoseconds(Duration d);
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr int64_t ToInt64Microseconds(Duration d);
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr int64_t ToInt64Milliseconds(Duration d);
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr int64_t ToInt64Seconds(Duration d);
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr int64_t ToInt64Minutes(Duration d);
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr int64_t ToInt64Hours(Duration d);

// ToDoubleNanoseconds()
// ToDoubleMicroseconds()
// ToDoubleMilliseconds()
// ToDoubleSeconds()
// ToDoubleMinutes()
// ToDoubleHours()
//
// Helper functions that convert a Duration to a floating point count of the
// indicated unit. These functions are shorthand for the `FDivDuration()`
// function above; see its documentation for details about overflow, etc.
//
// Example:
//
//   absl::Duration d = absl::Milliseconds(1500);
//   double dsec = absl::ToDoubleSeconds(d);  // dsec == 1.5
ABSL_ATTRIBUTE_CONST_FUNCTION double ToDoubleNanoseconds(Duration d);
ABSL_ATTRIBUTE_CONST_FUNCTION double ToDoubleMicroseconds(Duration d);
ABSL_ATTRIBUTE_CONST_FUNCTION double ToDoubleMilliseconds(Duration d);
ABSL_ATTRIBUTE_CONST_FUNCTION double ToDoubleSeconds(Duration d);
ABSL_ATTRIBUTE_CONST_FUNCTION double ToDoubleMinutes(Duration d);
ABSL_ATTRIBUTE_CONST_FUNCTION double ToDoubleHours(Duration d);

// FromChrono()
//
// Converts any of the pre-defined std::chrono durations to an absl::Duration.
//
// Example:
//
//   std::chrono::milliseconds ms(123);
//   absl::Duration d = absl::FromChrono(ms);
ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono(
    const std::chrono::nanoseconds& d);
ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono(
    const std::chrono::microseconds& d);
ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono(
    const std::chrono::milliseconds& d);
ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono(
    const std::chrono::seconds& d);
ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono(
    const std::chrono::minutes& d);
ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono(
    const std::chrono::hours& d);

// ToChronoNanoseconds()
// ToChronoMicroseconds()
// ToChronoMilliseconds()
// ToChronoSeconds()
// ToChronoMinutes()
// ToChronoHours()
//
// Converts an absl::Duration to any of the pre-defined std::chrono durations.
// If overflow would occur, the returned value will saturate at the min/max
// chrono duration value instead.
//
// Example:
//
//   absl::Duration d = absl::Microseconds(123);
//   auto x = absl::ToChronoMicroseconds(d);
//   auto y = absl::ToChronoNanoseconds(d);  // x == y
//   auto z = absl::ToChronoSeconds(absl::InfiniteDuration());
//   // z == std::chrono::seconds::max()
ABSL_ATTRIBUTE_CONST_FUNCTION std::chrono::nanoseconds ToChronoNanoseconds(
    Duration d);
ABSL_ATTRIBUTE_CONST_FUNCTION std::chrono::microseconds ToChronoMicroseconds(
    Duration d);
ABSL_ATTRIBUTE_CONST_FUNCTION std::chrono::milliseconds ToChronoMilliseconds(
    Duration d);
ABSL_ATTRIBUTE_CONST_FUNCTION std::chrono::seconds ToChronoSeconds(Duration d);
ABSL_ATTRIBUTE_CONST_FUNCTION std::chrono::minutes ToChronoMinutes(Duration d);
ABSL_ATTRIBUTE_CONST_FUNCTION std::chrono::hours ToChronoHours(Duration d);

// FormatDuration()
//
// Returns a string representing the duration in the form "72h3m0.5s".
// Returns "inf" or "-inf" for +/- `InfiniteDuration()`.
ABSL_ATTRIBUTE_CONST_FUNCTION std::string FormatDuration(Duration d);

// Output stream operator.
inline std::ostream& operator<<(std::ostream& os, Duration d) {
  return os << FormatDuration(d);
}

// Support for StrFormat(), StrCat() etc.
template <typename Sink>
void AbslStringify(Sink& sink, Duration d) {
  sink.Append(FormatDuration(d));
}

// ParseDuration()
//
// Parses a duration string consisting of a possibly signed sequence of
// decimal numbers, each with an optional fractional part and a unit
// suffix.  The valid suffixes are "ns", "us" "ms", "s", "m", and "h".
// Simple examples include "300ms", "-1.5h", and "2h45m".  Parses "0" as
// `ZeroDuration()`. Parses "inf" and "-inf" as +/- `InfiniteDuration()`.
bool ParseDuration(absl::string_view dur_string, Duration* d);

// AbslParseFlag()
//
// Parses a command-line flag string representation `text` into a Duration
// value. Duration flags must be specified in a format that is valid input for
// `absl::ParseDuration()`.
bool AbslParseFlag(absl::string_view text, Duration* dst, std::string* error);


// AbslUnparseFlag()
//
// Unparses a Duration value into a command-line string representation using
// the format specified by `absl::ParseDuration()`.
std::string AbslUnparseFlag(Duration d);

ABSL_DEPRECATED("Use AbslParseFlag() instead.")
bool ParseFlag(const std::string& text, Duration* dst, std::string* error);
ABSL_DEPRECATED("Use AbslUnparseFlag() instead.")
std::string UnparseFlag(Duration d);

// Time
//
// An `absl::Time` represents a specific instant in time. Arithmetic operators
// are provided for naturally expressing time calculations. Instances are
// created using `absl::Now()` and the `absl::From*()` factory functions that
// accept the gamut of other time representations. Formatting and parsing
// functions are provided for conversion to and from strings. `absl::Time` is
// trivially destructible and should be passed by value rather than const
// reference.
//
// `absl::Time` assumes there are 60 seconds in a minute, which means the
// underlying time scales must be "smeared" to eliminate leap seconds.
// See https://developers.google.com/time/smear.
//
// Even though `absl::Time` supports a wide range of timestamps, exercise
// caution when using values in the distant past. `absl::Time` uses the
// Proleptic Gregorian calendar, which extends the Gregorian calendar backward
// to dates before its introduction in 1582.
// See https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar
// for more information. Use the ICU calendar classes to convert a date in
// some other calendar (http://userguide.icu-project.org/datetime/calendar).
//
// Similarly, standardized time zones are a reasonably recent innovation, with
// the Greenwich prime meridian being established in 1884. The TZ database
// itself does not profess accurate offsets for timestamps prior to 1970. The
// breakdown of future timestamps is subject to the whim of regional
// governments.
//
// The `absl::Time` class represents an instant in time as a count of clock
// ticks of some granularity (resolution) from some starting point (epoch).
//
// `absl::Time` uses a resolution that is high enough to avoid loss in
// precision, and a range that is wide enough to avoid overflow, when
// converting between tick counts in most Google time scales (i.e., resolution
// of at least one nanosecond, and range +/-100 billion years).  Conversions
// between the time scales are performed by truncating (towards negative
// infinity) to the nearest representable point.
//
// Examples:
//
//   absl::Time t1 = ...;
//   absl::Time t2 = t1 + absl::Minutes(2);
//   absl::Duration d = t2 - t1;  // == absl::Minutes(2)
//
class Time {
 public:
  // Value semantics.

  // Returns the Unix epoch.  However, those reading your code may not know
  // or expect the Unix epoch as the default value, so make your code more
  // readable by explicitly initializing all instances before use.
  //
  // Example:
  //   absl::Time t = absl::UnixEpoch();
  //   absl::Time t = absl::Now();
  //   absl::Time t = absl::TimeFromTimeval(tv);
  //   absl::Time t = absl::InfinitePast();
  constexpr Time() = default;

  // Copyable.
  constexpr Time(const Time& t) = default;
  Time& operator=(const Time& t) = default;

  // Assignment operators.
  Time& operator+=(Duration d) {
    rep_ += d;
    return *this;
  }
  Time& operator-=(Duration d) {
    rep_ -= d;
    return *this;
  }

  // Time::Breakdown
  //
  // The calendar and wall-clock (aka "civil time") components of an
  // `absl::Time` in a certain `absl::TimeZone`. This struct is not
  // intended to represent an instant in time. So, rather than passing
  // a `Time::Breakdown` to a function, pass an `absl::Time` and an
  // `absl::TimeZone`.
  //
  // Deprecated. Use `absl::TimeZone::CivilInfo`.
  struct ABSL_DEPRECATED("Use `absl::TimeZone::CivilInfo`.") Breakdown {
    int64_t year;        // year (e.g., 2013)
    int month;           // month of year [1:12]
    int day;             // day of month [1:31]
    int hour;            // hour of day [0:23]
    int minute;          // minute of hour [0:59]
    int second;          // second of minute [0:59]
    Duration subsecond;  // [Seconds(0):Seconds(1)) if finite
    int weekday;         // 1==Mon, ..., 7=Sun
    int yearday;         // day of year [1:366]

    // Note: The following fields exist for backward compatibility
    // with older APIs.  Accessing these fields directly is a sign of
    // imprudent logic in the calling code.  Modern time-related code
    // should only access this data indirectly by way of FormatTime().
    // These fields are undefined for InfiniteFuture() and InfinitePast().
    int offset;             // seconds east of UTC
    bool is_dst;            // is offset non-standard?
    const char* zone_abbr;  // time-zone abbreviation (e.g., "PST")
  };

  // Time::In()
  //
  // Returns the breakdown of this instant in the given TimeZone.
  //
  // Deprecated. Use `absl::TimeZone::At(Time)`.
  ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
  ABSL_DEPRECATED("Use `absl::TimeZone::At(Time)`.")
  Breakdown In(TimeZone tz) const;
  ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING

  template <typename H>
  friend H AbslHashValue(H h, Time t) {
    return H::combine(std::move(h), t.rep_);
  }

 private:
  friend constexpr Time time_internal::FromUnixDuration(Duration d);
  friend constexpr Duration time_internal::ToUnixDuration(Time t);

#ifdef ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
  friend constexpr std::strong_ordering operator<=>(Time lhs, Time rhs);
#endif  // ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON

  friend constexpr bool operator<(Time lhs, Time rhs);
  friend constexpr bool operator==(Time lhs, Time rhs);
  friend Duration operator-(Time lhs, Time rhs);
  friend constexpr Time UniversalEpoch();
  friend constexpr Time InfiniteFuture();
  friend constexpr Time InfinitePast();
  constexpr explicit Time(Duration rep) : rep_(rep) {}
  Duration rep_;
};

// Relational Operators
#ifdef ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON

ABSL_ATTRIBUTE_CONST_FUNCTION constexpr std::strong_ordering operator<=>(
    Time lhs, Time rhs) {
  return lhs.rep_ <=> rhs.rep_;
}

#endif  // ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON

ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator<(Time lhs, Time rhs) {
  return lhs.rep_ < rhs.rep_;
}
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator>(Time lhs, Time rhs) {
  return rhs < lhs;
}
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator>=(Time lhs, Time rhs) {
  return !(lhs < rhs);
}
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator<=(Time lhs, Time rhs) {
  return !(rhs < lhs);
}
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator==(Time lhs, Time rhs) {
  return lhs.rep_ == rhs.rep_;
}
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator!=(Time lhs, Time rhs) {
  return !(lhs == rhs);
}

// Additive Operators
ABSL_ATTRIBUTE_CONST_FUNCTION inline Time operator+(Time lhs, Duration rhs) {
  return lhs += rhs;
}
ABSL_ATTRIBUTE_CONST_FUNCTION inline Time operator+(Duration lhs, Time rhs) {
  return rhs += lhs;
}
ABSL_ATTRIBUTE_CONST_FUNCTION inline Time operator-(Time lhs, Duration rhs) {
  return lhs -= rhs;
}
ABSL_ATTRIBUTE_CONST_FUNCTION inline Duration operator-(Time lhs, Time rhs) {
  return lhs.rep_ - rhs.rep_;
}

// UnixEpoch()
//
// Returns the `absl::Time` representing "1970-01-01 00:00:00.0 +0000".
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time UnixEpoch() { return Time(); }

// UniversalEpoch()
//
// Returns the `absl::Time` representing "0001-01-01 00:00:00.0 +0000", the
// epoch of the ICU Universal Time Scale.
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time UniversalEpoch() {
  // 719162 is the number of days from 0001-01-01 to 1970-01-01,
  // assuming the Gregorian calendar.
  return Time(
      time_internal::MakeDuration(-24 * 719162 * int64_t{3600}, uint32_t{0}));
}

// InfiniteFuture()
//
// Returns an `absl::Time` that is infinitely far in the future.
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time InfiniteFuture() {
  return Time(time_internal::MakeDuration((std::numeric_limits<int64_t>::max)(),
                                          ~uint32_t{0}));
}

// InfinitePast()
//
// Returns an `absl::Time` that is infinitely far in the past.
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time InfinitePast() {
  return Time(time_internal::MakeDuration((std::numeric_limits<int64_t>::min)(),
                                          ~uint32_t{0}));
}

// FromUnixNanos()
// FromUnixMicros()
// FromUnixMillis()
// FromUnixSeconds()
// FromTimeT()
// FromUDate()
// FromUniversal()
//
// Creates an `absl::Time` from a variety of other representations.  See
// https://unicode-org.github.io/icu/userguide/datetime/universaltimescale.html
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromUnixNanos(int64_t ns);
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromUnixMicros(int64_t us);
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromUnixMillis(int64_t ms);
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromUnixSeconds(int64_t s);
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromTimeT(time_t t);
ABSL_ATTRIBUTE_CONST_FUNCTION Time FromUDate(double udate);
ABSL_ATTRIBUTE_CONST_FUNCTION Time FromUniversal(int64_t universal);

// ToUnixNanos()
// ToUnixMicros()
// ToUnixMillis()
// ToUnixSeconds()
// ToTimeT()
// ToUDate()
// ToUniversal()
//
// Converts an `absl::Time` to a variety of other representations.  See
// https://unicode-org.github.io/icu/userguide/datetime/universaltimescale.html
//
// Note that these operations round down toward negative infinity where
// necessary to adjust to the resolution of the result type.  Beware of
// possible time_t over/underflow in ToTime{T,val,spec}() on 32-bit platforms.
ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToUnixNanos(Time t);
ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToUnixMicros(Time t);
ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToUnixMillis(Time t);
ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToUnixSeconds(Time t);
ABSL_ATTRIBUTE_CONST_FUNCTION time_t ToTimeT(Time t);
ABSL_ATTRIBUTE_CONST_FUNCTION double ToUDate(Time t);
ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToUniversal(Time t);

// DurationFromTimespec()
// DurationFromTimeval()
// ToTimespec()
// ToTimeval()
// TimeFromTimespec()
// TimeFromTimeval()
// ToTimespec()
// ToTimeval()
//
// Some APIs use a timespec or a timeval as a Duration (e.g., nanosleep(2)
// and select(2)), while others use them as a Time (e.g. clock_gettime(2)
// and gettimeofday(2)), so conversion functions are provided for both cases.
// The "to timespec/val" direction is easily handled via overloading, but
// for "from timespec/val" the desired type is part of the function name.
ABSL_ATTRIBUTE_CONST_FUNCTION Duration DurationFromTimespec(timespec ts);
ABSL_ATTRIBUTE_CONST_FUNCTION Duration DurationFromTimeval(timeval tv);
ABSL_ATTRIBUTE_CONST_FUNCTION timespec ToTimespec(Duration d);
ABSL_ATTRIBUTE_CONST_FUNCTION timeval ToTimeval(Duration d);
ABSL_ATTRIBUTE_CONST_FUNCTION Time TimeFromTimespec(timespec ts);
ABSL_ATTRIBUTE_CONST_FUNCTION Time TimeFromTimeval(timeval tv);
ABSL_ATTRIBUTE_CONST_FUNCTION timespec ToTimespec(Time t);
ABSL_ATTRIBUTE_CONST_FUNCTION timeval ToTimeval(Time t);

// FromChrono()
//
// Converts a std::chrono::system_clock::time_point to an absl::Time.
//
// Example:
//
//   auto tp = std::chrono::system_clock::from_time_t(123);
//   absl::Time t = absl::FromChrono(tp);
//   // t == absl::FromTimeT(123)
ABSL_ATTRIBUTE_PURE_FUNCTION Time
FromChrono(const std::chrono::system_clock::time_point& tp);

// ToChronoTime()
//
// Converts an absl::Time to a std::chrono::system_clock::time_point. If
// overflow would occur, the returned value will saturate at the min/max time
// point value instead.
//
// Example:
//
//   absl::Time t = absl::FromTimeT(123);
//   auto tp = absl::ToChronoTime(t);
//   // tp == std::chrono::system_clock::from_time_t(123);
ABSL_ATTRIBUTE_CONST_FUNCTION std::chrono::system_clock::time_point
    ToChronoTime(Time);

// AbslParseFlag()
//
// Parses the command-line flag string representation `text` into a Time value.
// Time flags must be specified in a format that matches absl::RFC3339_full.
//
// For example:
//
//   --start_time=2016-01-02T03:04:05.678+08:00
//
// Note: A UTC offset (or 'Z' indicating a zero-offset from UTC) is required.
//
// Additionally, if you'd like to specify a time as a count of
// seconds/milliseconds/etc from the Unix epoch, use an absl::Duration flag
// and add that duration to absl::UnixEpoch() to get an absl::Time.
bool AbslParseFlag(absl::string_view text, Time* t, std::string* error);

// AbslUnparseFlag()
//
// Unparses a Time value into a command-line string representation using
// the format specified by `absl::ParseTime()`.
std::string AbslUnparseFlag(Time t);

ABSL_DEPRECATED("Use AbslParseFlag() instead.")
bool ParseFlag(const std::string& text, Time* t, std::string* error);
ABSL_DEPRECATED("Use AbslUnparseFlag() instead.")
std::string UnparseFlag(Time t);

// TimeZone
//
// The `absl::TimeZone` is an opaque, small, value-type class representing a
// geo-political region within which particular rules are used for converting
// between absolute and civil times (see https://git.io/v59Ly). `absl::TimeZone`
// values are named using the TZ identifiers from the IANA Time Zone Database,
// such as "America/Los_Angeles" or "Australia/Sydney". `absl::TimeZone` values
// are created from factory functions such as `absl::LoadTimeZone()`. Note:
// strings like "PST" and "EDT" are not valid TZ identifiers. Prefer to pass by
// value rather than const reference.
//
// For more on the fundamental concepts of time zones, absolute times, and civil
// times, see https://github.com/google/cctz#fundamental-concepts
//
// Examples:
//
//   absl::TimeZone utc = absl::UTCTimeZone();
//   absl::TimeZone pst = absl::FixedTimeZone(-8 * 60 * 60);
//   absl::TimeZone loc = absl::LocalTimeZone();
//   absl::TimeZone lax;
//   if (!absl::LoadTimeZone("America/Los_Angeles", &lax)) {
//     // handle error case
//   }
//
// See also:
// - https://github.com/google/cctz
// - https://www.iana.org/time-zones
// - https://en.wikipedia.org/wiki/Zoneinfo
class TimeZone {
 public:
  explicit TimeZone(time_internal::cctz::time_zone tz) : cz_(tz) {}
  TimeZone() = default;  // UTC, but prefer UTCTimeZone() to be explicit.

  // Copyable.
  TimeZone(const TimeZone&) = default;
  TimeZone& operator=(const TimeZone&) = default;

  explicit operator time_internal::cctz::time_zone() const { return cz_; }

  std::string name() const { return cz_.name(); }

  // TimeZone::CivilInfo
  //
  // Information about the civil time corresponding to an absolute time.
  // This struct is not intended to represent an instant in time. So, rather
  // than passing a `TimeZone::CivilInfo` to a function, pass an `absl::Time`
  // and an `absl::TimeZone`.
  struct CivilInfo {
    CivilSecond cs;
    Duration subsecond;

    // Note: The following fields exist for backward compatibility
    // with older APIs.  Accessing these fields directly is a sign of
    // imprudent logic in the calling code.  Modern time-related code
    // should only access this data indirectly by way of FormatTime().
    // These fields are undefined for InfiniteFuture() and InfinitePast().
    int offset;             // seconds east of UTC
    bool is_dst;            // is offset non-standard?
    const char* zone_abbr;  // time-zone abbreviation (e.g., "PST")
  };

  // TimeZone::At(Time)
  //
  // Returns the civil time for this TimeZone at a certain `absl::Time`.
  // If the input time is infinite, the output civil second will be set to
  // CivilSecond::max() or min(), and the subsecond will be infinite.
  //
  // Example:
  //
  //   const auto epoch = lax.At(absl::UnixEpoch());
  //   // epoch.cs == 1969-12-31 16:00:00
  //   // epoch.subsecond == absl::ZeroDuration()
  //   // epoch.offset == -28800
  //   // epoch.is_dst == false
  //   // epoch.abbr == "PST"
  CivilInfo At(Time t) const;

  // TimeZone::TimeInfo
  //
  // Information about the absolute times corresponding to a civil time.
  // (Subseconds must be handled separately.)
  //
  // It is possible for a caller to pass a civil-time value that does
  // not represent an actual or unique instant in time (due to a shift
  // in UTC offset in the TimeZone, which results in a discontinuity in
  // the civil-time components). For example, a daylight-saving-time
  // transition skips or repeats civil times---in the United States,
  // March 13, 2011 02:15 never occurred, while November 6, 2011 01:15
  // occurred twice---so requests for such times are not well-defined.
  // To account for these possibilities, `absl::TimeZone::TimeInfo` is
  // richer than just a single `absl::Time`.
  struct TimeInfo {
    enum CivilKind {
      UNIQUE,    // the civil time was singular (pre == trans == post)
      SKIPPED,   // the civil time did not exist (pre >= trans > post)
      REPEATED,  // the civil time was ambiguous (pre < trans <= post)
    } kind;
    Time pre;    // time calculated using the pre-transition offset
    Time trans;  // when the civil-time discontinuity occurred
    Time post;   // time calculated using the post-transition offset
  };

  // TimeZone::At(CivilSecond)
  //
  // Returns an `absl::TimeInfo` containing the absolute time(s) for this
  // TimeZone at an `absl::CivilSecond`. When the civil time is skipped or
  // repeated, returns times calculated using the pre-transition and post-
  // transition UTC offsets, plus the transition time itself.
  //
  // Examples:
  //
  //   // A unique civil time
  //   const auto jan01 = lax.At(absl::CivilSecond(2011, 1, 1, 0, 0, 0));
  //   // jan01.kind == TimeZone::TimeInfo::UNIQUE
  //   // jan01.pre    is 2011-01-01 00:00:00 -0800
  //   // jan01.trans  is 2011-01-01 00:00:00 -0800
  //   // jan01.post   is 2011-01-01 00:00:00 -0800
  //
  //   // A Spring DST transition, when there is a gap in civil time
  //   const auto mar13 = lax.At(absl::CivilSecond(2011, 3, 13, 2, 15, 0));
  //   // mar13.kind == TimeZone::TimeInfo::SKIPPED
  //   // mar13.pre   is 2011-03-13 03:15:00 -0700
  //   // mar13.trans is 2011-03-13 03:00:00 -0700
  //   // mar13.post  is 2011-03-13 01:15:00 -0800
  //
  //   // A Fall DST transition, when civil times are repeated
  //   const auto nov06 = lax.At(absl::CivilSecond(2011, 11, 6, 1, 15, 0));
  //   // nov06.kind == TimeZone::TimeInfo::REPEATED
  //   // nov06.pre   is 2011-11-06 01:15:00 -0700
  //   // nov06.trans is 2011-11-06 01:00:00 -0800
  //   // nov06.post  is 2011-11-06 01:15:00 -0800
  TimeInfo At(CivilSecond ct) const;

  // TimeZone::NextTransition()
  // TimeZone::PrevTransition()
  //
  // Finds the time of the next/previous offset change in this time zone.
  //
  // By definition, `NextTransition(t, &trans)` returns false when `t` is
  // `InfiniteFuture()`, and `PrevTransition(t, &trans)` returns false
  // when `t` is `InfinitePast()`. If the zone has no transitions, the
  // result will also be false no matter what the argument.
  //
  // Otherwise, when `t` is `InfinitePast()`, `NextTransition(t, &trans)`
  // returns true and sets `trans` to the first recorded transition. Chains
  // of calls to `NextTransition()/PrevTransition()` will eventually return
  // false, but it is unspecified exactly when `NextTransition(t, &trans)`
  // jumps to false, or what time is set by `PrevTransition(t, &trans)` for
  // a very distant `t`.
  //
  // Note: Enumeration of time-zone transitions is for informational purposes
  // only. Modern time-related code should not care about when offset changes
  // occur.
  //
  // Example:
  //   absl::TimeZone nyc;
  //   if (!absl::LoadTimeZone("America/New_York", &nyc)) { ... }
  //   const auto now = absl::Now();
  //   auto t = absl::InfinitePast();
  //   absl::TimeZone::CivilTransition trans;
  //   while (t <= now && nyc.NextTransition(t, &trans)) {
  //     // transition: trans.from -> trans.to
  //     t = nyc.At(trans.to).trans;
  //   }
  struct CivilTransition {
    CivilSecond from;  // the civil time we jump from
    CivilSecond to;    // the civil time we jump to
  };
  bool NextTransition(Time t, CivilTransition* trans) const;
  bool PrevTransition(Time t, CivilTransition* trans) const;

  template <typename H>
  friend H AbslHashValue(H h, TimeZone tz) {
    return H::combine(std::move(h), tz.cz_);
  }

 private:
  friend bool operator==(TimeZone a, TimeZone b) { return a.cz_ == b.cz_; }
  friend bool operator!=(TimeZone a, TimeZone b) { return a.cz_ != b.cz_; }
  friend std::ostream& operator<<(std::ostream& os, TimeZone tz) {
    return os << tz.name();
  }

  time_internal::cctz::time_zone cz_;
};

// LoadTimeZone()
//
// Loads the named zone. May perform I/O on the initial load of the named
// zone. If the name is invalid, or some other kind of error occurs, returns
// `false` and `*tz` is set to the UTC time zone.
inline bool LoadTimeZone(absl::string_view name, TimeZone* tz) {
  if (name == "localtime") {
    *tz = TimeZone(time_internal::cctz::local_time_zone());
    return true;
  }
  time_internal::cctz::time_zone cz;
  const bool b = time_internal::cctz::load_time_zone(std::string(name), &cz);
  *tz = TimeZone(cz);
  return b;
}

// FixedTimeZone()
//
// Returns a TimeZone that is a fixed offset (seconds east) from UTC.
// Note: If the absolute value of the offset is greater than 24 hours
// you'll get UTC (i.e., no offset) instead.
inline TimeZone FixedTimeZone(int seconds) {
  return TimeZone(
      time_internal::cctz::fixed_time_zone(std::chrono::seconds(seconds)));
}

// UTCTimeZone()
//
// Convenience method returning the UTC time zone.
inline TimeZone UTCTimeZone() {
  return TimeZone(time_internal::cctz::utc_time_zone());
}

// LocalTimeZone()
//
// Convenience method returning the local time zone, or UTC if there is
// no configured local zone.  Warning: Be wary of using LocalTimeZone(),
// and particularly so in a server process, as the zone configured for the
// local machine should be irrelevant.  Prefer an explicit zone name.
inline TimeZone LocalTimeZone() {
  return TimeZone(time_internal::cctz::local_time_zone());
}

// ToCivilSecond()
// ToCivilMinute()
// ToCivilHour()
// ToCivilDay()
// ToCivilMonth()
// ToCivilYear()
//
// Helpers for TimeZone::At(Time) to return particularly aligned civil times.
//
// Example:
//
//   absl::Time t = ...;
//   absl::TimeZone tz = ...;
//   const auto cd = absl::ToCivilDay(t, tz);
ABSL_ATTRIBUTE_PURE_FUNCTION inline CivilSecond ToCivilSecond(Time t,
                                                              TimeZone tz) {
  return tz.At(t).cs;  // already a CivilSecond
}
ABSL_ATTRIBUTE_PURE_FUNCTION inline CivilMinute ToCivilMinute(Time t,
                                                              TimeZone tz) {
  return CivilMinute(tz.At(t).cs);
}
ABSL_ATTRIBUTE_PURE_FUNCTION inline CivilHour ToCivilHour(Time t, TimeZone tz) {
  return CivilHour(tz.At(t).cs);
}
ABSL_ATTRIBUTE_PURE_FUNCTION inline CivilDay ToCivilDay(Time t, TimeZone tz) {
  return CivilDay(tz.At(t).cs);
}
ABSL_ATTRIBUTE_PURE_FUNCTION inline CivilMonth ToCivilMonth(Time t,
                                                            TimeZone tz) {
  return CivilMonth(tz.At(t).cs);
}
ABSL_ATTRIBUTE_PURE_FUNCTION inline CivilYear ToCivilYear(Time t, TimeZone tz) {
  return CivilYear(tz.At(t).cs);
}

// FromCivil()
//
// Helper for TimeZone::At(CivilSecond) that provides "order-preserving
// semantics." If the civil time maps to a unique time, that time is
// returned. If the civil time is repeated in the given time zone, the
// time using the pre-transition offset is returned. Otherwise, the
// civil time is skipped in the given time zone, and the transition time
// is returned. This means that for any two civil times, ct1 and ct2,
// (ct1 < ct2) => (FromCivil(ct1) <= FromCivil(ct2)), the equal case
// being when two non-existent civil times map to the same transition time.
//
// Note: Accepts civil times of any alignment.
ABSL_ATTRIBUTE_PURE_FUNCTION inline Time FromCivil(CivilSecond ct,
                                                   TimeZone tz) {
  const auto ti = tz.At(ct);
  if (ti.kind == TimeZone::TimeInfo::SKIPPED) return ti.trans;
  return ti.pre;
}

// TimeConversion
//
// An `absl::TimeConversion` represents the conversion of year, month, day,
// hour, minute, and second values (i.e., a civil time), in a particular
// `absl::TimeZone`, to a time instant (an absolute time), as returned by
// `absl::ConvertDateTime()`. Legacy version of `absl::TimeZone::TimeInfo`.
//
// Deprecated. Use `absl::TimeZone::TimeInfo`.
struct ABSL_DEPRECATED("Use `absl::TimeZone::TimeInfo`.") TimeConversion {
  Time pre;    // time calculated using the pre-transition offset
  Time trans;  // when the civil-time discontinuity occurred
  Time post;   // time calculated using the post-transition offset

  enum Kind {
    UNIQUE,    // the civil time was singular (pre == trans == post)
    SKIPPED,   // the civil time did not exist
    REPEATED,  // the civil time was ambiguous
  };
  Kind kind;

  bool normalized;  // input values were outside their valid ranges
};

// ConvertDateTime()
//
// Legacy version of `absl::TimeZone::At(absl::CivilSecond)` that takes
// the civil time as six, separate values (YMDHMS).
//
// The input month, day, hour, minute, and second values can be outside
// of their valid ranges, in which case they will be "normalized" during
// the conversion.
//
// Example:
//
//   // "October 32" normalizes to "November 1".
//   absl::TimeConversion tc =
//       absl::ConvertDateTime(2013, 10, 32, 8, 30, 0, lax);
//   // tc.kind == TimeConversion::UNIQUE && tc.normalized == true
//   // absl::ToCivilDay(tc.pre, tz).month() == 11
//   // absl::ToCivilDay(tc.pre, tz).day() == 1
//
// Deprecated. Use `absl::TimeZone::At(CivilSecond)`.
ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
ABSL_DEPRECATED("Use `absl::TimeZone::At(CivilSecond)`.")
TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour,
                               int min, int sec, TimeZone tz);
ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING

// FromDateTime()
//
// A convenience wrapper for `absl::ConvertDateTime()` that simply returns
// the "pre" `absl::Time`.  That is, the unique result, or the instant that
// is correct using the pre-transition offset (as if the transition never
// happened).
//
// Example:
//
//   absl::Time t = absl::FromDateTime(2017, 9, 26, 9, 30, 0, lax);
//   // t = 2017-09-26 09:30:00 -0700
//
// Deprecated. Use `absl::FromCivil(CivilSecond, TimeZone)`. Note that the
// behavior of `FromCivil()` differs from `FromDateTime()` for skipped civil
// times. If you care about that see `absl::TimeZone::At(absl::CivilSecond)`.
ABSL_DEPRECATED("Use `absl::FromCivil(CivilSecond, TimeZone)`.")
inline Time FromDateTime(int64_t year, int mon, int day, int hour, int min,
                         int sec, TimeZone tz) {
  ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
  return ConvertDateTime(year, mon, day, hour, min, sec, tz).pre;
  ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
}

// FromTM()
//
// Converts the `tm_year`, `tm_mon`, `tm_mday`, `tm_hour`, `tm_min`, and
// `tm_sec` fields to an `absl::Time` using the given time zone. See ctime(3)
// for a description of the expected values of the tm fields. If the civil time
// is unique (see `absl::TimeZone::At(absl::CivilSecond)` above), the matching
// time instant is returned.  Otherwise, the `tm_isdst` field is consulted to
// choose between the possible results.  For a repeated civil time, `tm_isdst !=
// 0` returns the matching DST instant, while `tm_isdst == 0` returns the
// matching non-DST instant.  For a skipped civil time there is no matching
// instant, so `tm_isdst != 0` returns the DST instant, and `tm_isdst == 0`
// returns the non-DST instant, that would have matched if the transition never
// happened.
ABSL_ATTRIBUTE_PURE_FUNCTION Time FromTM(const struct tm& tm, TimeZone tz);

// ToTM()
//
// Converts the given `absl::Time` to a struct tm using the given time zone.
// See ctime(3) for a description of the values of the tm fields.
ABSL_ATTRIBUTE_PURE_FUNCTION struct tm ToTM(Time t, TimeZone tz);

// RFC3339_full
// RFC3339_sec
//
// FormatTime()/ParseTime() format specifiers for RFC3339 date/time strings,
// with trailing zeros trimmed or with fractional seconds omitted altogether.
//
// Note that RFC3339_sec[] matches an ISO 8601 extended format for date and
// time with UTC offset.  Also note the use of "%Y": RFC3339 mandates that
// years have exactly four digits, but we allow them to take their natural
// width.
ABSL_DLL extern const char RFC3339_full[];  // %Y-%m-%d%ET%H:%M:%E*S%Ez
ABSL_DLL extern const char RFC3339_sec[];   // %Y-%m-%d%ET%H:%M:%S%Ez

// RFC1123_full
// RFC1123_no_wday
//
// FormatTime()/ParseTime() format specifiers for RFC1123 date/time strings.
ABSL_DLL extern const char RFC1123_full[];     // %a, %d %b %E4Y %H:%M:%S %z
ABSL_DLL extern const char RFC1123_no_wday[];  // %d %b %E4Y %H:%M:%S %z

// FormatTime()
//
// Formats the given `absl::Time` in the `absl::TimeZone` according to the
// provided format string. Uses strftime()-like formatting options, with
// the following extensions:
//
//   - %Ez  - RFC3339-compatible numeric UTC offset (+hh:mm or -hh:mm)
//   - %E*z - Full-resolution numeric UTC offset (+hh:mm:ss or -hh:mm:ss)
//   - %E#S - Seconds with # digits of fractional precision
//   - %E*S - Seconds with full fractional precision (a literal '*')
//   - %E#f - Fractional seconds with # digits of precision
//   - %E*f - Fractional seconds with full precision (a literal '*')
//   - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999)
//   - %ET  - The RFC3339 "date-time" separator "T"
//
// Note that %E0S behaves like %S, and %E0f produces no characters.  In
// contrast %E*f always produces at least one digit, which may be '0'.
//
// Note that %Y produces as many characters as it takes to fully render the
// year.  A year outside of [-999:9999] when formatted with %E4Y will produce
// more than four characters, just like %Y.
//
// We recommend that format strings include the UTC offset (%z, %Ez, or %E*z)
// so that the result uniquely identifies a time instant.
//
// Example:
//
//   absl::CivilSecond cs(2013, 1, 2, 3, 4, 5);
//   absl::Time t = absl::FromCivil(cs, lax);
//   std::string f = absl::FormatTime("%H:%M:%S", t, lax);  // "03:04:05"
//   f = absl::FormatTime("%H:%M:%E3S", t, lax);  // "03:04:05.000"
//
// Note: If the given `absl::Time` is `absl::InfiniteFuture()`, the returned
// string will be exactly "infinite-future". If the given `absl::Time` is
// `absl::InfinitePast()`, the returned string will be exactly "infinite-past".
// In both cases the given format string and `absl::TimeZone` are ignored.
//
ABSL_ATTRIBUTE_PURE_FUNCTION std::string FormatTime(absl::string_view format,
                                                    Time t, TimeZone tz);

// Convenience functions that format the given time using the RFC3339_full
// format.  The first overload uses the provided TimeZone, while the second
// uses LocalTimeZone().
ABSL_ATTRIBUTE_PURE_FUNCTION std::string FormatTime(Time t, TimeZone tz);
ABSL_ATTRIBUTE_PURE_FUNCTION std::string FormatTime(Time t);

// Output stream operator.
inline std::ostream& operator<<(std::ostream& os, Time t) {
  return os << FormatTime(t);
}

// Support for StrFormat(), StrCat() etc.
template <typename Sink>
void AbslStringify(Sink& sink, Time t) {
  sink.Append(FormatTime(t));
}

// ParseTime()
//
// Parses an input string according to the provided format string and
// returns the corresponding `absl::Time`. Uses strftime()-like formatting
// options, with the same extensions as FormatTime(), but with the
// exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f.  %Ez
// and %E*z also accept the same inputs, which (along with %z) includes
// 'z' and 'Z' as synonyms for +00:00.  %ET accepts either 'T' or 't'.
//
// %Y consumes as many numeric characters as it can, so the matching data
// should always be terminated with a non-numeric.  %E4Y always consumes
// exactly four characters, including any sign.
//
// Unspecified fields are taken from the default date and time of ...
//
//   "1970-01-01 00:00:00.0 +0000"
//
// For example, parsing a string of "15:45" (%H:%M) will return an absl::Time
// that represents "1970-01-01 15:45:00.0 +0000".
//
// Note that since ParseTime() returns time instants, it makes the most sense
// to parse fully-specified date/time strings that include a UTC offset (%z,
// %Ez, or %E*z).
//
// Note also that `absl::ParseTime()` only heeds the fields year, month, day,
// hour, minute, (fractional) second, and UTC offset.  Other fields, like
// weekday (%a or %A), while parsed for syntactic validity, are ignored
// in the conversion.
//
// Date and time fields that are out-of-range will be treated as errors
// rather than normalizing them like `absl::CivilSecond` does.  For example,
// it is an error to parse the date "Oct 32, 2013" because 32 is out of range.
//
// A leap second of ":60" is normalized to ":00" of the following minute
// with fractional seconds discarded.  The following table shows how the
// given seconds and subseconds will be parsed:
//
//   "59.x" -> 59.x  // exact
//   "60.x" -> 00.0  // normalized
//   "00.x" -> 00.x  // exact
//
// Errors are indicated by returning false and assigning an error message
// to the "err" out param if it is non-null.
//
// Note: If the input string is exactly "infinite-future", the returned
// `absl::Time` will be `absl::InfiniteFuture()` and `true` will be returned.
// If the input string is "infinite-past", the returned `absl::Time` will be
// `absl::InfinitePast()` and `true` will be returned.
//
bool ParseTime(absl::string_view format, absl::string_view input, Time* time,
               std::string* err);

// Like ParseTime() above, but if the format string does not contain a UTC
// offset specification (%z/%Ez/%E*z) then the input is interpreted in the
// given TimeZone.  This means that the input, by itself, does not identify a
// unique instant.  Being time-zone dependent, it also admits the possibility
// of ambiguity or non-existence, in which case the "pre" time (as defined
// by TimeZone::TimeInfo) is returned.  For these reasons we recommend that
// all date/time strings include a UTC offset so they're context independent.
bool ParseTime(absl::string_view format, absl::string_view input, TimeZone tz,
               Time* time, std::string* err);

// ============================================================================
// Implementation Details Follow
// ============================================================================

namespace time_internal {

// Creates a Duration with a given representation.
// REQUIRES: hi,lo is a valid representation of a Duration as specified
// in time/duration.cc.
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration MakeDuration(int64_t hi,
                                                              uint32_t lo = 0) {
  return Duration(hi, lo);
}

ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration MakeDuration(int64_t hi,
                                                              int64_t lo) {
  return MakeDuration(hi, static_cast<uint32_t>(lo));
}

// Make a Duration value from a floating-point number, as long as that number
// is in the range [ 0 .. numeric_limits<int64_t>::max ), that is, as long as
// it's positive and can be converted to int64_t without risk of UB.
ABSL_ATTRIBUTE_CONST_FUNCTION inline Duration MakePosDoubleDuration(double n) {
  const int64_t int_secs = static_cast<int64_t>(n);
  const uint32_t ticks = static_cast<uint32_t>(
      std::round((n - static_cast<double>(int_secs)) * kTicksPerSecond));
  return ticks < kTicksPerSecond
             ? MakeDuration(int_secs, ticks)
             : MakeDuration(int_secs + 1, ticks - kTicksPerSecond);
}

// Creates a normalized Duration from an almost-normalized (sec,ticks)
// pair. sec may be positive or negative.  ticks must be in the range
// -kTicksPerSecond < *ticks < kTicksPerSecond.  If ticks is negative it
// will be normalized to a positive value in the resulting Duration.
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration MakeNormalizedDuration(
    int64_t sec, int64_t ticks) {
  return (ticks < 0) ? MakeDuration(sec - 1, ticks + kTicksPerSecond)
                     : MakeDuration(sec, ticks);
}

// Provide access to the Duration representation.
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr int64_t GetRepHi(Duration d) {
  return d.rep_hi_.Get();
}
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr uint32_t GetRepLo(Duration d) {
  return d.rep_lo_;
}

// Returns true iff d is positive or negative infinity.
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool IsInfiniteDuration(Duration d) {
  return GetRepLo(d) == ~uint32_t{0};
}

// Returns an infinite Duration with the opposite sign.
// REQUIRES: IsInfiniteDuration(d)
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration OppositeInfinity(Duration d) {
  return GetRepHi(d) < 0
             ? MakeDuration((std::numeric_limits<int64_t>::max)(), ~uint32_t{0})
             : MakeDuration((std::numeric_limits<int64_t>::min)(),
                            ~uint32_t{0});
}

// Returns (-n)-1 (equivalently -(n+1)) without avoidable overflow.
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr int64_t NegateAndSubtractOne(
    int64_t n) {
  // Note: Good compilers will optimize this expression to ~n when using
  // a two's-complement representation (which is required for int64_t).
  return (n < 0) ? -(n + 1) : (-n) - 1;
}

// Map between a Time and a Duration since the Unix epoch.  Note that these
// functions depend on the above mentioned choice of the Unix epoch for the
// Time representation (and both need to be Time friends).  Without this
// knowledge, we would need to add-in/subtract-out UnixEpoch() respectively.
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromUnixDuration(Duration d) {
  return Time(d);
}
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration ToUnixDuration(Time t) {
  return t.rep_;
}

template <std::intmax_t N>
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration FromInt64(int64_t v,
                                                           std::ratio<1, N>) {
  static_assert(0 < N && N <= 1000 * 1000 * 1000, "Unsupported ratio");
  // Subsecond ratios cannot overflow.
  return MakeNormalizedDuration(
      v / N, v % N * kTicksPerNanosecond * 1000 * 1000 * 1000 / N);
}
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration FromInt64(int64_t v,
                                                           std::ratio<60>) {
  return (v <= (std::numeric_limits<int64_t>::max)() / 60 &&
          v >= (std::numeric_limits<int64_t>::min)() / 60)
             ? MakeDuration(v * 60)
             : v > 0 ? InfiniteDuration() : -InfiniteDuration();
}
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration FromInt64(int64_t v,
                                                           std::ratio<3600>) {
  return (v <= (std::numeric_limits<int64_t>::max)() / 3600 &&
          v >= (std::numeric_limits<int64_t>::min)() / 3600)
             ? MakeDuration(v * 3600)
             : v > 0 ? InfiniteDuration() : -InfiniteDuration();
}

// IsValidRep64<T>(0) is true if the expression `int64_t{std::declval<T>()}` is
// valid. That is, if a T can be assigned to an int64_t without narrowing.
template <typename T>
constexpr auto IsValidRep64(int) -> decltype(int64_t{std::declval<T>()} == 0) {
  return true;
}
template <typename T>
constexpr auto IsValidRep64(char) -> bool {
  return false;
}

// Converts a std::chrono::duration to an absl::Duration.
template <typename Rep, typename Period>
ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono(
    const std::chrono::duration<Rep, Period>& d) {
  static_assert(IsValidRep64<Rep>(0), "duration::rep is invalid");
  return FromInt64(int64_t{d.count()}, Period{});
}

template <typename Ratio>
ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToInt64(Duration d, Ratio) {
  // Note: This may be used on MSVC, which may have a system_clock period of
  // std::ratio<1, 10 * 1000 * 1000>
  return ToInt64Seconds(d * Ratio::den / Ratio::num);
}
// Fastpath implementations for the 6 common duration units.
ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64(Duration d, std::nano) {
  return ToInt64Nanoseconds(d);
}
ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64(Duration d, std::micro) {
  return ToInt64Microseconds(d);
}
ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64(Duration d, std::milli) {
  return ToInt64Milliseconds(d);
}
ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64(Duration d,
                                                     std::ratio<1>) {
  return ToInt64Seconds(d);
}
ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64(Duration d,
                                                     std::ratio<60>) {
  return ToInt64Minutes(d);
}
ABSL_ATTRIBUTE_CONST_FUNCTION inline int64_t ToInt64(Duration d,
                                                     std::ratio<3600>) {
  return ToInt64Hours(d);
}

// Converts an absl::Duration to a chrono duration of type T.
template <typename T>
ABSL_ATTRIBUTE_CONST_FUNCTION T ToChronoDuration(Duration d) {
  using Rep = typename T::rep;
  using Period = typename T::period;
  static_assert(IsValidRep64<Rep>(0), "duration::rep is invalid");
  if (time_internal::IsInfiniteDuration(d))
    return d < ZeroDuration() ? (T::min)() : (T::max)();
  const auto v = ToInt64(d, Period{});
  if (v > (std::numeric_limits<Rep>::max)()) return (T::max)();
  if (v < (std::numeric_limits<Rep>::min)()) return (T::min)();
  return T{v};
}

}  // namespace time_internal

ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator<(Duration lhs,
                                                       Duration rhs) {
  return time_internal::GetRepHi(lhs) != time_internal::GetRepHi(rhs)
             ? time_internal::GetRepHi(lhs) < time_internal::GetRepHi(rhs)
         : time_internal::GetRepHi(lhs) == (std::numeric_limits<int64_t>::min)()
             ? time_internal::GetRepLo(lhs) + 1 <
                   time_internal::GetRepLo(rhs) + 1
             : time_internal::GetRepLo(lhs) < time_internal::GetRepLo(rhs);
}

#ifdef ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON

ABSL_ATTRIBUTE_CONST_FUNCTION constexpr std::strong_ordering operator<=>(
    Duration lhs, Duration rhs) {
  const int64_t lhs_hi = time_internal::GetRepHi(lhs);
  const int64_t rhs_hi = time_internal::GetRepHi(rhs);
  if (auto c = lhs_hi <=> rhs_hi; c != std::strong_ordering::equal) {
    return c;
  }
  const uint32_t lhs_lo = time_internal::GetRepLo(lhs);
  const uint32_t rhs_lo = time_internal::GetRepLo(rhs);
  return (lhs_hi == (std::numeric_limits<int64_t>::min)())
             ? (lhs_lo + 1) <=> (rhs_lo + 1)
             : lhs_lo <=> rhs_lo;
}

#endif  // ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON

ABSL_ATTRIBUTE_CONST_FUNCTION constexpr bool operator==(Duration lhs,
                                                        Duration rhs) {
  return time_internal::GetRepHi(lhs) == time_internal::GetRepHi(rhs) &&
         time_internal::GetRepLo(lhs) == time_internal::GetRepLo(rhs);
}

ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration operator-(Duration d) {
  // This is a little interesting because of the special cases.
  //
  // If rep_lo_ is zero, we have it easy; it's safe to negate rep_hi_, we're
  // dealing with an integral number of seconds, and the only special case is
  // the maximum negative finite duration, which can't be negated.
  //
  // Infinities stay infinite, and just change direction.
  //
  // Finally we're in the case where rep_lo_ is non-zero, and we can borrow
  // a second's worth of ticks and avoid overflow (as negating int64_t-min + 1
  // is safe).
  return time_internal::GetRepLo(d) == 0
             ? time_internal::GetRepHi(d) ==
                       (std::numeric_limits<int64_t>::min)()
                   ? InfiniteDuration()
                   : time_internal::MakeDuration(-time_internal::GetRepHi(d))
             : time_internal::IsInfiniteDuration(d)
                   ? time_internal::OppositeInfinity(d)
                   : time_internal::MakeDuration(
                         time_internal::NegateAndSubtractOne(
                             time_internal::GetRepHi(d)),
                         time_internal::kTicksPerSecond -
                             time_internal::GetRepLo(d));
}

ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration InfiniteDuration() {
  return time_internal::MakeDuration((std::numeric_limits<int64_t>::max)(),
                                     ~uint32_t{0});
}

ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono(
    const std::chrono::nanoseconds& d) {
  return time_internal::FromChrono(d);
}
ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono(
    const std::chrono::microseconds& d) {
  return time_internal::FromChrono(d);
}
ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono(
    const std::chrono::milliseconds& d) {
  return time_internal::FromChrono(d);
}
ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono(
    const std::chrono::seconds& d) {
  return time_internal::FromChrono(d);
}
ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono(
    const std::chrono::minutes& d) {
  return time_internal::FromChrono(d);
}
ABSL_ATTRIBUTE_PURE_FUNCTION constexpr Duration FromChrono(
    const std::chrono::hours& d) {
  return time_internal::FromChrono(d);
}

ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromUnixNanos(int64_t ns) {
  return time_internal::FromUnixDuration(Nanoseconds(ns));
}

ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromUnixMicros(int64_t us) {
  return time_internal::FromUnixDuration(Microseconds(us));
}

ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromUnixMillis(int64_t ms) {
  return time_internal::FromUnixDuration(Milliseconds(ms));
}

ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromUnixSeconds(int64_t s) {
  return time_internal::FromUnixDuration(Seconds(s));
}

ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Time FromTimeT(time_t t) {
  return time_internal::FromUnixDuration(Seconds(t));
}

ABSL_ATTRIBUTE_CONST_FUNCTION constexpr int64_t ToInt64Nanoseconds(Duration d) {
  if (time_internal::GetRepHi(d) >= 0 &&
      time_internal::GetRepHi(d) >> 33 == 0) {
    return (time_internal::GetRepHi(d) * 1000 * 1000 * 1000) +
           (time_internal::GetRepLo(d) / time_internal::kTicksPerNanosecond);
  } else {
    return d / Nanoseconds(1);
  }
}

ABSL_ATTRIBUTE_CONST_FUNCTION constexpr int64_t ToInt64Microseconds(
    Duration d) {
  if (time_internal::GetRepHi(d) >= 0 &&
      time_internal::GetRepHi(d) >> 43 == 0) {
    return (time_internal::GetRepHi(d) * 1000 * 1000) +
           (time_internal::GetRepLo(d) /
            (time_internal::kTicksPerNanosecond * 1000));
  } else {
    return d / Microseconds(1);
  }
}

ABSL_ATTRIBUTE_CONST_FUNCTION constexpr int64_t ToInt64Milliseconds(
    Duration d) {
  if (time_internal::GetRepHi(d) >= 0 &&
      time_internal::GetRepHi(d) >> 53 == 0) {
    return (time_internal::GetRepHi(d) * 1000) +
           (time_internal::GetRepLo(d) /
            (time_internal::kTicksPerNanosecond * 1000 * 1000));
  } else {
    return d / Milliseconds(1);
  }
}

ABSL_ATTRIBUTE_CONST_FUNCTION constexpr int64_t ToInt64Seconds(Duration d) {
  int64_t hi = time_internal::GetRepHi(d);
  if (time_internal::IsInfiniteDuration(d)) return hi;
  if (hi < 0 && time_internal::GetRepLo(d) != 0) ++hi;
  return hi;
}

ABSL_ATTRIBUTE_CONST_FUNCTION constexpr int64_t ToInt64Minutes(Duration d) {
  int64_t hi = time_internal::GetRepHi(d);
  if (time_internal::IsInfiniteDuration(d)) return hi;
  if (hi < 0 && time_internal::GetRepLo(d) != 0) ++hi;
  return hi / 60;
}

ABSL_ATTRIBUTE_CONST_FUNCTION constexpr int64_t ToInt64Hours(Duration d) {
  int64_t hi = time_internal::GetRepHi(d);
  if (time_internal::IsInfiniteDuration(d)) return hi;
  if (hi < 0 && time_internal::GetRepLo(d) != 0) ++hi;
  return hi / (60 * 60);
}

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_TIME_TIME_H_
*ë
wsoong/.intermediates/external/abseil-cpp/absl_base_endian_hdrs/gen/my_include_dir/absl/base/internal/unaligned_access.hï//
// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#ifndef ABSL_BASE_INTERNAL_UNALIGNED_ACCESS_H_
#define ABSL_BASE_INTERNAL_UNALIGNED_ACCESS_H_

#include <string.h>

#include <cstdint>

#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/nullability.h"

// unaligned APIs

// Portable handling of unaligned loads, stores, and copies.

// The unaligned API is C++ only.  The declarations use C++ features
// (namespaces, inline) which are absent or incompatible in C.
#if defined(__cplusplus)
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {

inline uint16_t UnalignedLoad16(const void* absl_nonnull p) {
  uint16_t t;
  memcpy(&t, p, sizeof t);
  return t;
}

inline uint32_t UnalignedLoad32(const void* absl_nonnull p) {
  uint32_t t;
  memcpy(&t, p, sizeof t);
  return t;
}

inline uint64_t UnalignedLoad64(const void* absl_nonnull p) {
  uint64_t t;
  memcpy(&t, p, sizeof t);
  return t;
}

inline void UnalignedStore16(void* absl_nonnull p, uint16_t v) {
  memcpy(p, &v, sizeof v);
}

inline void UnalignedStore32(void* absl_nonnull p, uint32_t v) {
  memcpy(p, &v, sizeof v);
}

inline void UnalignedStore64(void* absl_nonnull p, uint64_t v) {
  memcpy(p, &v, sizeof v);
}

}  // namespace base_internal
ABSL_NAMESPACE_END
}  // namespace absl

#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \
  (absl::base_internal::UnalignedLoad16(_p))
#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \
  (absl::base_internal::UnalignedLoad32(_p))
#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \
  (absl::base_internal::UnalignedLoad64(_p))

#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \
  (absl::base_internal::UnalignedStore16(_p, _val))
#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \
  (absl::base_internal::UnalignedStore32(_p, _val))
#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \
  (absl::base_internal::UnalignedStore64(_p, _val))

#endif  // defined(__cplusplus), end of unaligned API

#endif  // ABSL_BASE_INTERNAL_UNALIGNED_ACCESS_H_
*ÏP
Œsoong/.intermediates/external/abseil-cpp/absl_strings_cord_internal_hdrs/gen/my_include_dir/absl/strings/internal/cord_rep_btree_navigator.h½O// Copyright 2021 The Abseil Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_NAVIGATOR_H_
#define ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_NAVIGATOR_H_

#include <cassert>
#include <iostream>

#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_btree.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {

// CordRepBtreeNavigator is a bi-directional navigator allowing callers to
// navigate all the (leaf) data edges in a CordRepBtree instance.
//
// A CordRepBtreeNavigator instance is by default empty. Callers initialize a
// navigator instance by calling one of `InitFirst()`, `InitLast()` or
// `InitOffset()`, which establishes a current position. Callers can then
// navigate using the `Next`, `Previous`, `Skip` and `Seek` methods.
//
// The navigator instance does not take or adopt a reference on the provided
// `tree` on any of the initialization calls. Callers are responsible for
// guaranteeing the lifecycle of the provided tree. A navigator instance can
// be reset to the empty state by calling `Reset`.
//
// A navigator only keeps positional state on the 'current data edge', it does
// explicitly not keep any 'offset' state. The class does accept and return
// offsets in the `Read()`, `Skip()` and 'Seek()` methods as these would
// otherwise put a big burden on callers. Callers are expected to maintain
// (returned) offset info if they require such granular state.
class CordRepBtreeNavigator {
 public:
  // The logical position as returned by the Seek() and Skip() functions.
  // Returns the current leaf edge for the desired seek or skip position and
  // the offset of that position inside that edge.
  struct Position {
    CordRep* edge;
    size_t offset;
  };

  // The read result as returned by the Read() function.
  // `tree` contains the resulting tree which is identical to the result
  // of calling CordRepBtree::SubTree(...) on the tree being navigated.
  // `n` contains the number of bytes used from the last navigated to
  // edge of the tree.
  struct ReadResult {
    CordRep* tree;
    size_t n;
  };

  // Returns true if this instance is not empty.
  explicit operator bool() const;

  // Returns the tree for this instance or nullptr if empty.
  CordRepBtree* btree() const;

  // Returns the data edge of the current position.
  // Requires this instance to not be empty.
  CordRep* Current() const;

  // Resets this navigator to `tree`, returning the first data edge in the tree.
  CordRep* InitFirst(CordRepBtree* tree);

  // Resets this navigator to `tree`, returning the last data edge in the tree.
  CordRep* InitLast(CordRepBtree* tree);

  // Resets this navigator to `tree` returning the data edge at position
  // `offset` and the relative offset of `offset` into that data edge.
  // Returns `Position.edge = nullptr` if the provided offset is greater
  // than or equal to the length of the tree, in which case the state of
  // the navigator instance remains unchanged.
  Position InitOffset(CordRepBtree* tree, size_t offset);

  // Navigates to the next data edge.
  // Returns the next data edge or nullptr if there is no next data edge, in
  // which case the current position remains unchanged.
  CordRep* Next();

  // Navigates to the previous data edge.
  // Returns the previous data edge or nullptr if there is no previous data
  // edge, in which case the current position remains unchanged.
  CordRep* Previous();

  // Navigates to the data edge at position `offset`. Returns the navigated to
  // data edge in `Position.edge` and the relative offset of `offset` into that
  // data edge in `Position.offset`. Returns `Position.edge = nullptr` if the
  // provide offset is greater than or equal to the tree's length.
  Position Seek(size_t offset);

  // Reads `n` bytes of data starting at offset `edge_offset` of the current
  // data edge, and returns the result in `ReadResult.tree`. `ReadResult.n`
  // contains the 'bytes used` from the last / current data edge in the tree.
  // This allows users that mix regular navigation (using string views) and
  // 'read into cord' navigation to keep track of the current state, and which
  // bytes have been consumed from a navigator.
  // This function returns `ReadResult.tree = nullptr` if the requested length
  // exceeds the length of the tree starting at the current data edge.
  ReadResult Read(size_t edge_offset, size_t n);

  // Skips `n` bytes forward from the current data edge, returning the navigated
  // to data edge in `Position.edge` and `Position.offset` containing the offset
  // inside that data edge. Note that the state of the navigator is left
  // unchanged if `n` is smaller than the length of the current data edge.
  Position Skip(size_t n);

  // Resets this instance to the default / empty state.
  void Reset();

 private:
  // Slow path for Next() if Next() reached the end of a leaf node. Backtracks
  // up the stack until it finds a node that has a 'next' position available,
  // and then does a 'front dive' towards the next leaf node.
  CordRep* NextUp();

  // Slow path for Previous() if Previous() reached the beginning of a leaf
  // node. Backtracks up the stack until it finds a node that has a 'previous'
  // position available, and then does a 'back dive' towards the previous leaf
  // node.
  CordRep* PreviousUp();

  // Generic implementation of InitFirst() and InitLast().
  template <CordRepBtree::EdgeType edge_type>
  CordRep* Init(CordRepBtree* tree);

  // `height_` contains the height of the current tree, or -1 if empty.
  int height_ = -1;

  // `index_` and `node_` contain the navigation state as the 'path' to the
  // current data edge which is at `node_[0]->Edge(index_[0])`. The contents
  // of these are undefined until the instance is initialized (`height_ >= 0`).
  uint8_t index_[CordRepBtree::kMaxDepth];
  CordRepBtree* node_[CordRepBtree::kMaxDepth];
};

// Returns true if this instance is not empty.
inline CordRepBtreeNavigator::operator bool() const { return height_ >= 0; }

inline CordRepBtree* CordRepBtreeNavigator::btree() const {
  return height_ >= 0 ? node_[height_] : nullptr;
}

inline CordRep* CordRepBtreeNavigator::Current() const {
  assert(height_ >= 0);
  return node_[0]->Edge(index_[0]);
}

inline void CordRepBtreeNavigator::Reset() { height_ = -1; }

inline CordRep* CordRepBtreeNavigator::InitFirst(CordRepBtree* tree) {
  return Init<CordRepBtree::kFront>(tree);
}

inline CordRep* CordRepBtreeNavigator::InitLast(CordRepBtree* tree) {
  return Init<CordRepBtree::kBack>(tree);
}

template <CordRepBtree::EdgeType edge_type>
inline CordRep* CordRepBtreeNavigator::Init(CordRepBtree* tree) {
  assert(tree != nullptr);
  assert(tree->size() > 0);
  assert(tree->height() <= CordRepBtree::kMaxHeight);
  int height = height_ = tree->height();
  size_t index = tree->index(edge_type);
  node_[height] = tree;
  index_[height] = static_cast<uint8_t>(index);
  while (--height >= 0) {
    tree = tree->Edge(index)->btree();
    node_[height] = tree;
    index = tree->index(edge_type);
    index_[height] = static_cast<uint8_t>(index);
  }
  return node_[0]->Edge(index);
}

inline CordRepBtreeNavigator::Position CordRepBtreeNavigator::Seek(
    size_t offset) {
  assert(btree() != nullptr);
  int height = height_;
  CordRepBtree* edge = node_[height];
  if (ABSL_PREDICT_FALSE(offset >= edge->length)) return {nullptr, 0};
  CordRepBtree::Position index = edge->IndexOf(offset);
  index_[height] = static_cast<uint8_t>(index.index);
  while (--height >= 0) {
    edge = edge->Edge(index.index)->btree();
    node_[height] = edge;
    index = edge->IndexOf(index.n);
    index_[height] = static_cast<uint8_t>(index.index);
  }
  return {edge->Edge(index.index), index.n};
}

inline CordRepBtreeNavigator::Position CordRepBtreeNavigator::InitOffset(
    CordRepBtree* tree, size_t offset) {
  assert(tree != nullptr);
  assert(tree->height() <= CordRepBtree::kMaxHeight);
  if (ABSL_PREDICT_FALSE(offset >= tree->length)) return {nullptr, 0};
  height_ = tree->height();
  node_[height_] = tree;
  return Seek(offset);
}

inline CordRep* CordRepBtreeNavigator::Next() {
  CordRepBtree* edge = node_[0];
  return index_[0] == edge->back() ? NextUp() : edge->Edge(++index_[0]);
}

inline CordRep* CordRepBtreeNavigator::Previous() {
  CordRepBtree* edge = node_[0];
  return index_[0] == edge->begin() ? PreviousUp() : edge->Edge(--index_[0]);
}

inline CordRep* CordRepBtreeNavigator::NextUp() {
  assert(index_[0] == node_[0]->back());
  CordRepBtree* edge;
  size_t index;
  int height = 0;
  do {
    if (++height > height_) return nullptr;
    edge = node_[height];
    index = index_[height] + 1;
  } while (index == edge->end());
  index_[height] = static_cast<uint8_t>(index);
  do {
    node_[--height] = edge = edge->Edge(index)->btree();
    index_[height] = static_cast<uint8_t>(index = edge->begin());
  } while (height > 0);
  return edge->Edge(index);
}

inline CordRep* CordRepBtreeNavigator::PreviousUp() {
  assert(index_[0] == node_[0]->begin());
  CordRepBtree* edge;
  size_t index;
  int height = 0;
  do {
    if (++height > height_) return nullptr;
    edge = node_[height];
    index = index_[height];
  } while (index == edge->begin());
  index_[height] = static_cast<uint8_t>(--index);
  do {
    node_[--height] = edge = edge->Edge(index)->btree();
    index_[height] = static_cast<uint8_t>(index = edge->back());
  } while (height > 0);
  return edge->Edge(index);
}

}  // namespace cord_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_NAVIGATOR_H_
*ó 
soong/.intermediates/external/abseil-cpp/absl_strings_cordz_handle_hdrs/gen/my_include_dir/absl/strings/internal/cordz_handle.hï// Copyright 2019 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_STRINGS_INTERNAL_CORDZ_HANDLE_H_
#define ABSL_STRINGS_INTERNAL_CORDZ_HANDLE_H_

#include <atomic>
#include <vector>

#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {

// This base class allows multiple types of object (CordzInfo and
// CordzSampleToken) to exist simultaneously on the delete queue (pointed to by
// global_dq_tail and traversed using dq_prev_ and dq_next_). The
// delete queue guarantees that once a profiler creates a CordzSampleToken and
// has gained visibility into a CordzInfo object, that CordzInfo object will not
// be deleted prematurely. This allows the profiler to inspect all CordzInfo
// objects that are alive without needing to hold a global lock.
class ABSL_DLL CordzHandle {
 public:
  CordzHandle() : CordzHandle(false) {}

  bool is_snapshot() const { return is_snapshot_; }

  // Returns true if this instance is safe to be deleted because it is either a
  // snapshot, which is always safe to delete, or not included in the global
  // delete queue and thus not included in any snapshot.
  // Callers are responsible for making sure this instance can not be newly
  // discovered by other threads. For example, CordzInfo instances first de-list
  // themselves from the global CordzInfo list before determining if they are
  // safe to be deleted directly.
  // If SafeToDelete returns false, callers MUST use the Delete() method to
  // safely queue CordzHandle instances for deletion.
  bool SafeToDelete() const;

  // Deletes the provided instance, or puts it on the delete queue to be deleted
  // once there are no more sample tokens (snapshot) instances potentially
  // referencing the instance. `handle` should not be null.
  static void Delete(CordzHandle* handle);

  // Returns the current entries in the delete queue in LIFO order.
  static std::vector<const CordzHandle*> DiagnosticsGetDeleteQueue();

  // Returns true if the provided handle is nullptr or guarded by this handle.
  // Since the CordzSnapshot token is itself a CordzHandle, this method will
  // allow tests to check if that token is keeping an arbitrary CordzHandle
  // alive.
  bool DiagnosticsHandleIsSafeToInspect(const CordzHandle* handle) const;

  // Returns the current entries in the delete queue, in LIFO order, that are
  // protected by this. CordzHandle objects are only placed on the delete queue
  // after CordzHandle::Delete is called with them as an argument. Only
  // CordzHandle objects that are not also CordzSnapshot objects will be
  // included in the return vector. For each of the handles in the return
  // vector, the earliest that their memory can be freed is when this
  // CordzSnapshot object is deleted.
  std::vector<const CordzHandle*> DiagnosticsGetSafeToInspectDeletedHandles();

 protected:
  explicit CordzHandle(bool is_snapshot);
  virtual ~CordzHandle();

 private:
  const bool is_snapshot_;

  // dq_prev_ and dq_next_ require the global queue mutex to be held.
  // Unfortunately we can't use thread annotations such that the thread safety
  // analysis understands that queue_ and global_queue_ are one and the same.
  CordzHandle* dq_prev_  = nullptr;
  CordzHandle* dq_next_ = nullptr;
};

class CordzSnapshot : public CordzHandle {
 public:
  CordzSnapshot() : CordzHandle(true) {}
};

}  // namespace cord_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_CORDZ_HANDLE_H_
*Ò
tsoong/.intermediates/external/abseil-cpp/absl_base_hdrs/gen/my_include_dir/absl/base/internal/tsan_mutex_interface.hÙ// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// This file is intended solely for spinlock.h.
// It provides ThreadSanitizer annotations for custom mutexes.
// See <sanitizer/tsan_interface.h> for meaning of these annotations.

#ifndef ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_
#define ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_

#include "absl/base/config.h"

// ABSL_INTERNAL_HAVE_TSAN_INTERFACE
// Macro intended only for internal use.
//
// Checks whether LLVM Thread Sanitizer interfaces are available.
// First made available in LLVM 5.0 (Sep 2017).
#ifdef ABSL_INTERNAL_HAVE_TSAN_INTERFACE
#error "ABSL_INTERNAL_HAVE_TSAN_INTERFACE cannot be directly set."
#endif

#if defined(ABSL_HAVE_THREAD_SANITIZER) && defined(__has_include)
#if __has_include(<sanitizer/tsan_interface.h>)
#define ABSL_INTERNAL_HAVE_TSAN_INTERFACE 1
#endif
#endif

#ifdef ABSL_INTERNAL_HAVE_TSAN_INTERFACE
#include <sanitizer/tsan_interface.h>

#define ABSL_TSAN_MUTEX_CREATE __tsan_mutex_create
#define ABSL_TSAN_MUTEX_DESTROY __tsan_mutex_destroy
#define ABSL_TSAN_MUTEX_PRE_LOCK __tsan_mutex_pre_lock
#define ABSL_TSAN_MUTEX_POST_LOCK __tsan_mutex_post_lock
#define ABSL_TSAN_MUTEX_PRE_UNLOCK __tsan_mutex_pre_unlock
#define ABSL_TSAN_MUTEX_POST_UNLOCK __tsan_mutex_post_unlock
#define ABSL_TSAN_MUTEX_PRE_SIGNAL __tsan_mutex_pre_signal
#define ABSL_TSAN_MUTEX_POST_SIGNAL __tsan_mutex_post_signal
#define ABSL_TSAN_MUTEX_PRE_DIVERT __tsan_mutex_pre_divert
#define ABSL_TSAN_MUTEX_POST_DIVERT __tsan_mutex_post_divert

#else

#define ABSL_TSAN_MUTEX_CREATE(...)
#define ABSL_TSAN_MUTEX_DESTROY(...)
#define ABSL_TSAN_MUTEX_PRE_LOCK(...)
#define ABSL_TSAN_MUTEX_POST_LOCK(...)
#define ABSL_TSAN_MUTEX_PRE_UNLOCK(...)
#define ABSL_TSAN_MUTEX_POST_UNLOCK(...)
#define ABSL_TSAN_MUTEX_PRE_SIGNAL(...)
#define ABSL_TSAN_MUTEX_POST_SIGNAL(...)
#define ABSL_TSAN_MUTEX_PRE_DIVERT(...)
#define ABSL_TSAN_MUTEX_POST_DIVERT(...)

#endif

#endif  // ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_
*ð	
vsoong/.intermediates/external/abseil-cpp/absl_base_base_internal_hdrs/gen/my_include_dir/absl/base/internal/identity.hõ// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#ifndef ABSL_BASE_INTERNAL_IDENTITY_H_
#define ABSL_BASE_INTERNAL_IDENTITY_H_

#include "absl/base/config.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace internal {

// This is a back-fill of C++20's `std::type_identity`.
template <typename T>
struct type_identity {
  typedef T type;
};

// This is a back-fill of C++20's `std::type_identity_t`.
template <typename T>
using type_identity_t = typename type_identity<T>::type;

}  // namespace internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_BASE_INTERNAL_IDENTITY_H_
*Â
vsoong/.intermediates/external/abseil-cpp/absl_log_internal_voidify_hdrs/gen/my_include_dir/absl/log/internal/voidify.hÇ// 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/internal/voidify.h
// -----------------------------------------------------------------------------
//
// This class does the dispatching of the completed `absl::LogEntry` to
// applicable `absl::LogSink`s, and is used to explicitly ignore values in the
// conditional logging macros. This avoids compiler warnings like "value
// computed is not used" and "statement has no effect".

#ifndef ABSL_LOG_INTERNAL_VOIDIFY_H_
#define ABSL_LOG_INTERNAL_VOIDIFY_H_

#include "absl/base/attributes.h"
#include "absl/base/config.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace log_internal {

class Voidify final {
 public:
  // This has to be an operator with a precedence lower than << but higher than
  // ?:
  template <typename T>
  ABSL_ATTRIBUTE_COLD void operator&&(T&& message) const&& {
    // The dispatching of the completed `absl::LogEntry` to applicable
    // `absl::LogSink`s happens here.
    message.Flush();
  }
};

}  // namespace log_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_LOG_INTERNAL_VOIDIFY_H_
*Þ×
ˆsoong/.intermediates/external/abseil-cpp/absl_strings_str_format_internal_hdrs/gen/my_include_dir/absl/strings/internal/str_format/arg.hÏÖ// 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_STR_FORMAT_ARG_H_
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_ARG_H_

#include <string.h>
#include <wchar.h>

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <limits>
#include <memory>
#include <sstream>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>

#include "absl/base/config.h"
#include "absl/base/optimization.h"
#include "absl/meta/type_traits.h"
#include "absl/numeric/int128.h"
#include "absl/strings/has_absl_stringify.h"
#include "absl/strings/internal/str_format/extension.h"
#include "absl/strings/string_view.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

class Cord;
class FormatCountCapture;
class FormatSink;

template <absl::FormatConversionCharSet C>
struct FormatConvertResult;
class FormatConversionSpec;

namespace str_format_internal {

template <FormatConversionCharSet C>
struct ArgConvertResult {
  bool value;
};

using IntegralConvertResult = ArgConvertResult<FormatConversionCharSetUnion(
    FormatConversionCharSetInternal::c,
    FormatConversionCharSetInternal::kNumeric,
    FormatConversionCharSetInternal::kStar,
    FormatConversionCharSetInternal::v)>;
using FloatingConvertResult = ArgConvertResult<FormatConversionCharSetUnion(
    FormatConversionCharSetInternal::kFloating,
    FormatConversionCharSetInternal::v)>;
using CharConvertResult = ArgConvertResult<FormatConversionCharSetUnion(
    FormatConversionCharSetInternal::c,
    FormatConversionCharSetInternal::kNumeric,
    FormatConversionCharSetInternal::kStar)>;

template <typename T, typename = void>
struct HasUserDefinedConvert : std::false_type {};

template <typename T>
struct HasUserDefinedConvert<T, void_t<decltype(AbslFormatConvert(
                                    std::declval<const T&>(),
                                    std::declval<const FormatConversionSpec&>(),
                                    std::declval<FormatSink*>()))>>
    : std::true_type {};

// These declarations prevent ADL lookup from continuing in absl namespaces,
// we are deliberately using these as ADL hooks and want them to consider
// non-absl namespaces only.
void AbslFormatConvert();
void AbslStringify();

template <typename T>
bool ConvertIntArg(T v, FormatConversionSpecImpl conv, FormatSinkImpl* sink);

// Forward declarations of internal `ConvertIntArg` function template
// instantiations are here to avoid including the template body in the headers
// and instantiating it in large numbers of translation units. Explicit
// instantiations can be found in "absl/strings/internal/str_format/arg.cc"
extern template bool ConvertIntArg<char>(char v, FormatConversionSpecImpl conv,
                                         FormatSinkImpl* sink);
extern template bool ConvertIntArg<signed char>(signed char v,
                                                FormatConversionSpecImpl conv,
                                                FormatSinkImpl* sink);
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);
extern template bool ConvertIntArg<unsigned short>(   // NOLINT
    unsigned short v, FormatConversionSpecImpl conv,  // NOLINT
    FormatSinkImpl* sink);
extern template bool ConvertIntArg<int>(int v, FormatConversionSpecImpl conv,
                                        FormatSinkImpl* sink);
extern template bool ConvertIntArg<unsigned int>(unsigned int v,
                                                 FormatConversionSpecImpl conv,
                                                 FormatSinkImpl* sink);
extern template bool ConvertIntArg<long>(                           // NOLINT
    long v, FormatConversionSpecImpl conv, FormatSinkImpl* sink);   // NOLINT
extern template bool ConvertIntArg<unsigned long>(unsigned long v,  // NOLINT
                                                  FormatConversionSpecImpl conv,
                                                  FormatSinkImpl* sink);
extern template bool ConvertIntArg<long long>(long long v,  // NOLINT
                                              FormatConversionSpecImpl conv,
                                              FormatSinkImpl* sink);
extern template bool ConvertIntArg<unsigned long long>(   // NOLINT
    unsigned long long v, FormatConversionSpecImpl conv,  // NOLINT
    FormatSinkImpl* sink);

template <typename T>
auto FormatConvertImpl(const T& v, FormatConversionSpecImpl conv,
                       FormatSinkImpl* sink)
    -> decltype(AbslFormatConvert(v,
                                  std::declval<const FormatConversionSpec&>(),
                                  std::declval<FormatSink*>())) {
  using FormatConversionSpecT =
      absl::enable_if_t<sizeof(const T& (*)()) != 0, FormatConversionSpec>;
  using FormatSinkT =
      absl::enable_if_t<sizeof(const T& (*)()) != 0, FormatSink>;
  auto fcs = conv.Wrap<FormatConversionSpecT>();
  auto fs = sink->Wrap<FormatSinkT>();
  return AbslFormatConvert(v, fcs, &fs);
}

template <typename T>
auto FormatConvertImpl(const T& v, FormatConversionSpecImpl conv,
                       FormatSinkImpl* sink)
    -> std::enable_if_t<std::is_enum<T>::value &&
                            std::is_void<decltype(AbslStringify(
                                std::declval<FormatSink&>(), v))>::value,
                        IntegralConvertResult> {
  if (conv.conversion_char() == FormatConversionCharInternal::v) {
    using FormatSinkT =
        absl::enable_if_t<sizeof(const T& (*)()) != 0, FormatSink>;
    auto fs = sink->Wrap<FormatSinkT>();
    AbslStringify(fs, v);
    return {true};
  } else {
    return {ConvertIntArg(
        static_cast<typename std::underlying_type<T>::type>(v), conv, sink)};
  }
}

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>> {
  using FormatSinkT =
      absl::enable_if_t<sizeof(const T& (*)()) != 0, FormatSink>;
  auto fs = sink->Wrap<FormatSinkT>();
  AbslStringify(fs, v);
  return {true};
}

template <typename T>
class StreamedWrapper;

// If 'v' can be converted (in the printf sense) according to 'conv',
// then convert it, appending to `sink` and return `true`.
// Otherwise fail and return `false`.

// AbslFormatConvert(v, conv, sink) is intended to be found by ADL on 'v'
// as an extension mechanism. These FormatConvertImpl functions are the default
// implementations.
// The ADL search is augmented via the 'Sink*' parameter, which also
// serves as a disambiguator to reject possible unintended 'AbslFormatConvert'
// functions in the namespaces associated with 'v'.

// Raw pointers.
struct VoidPtr {
  VoidPtr() = default;
  template <typename T,
            decltype(reinterpret_cast<uintptr_t>(std::declval<T*>())) = 0>
  VoidPtr(T* ptr)  // NOLINT
      : value(ptr ? reinterpret_cast<uintptr_t>(ptr) : 0) {}
  uintptr_t value;
};

template <FormatConversionCharSet C>
constexpr FormatConversionCharSet ExtractCharSet(FormatConvertResult<C>) {
  return C;
}

template <FormatConversionCharSet C>
constexpr FormatConversionCharSet ExtractCharSet(ArgConvertResult<C>) {
  return C;
}

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);
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_USES_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>
StringConvertResult FormatConvertImpl(const AbslCord& value,
                                      FormatConversionSpecImpl conv,
                                      FormatSinkImpl* sink) {
  bool is_left = conv.has_left_flag();
  size_t space_remaining = 0;

  int width = conv.width();
  if (width >= 0) space_remaining = static_cast<size_t>(width);

  size_t to_write = value.size();

  int precision = conv.precision();
  if (precision >= 0)
    to_write = (std::min)(to_write, static_cast<size_t>(precision));

  space_remaining = Excess(to_write, space_remaining);

  if (space_remaining > 0 && !is_left) sink->Append(space_remaining, ' ');

  for (string_view piece : value.Chunks()) {
    if (piece.size() > to_write) {
      piece.remove_suffix(piece.size() - to_write);
      to_write = 0;
    } else {
      to_write -= piece.size();
    }
    sink->Append(piece);
    if (to_write == 0) {
      break;
    }
  }

  if (space_remaining > 0 && is_left) sink->Append(space_remaining, ' ');
  return {true};
}

bool ConvertBoolArg(bool v, FormatSinkImpl* sink);

// Floats.
FloatingConvertResult FormatConvertImpl(float v, FormatConversionSpecImpl conv,
                                        FormatSinkImpl* sink);
FloatingConvertResult FormatConvertImpl(double v, FormatConversionSpecImpl conv,
                                        FormatSinkImpl* sink);
FloatingConvertResult FormatConvertImpl(long double v,
                                        FormatConversionSpecImpl conv,
                                        FormatSinkImpl* sink);

// Chars.
CharConvertResult FormatConvertImpl(char v, FormatConversionSpecImpl conv,
                                    FormatSinkImpl* sink);
CharConvertResult FormatConvertImpl(wchar_t v,
                                    FormatConversionSpecImpl conv,
                                    FormatSinkImpl* sink);

// Ints.
IntegralConvertResult FormatConvertImpl(signed char v,
                                        FormatConversionSpecImpl conv,
                                        FormatSinkImpl* sink);
IntegralConvertResult FormatConvertImpl(unsigned char v,
                                        FormatConversionSpecImpl conv,
                                        FormatSinkImpl* sink);
IntegralConvertResult FormatConvertImpl(short v,  // NOLINT
                                        FormatConversionSpecImpl conv,
                                        FormatSinkImpl* sink);
IntegralConvertResult FormatConvertImpl(unsigned short v,  // NOLINT
                                        FormatConversionSpecImpl conv,
                                        FormatSinkImpl* sink);
IntegralConvertResult FormatConvertImpl(int v, FormatConversionSpecImpl conv,
                                        FormatSinkImpl* sink);
IntegralConvertResult FormatConvertImpl(unsigned v,
                                        FormatConversionSpecImpl conv,
                                        FormatSinkImpl* sink);
IntegralConvertResult FormatConvertImpl(long v,  // NOLINT
                                        FormatConversionSpecImpl conv,
                                        FormatSinkImpl* sink);
IntegralConvertResult FormatConvertImpl(unsigned long v,  // NOLINT
                                        FormatConversionSpecImpl conv,
                                        FormatSinkImpl* sink);
IntegralConvertResult FormatConvertImpl(long long v,  // NOLINT
                                        FormatConversionSpecImpl conv,
                                        FormatSinkImpl* sink);
IntegralConvertResult FormatConvertImpl(unsigned long long v,  // NOLINT
                                        FormatConversionSpecImpl conv,
                                        FormatSinkImpl* sink);
IntegralConvertResult FormatConvertImpl(int128 v, FormatConversionSpecImpl conv,
                                        FormatSinkImpl* sink);
IntegralConvertResult FormatConvertImpl(uint128 v,
                                        FormatConversionSpecImpl conv,
                                        FormatSinkImpl* sink);

// This function needs to be a template due to ambiguity regarding type
// conversions.
template <typename T, enable_if_t<std::is_same<T, bool>::value, int> = 0>
IntegralConvertResult FormatConvertImpl(T v, FormatConversionSpecImpl conv,
                                        FormatSinkImpl* sink) {
  if (conv.conversion_char() == FormatConversionCharInternal::v) {
    return {ConvertBoolArg(v, sink)};
  }

  return FormatConvertImpl(static_cast<int>(v), conv, sink);
}

// We provide this function to help the checker, but it is never defined.
// FormatArgImpl will use the underlying Convert functions instead.
template <typename T>
typename std::enable_if<std::is_enum<T>::value &&
                            !HasUserDefinedConvert<T>::value &&
                            !HasAbslStringify<T>::value,
                        IntegralConvertResult>::type
FormatConvertImpl(T v, FormatConversionSpecImpl conv, FormatSinkImpl* sink);

template <typename T>
StringConvertResult FormatConvertImpl(const StreamedWrapper<T>& v,
                                      FormatConversionSpecImpl conv,
                                      FormatSinkImpl* out) {
  std::ostringstream oss;
  oss << v.v_;
  if (!oss) return {false};
  return str_format_internal::FormatConvertImpl(oss.str(), conv, out);
}

// Use templates and dependent types to delay evaluation of the function
// until after FormatCountCapture is fully defined.
struct FormatCountCaptureHelper {
  template <class T = int>
  static ArgConvertResult<FormatConversionCharSetInternal::n> ConvertHelper(
      const FormatCountCapture& v, FormatConversionSpecImpl conv,
      FormatSinkImpl* sink) {
    const absl::enable_if_t<sizeof(T) != 0, FormatCountCapture>& v2 = v;

    if (conv.conversion_char() !=
        str_format_internal::FormatConversionCharInternal::n) {
      return {false};
    }
    *v2.p_ = static_cast<int>(sink->size());
    return {true};
  }
};

template <class T = int>
ArgConvertResult<FormatConversionCharSetInternal::n> FormatConvertImpl(
    const FormatCountCapture& v, FormatConversionSpecImpl conv,
    FormatSinkImpl* sink) {
  return FormatCountCaptureHelper::ConvertHelper(v, conv, sink);
}

// Helper friend struct to hide implementation details from the public API of
// FormatArgImpl.
struct FormatArgImplFriend {
  template <typename Arg>
  static bool ToInt(Arg arg, int* out) {
    // A value initialized FormatConversionSpecImpl has a `none` conv, which
    // tells the dispatcher to run the `int` conversion.
    return arg.dispatcher_(arg.data_, {}, out);
  }

  template <typename Arg>
  static bool Convert(Arg arg, FormatConversionSpecImpl conv,
                      FormatSinkImpl* out) {
    return arg.dispatcher_(arg.data_, conv, out);
  }

  template <typename Arg>
  static typename Arg::Dispatcher GetVTablePtrForTest(Arg arg) {
    return arg.dispatcher_;
  }
};

template <typename Arg>
constexpr FormatConversionCharSet ArgumentToConv() {
  using ConvResult = decltype(str_format_internal::FormatConvertImpl(
      std::declval<const Arg&>(),
      std::declval<const FormatConversionSpecImpl&>(),
      std::declval<FormatSinkImpl*>()));
  return absl::str_format_internal::ExtractCharSet(ConvResult{});
}

// A type-erased handle to a format argument.
class FormatArgImpl {
 private:
  enum { kInlinedSpace = 8 };

  using VoidPtr = str_format_internal::VoidPtr;

  union Data {
    const void* ptr;
    const volatile void* volatile_ptr;
    char buf[kInlinedSpace];
  };

  using Dispatcher = bool (*)(Data, FormatConversionSpecImpl, void* out);

  template <typename T>
  struct store_by_value
      : std::integral_constant<bool, (sizeof(T) <= kInlinedSpace) &&
                                         (std::is_integral<T>::value ||
                                          std::is_floating_point<T>::value ||
                                          std::is_pointer<T>::value ||
                                          std::is_same<VoidPtr, T>::value)> {};

  enum StoragePolicy { ByPointer, ByVolatilePointer, ByValue };
  template <typename T>
  struct storage_policy
      : std::integral_constant<StoragePolicy,
                               (std::is_volatile<T>::value
                                    ? ByVolatilePointer
                                    : (store_by_value<T>::value ? ByValue
                                                                : ByPointer))> {
  };

  // To reduce the number of vtables we will decay values before hand.
  // 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*.
  template <typename T, typename = void>
  struct DecayType {
    static constexpr bool kHasUserDefined =
        str_format_internal::HasUserDefinedConvert<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, 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 &&
             !HasAbslStringify<T>::value && std::is_enum<T>::value>::type> {
    using type = decltype(+typename std::underlying_type<T>::type());
  };

 public:
  template <typename T>
  explicit FormatArgImpl(const T& value) {
    using D = typename DecayType<T>::type;
    static_assert(
        std::is_same<D, const T&>::value || storage_policy<D>::value == ByValue,
        "Decayed types must be stored by value");
    Init(static_cast<D>(value));
  }

 private:
  friend struct str_format_internal::FormatArgImplFriend;
  template <typename T, StoragePolicy = storage_policy<T>::value>
  struct Manager;

  template <typename T>
  struct Manager<T, ByPointer> {
    static Data SetValue(const T& value) {
      Data data;
      data.ptr = std::addressof(value);
      return data;
    }

    static const T& Value(Data arg) { return *static_cast<const T*>(arg.ptr); }
  };

  template <typename T>
  struct Manager<T, ByVolatilePointer> {
    static Data SetValue(const T& value) {
      Data data;
      data.volatile_ptr = &value;
      return data;
    }

    static const T& Value(Data arg) {
      return *static_cast<const T*>(arg.volatile_ptr);
    }
  };

  template <typename T>
  struct Manager<T, ByValue> {
    static Data SetValue(const T& value) {
      Data data;
      memcpy(data.buf, &value, sizeof(value));
      return data;
    }

    static T Value(Data arg) {
      T value;
      memcpy(&value, arg.buf, sizeof(T));
      return value;
    }
  };

  template <typename T>
  void Init(const T& value) {
    data_ = Manager<T>::SetValue(value);
    dispatcher_ = &Dispatch<T>;
  }

  template <typename T>
  static int ToIntVal(const T& val) {
    using CommonType = typename std::conditional<std::is_signed<T>::value,
                                                 int64_t, uint64_t>::type;
    if (static_cast<CommonType>(val) >
        static_cast<CommonType>((std::numeric_limits<int>::max)())) {
      return (std::numeric_limits<int>::max)();
    } else if (std::is_signed<T>::value &&
               static_cast<CommonType>(val) <
                   static_cast<CommonType>((std::numeric_limits<int>::min)())) {
      return (std::numeric_limits<int>::min)();
    }
    return static_cast<int>(val);
  }

  template <typename T>
  static bool ToInt(Data arg, int* out, std::true_type /* is_integral */,
                    std::false_type) {
    *out = ToIntVal(Manager<T>::Value(arg));
    return true;
  }

  template <typename T>
  static bool ToInt(Data arg, int* out, std::false_type,
                    std::true_type /* is_enum */) {
    *out = ToIntVal(static_cast<typename std::underlying_type<T>::type>(
        Manager<T>::Value(arg)));
    return true;
  }

  template <typename T>
  static bool ToInt(Data, int*, std::false_type, std::false_type) {
    return false;
  }

  template <typename T>
  static bool Dispatch(Data arg, FormatConversionSpecImpl spec, void* out) {
    // A `none` conv indicates that we want the `int` conversion.
    if (ABSL_PREDICT_FALSE(spec.conversion_char() ==
                           FormatConversionCharInternal::kNone)) {
      return ToInt<T>(arg, static_cast<int*>(out), std::is_integral<T>(),
                      std::is_enum<T>());
    }
    if (ABSL_PREDICT_FALSE(!Contains(ArgumentToConv<T>(),
                                     spec.conversion_char()))) {
      return false;
    }
    return str_format_internal::FormatConvertImpl(
               Manager<T>::Value(arg), spec,
               static_cast<FormatSinkImpl*>(out))
        .value;
  }

  Data data_;
  Dispatcher dispatcher_;
};

#define ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(T, E)                     \
  E template bool FormatArgImpl::Dispatch<T>(Data, FormatConversionSpecImpl, \
                                             void*)

#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__);               \
  ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(char, __VA_ARGS__);               \
  ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(signed char, __VA_ARGS__);        \
  ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(unsigned char, __VA_ARGS__);      \
  ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(short, __VA_ARGS__); /* NOLINT */ \
  ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(unsigned short,      /* NOLINT */ \
                                             __VA_ARGS__);                     \
  ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(int, __VA_ARGS__);                \
  ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(unsigned int, __VA_ARGS__);       \
  ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(long, __VA_ARGS__); /* NOLINT */  \
  ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(unsigned long,      /* NOLINT */  \
                                             __VA_ARGS__);                     \
  ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(long long, /* NOLINT */           \
                                             __VA_ARGS__);                     \
  ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(unsigned long long, /* NOLINT */  \
                                             __VA_ARGS__);                     \
  ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(int128, __VA_ARGS__);             \
  ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(uint128, __VA_ARGS__);            \
  ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(float, __VA_ARGS__);              \
  ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(double, __VA_ARGS__);             \
  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_(const wchar_t*, __VA_ARGS__);     \
  ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(std::wstring, __VA_ARGS__)

#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__)

ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_(extern);


}  // namespace str_format_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_STR_FORMAT_ARG_H_
*ìŸ
nsoong/.intermediates/external/abseil-cpp/absl_meta_type_traits_hdrs/gen/my_include_dir/absl/meta/type_traits.høž//
// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// type_traits.h
// -----------------------------------------------------------------------------
//
// This file contains C++11-compatible versions of standard <type_traits> API
// functions for determining the characteristics of types. Such traits can
// support type inference, classification, and transformation, as well as
// make it easier to write templates based on generic type behavior.
//
// See https://en.cppreference.com/w/cpp/header/type_traits
//
// WARNING: use of many of the constructs in this header will count as "complex
// template metaprogramming", so before proceeding, please carefully consider
// https://google.github.io/styleguide/cppguide.html#Template_metaprogramming
//
// WARNING: using template metaprogramming to detect or depend on API
// features is brittle and not guaranteed. Neither the standard library nor
// Abseil provides any guarantee that APIs are stable in the face of template
// metaprogramming. Use with caution.
#ifndef ABSL_META_TYPE_TRAITS_H_
#define ABSL_META_TYPE_TRAITS_H_

#include <cstddef>
#include <functional>
#include <string>
#include <string_view>
#include <type_traits>
#include <vector>

#include "absl/base/attributes.h"
#include "absl/base/config.h"

#ifdef __cpp_lib_span
#include <span>  // NOLINT(build/c++20)
#endif

// Defines the default alignment. `__STDCPP_DEFAULT_NEW_ALIGNMENT__` is a C++17
// feature.
#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__)
#define ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT __STDCPP_DEFAULT_NEW_ALIGNMENT__
#else  // defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__)
#define ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT alignof(std::max_align_t)
#endif  // defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__)

namespace absl {
ABSL_NAMESPACE_BEGIN

namespace type_traits_internal {

template <typename... Ts>
struct VoidTImpl {
  using type = void;
};

////////////////////////////////
// Library Fundamentals V2 TS //
////////////////////////////////

// NOTE: The `is_detected` family of templates here differ from the library
// fundamentals specification in that for library fundamentals, `Op<Args...>` is
// evaluated as soon as the type `is_detected<Op, Args...>` undergoes
// substitution, regardless of whether or not the `::value` is accessed. That
// is inconsistent with all other standard traits and prevents lazy evaluation
// in larger contexts (such as if the `is_detected` check is a trailing argument
// of a `conjunction`. This implementation opts to instead be lazy in the same
// way that the standard traits are (this "defect" of the detection idiom
// specifications has been reported).

template <class Enabler, template <class...> class Op, class... Args>
struct is_detected_impl {
  using type = std::false_type;
};

template <template <class...> class Op, class... Args>
struct is_detected_impl<typename VoidTImpl<Op<Args...>>::type, Op, Args...> {
  using type = std::true_type;
};

template <template <class...> class Op, class... Args>
struct is_detected : is_detected_impl<void, Op, Args...>::type {};

}  // namespace type_traits_internal

// void_t()
//
// Ignores the type of any its arguments and returns `void`. In general, this
// metafunction allows you to create a general case that maps to `void` while
// allowing specializations that map to specific types.
//
// This metafunction is not 100% compatible with the C++17 `std::void_t`
// metafunction. It has slightly different behavior, such as when ordering
// partial specializations. It is recommended to use `std::void_t` instead.
template <typename... Ts>
using void_t = typename type_traits_internal::VoidTImpl<Ts...>::type;

// Historical note: Abseil once provided implementations of these type traits
// for platforms that lacked full support. New code should prefer to use the
// std variants.
//
// See the documentation for the STL <type_traits> header for more information:
// https://en.cppreference.com/w/cpp/header/type_traits
using std::add_const_t;
using std::add_cv_t;
using std::add_lvalue_reference_t;
using std::add_pointer_t;
using std::add_rvalue_reference_t;
using std::add_volatile_t;
using std::common_type_t;
using std::conditional_t;
using std::conjunction;
using std::decay_t;
using std::enable_if_t;
using std::disjunction;
using std::is_copy_assignable;
using std::is_function;
using std::is_move_assignable;
using std::is_trivially_copy_assignable;
using std::is_trivially_copy_constructible;
using std::is_trivially_default_constructible;
using std::is_trivially_destructible;
using std::is_trivially_move_assignable;
using std::is_trivially_move_constructible;
using std::make_signed_t;
using std::make_unsigned_t;
using std::negation;
using std::remove_all_extents_t;
using std::remove_const_t;
using std::remove_cv_t;
using std::remove_extent_t;
using std::remove_pointer_t;
using std::remove_reference_t;
using std::remove_volatile_t;
using std::underlying_type_t;

#if defined(__cpp_lib_remove_cvref) && __cpp_lib_remove_cvref >= 201711L
template <typename T>
using remove_cvref = std::remove_cvref<T>;

template <typename T>
using remove_cvref_t = typename std::remove_cvref<T>::type;
#else
// remove_cvref()
//
// C++11 compatible implementation of std::remove_cvref which was added in
// C++20.
template <typename T>
struct remove_cvref {
  using type =
      typename std::remove_cv<typename std::remove_reference<T>::type>::type;
};

template <typename T>
using remove_cvref_t = typename remove_cvref<T>::type;
#endif

namespace type_traits_internal {

#if (defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703L) || \
    (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
// std::result_of is deprecated (C++17) or removed (C++20)
template <typename>
struct result_of;
template <typename F, typename... Args>
struct result_of<F(Args...)> : std::invoke_result<F, Args...> {};
#else
template <typename F>
using result_of = std::result_of<F>;
#endif

}  // namespace type_traits_internal

template <typename F>
using result_of_t = typename type_traits_internal::result_of<F>::type;

namespace type_traits_internal {
// In MSVC we can't probe std::hash or stdext::hash because it triggers a
// static_assert instead of failing substitution. Libc++ prior to 4.0
// also used a static_assert.
//
#if defined(_MSC_VER) || (defined(_LIBCPP_VERSION) && \
                          _LIBCPP_VERSION < 4000 && _LIBCPP_STD_VER > 11)
#define ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 0
#else
#define ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 1
#endif

#if !ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
template <typename Key, typename = size_t>
struct IsHashable : std::true_type {};
#else   // ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
template <typename Key, typename = void>
struct IsHashable : std::false_type {};

template <typename Key>
struct IsHashable<
    Key,
    absl::enable_if_t<std::is_convertible<
        decltype(std::declval<std::hash<Key>&>()(std::declval<Key const&>())),
        std::size_t>::value>> : std::true_type {};
#endif  // !ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_

struct AssertHashEnabledHelper {
 private:
  static void Sink(...) {}
  struct NAT {};

  template <class Key>
  static auto GetReturnType(int)
      -> decltype(std::declval<std::hash<Key>>()(std::declval<Key const&>()));
  template <class Key>
  static NAT GetReturnType(...);

  template <class Key>
  static std::nullptr_t DoIt() {
    static_assert(IsHashable<Key>::value,
                  "std::hash<Key> does not provide a call operator");
    static_assert(
        std::is_default_constructible<std::hash<Key>>::value,
        "std::hash<Key> must be default constructible when it is enabled");
    static_assert(
        std::is_copy_constructible<std::hash<Key>>::value,
        "std::hash<Key> must be copy constructible when it is enabled");
    static_assert(absl::is_copy_assignable<std::hash<Key>>::value,
                  "std::hash<Key> must be copy assignable when it is enabled");
    // is_destructible is unchecked as it's implied by each of the
    // is_constructible checks.
    using ReturnType = decltype(GetReturnType<Key>(0));
    static_assert(std::is_same<ReturnType, NAT>::value ||
                      std::is_same<ReturnType, size_t>::value,
                  "std::hash<Key> must return size_t");
    return nullptr;
  }

  template <class... Ts>
  friend void AssertHashEnabled();
};

template <class... Ts>
inline void AssertHashEnabled() {
  using Helper = AssertHashEnabledHelper;
  Helper::Sink(Helper::DoIt<Ts>()...);
}

}  // namespace type_traits_internal

// An internal namespace that is required to implement the C++17 swap traits.
// It is not further nested in type_traits_internal to avoid long symbol names.
namespace swap_internal {

// Necessary for the traits.
using std::swap;

// This declaration prevents global `swap` and `absl::swap` overloads from being
// considered unless ADL picks them up.
void swap();

template <class T>
using IsSwappableImpl = decltype(swap(std::declval<T&>(), std::declval<T&>()));

// NOTE: This dance with the default template parameter is for MSVC.
template <class T,
          class IsNoexcept = std::integral_constant<
              bool, noexcept(swap(std::declval<T&>(), std::declval<T&>()))>>
using IsNothrowSwappableImpl = typename std::enable_if<IsNoexcept::value>::type;

// IsSwappable
//
// Determines whether the standard swap idiom is a valid expression for
// arguments of type `T`.
template <class T>
struct IsSwappable
    : absl::type_traits_internal::is_detected<IsSwappableImpl, T> {};

// IsNothrowSwappable
//
// Determines whether the standard swap idiom is a valid expression for
// arguments of type `T` and is noexcept.
template <class T>
struct IsNothrowSwappable
    : absl::type_traits_internal::is_detected<IsNothrowSwappableImpl, T> {};

// Swap()
//
// Performs the swap idiom from a namespace where valid candidates may only be
// found in `std` or via ADL.
template <class T, absl::enable_if_t<IsSwappable<T>::value, int> = 0>
void Swap(T& lhs, T& rhs) noexcept(IsNothrowSwappable<T>::value) {
  swap(lhs, rhs);
}

// StdSwapIsUnconstrained
//
// Some standard library implementations are broken in that they do not
// constrain `std::swap`. This will effectively tell us if we are dealing with
// one of those implementations.
using StdSwapIsUnconstrained = IsSwappable<void()>;

}  // namespace swap_internal

namespace type_traits_internal {

// Make the swap-related traits/function accessible from this namespace.
using swap_internal::IsNothrowSwappable;
using swap_internal::IsSwappable;
using swap_internal::StdSwapIsUnconstrained;
using swap_internal::Swap;

}  // namespace type_traits_internal

// absl::is_trivially_relocatable<T>
//
// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2786r11.html
//
// Detects whether a type is known to be "trivially relocatable" -- meaning it
// can be relocated from one place to another as if by memcpy/memmove.
// This implies that its object representation doesn't depend on its address,
// and also none of its special member functions do anything strange.
//
// Note that when relocating the caller code should ensure that if the object is
// polymorphic, the dynamic type is of the most derived type. Padding bytes
// should not be copied.
//
// This trait is conservative. If it's true then the type is definitely
// trivially relocatable, but if it's false then the type may or may not be. For
// example, std::vector<int> is trivially relocatable on every known STL
// implementation, but absl::is_trivially_relocatable<std::vector<int>> remains
// false.
//
// Example:
//
// if constexpr (absl::is_trivially_relocatable<T>::value) {
//   memcpy(new_location, old_location, sizeof(T));
// } else {
//   new(new_location) T(std::move(*old_location));
//   old_location->~T();
// }
//
// Upstream documentation:
//
// https://clang.llvm.org/docs/LanguageExtensions.html#:~:text=__builtin_is_cpp_trivially_relocatable
//
// Clang on Windows has the builtin, but it falsely claims types with a
// user-provided destructor are trivial (http://b/275003464). So we opt out
// there.
//
// TODO(b/275003464): remove the opt-out once the bug is fixed.
//
// Starting with Xcode 15, the Apple compiler will falsely say a type
// with a user-provided move constructor is trivially relocatable
// (b/324278148). We will opt out without a version check, due to
// the fluidity of Apple versions.
//
// TODO(b/324278148): If all versions we use have the bug fixed, then
// remove the condition.
//
// Clang on all platforms fails to detect that a type with a user-provided
// move-assignment operator is not trivially relocatable so we also check for
// is_trivially_move_assignable for Clang.
//
// TODO(b/325479096): Remove the Clang is_trivially_move_assignable version once
// Clang's behavior is fixed.
//
// According to https://github.com/abseil/abseil-cpp/issues/1479, this does not
// work with NVCC either.
#if ABSL_HAVE_BUILTIN(__builtin_is_cpp_trivially_relocatable)
// https://github.com/llvm/llvm-project/pull/127636#pullrequestreview-2637005293
// In the current implementation, __builtin_is_cpp_trivially_relocatable will
// only return true for types that are trivially relocatable according to the
// standard. Notably, this means that marking a type [[clang::trivial_abi]] aka
// ABSL_HAVE_ATTRIBUTE_TRIVIAL_ABI will have no effect on this trait.
template <class T>
struct is_trivially_relocatable
    : std::integral_constant<bool, __builtin_is_cpp_trivially_relocatable(T)> {
};
#elif ABSL_HAVE_BUILTIN(__is_trivially_relocatable) && defined(__clang__) && \
    !(defined(_WIN32) || defined(_WIN64)) && !defined(__APPLE__) &&          \
    !defined(__NVCC__)
// https://github.com/llvm/llvm-project/pull/139061
//  __is_trivially_relocatable is deprecated.
// TODO(b/325479096): Remove this case.
template <class T>
struct is_trivially_relocatable
    : std::integral_constant<
          bool, std::is_trivially_copyable<T>::value ||
                    (__is_trivially_relocatable(T) &&
                     std::is_trivially_move_assignable<T>::value)> {};
#else
// Otherwise we use a fallback that detects only those types we can feasibly
// detect. Any type that is trivially copyable is by definition trivially
// relocatable.
template <class T>
struct is_trivially_relocatable : std::is_trivially_copyable<T> {};
#endif

// absl::is_constant_evaluated()
//
// Detects whether the function call occurs within a constant-evaluated context.
// Returns true if the evaluation of the call occurs within the evaluation of an
// expression or conversion that is manifestly constant-evaluated; otherwise
// returns false.
//
// This function is implemented in terms of `std::is_constant_evaluated` for
// c++20 and up. For older c++ versions, the function is implemented in terms
// of `__builtin_is_constant_evaluated` if available, otherwise the function
// will fail to compile.
//
// Applications can inspect `ABSL_HAVE_CONSTANT_EVALUATED` at compile time
// to check if this function is supported.
//
// Example:
//
// constexpr MyClass::MyClass(int param) {
// #ifdef ABSL_HAVE_CONSTANT_EVALUATED
//   if (!absl::is_constant_evaluated()) {
//     ABSL_LOG(INFO) << "MyClass(" << param << ")";
//   }
// #endif  // ABSL_HAVE_CONSTANT_EVALUATED
// }
//
// Upstream documentation:
//
// http://en.cppreference.com/w/cpp/types/is_constant_evaluated
// http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#:~:text=__builtin_is_constant_evaluated
//
#if defined(ABSL_HAVE_CONSTANT_EVALUATED)
constexpr bool is_constant_evaluated() noexcept {
#ifdef __cpp_lib_is_constant_evaluated
  return std::is_constant_evaluated();
#elif ABSL_HAVE_BUILTIN(__builtin_is_constant_evaluated)
  return __builtin_is_constant_evaluated();
#endif
}
#endif  // ABSL_HAVE_CONSTANT_EVALUATED

namespace type_traits_internal {

// Detects if a class's definition has declared itself to be an owner by
// declaring
//   using absl_internal_is_view = std::true_type;
// as a member.
// Types that don't want either must either omit this declaration entirely, or
// (if e.g. inheriting from a base class) define the member to something that
// isn't a Boolean trait class, such as `void`.
// Do not specialize or use this directly. It's an implementation detail.
template <typename T, typename = void>
struct IsOwnerImpl : std::false_type {
  static_assert(std::is_same<T, absl::remove_cvref_t<T>>::value,
                "type must lack qualifiers");
};

template <typename T>
struct IsOwnerImpl<
    T,
    std::enable_if_t<std::is_class<typename T::absl_internal_is_view>::value>>
    : absl::negation<typename T::absl_internal_is_view> {};

// A trait to determine whether a type is an owner.
// Do *not* depend on the correctness of this trait for correct code behavior.
// It is only a safety feature and its value may change in the future.
// Do not specialize this; instead, define the member trait inside your type so
// that it can be auto-detected, and to prevent ODR violations.
// If it ever becomes possible to detect [[gsl::Owner]], we should leverage it:
// https://wg21.link/p1179
template <typename T>
struct IsOwner : IsOwnerImpl<T> {};

template <typename T, typename Traits, typename Alloc>
struct IsOwner<std::basic_string<T, Traits, Alloc>> : std::true_type {};

template <typename T, typename Alloc>
struct IsOwner<std::vector<T, Alloc>> : std::true_type {};

// Detects if a class's definition has declared itself to be a view by declaring
//   using absl_internal_is_view = std::true_type;
// as a member.
// Do not specialize or use this directly.
template <typename T, typename = void>
struct IsViewImpl : std::false_type {
  static_assert(std::is_same<T, absl::remove_cvref_t<T>>::value,
                "type must lack qualifiers");
};

template <typename T>
struct IsViewImpl<
    T,
    std::enable_if_t<std::is_class<typename T::absl_internal_is_view>::value>>
    : T::absl_internal_is_view {};

// A trait to determine whether a type is a view.
// Do *not* depend on the correctness of this trait for correct code behavior.
// It is only a safety feature, and its value may change in the future.
// Do not specialize this trait. Instead, define the member
//   using absl_internal_is_view = std::true_type;
// in your class to allow its detection while preventing ODR violations.
// If it ever becomes possible to detect [[gsl::Pointer]], we should leverage
// it: https://wg21.link/p1179
template <typename T>
struct IsView : std::integral_constant<bool, std::is_pointer<T>::value ||
                                                 IsViewImpl<T>::value> {};

template <typename Char, typename Traits>
struct IsView<std::basic_string_view<Char, Traits>> : std::true_type {};

#ifdef __cpp_lib_span
template <typename T>
struct IsView<std::span<T>> : std::true_type {};
#endif

// Determines whether the assignment of the given types is lifetime-bound.
// Do *not* depend on the correctness of this trait for correct code behavior.
// It is only a safety feature and its value may change in the future.
// If it ever becomes possible to detect [[clang::lifetimebound]] directly,
// we should change the implementation to leverage that.
// Until then, we consider an assignment from an "owner" (such as std::string)
// to a "view" (such as std::string_view) to be a lifetime-bound assignment.
template <typename T, typename U>
using IsLifetimeBoundAssignment = absl::conjunction<
    std::integral_constant<bool, !std::is_lvalue_reference<U>::value>,
    IsOwner<absl::remove_cvref_t<U>>, IsView<absl::remove_cvref_t<T>>>;

}  // namespace type_traits_internal

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_META_TYPE_TRAITS_H_
*Ð¼
dsoong/.intermediates/external/abseil-cpp/absl_strings_hdrs/gen/my_include_dir/absl/strings/str_cat.hæ»//
// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// File: str_cat.h
// -----------------------------------------------------------------------------
//
// This package contains functions for efficiently concatenating and appending
// strings: `StrCat()` and `StrAppend()`. Most of the work within these routines
// is actually handled through use of a special AlphaNum type, which was
// designed to be used as a parameter type that efficiently manages conversion
// to strings and avoids copies in the above operations.
//
// Any routine accepting either a string or a number may accept `AlphaNum`.
// The basic idea is that by accepting a `const AlphaNum &` as an argument
// to your function, your callers will automagically convert bools, integers,
// and floating point values to strings for you.
//
// NOTE: Use of `AlphaNum` outside of the //absl/strings package is unsupported
// except for the specific case of function parameters of type `AlphaNum` or
// `const AlphaNum &`. In particular, instantiating `AlphaNum` directly as a
// stack variable is not supported.
//
// Conversion from 8-bit values is not accepted because, if it were, then an
// attempt to pass ':' instead of ":" might result in a 58 ending up in your
// result.
//
// Bools convert to "0" or "1". Pointers to types other than `char *` are not
// valid inputs. No output is generated for null `char *` pointers.
//
// Floating point numbers are formatted with six-digit precision, which is
// the default for "std::cout <<" or printf "%g" (the same as "%.6g").
//
// You can convert to hexadecimal output rather than decimal output using the
// `Hex` type contained here. To do so, pass `Hex(my_int)` as a parameter to
// `StrCat()` or `StrAppend()`. You may specify a minimum hex field width using
// a `PadSpec` enum.
//
// User-defined types can be formatted with the `AbslStringify()` customization
// point. The API relies on detecting an overload in the user-defined type's
// namespace of a free (non-member) `AbslStringify()` function as a definition
// (typically declared as a friend and implemented in-line.
// with the following signature:
//
// class MyClass { ... };
//
// template <typename Sink>
// void AbslStringify(Sink& sink, const MyClass& value);
//
// An `AbslStringify()` overload for a type should only be declared in the same
// file and namespace as said type.
//
// Note that `AbslStringify()` also supports use with `absl::StrFormat()` and
// `absl::Substitute()`.
//
// Example:
//
// struct Point {
//   // To add formatting support to `Point`, we simply need to add a free
//   // (non-member) function `AbslStringify()`. This method specifies how
//   // Point should be printed when absl::StrCat() is called on it. You can add
//   // such a free function using a friend declaration within the body of the
//   // class. The sink parameter is a templated type to avoid requiring
//   // dependencies.
//   template <typename Sink> friend void AbslStringify(Sink&
//   sink, const Point& p) {
//     absl::Format(&sink, "(%v, %v)", p.x, p.y);
//   }
//
//   int x;
//   int y;
// };
// -----------------------------------------------------------------------------

#ifndef ABSL_STRINGS_STR_CAT_H_
#define ABSL_STRINGS_STR_CAT_H_

#include <algorithm>
#include <array>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <initializer_list>
#include <limits>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>

#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/nullability.h"
#include "absl/base/port.h"
#include "absl/meta/type_traits.h"
#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"

#if !defined(ABSL_USES_STD_STRING_VIEW)
#include <string_view>
#endif

namespace absl {
ABSL_NAMESPACE_BEGIN

namespace strings_internal {
// AlphaNumBuffer allows a way to pass a string to StrCat without having to do
// memory allocation.  It is simply a pair of a fixed-size character array, and
// a size.  Please don't use outside of absl, yet.
template <size_t max_size>
struct AlphaNumBuffer {
  std::array<char, max_size> data;
  size_t size;
};

}  // namespace strings_internal

// Enum that specifies the number of significant digits to return in a `Hex` or
// `Dec` conversion and fill character to use. A `kZeroPad2` value, for example,
// would produce hexadecimal strings such as "0a","0f" and a 'kSpacePad5' value
// would produce hexadecimal strings such as "    a","    f".
enum PadSpec : uint8_t {
  kNoPad = 1,
  kZeroPad2,
  kZeroPad3,
  kZeroPad4,
  kZeroPad5,
  kZeroPad6,
  kZeroPad7,
  kZeroPad8,
  kZeroPad9,
  kZeroPad10,
  kZeroPad11,
  kZeroPad12,
  kZeroPad13,
  kZeroPad14,
  kZeroPad15,
  kZeroPad16,
  kZeroPad17,
  kZeroPad18,
  kZeroPad19,
  kZeroPad20,

  kSpacePad2 = kZeroPad2 + 64,
  kSpacePad3,
  kSpacePad4,
  kSpacePad5,
  kSpacePad6,
  kSpacePad7,
  kSpacePad8,
  kSpacePad9,
  kSpacePad10,
  kSpacePad11,
  kSpacePad12,
  kSpacePad13,
  kSpacePad14,
  kSpacePad15,
  kSpacePad16,
  kSpacePad17,
  kSpacePad18,
  kSpacePad19,
  kSpacePad20,
};

// -----------------------------------------------------------------------------
// Hex
// -----------------------------------------------------------------------------
//
// `Hex` stores a set of hexadecimal string conversion parameters for use
// within `AlphaNum` string conversions.
struct Hex {
  uint64_t value;
  uint8_t width;
  char fill;

  template <typename Int>
  explicit Hex(
      Int v, PadSpec spec = absl::kNoPad,
      std::enable_if_t<sizeof(Int) == 1 && !std::is_pointer<Int>::value, bool> =
          true)
      : Hex(spec, static_cast<uint8_t>(v)) {}
  template <typename Int>
  explicit Hex(
      Int v, PadSpec spec = absl::kNoPad,
      std::enable_if_t<sizeof(Int) == 2 && !std::is_pointer<Int>::value, bool> =
          true)
      : Hex(spec, static_cast<uint16_t>(v)) {}
  template <typename Int>
  explicit Hex(
      Int v, PadSpec spec = absl::kNoPad,
      std::enable_if_t<sizeof(Int) == 4 && !std::is_pointer<Int>::value, bool> =
          true)
      : Hex(spec, static_cast<uint32_t>(v)) {}
  template <typename Int>
  explicit Hex(
      Int v, PadSpec spec = absl::kNoPad,
      std::enable_if_t<sizeof(Int) == 8 && !std::is_pointer<Int>::value, bool> =
          true)
      : Hex(spec, static_cast<uint64_t>(v)) {}
  template <typename Pointee>
  explicit Hex(Pointee* absl_nullable v, PadSpec spec = absl::kNoPad)
      : Hex(spec, reinterpret_cast<uintptr_t>(v)) {}

  template <typename S>
  friend void AbslStringify(S& sink, Hex hex) {
    static_assert(
        numbers_internal::kFastToBufferSize >= 32,
        "This function only works when output buffer >= 32 bytes long");
    char buffer[numbers_internal::kFastToBufferSize];
    char* const end = &buffer[numbers_internal::kFastToBufferSize];
    auto real_width =
        absl::numbers_internal::FastHexToBufferZeroPad16(hex.value, end - 16);
    if (real_width >= hex.width) {
      sink.Append(absl::string_view(end - real_width, real_width));
    } else {
      // Pad first 16 chars because FastHexToBufferZeroPad16 pads only to 16 and
      // max pad width can be up to 20.
      std::memset(end - 32, hex.fill, 16);
      // Patch up everything else up to the real_width.
      std::memset(end - real_width - 16, hex.fill, 16);
      sink.Append(absl::string_view(end - hex.width, hex.width));
    }
  }

 private:
  Hex(PadSpec spec, uint64_t v)
      : value(v),
        width(spec == absl::kNoPad
                  ? 1
                  : spec >= absl::kSpacePad2 ? spec - absl::kSpacePad2 + 2
                                             : spec - absl::kZeroPad2 + 2),
        fill(spec >= absl::kSpacePad2 ? ' ' : '0') {}
};

// -----------------------------------------------------------------------------
// Dec
// -----------------------------------------------------------------------------
//
// `Dec` stores a set of decimal string conversion parameters for use
// within `AlphaNum` string conversions.  Dec is slower than the default
// integer conversion, so use it only if you need padding.
struct Dec {
  uint64_t value;
  uint8_t width;
  char fill;
  bool neg;

  template <typename Int>
  explicit Dec(Int v, PadSpec spec = absl::kNoPad,
               std::enable_if_t<sizeof(Int) <= 8, bool> = true)
      : 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),
        fill(spec >= absl::kSpacePad2 ? ' ' : '0'),
        neg(v < 0) {}

  template <typename S>
  friend void AbslStringify(S& sink, Dec dec) {
    assert(dec.width <= numbers_internal::kFastToBufferSize);
    char buffer[numbers_internal::kFastToBufferSize];
    char* const end = &buffer[numbers_internal::kFastToBufferSize];
    char* const minfill = end - dec.width;
    char* writer = end;
    uint64_t val = dec.value;
    while (val > 9) {
      *--writer = '0' + (val % 10);
      val /= 10;
    }
    *--writer = '0' + static_cast<char>(val);
    if (dec.neg) *--writer = '-';

    ptrdiff_t fillers = writer - minfill;
    if (fillers > 0) {
      // Tricky: if the fill character is ' ', then it's <fill><+/-><digits>
      // But...: if the fill character is '0', then it's <+/-><fill><digits>
      bool add_sign_again = false;
      if (dec.neg && dec.fill == '0') {  // If filling with '0',
        ++writer;                    // ignore the sign we just added
        add_sign_again = true;       // and re-add the sign later.
      }
      writer -= fillers;
      std::fill_n(writer, fillers, dec.fill);
      if (add_sign_again) *--writer = '-';
    }

    sink.Append(absl::string_view(writer, static_cast<size_t>(end - writer)));
  }
};

// -----------------------------------------------------------------------------
// AlphaNum
// -----------------------------------------------------------------------------
//
// The `AlphaNum` class acts as the main parameter type for `StrCat()` and
// `StrAppend()`, providing efficient conversion of numeric, boolean, decimal,
// and hexadecimal values (through the `Dec` and `Hex` types) into strings.
// `AlphaNum` should only be used as a function parameter. Do not instantiate
//  `AlphaNum` directly as a stack variable.

class AlphaNum {
 public:
  // No bool ctor -- bools convert to an integral type.
  // A bool ctor would also convert incoming pointers (bletch).

  // Prevent brace initialization
  template <typename T>
  AlphaNum(std::initializer_list<T>) = delete;  // NOLINT(runtime/explicit)

  AlphaNum(int x)  // NOLINT(runtime/explicit)
      : piece_(digits_, static_cast<size_t>(
                            numbers_internal::FastIntToBuffer(x, digits_) -
                            &digits_[0])) {}
  AlphaNum(unsigned int x)  // NOLINT(runtime/explicit)
      : piece_(digits_, static_cast<size_t>(
                            numbers_internal::FastIntToBuffer(x, digits_) -
                            &digits_[0])) {}
  AlphaNum(long x)  // NOLINT(*)
      : piece_(digits_, static_cast<size_t>(
                            numbers_internal::FastIntToBuffer(x, digits_) -
                            &digits_[0])) {}
  AlphaNum(unsigned long x)  // NOLINT(*)
      : piece_(digits_, static_cast<size_t>(
                            numbers_internal::FastIntToBuffer(x, digits_) -
                            &digits_[0])) {}
  AlphaNum(long long x)  // NOLINT(*)
      : piece_(digits_, static_cast<size_t>(
                            numbers_internal::FastIntToBuffer(x, digits_) -
                            &digits_[0])) {}
  AlphaNum(unsigned long long x)  // NOLINT(*)
      : piece_(digits_, static_cast<size_t>(
                            numbers_internal::FastIntToBuffer(x, digits_) -
                            &digits_[0])) {}

  AlphaNum(float f)  // NOLINT(runtime/explicit)
      : piece_(digits_, numbers_internal::SixDigitsToBuffer(f, digits_)) {}
  AlphaNum(double f)  // NOLINT(runtime/explicit)
      : piece_(digits_, numbers_internal::SixDigitsToBuffer(f, digits_)) {}

  template <size_t size>
  AlphaNum(  // NOLINT(runtime/explicit)
      const strings_internal::AlphaNumBuffer<size>& buf
          ABSL_ATTRIBUTE_LIFETIME_BOUND)
      : piece_(&buf.data[0], buf.size) {}

  AlphaNum(const char* absl_nullable c_str  // NOLINT(runtime/explicit)
               ABSL_ATTRIBUTE_LIFETIME_BOUND)
      : piece_(NullSafeStringView(c_str)) {}
  AlphaNum(absl::string_view pc  // NOLINT(runtime/explicit)
               ABSL_ATTRIBUTE_LIFETIME_BOUND)
      : piece_(pc) {}

#if !defined(ABSL_USES_STD_STRING_VIEW)
  AlphaNum(std::string_view pc  // NOLINT(runtime/explicit)
               ABSL_ATTRIBUTE_LIFETIME_BOUND)
      : piece_(pc.data(), pc.size()) {}
#endif  // !ABSL_USES_STD_STRING_VIEW

  template <typename T, typename = typename std::enable_if<
                            HasAbslStringify<T>::value>::type>
  AlphaNum(  // NOLINT(runtime/explicit)
      const T& v ABSL_ATTRIBUTE_LIFETIME_BOUND,
      strings_internal::StringifySink&& sink ABSL_ATTRIBUTE_LIFETIME_BOUND = {})
      : piece_(strings_internal::ExtractStringification(sink, v)) {}

  template <typename Allocator>
  AlphaNum(  // NOLINT(runtime/explicit)
      const std::basic_string<char, std::char_traits<char>, Allocator>& str
          ABSL_ATTRIBUTE_LIFETIME_BOUND)
      : piece_(str) {}

  // Use string literals ":" instead of character literals ':'.
  AlphaNum(char c) = delete;  // NOLINT(runtime/explicit)

  AlphaNum(const AlphaNum&) = delete;
  AlphaNum& operator=(const AlphaNum&) = delete;

  absl::string_view::size_type size() const { return piece_.size(); }
  const char* absl_nullable data() const { return piece_.data(); }
  absl::string_view Piece() const { return piece_; }

  // Match unscoped enums.  Use integral promotion so that a `char`-backed
  // enum becomes a wider integral type AlphaNum will accept.
  template <typename T,
            typename = typename std::enable_if<
                std::is_enum<T>{} && std::is_convertible<T, int>{} &&
                !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>{} &&
                                        !HasAbslStringify<T>::value,
                                    char*>::type = nullptr>
  AlphaNum(T e)  // NOLINT(runtime/explicit)
      : AlphaNum(+static_cast<typename std::underlying_type<T>::type>(e)) {}

  // vector<bool>::reference and const_reference require special help to
  // convert to `AlphaNum` because it requires two user defined conversions.
  template <
      typename T,
      typename std::enable_if<
          std::is_class<T>::value &&
          (std::is_same<T, std::vector<bool>::reference>::value ||
           std::is_same<T, std::vector<bool>::const_reference>::value)>::type* =
          nullptr>
  AlphaNum(T e) : AlphaNum(static_cast<bool>(e)) {}  // NOLINT(runtime/explicit)

 private:
  absl::string_view piece_;
  char digits_[numbers_internal::kFastToBufferSize];
};

// -----------------------------------------------------------------------------
// StrCat()
// -----------------------------------------------------------------------------
//
// Merges given strings or numbers, using no delimiter(s), returning the merged
// result as a string.
//
// `StrCat()` is designed to be the fastest possible way to construct a string
// out of a mix of raw C strings, string_views, strings, bool values,
// and numeric values.
//
// Don't use `StrCat()` for user-visible strings. The localization process
// works poorly on strings built up out of fragments.
//
// For clarity and performance, don't use `StrCat()` when appending to a
// string. Use `StrAppend()` instead. In particular, avoid using any of these
// (anti-)patterns:
//
//   str.append(StrCat(...))
//   str += StrCat(...)
//   str = StrCat(str, ...)
//
// The last case is the worst, with a potential to change a loop
// from a linear time operation with O(1) dynamic allocations into a
// quadratic time operation with O(n) dynamic allocations.
//
// See `StrAppend()` below for more information.

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* absl_nonnull dest,
                  std::initializer_list<absl::string_view> pieces);

template <typename Integer>
std::string IntegerToString(Integer i) {
  // Any integer (signed/unsigned) up to 64 bits can be formatted into a buffer
  // with 22 bytes (including NULL at the end).
  constexpr size_t kMaxDigits10 = 22;
  std::string result;
  strings_internal::STLStringResizeUninitialized(&result, kMaxDigits10);
  char* start = &result[0];
  // note: this can be optimized to not write last zero.
  char* end = numbers_internal::FastIntToBuffer(i, start);
  auto size = static_cast<size_t>(end - start);
  assert((size < result.size()) &&
         "StrCat(Integer) does not fit into kMaxDigits10");
  result.erase(size);
  return result;
}
template <typename Float>
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;
}

// `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`.
inline std::string SingleArgStrCat(int x) { return IntegerToString(x); }
inline std::string SingleArgStrCat(unsigned int x) {
  return IntegerToString(x);
}
// NOLINTNEXTLINE
inline std::string SingleArgStrCat(long x) { return IntegerToString(x); }
// NOLINTNEXTLINE
inline std::string SingleArgStrCat(unsigned long x) {
  return IntegerToString(x);
}
// NOLINTNEXTLINE
inline std::string SingleArgStrCat(long long x) { return IntegerToString(x); }
// NOLINTNEXTLINE
inline std::string SingleArgStrCat(unsigned long long x) {
  return IntegerToString(x);
}
inline std::string SingleArgStrCat(float x) { return FloatToString(x); }
inline std::string SingleArgStrCat(double x) { return FloatToString(x); }

// As of September 2023, the SingleArgStrCat() optimization is only enabled for
// libc++. The reasons for this are:
// 1) The SSO size for libc++ is 23, while libstdc++ and MSSTL have an SSO size
// of 15. Since IntegerToString unconditionally resizes the string to 22 bytes,
// this causes both libstdc++ and MSSTL to allocate.
// 2) strings_internal::STLStringResizeUninitialized() only has an
// implementation that avoids initialization when using libc++. This isn't as
// relevant as (1), and the cost should be benchmarked if (1) ever changes on
// libstc++ or MSSTL.
#ifdef _LIBCPP_VERSION
#define ABSL_INTERNAL_STRCAT_ENABLE_FAST_CASE true
#else
#define ABSL_INTERNAL_STRCAT_ENABLE_FAST_CASE false
#endif

template <typename T, typename = std::enable_if_t<
                          ABSL_INTERNAL_STRCAT_ENABLE_FAST_CASE &&
                          std::is_arithmetic<T>{} && !std::is_same<T, char>{}>>
using EnableIfFastCase = T;

#undef ABSL_INTERNAL_STRCAT_ENABLE_FAST_CASE

}  // namespace strings_internal

[[nodiscard]] inline std::string StrCat() { return std::string(); }

template <typename T>
[[nodiscard]] inline std::string StrCat(
    strings_internal::EnableIfFastCase<T> a) {
  return strings_internal::SingleArgStrCat(a);
}
[[nodiscard]] inline std::string StrCat(const AlphaNum& a) {
  return std::string(a.data(), a.size());
}

[[nodiscard]] std::string StrCat(const AlphaNum& a, const AlphaNum& b);
[[nodiscard]] std::string StrCat(const AlphaNum& a, const AlphaNum& b,
                                 const AlphaNum& c);
[[nodiscard]] std::string StrCat(const AlphaNum& a, const AlphaNum& b,
                                 const AlphaNum& c, const AlphaNum& d);

// Support 5 or more arguments
template <typename... AV>
[[nodiscard]] inline std::string StrCat(const AlphaNum& a, const AlphaNum& b,
                                        const AlphaNum& c, const AlphaNum& d,
                                        const AlphaNum& e, const AV&... args) {
  return strings_internal::CatPieces(
      {a.Piece(), b.Piece(), c.Piece(), d.Piece(), e.Piece(),
       static_cast<const AlphaNum&>(args).Piece()...});
}

// -----------------------------------------------------------------------------
// StrAppend()
// -----------------------------------------------------------------------------
//
// Appends a string or set of strings to an existing string, in a similar
// fashion to `StrCat()`.
//
// WARNING: `StrAppend(&str, a, b, c, ...)` requires that none of the
// a, b, c, parameters be a reference into str. For speed, `StrAppend()` does
// not try to check each of its input arguments to be sure that they are not
// a subset of the string being appended to. That is, while this will work:
//
//   std::string s = "foo";
//   s += s;
//
// This output is undefined:
//
//   std::string s = "foo";
//   StrAppend(&s, s);
//
// This output is undefined as well, since `absl::string_view` does not own its
// data:
//
//   std::string s = "foobar";
//   absl::string_view p = s;
//   StrAppend(&s, p);

inline void StrAppend(std::string* absl_nonnull) {}
void StrAppend(std::string* absl_nonnull dest, const AlphaNum& a);
void StrAppend(std::string* absl_nonnull dest, const AlphaNum& a,
               const AlphaNum& b);
void StrAppend(std::string* absl_nonnull dest, const AlphaNum& a,
               const AlphaNum& b, const AlphaNum& c);
void StrAppend(std::string* absl_nonnull 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* absl_nonnull 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()...});
}

// Helper function for the future StrCat default floating-point format, %.6g
// This is fast.
inline strings_internal::AlphaNumBuffer<
    numbers_internal::kSixDigitsToBufferSize>
SixDigits(double d) {
  strings_internal::AlphaNumBuffer<numbers_internal::kSixDigitsToBufferSize>
      result;
  result.size = numbers_internal::SixDigitsToBuffer(d, &result.data[0]);
  return result;
}

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_STR_CAT_H_
*¡ 
…soong/.intermediates/external/abseil-cpp/absl_functional_function_ref_hdrs/gen/my_include_dir/absl/functional/internal/function_ref.h–// Copyright 2019 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_FUNCTIONAL_INTERNAL_FUNCTION_REF_H_
#define ABSL_FUNCTIONAL_INTERNAL_FUNCTION_REF_H_

#include <cassert>
#include <functional>
#include <type_traits>

#include "absl/functional/any_invocable.h"
#include "absl/meta/type_traits.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace functional_internal {

// Like a void* that can handle function pointers as well. The standard does not
// allow function pointers to round-trip through void*, but void(*)() is fine.
//
// Note: It's important that this class remains trivial and is the same size as
// a pointer, since this allows the compiler to perform tail-call optimizations
// when the underlying function is a callable object with a matching signature.
union VoidPtr {
  const void* obj;
  void (*fun)();
};

// Chooses the best type for passing T as an argument.
// Attempt to be close to SystemV AMD64 ABI. Objects with trivial copy ctor are
// passed by value.
template <typename T,
          bool IsLValueReference = std::is_lvalue_reference<T>::value>
struct PassByValue : std::false_type {};

template <typename T>
struct PassByValue<T, /*IsLValueReference=*/false>
    : std::integral_constant<bool,
                             absl::is_trivially_copy_constructible<T>::value &&
                                 absl::is_trivially_copy_assignable<
                                     typename std::remove_cv<T>::type>::value &&
                                 std::is_trivially_destructible<T>::value &&
                                 sizeof(T) <= 2 * sizeof(void*)> {};

template <typename T>
struct ForwardT : std::conditional<PassByValue<T>::value, T, T&&> {};

// An Invoker takes a pointer to the type-erased invokable object, followed by
// the arguments that the invokable object expects.
//
// Note: The order of arguments here is an optimization, since member functions
// have an implicit "this" pointer as their first argument, putting VoidPtr
// first allows the compiler to perform tail-call optimization in many cases.
template <typename R, typename... Args>
using Invoker = R (*)(VoidPtr, typename ForwardT<Args>::type...);

//
// InvokeObject and InvokeFunction provide static "Invoke" functions that can be
// used as Invokers for objects or functions respectively.
//
// static_cast<R> handles the case the return type is void.
template <typename Obj, typename R, typename... Args>
R InvokeObject(VoidPtr ptr, typename ForwardT<Args>::type... args) {
  auto o = static_cast<const Obj*>(ptr.obj);
  return static_cast<R>(std::invoke(*o, std::forward<Args>(args)...));
}

template <typename Fun, typename R, typename... Args>
R InvokeFunction(VoidPtr ptr, typename ForwardT<Args>::type... args) {
  auto f = reinterpret_cast<Fun>(ptr.fun);
  return static_cast<R>(std::invoke(f, std::forward<Args>(args)...));
}

template <typename Sig>
void AssertNonNull(const std::function<Sig>& f) {
  assert(f != nullptr);
  (void)f;
}

template <typename Sig>
void AssertNonNull(const AnyInvocable<Sig>& f) {
  assert(f != nullptr);
  (void)f;
}

template <typename F>
void AssertNonNull(const F&) {}

template <typename F, typename C>
void AssertNonNull(F C::*f) {
  assert(f != nullptr);
  (void)f;
}

template <bool C>
using EnableIf = typename ::std::enable_if<C, int>::type;

}  // namespace functional_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_FUNCTIONAL_INTERNAL_FUNCTION_REF_H_
*›
€soong/.intermediates/external/abseil-cpp/absl_strings_cord_internal_hdrs/gen/my_include_dir/absl/strings/internal/cord_rep_crc.h•// Copyright 2021 The Abseil Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_CRC_H_
#define ABSL_STRINGS_INTERNAL_CORD_REP_CRC_H_

#include <cassert>
#include <cstdint>

#include "absl/base/config.h"
#include "absl/base/optimization.h"
#include "absl/crc/internal/crc_cord_state.h"
#include "absl/strings/internal/cord_internal.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {

// CordRepCrc is a CordRep node intended only to appear at the top level of a
// cord tree.  It associates an "expected CRC" with the contained data, to allow
// for easy passage of checksum data in Cord data flows.
//
// From Cord's perspective, the crc value has no semantics; any validation of
// the contained checksum is the user's responsibility.
struct CordRepCrc : public CordRep {
  CordRep* child;
  absl::crc_internal::CrcCordState crc_cord_state;

  // Consumes `child` and returns a CordRepCrc prefixed tree containing `child`.
  // If the specified `child` is itself a CordRepCrc node, then this method
  // either replaces the existing node, or directly updates the crc state in it
  // depending on the node being shared or not, i.e.: refcount.IsOne().
  // `child` must only be null if the Cord is empty. Never returns null.
  static CordRepCrc* New(CordRep* child, crc_internal::CrcCordState state);

  // Destroys (deletes) the provided node. `node` must not be null.
  static void Destroy(CordRepCrc* node);
};

// Consumes `rep` and returns a CordRep* with any outer CordRepCrc wrapper
// removed.  This is usually a no-op (returning `rep`), but this will remove and
// unref an outer CordRepCrc node.
inline CordRep* RemoveCrcNode(CordRep* rep) {
  assert(rep != nullptr);
  if (ABSL_PREDICT_FALSE(rep->IsCrc())) {
    CordRep* child = rep->crc()->child;
    if (rep->refcount.IsOne()) {
      delete rep->crc();
    } else {
      CordRep::Ref(child);
      CordRep::Unref(rep);
    }
    return child;
  }
  return rep;
}

// Returns `rep` if it is not a CordRepCrc node, or its child if it is.
// Does not consume or create a reference on `rep` or the returned value.
inline CordRep* SkipCrcNode(CordRep* rep) {
  assert(rep != nullptr);
  if (ABSL_PREDICT_FALSE(rep->IsCrc())) {
    return rep->crc()->child;
  } else {
    return rep;
  }
}

inline const CordRep* SkipCrcNode(const CordRep* rep) {
  assert(rep != nullptr);
  if (ABSL_PREDICT_FALSE(rep->IsCrc())) {
    return rep->crc()->child;
  } else {
    return rep;
  }
}

inline CordRepCrc* CordRep::crc() {
  assert(IsCrc());
  return static_cast<CordRepCrc*>(this);
}

inline const CordRepCrc* CordRep::crc() const {
  assert(IsCrc());
  return static_cast<const CordRepCrc*>(this);
}

}  // namespace cord_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_CORD_REP_CRC_H_
*¥
wsoong/.intermediates/external/abseil-cpp/absl_base_errno_saver_hdrs/gen/my_include_dir/absl/base/internal/errno_saver.h©
// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_BASE_INTERNAL_ERRNO_SAVER_H_
#define ABSL_BASE_INTERNAL_ERRNO_SAVER_H_

#include <cerrno>

#include "absl/base/config.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {

// `ErrnoSaver` captures the value of `errno` upon construction and restores it
// upon deletion.  It is used in low-level code and must be super fast.  Do not
// add instrumentation, even in debug modes.
class ErrnoSaver {
 public:
  ErrnoSaver() : saved_errno_(errno) {}
  ~ErrnoSaver() { errno = saved_errno_; }
  int operator()() const { return saved_errno_; }

 private:
  const int saved_errno_;
};

}  // namespace base_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_BASE_INTERNAL_ERRNO_SAVER_H_
* –
‡soong/.intermediates/external/abseil-cpp/absl_functional_any_invocable_hdrs/gen/my_include_dir/absl/functional/internal/any_invocable.h’•// 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.
//
// Implementation details for `absl::AnyInvocable`

#ifndef ABSL_FUNCTIONAL_INTERNAL_ANY_INVOCABLE_H_
#define ABSL_FUNCTIONAL_INTERNAL_ANY_INVOCABLE_H_

////////////////////////////////////////////////////////////////////////////////
//                                                                            //
// This implementation chooses between local storage and remote storage for   //
// the contained target object based on the target object's size, alignment   //
// requirements, and whether or not it has a nothrow move constructor.        //
// Additional optimizations are performed when the object is a trivially      //
// copyable type [basic.types].                                               //
//                                                                            //
// There are three datamembers per `AnyInvocable` instance                    //
//                                                                            //
// 1) A union containing either                                               //
//        - A pointer to the target object referred to via a void*, or        //
//        - the target object, emplaced into a raw char buffer                //
//                                                                            //
// 2) A function pointer to a "manager" function operation that takes a       //
//    discriminator and logically branches to either perform a move operation //
//    or destroy operation based on that discriminator.                       //
//                                                                            //
// 3) A function pointer to an "invoker" function operation that invokes the  //
//    target object, directly returning the result.                           //
//                                                                            //
// When in the logically empty state, the manager function is an empty        //
// function and the invoker function is one that would be undefined behavior  //
// to call.                                                                   //
//                                                                            //
// An additional optimization is performed when converting from one           //
// AnyInvocable to another where only the noexcept specification and/or the   //
// cv/ref qualifiers of the function type differ. In these cases, the         //
// conversion works by "moving the guts", similar to if they were the same    //
// exact type, as opposed to having to perform an additional layer of         //
// wrapping through remote storage.                                           //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////

// IWYU pragma: private, include "absl/functional/any_invocable.h"

#include <cassert>
#include <cstddef>
#include <cstring>
#include <exception>
#include <functional>
#include <memory>
#include <new>
#include <type_traits>
#include <utility>

#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/base/optimization.h"
#include "absl/meta/type_traits.h"
#include "absl/utility/utility.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

// Defined in functional/any_invocable.h
template <class Sig>
class AnyInvocable;

namespace internal_any_invocable {

// Constants relating to the small-object-storage for AnyInvocable
enum StorageProperty : std::size_t {
  kAlignment = alignof(std::max_align_t),  // The alignment of the storage
  kStorageSize = sizeof(void*) * 2         // The size of the storage
};

////////////////////////////////////////////////////////////////////////////////
//
// A metafunction for checking if a type is an AnyInvocable instantiation.
// This is used during conversion operations.
template <class T>
struct IsAnyInvocable : std::false_type {};

template <class Sig>
struct IsAnyInvocable<AnyInvocable<Sig>> : std::true_type {};
//
////////////////////////////////////////////////////////////////////////////////

// A metafunction that tells us whether or not a target function type should be
// stored locally in the small object optimization storage
template <class T>
constexpr bool IsStoredLocally() {
  if constexpr (sizeof(T) <= kStorageSize && alignof(T) <= kAlignment &&
                kAlignment % alignof(T) == 0) {
    return std::is_nothrow_move_constructible<T>::value;
  }
  return false;
}

// An implementation of std::remove_cvref_t of C++20.
template <class T>
using RemoveCVRef =
    typename std::remove_cv<typename std::remove_reference<T>::type>::type;

// An implementation of std::invoke_r of C++23.
template <class ReturnType, class F, class... P>
ReturnType InvokeR(F&& f, P&&... args) {
  if constexpr (std::is_void_v<ReturnType>) {
    std::invoke(std::forward<F>(f), std::forward<P>(args)...);
  } else {
    return std::invoke(std::forward<F>(f), std::forward<P>(args)...);
  }
}

//
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
///
// A metafunction that takes a "T" corresponding to a parameter type of the
// user's specified function type, and yields the parameter type to use for the
// type-erased invoker. In order to prevent observable moves, this must be
// either a reference or, if the type is trivial, the original parameter type
// itself. Since the parameter type may be incomplete at the point that this
// metafunction is used, we can only do this optimization for scalar types
// rather than for any trivial type.
template <typename T>
T ForwardImpl(std::true_type);

template <typename T>
T&& ForwardImpl(std::false_type);

// NOTE: We deliberately use an intermediate struct instead of a direct alias,
// as a workaround for b/206991861 on MSVC versions < 1924.
template <class T>
struct ForwardedParameter {
  using type = decltype((
      ForwardImpl<T>)(std::integral_constant<bool,
                                             std::is_scalar<T>::value>()));
};

template <class T>
using ForwardedParameterType = typename ForwardedParameter<T>::type;
//
////////////////////////////////////////////////////////////////////////////////

// A discriminator when calling the "manager" function that describes operation
// type-erased operation should be invoked.
//
// "relocate_from_to" specifies that the manager should perform a move.
//
// "dispose" specifies that the manager should perform a destroy.
enum class FunctionToCall : bool { relocate_from_to, dispose };

// The portion of `AnyInvocable` state that contains either a pointer to the
// target object or the object itself in local storage
union TypeErasedState {
  struct {
    // A pointer to the type-erased object when remotely stored
    void* target;
    // The size of the object for `RemoteManagerTrivial`
    std::size_t size;
  } remote;

  // Local-storage for the type-erased object when small and trivial enough
  alignas(kAlignment) unsigned char storage[kStorageSize];
};

// A typed accessor for the object in `TypeErasedState` storage
template <class T>
T& ObjectInLocalStorage(TypeErasedState* const state) {
  // We launder here because the storage may be reused with the same type.
  return *std::launder(reinterpret_cast<T*>(&state->storage));
}

// The type for functions issuing lifetime-related operations: move and dispose
// A pointer to such a function is contained in each `AnyInvocable` instance.
// NOTE: When specifying `FunctionToCall::`dispose, the same state must be
// passed as both "from" and "to".
using ManagerType = void(FunctionToCall /*operation*/,
                         TypeErasedState* /*from*/,
                         TypeErasedState* /*to*/) noexcept(true);

// The type for functions issuing the actual invocation of the object
// A pointer to such a function is contained in each AnyInvocable instance.
template <bool SigIsNoexcept, class ReturnType, class... P>
using InvokerType = ReturnType(
    TypeErasedState*, ForwardedParameterType<P>...) noexcept(SigIsNoexcept);

// The manager that is used when AnyInvocable is empty
inline void EmptyManager(FunctionToCall /*operation*/,
                         TypeErasedState* /*from*/,
                         TypeErasedState* /*to*/) noexcept {}

// The manager that is used when a target function is in local storage and is
// a trivially copyable type.
inline void LocalManagerTrivial(FunctionToCall /*operation*/,
                                TypeErasedState* const from,
                                TypeErasedState* const to) noexcept {
  // This single statement without branching handles both possible operations.
  //
  // For FunctionToCall::dispose, "from" and "to" point to the same state, and
  // so this assignment logically would do nothing.
  //
  // Note: Correctness here relies on http://wg21.link/p0593, which has only
  // become standard in C++20, though implementations do not break it in
  // practice for earlier versions of C++.
  //
  // The correct way to do this without that paper is to first placement-new a
  // default-constructed T in "to->storage" prior to the memmove, but doing so
  // requires a different function to be created for each T that is stored
  // locally, which can cause unnecessary bloat and be less cache friendly.
  *to = *from;

  // Note: Because the type is trivially copyable, the destructor does not need
  // to be called ("trivially copyable" requires a trivial destructor).
}

// The manager that is used when a target function is in local storage and is
// not a trivially copyable type.
template <class T>
void LocalManagerNontrivial(FunctionToCall operation,
                            TypeErasedState* const from,
                            TypeErasedState* const to) noexcept {
  static_assert(IsStoredLocally<T>(),
                "Local storage must only be used for supported types.");
  static_assert(!std::is_trivially_copyable<T>::value,
                "Locally stored types must be trivially copyable.");

  T& from_object = (ObjectInLocalStorage<T>)(from);

  switch (operation) {
    case FunctionToCall::relocate_from_to:
      // NOTE: Requires that the left-hand operand is already empty.
      ::new (static_cast<void*>(&to->storage)) T(std::move(from_object));
      ABSL_FALLTHROUGH_INTENDED;
    case FunctionToCall::dispose:
      from_object.~T();  // Must not throw. // NOLINT
      return;
  }
  ABSL_UNREACHABLE();
}

// The invoker that is used when a target function is in local storage
// Note: QualTRef here is the target function type along with cv and reference
// qualifiers that must be used when calling the function.
template <bool SigIsNoexcept, class ReturnType, class QualTRef, class... P>
ReturnType LocalInvoker(
    TypeErasedState* const state,
    ForwardedParameterType<P>... args) noexcept(SigIsNoexcept) {
  using RawT = RemoveCVRef<QualTRef>;
  static_assert(
      IsStoredLocally<RawT>(),
      "Target object must be in local storage in order to be invoked from it.");

  auto& f = (ObjectInLocalStorage<RawT>)(state);
  return (InvokeR<ReturnType>)(static_cast<QualTRef>(f),
                               static_cast<ForwardedParameterType<P>>(args)...);
}

// The manager that is used when a target function is in remote storage and it
// has a trivial destructor
inline void RemoteManagerTrivial(FunctionToCall operation,
                                 TypeErasedState* const from,
                                 TypeErasedState* const to) noexcept {
  switch (operation) {
    case FunctionToCall::relocate_from_to:
      // NOTE: Requires that the left-hand operand is already empty.
      to->remote = from->remote;
      return;
    case FunctionToCall::dispose:
#if defined(__cpp_sized_deallocation)
      ::operator delete(from->remote.target, from->remote.size);
#else   // __cpp_sized_deallocation
      ::operator delete(from->remote.target);
#endif  // __cpp_sized_deallocation
      return;
  }
  ABSL_UNREACHABLE();
}

// The manager that is used when a target function is in remote storage and the
// destructor of the type is not trivial
template <class T>
void RemoteManagerNontrivial(FunctionToCall operation,
                             TypeErasedState* const from,
                             TypeErasedState* const to) noexcept {
  static_assert(!IsStoredLocally<T>(),
                "Remote storage must only be used for types that do not "
                "qualify for local storage.");

  switch (operation) {
    case FunctionToCall::relocate_from_to:
      // NOTE: Requires that the left-hand operand is already empty.
      to->remote.target = from->remote.target;
      return;
    case FunctionToCall::dispose:
      ::delete static_cast<T*>(from->remote.target);  // Must not throw.
      return;
  }
  ABSL_UNREACHABLE();
}

// The invoker that is used when a target function is in remote storage
template <bool SigIsNoexcept, class ReturnType, class QualTRef, class... P>
ReturnType RemoteInvoker(
    TypeErasedState* const state,
    ForwardedParameterType<P>... args) noexcept(SigIsNoexcept) {
  using RawT = RemoveCVRef<QualTRef>;
  static_assert(!IsStoredLocally<RawT>(),
                "Target object must be in remote storage in order to be "
                "invoked from it.");

  auto& f = *static_cast<RawT*>(state->remote.target);
  return (InvokeR<ReturnType>)(static_cast<QualTRef>(f),
                               static_cast<ForwardedParameterType<P>>(args)...);
}

////////////////////////////////////////////////////////////////////////////////
//
// A metafunction that checks if a type T is an instantiation of
// absl::in_place_type_t (needed for constructor constraints of AnyInvocable).
template <class T>
struct IsInPlaceType : std::false_type {};

template <class T>
struct IsInPlaceType<absl::in_place_type_t<T>> : std::true_type {};
//
////////////////////////////////////////////////////////////////////////////////

// A constructor name-tag used with CoreImpl (below) to request the
// conversion-constructor. QualDecayedTRef is the decayed-type of the object to
// wrap, along with the cv and reference qualifiers that must be applied when
// performing an invocation of the wrapped object.
template <class QualDecayedTRef>
struct TypedConversionConstruct {};

// A helper base class for all core operations of AnyInvocable. Most notably,
// this class creates the function call operator and constraint-checkers so that
// the top-level class does not have to be a series of partial specializations.
//
// Note: This definition exists (as opposed to being a declaration) so that if
// the user of the top-level template accidentally passes a template argument
// that is not a function type, they will get a static_assert in AnyInvocable's
// class body rather than an error stating that Impl is not defined.
template <class Sig>
class Impl {};  // Note: This is partially-specialized later.

// A std::unique_ptr deleter that deletes memory allocated via ::operator new.
#if defined(__cpp_sized_deallocation)
class TrivialDeleter {
 public:
  explicit TrivialDeleter(std::size_t size) : size_(size) {}

  void operator()(void* target) const {
    ::operator delete(target, size_);
  }

 private:
  std::size_t size_;
};
#else   // __cpp_sized_deallocation
class TrivialDeleter {
 public:
  explicit TrivialDeleter(std::size_t) {}

  void operator()(void* target) const { ::operator delete(target); }
};
#endif  // __cpp_sized_deallocation

template <bool SigIsNoexcept, class ReturnType, class... P>
class CoreImpl;

constexpr bool IsCompatibleConversion(void*, void*) { return false; }
template <bool NoExceptSrc, bool NoExceptDest, class... T>
constexpr bool IsCompatibleConversion(CoreImpl<NoExceptSrc, T...>*,
                                      CoreImpl<NoExceptDest, T...>*) {
  return !NoExceptDest || NoExceptSrc;
}

// A helper base class for all core operations of AnyInvocable that do not
// depend on the cv/ref qualifiers of the function type.
template <bool SigIsNoexcept, class ReturnType, class... P>
class CoreImpl {
 public:
  using result_type = ReturnType;

  CoreImpl() noexcept : manager_(EmptyManager), invoker_(nullptr) {}

  // Note: QualDecayedTRef here includes the cv-ref qualifiers associated with
  // the invocation of the Invocable. The unqualified type is the target object
  // type to be stored.
  template <class QualDecayedTRef, class F>
  explicit CoreImpl(TypedConversionConstruct<QualDecayedTRef>, F&& f) {
    using DecayedT = RemoveCVRef<QualDecayedTRef>;

    if constexpr (std::is_pointer<DecayedT>::value ||
                  std::is_member_pointer<DecayedT>::value) {
      // This condition handles types that decay into pointers. This includes
      // function references, which cannot be null. GCC warns against comparing
      // their decayed form with nullptr (https://godbolt.org/z/9r9TMTcPK).
      // We could work around this warning with constexpr programming, using
      // std::is_function_v<std::remove_reference_t<F>>, but we choose to ignore
      // it instead of writing more code.
#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"
#endif
      if (static_cast<DecayedT>(f) == nullptr) {
#if !defined(__clang__) && defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
        manager_ = EmptyManager;
        invoker_ = nullptr;
      } else {
        InitializeStorage<QualDecayedTRef>(std::forward<F>(f));
      }
    } else if constexpr (IsCompatibleAnyInvocable<DecayedT>::value) {
      // In this case we can "steal the guts" of the other AnyInvocable.
      f.manager_(FunctionToCall::relocate_from_to, &f.state_, &state_);
      manager_ = f.manager_;
      invoker_ = f.invoker_;

      f.manager_ = EmptyManager;
      f.invoker_ = nullptr;
    } else if constexpr (IsAnyInvocable<DecayedT>::value) {
      if (f.HasValue()) {
        InitializeStorage<QualDecayedTRef>(std::forward<F>(f));
      } else {
        manager_ = EmptyManager;
        invoker_ = nullptr;
      }
    } else {
      InitializeStorage<QualDecayedTRef>(std::forward<F>(f));
    }
  }

  // Note: QualTRef here includes the cv-ref qualifiers associated with the
  // invocation of the Invocable. The unqualified type is the target object
  // type to be stored.
  template <class QualTRef, class... Args>
  explicit CoreImpl(absl::in_place_type_t<QualTRef>, Args&&... args) {
    InitializeStorage<QualTRef>(std::forward<Args>(args)...);
  }

  CoreImpl(CoreImpl&& other) noexcept {
    other.manager_(FunctionToCall::relocate_from_to, &other.state_, &state_);
    manager_ = other.manager_;
    invoker_ = other.invoker_;
    other.manager_ = EmptyManager;
    other.invoker_ = nullptr;
  }

  CoreImpl& operator=(CoreImpl&& other) noexcept {
    // Put the left-hand operand in an empty state.
    //
    // Note: A full reset that leaves us with an object that has its invariants
    // intact is necessary in order to handle self-move. This is required by
    // types that are used with certain operations of the standard library, such
    // as the default definition of std::swap when both operands target the same
    // object.
    Clear();

    // Perform the actual move/destroy operation on the target function.
    other.manager_(FunctionToCall::relocate_from_to, &other.state_, &state_);
    manager_ = other.manager_;
    invoker_ = other.invoker_;
    other.manager_ = EmptyManager;
    other.invoker_ = nullptr;

    return *this;
  }

  ~CoreImpl() { manager_(FunctionToCall::dispose, &state_, &state_); }

  // Check whether or not the AnyInvocable is in the empty state.
  bool HasValue() const { return invoker_ != nullptr; }

  // Effects: Puts the object into its empty state.
  void Clear() {
    manager_(FunctionToCall::dispose, &state_, &state_);
    manager_ = EmptyManager;
    invoker_ = nullptr;
  }

  // Use local (inline) storage for applicable target object types.
  template <class QualTRef, class... Args>
  void InitializeStorage(Args&&... args) {
    using RawT = RemoveCVRef<QualTRef>;
    if constexpr (IsStoredLocally<RawT>()) {
      ::new (static_cast<void*>(&state_.storage))
          RawT(std::forward<Args>(args)...);
      invoker_ = LocalInvoker<SigIsNoexcept, ReturnType, QualTRef, P...>;
      // We can simplify our manager if we know the type is trivially copyable.
      if constexpr (std::is_trivially_copyable_v<RawT>) {
        manager_ = LocalManagerTrivial;
      } else {
        manager_ = LocalManagerNontrivial<RawT>;
      }
    } else {
      InitializeRemoteManager<RawT>(std::forward<Args>(args)...);
      // This is set after everything else in case an exception is thrown in an
      // earlier step of the initialization.
      invoker_ = RemoteInvoker<SigIsNoexcept, ReturnType, QualTRef, P...>;
    }
  }

  template <class T, class... Args>
  void InitializeRemoteManager(Args&&... args) {
    if constexpr (std::is_trivially_destructible_v<T> &&
                  alignof(T) <= ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT) {
      // unique_ptr is used for exception-safety in case construction throws.
      std::unique_ptr<void, TrivialDeleter> uninitialized_target(
          ::operator new(sizeof(T)), TrivialDeleter(sizeof(T)));
      ::new (uninitialized_target.get()) T(std::forward<Args>(args)...);
      state_.remote.target = uninitialized_target.release();
      state_.remote.size = sizeof(T);
      manager_ = RemoteManagerTrivial;
    } else {
      state_.remote.target = ::new T(std::forward<Args>(args)...);
      manager_ = RemoteManagerNontrivial<T>;
    }
  }

  //////////////////////////////////////////////////////////////////////////////
  //
  // Type trait to determine if the template argument is an AnyInvocable whose
  // function type is compatible enough with ours such that we can
  // "move the guts" out of it when moving, rather than having to place a new
  // object into remote storage.

  template <typename Other>
  struct IsCompatibleAnyInvocable {
    static constexpr bool value = false;
  };

  template <typename Sig>
  struct IsCompatibleAnyInvocable<AnyInvocable<Sig>> {
    static constexpr bool value =
        (IsCompatibleConversion)(static_cast<
                                     typename AnyInvocable<Sig>::CoreImpl*>(
                                     nullptr),
                                 static_cast<CoreImpl*>(nullptr));
  };

  //
  //////////////////////////////////////////////////////////////////////////////

  TypeErasedState state_;
  ManagerType* manager_;
  InvokerType<SigIsNoexcept, ReturnType, P...>* invoker_;
};

// A constructor name-tag used with Impl to request the
// conversion-constructor
struct ConversionConstruct {};

////////////////////////////////////////////////////////////////////////////////
//
// A metafunction that is normally an identity metafunction except that when
// given a std::reference_wrapper<T>, it yields T&. This is necessary because
// currently std::reference_wrapper's operator() is not conditionally noexcept,
// so when checking if such an Invocable is nothrow-invocable, we must pull out
// the underlying type.
template <class T>
struct UnwrapStdReferenceWrapperImpl {
  using type = T;
};

template <class T>
struct UnwrapStdReferenceWrapperImpl<std::reference_wrapper<T>> {
  using type = T&;
};

template <class T>
using UnwrapStdReferenceWrapper =
    typename UnwrapStdReferenceWrapperImpl<T>::type;
//
////////////////////////////////////////////////////////////////////////////////

// An alias that always yields std::true_type (used with constraints) where
// substitution failures happen when forming the template arguments.
template <class... T>
using TrueAlias =
    std::integral_constant<bool, sizeof(absl::void_t<T...>*) != 0>;

/*SFINAE constraints for the conversion-constructor.*/
template <class Sig, class F,
          class = absl::enable_if_t<
              !std::is_same<RemoveCVRef<F>, AnyInvocable<Sig>>::value>>
using CanConvert = TrueAlias<
    absl::enable_if_t<!IsInPlaceType<RemoveCVRef<F>>::value>,
    absl::enable_if_t<Impl<Sig>::template CallIsValid<F>::value>,
    absl::enable_if_t<
        Impl<Sig>::template CallIsNoexceptIfSigIsNoexcept<F>::value>,
    absl::enable_if_t<std::is_constructible<absl::decay_t<F>, F>::value>>;

/*SFINAE constraints for the std::in_place constructors.*/
template <class Sig, class F, class... Args>
using CanEmplace = TrueAlias<
    absl::enable_if_t<Impl<Sig>::template CallIsValid<F>::value>,
    absl::enable_if_t<
        Impl<Sig>::template CallIsNoexceptIfSigIsNoexcept<F>::value>,
    absl::enable_if_t<std::is_constructible<absl::decay_t<F>, Args...>::value>>;

/*SFINAE constraints for the conversion-assign operator.*/
template <class Sig, class F,
          class = absl::enable_if_t<
              !std::is_same<RemoveCVRef<F>, AnyInvocable<Sig>>::value>>
using CanAssign = TrueAlias<
    absl::enable_if_t<Impl<Sig>::template CallIsValid<F>::value>,
    absl::enable_if_t<
        Impl<Sig>::template CallIsNoexceptIfSigIsNoexcept<F>::value>,
    absl::enable_if_t<std::is_constructible<absl::decay_t<F>, F>::value>>;

/*SFINAE constraints for the reference-wrapper conversion-assign operator.*/
template <class Sig, class F>
using CanAssignReferenceWrapper = TrueAlias<
    absl::enable_if_t<
        Impl<Sig>::template CallIsValid<std::reference_wrapper<F>>::value>,
    absl::enable_if_t<Impl<Sig>::template CallIsNoexceptIfSigIsNoexcept<
        std::reference_wrapper<F>>::value>>;

// The constraint for checking whether or not a call meets the noexcept
// callability requirements. We use a preprocessor macro because specifying it
// this way as opposed to a disjunction/branch can improve the user-side error
// messages and avoids an instantiation of std::is_nothrow_invocable_r in the
// cases where the user did not specify a noexcept function type.
//
// The disjunction below is because we can't rely on std::is_nothrow_invocable_r
// to give the right result when ReturnType is non-moveable in toolchains that
// don't treat non-moveable result types correctly. For example this was the
// case in libc++ before commit c3a24882 (2022-05).
#define ABSL_INTERNAL_ANY_INVOCABLE_NOEXCEPT_CONSTRAINT_true(inv_quals)      \
  absl::enable_if_t<absl::disjunction<                                       \
      std::is_nothrow_invocable_r<                                           \
          ReturnType, UnwrapStdReferenceWrapper<absl::decay_t<F>> inv_quals, \
          P...>,                                                             \
      std::conjunction<                                                      \
          std::is_nothrow_invocable<                                         \
              UnwrapStdReferenceWrapper<absl::decay_t<F>> inv_quals, P...>,  \
          std::is_same<                                                      \
              ReturnType,                                                    \
              std::invoke_result_t<                                          \
                  UnwrapStdReferenceWrapper<absl::decay_t<F>> inv_quals,     \
                  P...>>>>::value>

#define ABSL_INTERNAL_ANY_INVOCABLE_NOEXCEPT_CONSTRAINT_false(inv_quals)
//
////////////////////////////////////////////////////////////////////////////////

// A macro to generate partial specializations of Impl with the different
// combinations of supported cv/reference qualifiers and noexcept specifier.
//
// Here, `cv` are the cv-qualifiers if any, `ref` is the ref-qualifier if any,
// inv_quals is the reference type to be used when invoking the target, and
// noex is "true" if the function type is noexcept, or false if it is not.
//
// The CallIsValid condition is more complicated than simply using
// std::is_invocable_r because we can't rely on it to give the right result
// when ReturnType is non-moveable in toolchains that don't treat non-moveable
// result types correctly. For example this was the case in libc++ before commit
// c3a24882 (2022-05).
#define ABSL_INTERNAL_ANY_INVOCABLE_IMPL_(cv, ref, inv_quals, noex)            \
  template <class ReturnType, class... P>                                      \
  class Impl<ReturnType(P...) cv ref noexcept(noex)>                           \
      : public CoreImpl<noex, ReturnType, P...> {                              \
   public:                                                                     \
    /*The base class, which contains the datamembers and core operations*/     \
    using Core = CoreImpl<noex, ReturnType, P...>;                             \
                                                                               \
    /*SFINAE constraint to check if F is invocable with the proper signature*/ \
    template <class F>                                                         \
    using CallIsValid = TrueAlias<absl::enable_if_t<absl::disjunction<         \
        std::is_invocable_r<ReturnType, absl::decay_t<F> inv_quals, P...>,     \
        std::is_same<                                                          \
            ReturnType,                                                        \
            std::invoke_result_t<absl::decay_t<F> inv_quals, P...>>>::value>>; \
                                                                               \
    /*SFINAE constraint to check if F is nothrow-invocable when necessary*/    \
    template <class F>                                                         \
    using CallIsNoexceptIfSigIsNoexcept =                                      \
        TrueAlias<ABSL_INTERNAL_ANY_INVOCABLE_NOEXCEPT_CONSTRAINT_##noex(      \
            inv_quals)>;                                                       \
                                                                               \
    /*Put the AnyInvocable into an empty state.*/                              \
    Impl() = default;                                                          \
                                                                               \
    /*The implementation of a conversion-constructor from "f*/                 \
    /*This forwards to Core, attaching inv_quals so that the base class*/      \
    /*knows how to properly type-erase the invocation.*/                       \
    template <class F>                                                         \
    explicit Impl(ConversionConstruct, F&& f)                                  \
        : Core(TypedConversionConstruct<                                       \
                   typename std::decay<F>::type inv_quals>(),                  \
               std::forward<F>(f)) {}                                          \
                                                                               \
    /*Forward along the in-place construction parameters.*/                    \
    template <class T, class... Args>                                          \
    explicit Impl(absl::in_place_type_t<T>, Args&&... args)                    \
        : Core(absl::in_place_type<absl::decay_t<T> inv_quals>,                \
               std::forward<Args>(args)...) {}                                 \
                                                                               \
    /*Raises a fatal error when the AnyInvocable is invoked after a move*/     \
    static ReturnType InvokedAfterMove(                                        \
        TypeErasedState*, ForwardedParameterType<P>...) noexcept(noex) {       \
      ABSL_HARDENING_ASSERT(false && "AnyInvocable use-after-move");           \
      std::terminate();                                                        \
    }                                                                          \
                                                                               \
    InvokerType<noex, ReturnType, P...>* ExtractInvoker() cv {                 \
      using QualifiedTestType = int cv ref;                                    \
      auto* invoker = this->invoker_;                                          \
      if (!std::is_const<QualifiedTestType>::value &&                          \
          std::is_rvalue_reference<QualifiedTestType>::value) {                \
        ABSL_ASSERT([this]() {                                                 \
          /* We checked that this isn't const above, so const_cast is safe */  \
          const_cast<Impl*>(this)->invoker_ = InvokedAfterMove;                \
          return this->HasValue();                                             \
        }());                                                                  \
      }                                                                        \
      return invoker;                                                          \
    }                                                                          \
                                                                               \
    /*The actual invocation operation with the proper signature*/              \
    ReturnType operator()(P... args) cv ref noexcept(noex) {                   \
      assert(this->invoker_ != nullptr);                                       \
      return this->ExtractInvoker()(                                           \
          const_cast<TypeErasedState*>(&this->state_),                         \
          static_cast<ForwardedParameterType<P>>(args)...);                    \
    }                                                                          \
  }

// A convenience macro that defines specializations for the noexcept(true) and
// noexcept(false) forms, given the other properties.
#define ABSL_INTERNAL_ANY_INVOCABLE_IMPL(cv, ref, inv_quals)    \
  ABSL_INTERNAL_ANY_INVOCABLE_IMPL_(cv, ref, inv_quals, false); \
  ABSL_INTERNAL_ANY_INVOCABLE_IMPL_(cv, ref, inv_quals, true)

// Non-ref-qualified partial specializations
ABSL_INTERNAL_ANY_INVOCABLE_IMPL(, , &);
ABSL_INTERNAL_ANY_INVOCABLE_IMPL(const, , const&);

// Lvalue-ref-qualified partial specializations
ABSL_INTERNAL_ANY_INVOCABLE_IMPL(, &, &);
ABSL_INTERNAL_ANY_INVOCABLE_IMPL(const, &, const&);

// Rvalue-ref-qualified partial specializations
ABSL_INTERNAL_ANY_INVOCABLE_IMPL(, &&, &&);
ABSL_INTERNAL_ANY_INVOCABLE_IMPL(const, &&, const&&);

// Undef the detail-only macros.
#undef ABSL_INTERNAL_ANY_INVOCABLE_IMPL
#undef ABSL_INTERNAL_ANY_INVOCABLE_IMPL_
#undef ABSL_INTERNAL_ANY_INVOCABLE_NOEXCEPT_CONSTRAINT_false
#undef ABSL_INTERNAL_ANY_INVOCABLE_NOEXCEPT_CONSTRAINT_true

}  // namespace internal_any_invocable
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_FUNCTIONAL_INTERNAL_ANY_INVOCABLE_H_
*”
‹soong/.intermediates/external/abseil-cpp/absl_strings_cordz_update_scope_hdrs/gen/my_include_dir/absl/strings/internal/cordz_update_scope.hƒ// Copyright 2021 The Abseil Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_SCOPE_H_
#define ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_SCOPE_H_

#include "absl/base/config.h"
#include "absl/base/optimization.h"
#include "absl/base/thread_annotations.h"
#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cordz_info.h"
#include "absl/strings/internal/cordz_update_tracker.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {

// CordzUpdateScope scopes an update to the provided CordzInfo.
// The class invokes `info->Lock(method)` and `info->Unlock()` to guard
// cordrep updates. This class does nothing if `info` is null.
// See also the 'Lock`, `Unlock` and `SetCordRep` methods in `CordzInfo`.
class ABSL_SCOPED_LOCKABLE CordzUpdateScope {
 public:
  CordzUpdateScope(CordzInfo* info, CordzUpdateTracker::MethodIdentifier method)
      ABSL_EXCLUSIVE_LOCK_FUNCTION(info)
      : info_(info) {
    if (ABSL_PREDICT_FALSE(info_)) {
      info->Lock(method);
    }
  }

  // CordzUpdateScope can not be copied or assigned to.
  CordzUpdateScope(CordzUpdateScope&& rhs) = delete;
  CordzUpdateScope(const CordzUpdateScope&) = delete;
  CordzUpdateScope& operator=(CordzUpdateScope&& rhs) = delete;
  CordzUpdateScope& operator=(const CordzUpdateScope&) = delete;

  ~CordzUpdateScope() ABSL_UNLOCK_FUNCTION() {
    if (ABSL_PREDICT_FALSE(info_)) {
      info_->Unlock();
    }
  }

  void SetCordRep(CordRep* rep) const {
    if (ABSL_PREDICT_FALSE(info_)) {
      info_->SetCordRep(rep);
    }
  }

  CordzInfo* info() const { return info_; }

 private:
  CordzInfo* info_;
};

}  // namespace cord_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_CORDZ_UPDATE_SCOPE_H_
*¶P
hsoong/.intermediates/external/abseil-cpp/absl_base_hdrs/gen/my_include_dir/absl/base/internal/spinlock.hÉO//
// 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.
//

//  Most users requiring mutual exclusion should use Mutex.
//  SpinLock is provided for use in two situations:
//   - for use by Abseil internal code that Mutex itself depends on
//   - for async signal safety (see below)

// 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.

#ifndef ABSL_BASE_INTERNAL_SPINLOCK_H_
#define ABSL_BASE_INTERNAL_SPINLOCK_H_

#include <atomic>
#include <cstdint>

#include "absl/base/attributes.h"
#include "absl/base/const_init.h"
#include "absl/base/dynamic_annotations.h"
#include "absl/base/internal/low_level_scheduling.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/internal/scheduling_mode.h"
#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 {

class ABSL_LOCKABLE ABSL_ATTRIBUTE_WARN_UNUSED SpinLock {
 public:
  SpinLock() : lockword_(kSpinLockCooperative) {
    ABSL_TSAN_MUTEX_CREATE(this, __tsan_mutex_not_static);
  }

  // Constructors that allow non-cooperative spinlocks to be created for use
  // inside thread schedulers.  Normal clients should not use these.
  explicit SpinLock(base_internal::SchedulingMode mode);

  // Constructor for global SpinLock instances.  See absl/base/const_init.h.
  constexpr SpinLock(absl::ConstInitType, base_internal::SchedulingMode mode)
      : lockword_(IsCooperative(mode) ? kSpinLockCooperative : 0) {}

  // For global SpinLock instances prefer trivial destructor when possible.
  // Default but non-trivial destructor in some build configurations causes an
  // extra static initializer.
#ifdef ABSL_INTERNAL_HAVE_TSAN_INTERFACE
  ~SpinLock() { ABSL_TSAN_MUTEX_DESTROY(this, __tsan_mutex_not_static); }
#else
  ~SpinLock() = default;
#endif

  // Acquire this SpinLock.
  inline void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION() {
    ABSL_TSAN_MUTEX_PRE_LOCK(this, 0);
    if (!TryLockImpl()) {
      SlowLock();
    }
    ABSL_TSAN_MUTEX_POST_LOCK(this, 0, 0);
  }

  // Try to acquire this SpinLock without blocking and return true if the
  // acquisition was successful.  If the lock was not acquired, false is
  // returned.  If this SpinLock is free at the time of the call, TryLock
  // will return true with high probability.
  [[nodiscard]] inline bool TryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true) {
    ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_try_lock);
    bool res = TryLockImpl();
    ABSL_TSAN_MUTEX_POST_LOCK(
        this, __tsan_mutex_try_lock | (res ? 0 : __tsan_mutex_try_lock_failed),
        0);
    return res;
  }

  // Release this SpinLock, which must be held by the calling thread.
  inline void Unlock() ABSL_UNLOCK_FUNCTION() {
    ABSL_TSAN_MUTEX_PRE_UNLOCK(this, 0);
    uint32_t lock_value = lockword_.load(std::memory_order_relaxed);
    lock_value = lockword_.exchange(lock_value & kSpinLockCooperative,
                                    std::memory_order_release);

    if ((lock_value & kSpinLockDisabledScheduling) != 0) {
      base_internal::SchedulingGuard::EnableRescheduling(true);
    }
    if ((lock_value & kWaitTimeMask) != 0) {
      // Collect contentionz profile info, and speed the wakeup of any waiter.
      // The wait_cycles value indicates how long this thread spent waiting
      // for the lock.
      SlowUnlock(lock_value);
    }
    ABSL_TSAN_MUTEX_POST_UNLOCK(this, 0);
  }

  // Determine if the lock is held.  When the lock is held by the invoking
  // thread, true will always be returned. Intended to be used as
  // CHECK(lock.IsHeld()).
  [[nodiscard]] inline bool IsHeld() const {
    return (lockword_.load(std::memory_order_relaxed) & kSpinLockHeld) != 0;
  }

  // Return immediately if this thread holds the SpinLock exclusively.
  // Otherwise, report an error by crashing with a diagnostic.
  inline void AssertHeld() const ABSL_ASSERT_EXCLUSIVE_LOCK() {
    if (!IsHeld()) {
      ABSL_RAW_LOG(FATAL, "thread should hold the lock on SpinLock");
    }
  }

 protected:
  // These should not be exported except for testing.

  // Store number of cycles between wait_start_time and wait_end_time in a
  // lock value.
  static uint32_t EncodeWaitCycles(int64_t wait_start_time,
                                   int64_t wait_end_time);

  // Extract number of wait cycles in a lock value.
  static int64_t DecodeWaitCycles(uint32_t lock_value);

  // 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:
  //
  // bit[0] encodes whether a lock is being held.
  // bit[1] encodes whether a lock uses cooperative scheduling.
  // bit[2] encodes whether the current lock holder disabled scheduling when
  //        acquiring the lock. Only set when kSpinLockHeld is also set.
  // bit[3:31] encodes time a lock spent on waiting as a 29-bit unsigned int.
  //        This is set by the lock holder to indicate how long it waited on
  //        the lock before eventually acquiring it. The number of cycles is
  //        encoded as a 29-bit unsigned int, or in the case that the current
  //        holder did not wait but another waiter is queued, the LSB
  //        (kSpinLockSleeper) is set. The implementation does not explicitly
  //        track the number of queued waiters beyond this. It must always be
  //        assumed that waiters may exist if the current holder was required to
  //        queue.
  //
  // Invariant: if the lock is not held, the value is either 0 or
  // kSpinLockCooperative.
  static constexpr uint32_t kSpinLockHeld = 1;
  static constexpr uint32_t kSpinLockCooperative = 2;
  static constexpr uint32_t kSpinLockDisabledScheduling = 4;
  static constexpr uint32_t kSpinLockSleeper = 8;
  // Includes kSpinLockSleeper.
  static constexpr uint32_t kWaitTimeMask =
      ~(kSpinLockHeld | kSpinLockCooperative | kSpinLockDisabledScheduling);

  // Returns true if the provided scheduling mode is cooperative.
  static constexpr bool IsCooperative(
      base_internal::SchedulingMode scheduling_mode) {
    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;
  uint32_t SpinLoop();

  inline bool TryLockImpl() {
    uint32_t lock_value = lockword_.load(std::memory_order_relaxed);
    return (TryLockInternal(lock_value, 0) & kSpinLockHeld) == 0;
  }

  std::atomic<uint32_t> lockword_;

  SpinLock(const SpinLock&) = delete;
  SpinLock& operator=(const SpinLock&) = delete;
};

// Corresponding locker object that arranges to acquire a spinlock for
// the duration of a C++ scope.
class ABSL_SCOPED_LOCKABLE [[nodiscard]] SpinLockHolder {
 public:
  inline explicit SpinLockHolder(SpinLock* l) ABSL_EXCLUSIVE_LOCK_FUNCTION(l)
      : lock_(l) {
    l->Lock();
  }
  inline ~SpinLockHolder() ABSL_UNLOCK_FUNCTION() { lock_->Unlock(); }

  SpinLockHolder(const SpinLockHolder&) = delete;
  SpinLockHolder& operator=(const SpinLockHolder&) = delete;

 private:
  SpinLock* lock_;
};

// Register a hook for profiling support.
//
// The function pointer registered here will be called whenever a spinlock is
// contended.  The callback is given an opaque handle to the contended spinlock
// and the number of wait cycles.  This is thread-safe, but only a single
// profiler can be registered.  It is an error to call this function multiple
// times with different arguments.
void RegisterSpinLockProfiler(void (*fn)(const void* lock,
                                         int64_t wait_cycles));

//------------------------------------------------------------------------------
// Public interface ends here.
//------------------------------------------------------------------------------

// If (result & kSpinLockHeld) == 0, then *this was successfully locked.
// Otherwise, returns last observed value for lockword_.
inline uint32_t SpinLock::TryLockInternal(uint32_t lock_value,
                                          uint32_t wait_cycles) {
  if ((lock_value & kSpinLockHeld) != 0) {
    return lock_value;
  }

  uint32_t sched_disabled_bit = 0;
  if ((lock_value & kSpinLockCooperative) == 0) {
    // For non-cooperative locks we must make sure we mark ourselves as
    // non-reschedulable before we attempt to CompareAndSwap.
    if (base_internal::SchedulingGuard::DisableRescheduling()) {
      sched_disabled_bit = kSpinLockDisabledScheduling;
    }
  }

  if (!lockword_.compare_exchange_strong(
          lock_value,
          kSpinLockHeld | lock_value | wait_cycles | sched_disabled_bit,
          std::memory_order_acquire, std::memory_order_relaxed)) {
    base_internal::SchedulingGuard::EnableRescheduling(sched_disabled_bit != 0);
  }

  return lock_value;
}

}  // namespace base_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_BASE_INTERNAL_SPINLOCK_H_
*ù
Œsoong/.intermediates/external/abseil-cpp/absl_strings_str_format_internal_hdrs/gen/my_include_dir/absl/strings/internal/str_format/checker.hç// 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_STR_FORMAT_CHECKER_H_
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_

#include <algorithm>

#include "absl/base/attributes.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"

// Compile time check support for entry points.

#ifndef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
// We disable format checker under vscode intellisense compilation.
// See https://github.com/microsoft/vscode-cpptools/issues/3683 for
// more details.
#if ABSL_HAVE_ATTRIBUTE(enable_if) && !defined(__native_client__) && \
    !defined(__INTELLISENSE__)
#define ABSL_INTERNAL_ENABLE_FORMAT_CHECKER 1
#endif  // ABSL_HAVE_ATTRIBUTE(enable_if) && !defined(__native_client__) &&
        // !defined(__INTELLISENSE__)
#endif  // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace str_format_internal {

#ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER

template <FormatConversionCharSet... C>
constexpr bool ValidFormatImpl(string_view format) {
  int next_arg = 0;
  const char* p = format.data();
  const char* const end = p + format.size();
  constexpr FormatConversionCharSet
      kAllowedConvs[(std::max)(sizeof...(C), size_t{1})] = {C...};
  bool used[(std::max)(sizeof...(C), size_t{1})]{};
  constexpr int kNumArgs = sizeof...(C);
  while (p != end) {
    while (p != end && *p != '%') ++p;
    if (p == end) {
      break;
    }
    if (p + 1 >= end) return false;
    if (p[1] == '%') {
      // %%
      p += 2;
      continue;
    }

    UnboundConversion conv(absl::kConstInit);
    p = ConsumeUnboundConversion(p + 1, end, &conv, &next_arg);
    if (p == nullptr) return false;
    if (conv.arg_position <= 0 || conv.arg_position > kNumArgs) {
      return false;
    }
    if (!Contains(kAllowedConvs[conv.arg_position - 1], conv.conv)) {
      return false;
    }
    used[conv.arg_position - 1] = true;
    for (auto extra : {conv.width, conv.precision}) {
      if (extra.is_from_arg()) {
        int pos = extra.get_from_arg();
        if (pos <= 0 || pos > kNumArgs) return false;
        used[pos - 1] = true;
        if (!Contains(kAllowedConvs[pos - 1], '*')) {
          return false;
        }
      }
    }
  }
  if (sizeof...(C) != 0) {
    for (bool b : used) {
      if (!b) return false;
    }
  }
  return true;
}

#endif  // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER

}  // namespace str_format_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_
*Õ=
�soong/.intermediates/external/abseil-cpp/absl_strings_cord_internal_hdrs/gen/my_include_dir/absl/strings/internal/cord_rep_flat.hÎ<// 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_FLAT_H_
#define ABSL_STRINGS_INTERNAL_CORD_REP_FLAT_H_

#include <cassert>
#include <cstddef>
#include <cstdint>
#include <memory>

#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/strings/internal/cord_internal.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {

// Note: all constants below are never ODR used and internal to cord, we define
// these as static constexpr to avoid 'in struct' definition and usage clutter.

// Largest and smallest flat node lengths we are willing to allocate
// Flat allocation size is stored in tag, which currently can encode sizes up
// to 4K, encoded as multiple of either 8 or 32 bytes.
// If we allow for larger sizes, we need to change this to 8/64, 16/128, etc.
// kMinFlatSize is bounded by tag needing to be at least FLAT * 8 bytes, and
// ideally a 'nice' size aligning with allocation and cacheline sizes like 32.
// kMaxFlatSize is bounded by the size resulting in a computed tag no greater
// than MAX_FLAT_TAG. MAX_FLAT_TAG provides for additional 'high' tag values.
static constexpr size_t kFlatOverhead = offsetof(CordRep, storage);
static constexpr size_t kMinFlatSize = 32;
static constexpr size_t kMaxFlatSize = 4096;
static constexpr size_t kMaxFlatLength = kMaxFlatSize - kFlatOverhead;
static constexpr size_t kMinFlatLength = kMinFlatSize - kFlatOverhead;
static constexpr size_t kMaxLargeFlatSize = 256 * 1024;
static constexpr size_t kMaxLargeFlatLength = kMaxLargeFlatSize - kFlatOverhead;

// kTagBase should make the Size <--> Tag computation resilient
// against changes to the value of FLAT when we add a new tag..
static constexpr uint8_t kTagBase = FLAT - 4;

// Converts the provided rounded size to the corresponding tag
constexpr uint8_t AllocatedSizeToTagUnchecked(size_t size) {
  return static_cast<uint8_t>(size <= 512 ? kTagBase + size / 8
                              : size <= 8192
                                  ? kTagBase + 512 / 8 + size / 64 - 512 / 64
                                  : kTagBase + 512 / 8 + ((8192 - 512) / 64) +
                                        size / 4096 - 8192 / 4096);
}

// Converts the provided tag to the corresponding allocated size
constexpr size_t TagToAllocatedSize(uint8_t tag) {
  return (tag <= kTagBase + 512 / 8) ? tag * 8 - kTagBase * 8
         : (tag <= kTagBase + (512 / 8) + ((8192 - 512) / 64))
             ? 512 + tag * 64 - kTagBase * 64 - 512 / 8 * 64
             : 8192 + tag * 4096 - kTagBase * 4096 -
                   ((512 / 8) + ((8192 - 512) / 64)) * 4096;
}

static_assert(AllocatedSizeToTagUnchecked(kMinFlatSize) == FLAT, "");
static_assert(AllocatedSizeToTagUnchecked(kMaxLargeFlatSize) == MAX_FLAT_TAG,
              "");

// RoundUp logically performs `((n + m - 1) / m) * m` to round up to the nearest
// multiple of `m`, optimized for the invariant that `m` is a power of 2.
constexpr size_t RoundUp(size_t n, size_t m) {
  return (n + m - 1) & (0 - m);
}

// Returns the size to the nearest equal or larger value that can be
// expressed exactly as a tag value.
inline size_t RoundUpForTag(size_t size) {
  return RoundUp(size, (size <= 512) ? 8 : (size <= 8192 ? 64 : 4096));
}

// Converts the allocated size to a tag, rounding down if the size
// does not exactly match a 'tag expressible' size value. The result is
// undefined if the size exceeds the maximum size that can be encoded in
// a tag, i.e., if size is larger than TagToAllocatedSize(<max tag>).
inline uint8_t AllocatedSizeToTag(size_t size) {
  const uint8_t tag = AllocatedSizeToTagUnchecked(size);
  assert(tag <= MAX_FLAT_TAG);
  return tag;
}

// Converts the provided tag to the corresponding available data length
constexpr size_t TagToLength(uint8_t tag) {
  return TagToAllocatedSize(tag) - kFlatOverhead;
}

// Enforce that kMaxFlatSize maps to a well-known exact tag value.
static_assert(TagToAllocatedSize(MAX_FLAT_TAG) == kMaxLargeFlatSize,
              "Bad tag logic");

struct CordRepFlat : public CordRep {
  // Tag for explicit 'large flat' allocation
  struct Large {};

  // Creates a new flat node.
  template <size_t max_flat_size, typename... Args>
  static CordRepFlat* NewImpl(size_t len, Args... args ABSL_ATTRIBUTE_UNUSED) {
    if (len <= kMinFlatLength) {
      len = kMinFlatLength;
    } else if (len > max_flat_size - kFlatOverhead) {
      len = max_flat_size - kFlatOverhead;
    }

    // Round size up so it matches a size we can exactly express in a tag.
    const size_t size = RoundUpForTag(len + kFlatOverhead);
    void* const raw_rep = ::operator new(size);
    // GCC 13 has a false-positive -Wstringop-overflow warning here.
    #if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(13, 0)
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wstringop-overflow"
    #endif
    CordRepFlat* rep = new (raw_rep) CordRepFlat();
    rep->tag = AllocatedSizeToTag(size);
    #if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(13, 0)
    #pragma GCC diagnostic pop
    #endif
    return rep;
  }

  static CordRepFlat* New(size_t len) { return NewImpl<kMaxFlatSize>(len); }

  static CordRepFlat* New(Large, size_t len) {
    return NewImpl<kMaxLargeFlatSize>(len);
  }

  // Deletes a CordRepFlat instance created previously through a call to New().
  // Flat CordReps are allocated and constructed with raw ::operator new and
  // placement new, and must be destructed and deallocated accordingly.
  static void Delete(CordRep*rep) {
    assert(rep->tag >= FLAT && rep->tag <= MAX_FLAT_TAG);

#if defined(__cpp_sized_deallocation)
    size_t size = TagToAllocatedSize(rep->tag);
    rep->~CordRep();
    ::operator delete(rep, size);
#else
    rep->~CordRep();
    ::operator delete(rep);
#endif
  }

  // Create a CordRepFlat containing `data`, with an optional additional
  // extra capacity of up to `extra` bytes. Requires that `data.size()`
  // is less than kMaxFlatLength.
  static CordRepFlat* Create(absl::string_view data, size_t extra = 0) {
    assert(data.size() <= kMaxFlatLength);
    CordRepFlat* flat = New(data.size() + (std::min)(extra, kMaxFlatLength));
    memcpy(flat->Data(), data.data(), data.size());
    flat->length = data.size();
    return flat;
  }

  // Returns a pointer to the data inside this flat rep.
  char* Data() { return reinterpret_cast<char*>(storage); }
  const char* Data() const { return reinterpret_cast<const char*>(storage); }

  // Returns the maximum capacity (payload size) of this instance.
  size_t Capacity() const { return TagToLength(tag); }

  // Returns the allocated size (payload + overhead) of this instance.
  size_t AllocatedSize() const { return TagToAllocatedSize(tag); }
};

// Now that CordRepFlat is defined, we can define CordRep's helper casts:
inline CordRepFlat* CordRep::flat() {
  assert(tag >= FLAT && tag <= MAX_FLAT_TAG);
  return reinterpret_cast<CordRepFlat*>(this);
}

inline const CordRepFlat* CordRep::flat() const {
  assert(tag >= FLAT && tag <= MAX_FLAT_TAG);
  return reinterpret_cast<const CordRepFlat*>(this);
}

}  // namespace cord_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_CORD_REP_FLAT_H_
*õ¦
usoong/.intermediates/external/abseil-cpp/absl_container_btree_hdrs/gen/my_include_dir/absl/container/internal/btree.hú¥// Copyright 2018 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// A btree implementation of the STL set and map interfaces. A btree is smaller
// and generally also faster than STL set/map (refer to the benchmarks below).
// The red-black tree implementation of STL set/map has an overhead of 3
// pointers (left, right and parent) plus the node color information for each
// stored value. So a set<int32_t> consumes 40 bytes for each value stored in
// 64-bit mode. This btree implementation stores multiple values on fixed
// size nodes (usually 256 bytes) and doesn't store child pointers for leaf
// nodes. The result is that a btree_set<int32_t> may use much less memory per
// stored value. For the random insertion benchmark in btree_bench.cc, a
// btree_set<int32_t> with node-size of 256 uses 5.1 bytes per stored value.
//
// The packing of multiple values on to each node of a btree has another effect
// besides better space utilization: better cache locality due to fewer cache
// lines being accessed. Better cache locality translates into faster
// operations.
//
// CAVEATS
//
// Insertions and deletions on a btree can cause splitting, merging or
// rebalancing of btree nodes. And even without these operations, insertions
// and deletions on a btree will move values around within a node. In both
// cases, the result is that insertions and deletions can invalidate iterators
// pointing to values other than the one being inserted/deleted. Therefore, this
// container does not provide pointer stability. This is notably different from
// STL set/map which takes care to not invalidate iterators on insert/erase
// except, of course, for iterators pointing to the value being erased.  A
// partial workaround when erasing is available: erase() returns an iterator
// pointing to the item just after the one that was erased (or end() if none
// exists).

#ifndef ABSL_CONTAINER_INTERNAL_BTREE_H_
#define ABSL_CONTAINER_INTERNAL_BTREE_H_

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <functional>
#include <iterator>
#include <limits>
#include <string>
#include <type_traits>
#include <utility>

#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/macros.h"
#include "absl/base/optimization.h"
#include "absl/container/internal/common.h"
#include "absl/container/internal/common_policy_traits.h"
#include "absl/container/internal/compressed_tuple.h"
#include "absl/container/internal/container_memory.h"
#include "absl/container/internal/layout.h"
#include "absl/memory/memory.h"
#include "absl/meta/type_traits.h"
#include "absl/strings/cord.h"
#include "absl/strings/string_view.h"
#include "absl/types/compare.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace container_internal {

#ifdef ABSL_BTREE_ENABLE_GENERATIONS
#error ABSL_BTREE_ENABLE_GENERATIONS cannot be directly set
#elif (defined(ABSL_HAVE_ADDRESS_SANITIZER) ||   \
       defined(ABSL_HAVE_HWADDRESS_SANITIZER) || \
       defined(ABSL_HAVE_MEMORY_SANITIZER)) &&   \
    !defined(NDEBUG_SANITIZER)  // If defined, performance is important.
// When compiled in sanitizer mode, we add generation integers to the nodes and
// iterators. When iterators are used, we validate that the container has not
// been mutated since the iterator was constructed.
#define ABSL_BTREE_ENABLE_GENERATIONS
#endif

#ifdef ABSL_BTREE_ENABLE_GENERATIONS
constexpr bool BtreeGenerationsEnabled() { return true; }
#else
constexpr bool BtreeGenerationsEnabled() { return false; }
#endif

template <typename Compare, typename T, typename U>
using compare_result_t = absl::result_of_t<const Compare(const T &, const U &)>;

// A helper class that indicates if the Compare parameter is a key-compare-to
// comparator.
template <typename Compare, typename T>
using btree_is_key_compare_to =
    std::is_convertible<compare_result_t<Compare, T, T>, absl::weak_ordering>;

struct StringBtreeDefaultLess {
  using is_transparent = void;

  StringBtreeDefaultLess() = default;

  // Compatibility constructor.
  StringBtreeDefaultLess(std::less<std::string>) {}        // NOLINT
  StringBtreeDefaultLess(std::less<absl::string_view>) {}  // NOLINT

  // Allow converting to std::less for use in key_comp()/value_comp().
  explicit operator std::less<std::string>() const { return {}; }
  explicit operator std::less<absl::string_view>() const { return {}; }
  explicit operator std::less<absl::Cord>() const { return {}; }

  absl::weak_ordering operator()(absl::string_view lhs,
                                 absl::string_view rhs) const {
    return compare_internal::compare_result_as_ordering(lhs.compare(rhs));
  }
  StringBtreeDefaultLess(std::less<absl::Cord>) {}  // NOLINT
  absl::weak_ordering operator()(const absl::Cord &lhs,
                                 const absl::Cord &rhs) const {
    return compare_internal::compare_result_as_ordering(lhs.Compare(rhs));
  }
  absl::weak_ordering operator()(const absl::Cord &lhs,
                                 absl::string_view rhs) const {
    return compare_internal::compare_result_as_ordering(lhs.Compare(rhs));
  }
  absl::weak_ordering operator()(absl::string_view lhs,
                                 const absl::Cord &rhs) const {
    return compare_internal::compare_result_as_ordering(-rhs.Compare(lhs));
  }
};

struct StringBtreeDefaultGreater {
  using is_transparent = void;

  StringBtreeDefaultGreater() = default;

  StringBtreeDefaultGreater(std::greater<std::string>) {}        // NOLINT
  StringBtreeDefaultGreater(std::greater<absl::string_view>) {}  // NOLINT

  // Allow converting to std::greater for use in key_comp()/value_comp().
  explicit operator std::greater<std::string>() const { return {}; }
  explicit operator std::greater<absl::string_view>() const { return {}; }
  explicit operator std::greater<absl::Cord>() const { return {}; }

  absl::weak_ordering operator()(absl::string_view lhs,
                                 absl::string_view rhs) const {
    return compare_internal::compare_result_as_ordering(rhs.compare(lhs));
  }
  StringBtreeDefaultGreater(std::greater<absl::Cord>) {}  // NOLINT
  absl::weak_ordering operator()(const absl::Cord &lhs,
                                 const absl::Cord &rhs) const {
    return compare_internal::compare_result_as_ordering(rhs.Compare(lhs));
  }
  absl::weak_ordering operator()(const absl::Cord &lhs,
                                 absl::string_view rhs) const {
    return compare_internal::compare_result_as_ordering(-lhs.Compare(rhs));
  }
  absl::weak_ordering operator()(absl::string_view lhs,
                                 const absl::Cord &rhs) const {
    return compare_internal::compare_result_as_ordering(rhs.Compare(lhs));
  }
};

// See below comments for checked_compare.
template <typename Compare, bool is_class = std::is_class<Compare>::value>
struct checked_compare_base : Compare {
  using Compare::Compare;
  explicit checked_compare_base(Compare c) : Compare(std::move(c)) {}
  const Compare &comp() const { return *this; }
};
template <typename Compare>
struct checked_compare_base<Compare, false> {
  explicit checked_compare_base(Compare c) : compare(std::move(c)) {}
  const Compare &comp() const { return compare; }
  Compare compare;
};

// A mechanism for opting out of checked_compare for use only in btree_test.cc.
struct BtreeTestOnlyCheckedCompareOptOutBase {};

// A helper class to adapt the specified comparator for two use cases:
// (1) When using common Abseil string types with common comparison functors,
// convert a boolean comparison into a three-way comparison that returns an
// `absl::weak_ordering`. This helper class is specialized for
// less<std::string>, greater<std::string>, less<string_view>,
// greater<string_view>, less<absl::Cord>, and greater<absl::Cord>.
// (2) Adapt the comparator to diagnose cases of non-strict-weak-ordering (see
// https://en.cppreference.com/w/cpp/named_req/Compare) in debug mode. Whenever
// a comparison is made, we will make assertions to verify that the comparator
// is valid.
template <typename Compare, typename Key>
struct key_compare_adapter {
  // Inherit from checked_compare_base to support function pointers and also
  // keep empty-base-optimization (EBO) support for classes.
  // Note: we can't use CompressedTuple here because that would interfere
  // with the EBO for `btree::rightmost_`. `btree::rightmost_` is itself a
  // CompressedTuple and nested `CompressedTuple`s don't support EBO.
  // TODO(b/214288561): use CompressedTuple instead once it supports EBO for
  // nested `CompressedTuple`s.
  struct checked_compare : checked_compare_base<Compare> {
   private:
    using Base = typename checked_compare::checked_compare_base;
    using Base::comp;

    // If possible, returns whether `t` is equivalent to itself. We can only do
    // this for `Key`s because we can't be sure that it's safe to call
    // `comp()(k, k)` otherwise. Even if SFINAE allows it, there could be a
    // compilation failure inside the implementation of the comparison operator.
    bool is_self_equivalent(const Key &k) const {
      // Note: this works for both boolean and three-way comparators.
      return comp()(k, k) == 0;
    }
    // If we can't compare `t` with itself, returns true unconditionally.
    template <typename T>
    bool is_self_equivalent(const T &) const {
      return true;
    }

   public:
    using Base::Base;
    checked_compare(Compare cmp) : Base(std::move(cmp)) {}  // NOLINT

    // Allow converting to Compare for use in key_comp()/value_comp().
    explicit operator Compare() const { return comp(); }

    template <typename T, typename U,
              absl::enable_if_t<
                  std::is_same<bool, compare_result_t<Compare, T, U>>::value,
                  int> = 0>
    bool operator()(const T &lhs, const U &rhs) const {
      // NOTE: if any of these assertions fail, then the comparator does not
      // establish a strict-weak-ordering (see
      // https://en.cppreference.com/w/cpp/named_req/Compare).
      assert(is_self_equivalent(lhs));
      assert(is_self_equivalent(rhs));
      const bool lhs_comp_rhs = comp()(lhs, rhs);
      assert(!lhs_comp_rhs || !comp()(rhs, lhs));
      return lhs_comp_rhs;
    }

    template <
        typename T, typename U,
        absl::enable_if_t<std::is_convertible<compare_result_t<Compare, T, U>,
                                              absl::weak_ordering>::value,
                          int> = 0>
    absl::weak_ordering operator()(const T &lhs, const U &rhs) const {
      // NOTE: if any of these assertions fail, then the comparator does not
      // establish a strict-weak-ordering (see
      // https://en.cppreference.com/w/cpp/named_req/Compare).
      assert(is_self_equivalent(lhs));
      assert(is_self_equivalent(rhs));
      const absl::weak_ordering lhs_comp_rhs = comp()(lhs, rhs);
#ifndef NDEBUG
      const absl::weak_ordering rhs_comp_lhs = comp()(rhs, lhs);
      if (lhs_comp_rhs > 0) {
        assert(rhs_comp_lhs < 0 && "lhs_comp_rhs > 0 -> rhs_comp_lhs < 0");
      } else if (lhs_comp_rhs == 0) {
        assert(rhs_comp_lhs == 0 && "lhs_comp_rhs == 0 -> rhs_comp_lhs == 0");
      } else {
        assert(rhs_comp_lhs > 0 && "lhs_comp_rhs < 0 -> rhs_comp_lhs > 0");
      }
#endif
      return lhs_comp_rhs;
    }
  };
  using type = absl::conditional_t<
      std::is_base_of<BtreeTestOnlyCheckedCompareOptOutBase, Compare>::value,
      Compare, checked_compare>;
};

template <>
struct key_compare_adapter<std::less<std::string>, std::string> {
  using type = StringBtreeDefaultLess;
};

template <>
struct key_compare_adapter<std::greater<std::string>, std::string> {
  using type = StringBtreeDefaultGreater;
};

template <>
struct key_compare_adapter<std::less<absl::string_view>, absl::string_view> {
  using type = StringBtreeDefaultLess;
};

template <>
struct key_compare_adapter<std::greater<absl::string_view>, absl::string_view> {
  using type = StringBtreeDefaultGreater;
};

template <>
struct key_compare_adapter<std::less<absl::Cord>, absl::Cord> {
  using type = StringBtreeDefaultLess;
};

template <>
struct key_compare_adapter<std::greater<absl::Cord>, absl::Cord> {
  using type = StringBtreeDefaultGreater;
};

// Detects an 'absl_btree_prefer_linear_node_search' member. This is
// a protocol used as an opt-in or opt-out of linear search.
//
//  For example, this would be useful for key types that wrap an integer
//  and define their own cheap operator<(). For example:
//
//   class K {
//    public:
//     using absl_btree_prefer_linear_node_search = std::true_type;
//     ...
//    private:
//     friend bool operator<(K a, K b) { return a.k_ < b.k_; }
//     int k_;
//   };
//
//   btree_map<K, V> m;  // Uses linear search
//
// If T has the preference tag, then it has a preference.
// Btree will use the tag's truth value.
template <typename T, typename = void>
struct has_linear_node_search_preference : std::false_type {};
template <typename T, typename = void>
struct prefers_linear_node_search : std::false_type {};
template <typename T>
struct has_linear_node_search_preference<
    T, absl::void_t<typename T::absl_btree_prefer_linear_node_search>>
    : std::true_type {};
template <typename T>
struct prefers_linear_node_search<
    T, absl::void_t<typename T::absl_btree_prefer_linear_node_search>>
    : T::absl_btree_prefer_linear_node_search {};

template <typename Compare, typename Key>
constexpr bool compare_has_valid_result_type() {
  using compare_result_type = compare_result_t<Compare, Key, Key>;
  return std::is_same<compare_result_type, bool>::value ||
         std::is_convertible<compare_result_type, absl::weak_ordering>::value;
}

template <typename original_key_compare, typename value_type>
class map_value_compare {
  template <typename Params>
  friend class btree;

  // Note: this `protected` is part of the API of std::map::value_compare. See
  // https://en.cppreference.com/w/cpp/container/map/value_compare.
 protected:
  explicit map_value_compare(original_key_compare c) : comp(std::move(c)) {}

  original_key_compare comp;  // NOLINT

 public:
  auto operator()(const value_type &lhs, const value_type &rhs) const
      -> decltype(comp(lhs.first, rhs.first)) {
    return comp(lhs.first, rhs.first);
  }
};

template <typename Key, typename Compare, typename Alloc, int TargetNodeSize,
          bool IsMulti, bool IsMap, typename SlotPolicy>
struct common_params : common_policy_traits<SlotPolicy> {
  using original_key_compare = Compare;

  // If Compare is a common comparator for a string-like type, then we adapt it
  // to use heterogeneous lookup and to be a key-compare-to comparator.
  // We also adapt the comparator to diagnose invalid comparators in debug mode.
  // We disable this when `Compare` is invalid in a way that will cause
  // adaptation to fail (having invalid return type) so that we can give a
  // better compilation failure in static_assert_validation. If we don't do
  // this, then there will be cascading compilation failures that are confusing
  // for users.
  using key_compare =
      absl::conditional_t<!compare_has_valid_result_type<Compare, Key>(),
                          Compare,
                          typename key_compare_adapter<Compare, Key>::type>;

  static constexpr bool kIsKeyCompareStringAdapted =
      std::is_same<key_compare, StringBtreeDefaultLess>::value ||
      std::is_same<key_compare, StringBtreeDefaultGreater>::value;
  static constexpr bool kIsKeyCompareTransparent =
      IsTransparent<original_key_compare>::value || kIsKeyCompareStringAdapted;

  // A type which indicates if we have a key-compare-to functor or a plain old
  // key-compare functor.
  using is_key_compare_to = btree_is_key_compare_to<key_compare, Key>;

  using allocator_type = Alloc;
  using key_type = Key;
  using size_type = size_t;
  using difference_type = ptrdiff_t;

  using slot_policy = SlotPolicy;
  using slot_type = typename slot_policy::slot_type;
  using value_type = typename slot_policy::value_type;
  using init_type = typename slot_policy::mutable_value_type;
  using pointer = value_type *;
  using const_pointer = const value_type *;
  using reference = value_type &;
  using const_reference = const value_type &;

  using value_compare =
      absl::conditional_t<IsMap,
                          map_value_compare<original_key_compare, value_type>,
                          original_key_compare>;
  using is_map_container = std::integral_constant<bool, IsMap>;

  // For the given lookup key type, returns whether we can have multiple
  // equivalent keys in the btree. If this is a multi-container, then we can.
  // Otherwise, we can have multiple equivalent keys only if all of the
  // following conditions are met:
  // - The comparator is transparent.
  // - The lookup key type is not the same as key_type.
  // - The comparator is not a StringBtreeDefault{Less,Greater} comparator
  //   that we know has the same equivalence classes for all lookup types.
  template <typename LookupKey>
  constexpr static bool can_have_multiple_equivalent_keys() {
    return IsMulti || (IsTransparent<key_compare>::value &&
                       !std::is_same<LookupKey, Key>::value &&
                       !kIsKeyCompareStringAdapted);
  }

  enum {
    kTargetNodeSize = TargetNodeSize,

    // Upper bound for the available space for slots. This is largest for leaf
    // nodes, which have overhead of at least a pointer + 4 bytes (for storing
    // 3 field_types and an enum).
    kNodeSlotSpace = TargetNodeSize - /*minimum overhead=*/(sizeof(void *) + 4),
  };

  // This is an integral type large enough to hold as many slots as will fit a
  // node of TargetNodeSize bytes.
  using node_count_type =
      absl::conditional_t<(kNodeSlotSpace / sizeof(slot_type) >
                           (std::numeric_limits<uint8_t>::max)()),
                          uint16_t, uint8_t>;  // NOLINT
};

// An adapter class that converts a lower-bound compare into an upper-bound
// compare. Note: there is no need to make a version of this adapter specialized
// for key-compare-to functors because the upper-bound (the first value greater
// than the input) is never an exact match.
template <typename Compare>
struct upper_bound_adapter {
  explicit upper_bound_adapter(const Compare &c) : comp(c) {}
  template <typename K1, typename K2>
  bool operator()(const K1 &a, const K2 &b) const {
    // Returns true when a is not greater than b.
    return !compare_internal::compare_result_as_less_than(comp(b, a));
  }

 private:
  Compare comp;
};

enum class MatchKind : uint8_t { kEq, kNe };

template <typename V, bool IsCompareTo>
struct SearchResult {
  V value;
  MatchKind match;

  static constexpr bool HasMatch() { return true; }
  bool IsEq() const { return match == MatchKind::kEq; }
};

// When we don't use CompareTo, `match` is not present.
// This ensures that callers can't use it accidentally when it provides no
// useful information.
template <typename V>
struct SearchResult<V, false> {
  SearchResult() = default;
  explicit SearchResult(V v) : value(v) {}
  SearchResult(V v, MatchKind /*match*/) : value(v) {}

  V value;

  static constexpr bool HasMatch() { return false; }
  static constexpr bool IsEq() { return false; }
};

// A node in the btree holding. The same node type is used for both internal
// and leaf nodes in the btree, though the nodes are allocated in such a way
// that the children array is only valid in internal nodes.
template <typename Params>
class btree_node {
  using is_key_compare_to = typename Params::is_key_compare_to;
  using field_type = typename Params::node_count_type;
  using allocator_type = typename Params::allocator_type;
  using slot_type = typename Params::slot_type;
  using original_key_compare = typename Params::original_key_compare;

 public:
  using params_type = Params;
  using key_type = typename Params::key_type;
  using value_type = typename Params::value_type;
  using pointer = typename Params::pointer;
  using const_pointer = typename Params::const_pointer;
  using reference = typename Params::reference;
  using const_reference = typename Params::const_reference;
  using key_compare = typename Params::key_compare;
  using size_type = typename Params::size_type;
  using difference_type = typename Params::difference_type;

  // Btree decides whether to use linear node search as follows:
  //   - If the comparator expresses a preference, use that.
  //   - If the key expresses a preference, use that.
  //   - If the key is arithmetic and the comparator is std::less or
  //     std::greater, choose linear.
  //   - Otherwise, choose binary.
  // TODO(ezb): Might make sense to add condition(s) based on node-size.
  using use_linear_search = std::integral_constant<
      bool, has_linear_node_search_preference<original_key_compare>::value
                ? prefers_linear_node_search<original_key_compare>::value
            : has_linear_node_search_preference<key_type>::value
                ? prefers_linear_node_search<key_type>::value
                : std::is_arithmetic<key_type>::value &&
                      (std::is_same<std::less<key_type>,
                                    original_key_compare>::value ||
                       std::is_same<std::greater<key_type>,
                                    original_key_compare>::value)>;

  // This class is organized by absl::container_internal::Layout as if it had
  // the following structure:
  //   // A pointer to the node's parent.
  //   btree_node *parent;
  //
  //   // When ABSL_BTREE_ENABLE_GENERATIONS is defined, we also have a
  //   // generation integer in order to check that when iterators are
  //   // used, they haven't been invalidated already. Only the generation on
  //   // the root is used, but we have one on each node because whether a node
  //   // is root or not can change.
  //   uint32_t generation;
  //
  //   // The position of the node in the node's parent.
  //   field_type position;
  //   // The index of the first populated value in `values`.
  //   // TODO(ezb): right now, `start` is always 0. Update insertion/merge
  //   // logic to allow for floating storage within nodes.
  //   field_type start;
  //   // The index after the last populated value in `values`. Currently, this
  //   // is the same as the count of values.
  //   field_type finish;
  //   // The maximum number of values the node can hold. This is an integer in
  //   // [1, kNodeSlots] for root leaf nodes, kNodeSlots for non-root leaf
  //   // nodes, and kInternalNodeMaxCount (as a sentinel value) for internal
  //   // nodes (even though there are still kNodeSlots values in the node).
  //   // TODO(ezb): make max_count use only 4 bits and record log2(capacity)
  //   // to free extra bits for is_root, etc.
  //   field_type max_count;
  //
  //   // The array of values. The capacity is `max_count` for leaf nodes and
  //   // kNodeSlots for internal nodes. Only the values in
  //   // [start, finish) have been initialized and are valid.
  //   slot_type values[max_count];
  //
  //   // The array of child pointers. The keys in children[i] are all less
  //   // than key(i). The keys in children[i + 1] are all greater than key(i).
  //   // There are 0 children for leaf nodes and kNodeSlots + 1 children for
  //   // internal nodes.
  //   btree_node *children[kNodeSlots + 1];
  //
  // This class is only constructed by EmptyNodeType. Normally, pointers to the
  // layout above are allocated, cast to btree_node*, and de-allocated within
  // the btree implementation.
  ~btree_node() = default;
  btree_node(btree_node const &) = delete;
  btree_node &operator=(btree_node const &) = delete;

 protected:
  btree_node() = default;

 private:
  using layout_type =
      absl::container_internal::Layout<btree_node *, uint32_t, field_type,
                                       slot_type, btree_node *>;
  using leaf_layout_type = typename layout_type::template WithStaticSizes<
      /*parent*/ 1,
      /*generation*/ BtreeGenerationsEnabled() ? 1 : 0,
      /*position, start, finish, max_count*/ 4>;
  constexpr static size_type SizeWithNSlots(size_type n) {
    return leaf_layout_type(/*slots*/ n, /*children*/ 0).AllocSize();
  }
  // A lower bound for the overhead of fields other than slots in a leaf node.
  constexpr static size_type MinimumOverhead() {
    return SizeWithNSlots(1) - sizeof(slot_type);
  }

  // Compute how many values we can fit onto a leaf node taking into account
  // padding.
  constexpr static size_type NodeTargetSlots(const size_type begin,
                                             const size_type end) {
    return begin == end ? begin
           : SizeWithNSlots((begin + end) / 2 + 1) >
                   params_type::kTargetNodeSize
               ? NodeTargetSlots(begin, (begin + end) / 2)
               : NodeTargetSlots((begin + end) / 2 + 1, end);
  }

  constexpr static size_type kTargetNodeSize = params_type::kTargetNodeSize;
  constexpr static size_type kNodeTargetSlots =
      NodeTargetSlots(0, kTargetNodeSize);

  // We need a minimum of 3 slots per internal node in order to perform
  // splitting (1 value for the two nodes involved in the split and 1 value
  // propagated to the parent as the delimiter for the split). For performance
  // reasons, we don't allow 3 slots-per-node due to bad worst case occupancy of
  // 1/3 (for a node, not a b-tree).
  constexpr static size_type kMinNodeSlots = 4;

  constexpr static size_type kNodeSlots =
      kNodeTargetSlots >= kMinNodeSlots ? kNodeTargetSlots : kMinNodeSlots;

  using internal_layout_type = typename layout_type::template WithStaticSizes<
      /*parent*/ 1,
      /*generation*/ BtreeGenerationsEnabled() ? 1 : 0,
      /*position, start, finish, max_count*/ 4, /*slots*/ kNodeSlots,
      /*children*/ kNodeSlots + 1>;

  // The node is internal (i.e. is not a leaf node) if and only if `max_count`
  // has this value.
  constexpr static field_type kInternalNodeMaxCount = 0;

  // Leaves can have less than kNodeSlots values.
  constexpr static leaf_layout_type LeafLayout(
      const size_type slot_count = kNodeSlots) {
    return leaf_layout_type(slot_count, 0);
  }
  constexpr static auto InternalLayout() { return internal_layout_type(); }
  constexpr static size_type LeafSize(const size_type slot_count = kNodeSlots) {
    return LeafLayout(slot_count).AllocSize();
  }
  constexpr static size_type InternalSize() {
    return InternalLayout().AllocSize();
  }

  constexpr static size_type Alignment() {
    static_assert(LeafLayout(1).Alignment() == InternalLayout().Alignment(),
                  "Alignment of all nodes must be equal.");
    return InternalLayout().Alignment();
  }

  // N is the index of the type in the Layout definition.
  // ElementType<N> is the Nth type in the Layout definition.
  template <size_type N>
  inline typename layout_type::template ElementType<N> *GetField() {
    // We assert that we don't read from values that aren't there.
    assert(N < 4 || is_internal());
    return InternalLayout().template Pointer<N>(reinterpret_cast<char *>(this));
  }
  template <size_type N>
  inline const typename layout_type::template ElementType<N> *GetField() const {
    assert(N < 4 || is_internal());
    return InternalLayout().template Pointer<N>(
        reinterpret_cast<const char *>(this));
  }
  void set_parent(btree_node *p) { *GetField<0>() = p; }
  field_type &mutable_finish() { return GetField<2>()[2]; }
  slot_type *slot(size_type i) { return &GetField<3>()[i]; }
  slot_type *start_slot() { return slot(start()); }
  slot_type *finish_slot() { return slot(finish()); }
  const slot_type *slot(size_type i) const { return &GetField<3>()[i]; }
  void set_position(field_type v) { GetField<2>()[0] = v; }
  void set_start(field_type v) { GetField<2>()[1] = v; }
  void set_finish(field_type v) { GetField<2>()[2] = v; }
  // This method is only called by the node init methods.
  void set_max_count(field_type v) { GetField<2>()[3] = v; }

 public:
  // Whether this is a leaf node or not. This value doesn't change after the
  // node is created.
  bool is_leaf() const { return GetField<2>()[3] != kInternalNodeMaxCount; }
  // Whether this is an internal node or not. This value doesn't change after
  // the node is created.
  bool is_internal() const { return !is_leaf(); }

  // Getter for the position of this node in its parent.
  field_type position() const { return GetField<2>()[0]; }

  // Getter for the offset of the first value in the `values` array.
  field_type start() const {
    // TODO(ezb): when floating storage is implemented, return GetField<2>()[1];
    assert(GetField<2>()[1] == 0);
    return 0;
  }

  // Getter for the offset after the last value in the `values` array.
  field_type finish() const { return GetField<2>()[2]; }

  // Getters for the number of values stored in this node.
  field_type count() const {
    assert(finish() >= start());
    return finish() - start();
  }
  field_type max_count() const {
    // Internal nodes have max_count==kInternalNodeMaxCount.
    // Leaf nodes have max_count in [1, kNodeSlots].
    const field_type max_count = GetField<2>()[3];
    return max_count == field_type{kInternalNodeMaxCount}
               ? field_type{kNodeSlots}
               : max_count;
  }

  // Getter for the parent of this node.
  // TODO(ezb): assert that the child of the returned node at position
  // `node_->position()` maps to the current node.
  btree_node *parent() const { return *GetField<0>(); }
  // Getter for whether the node is the root of the tree. The parent of the
  // root of the tree is the leftmost node in the tree which is guaranteed to
  // be a leaf.
  bool is_root() const { return parent()->is_leaf(); }
  void make_root() {
    assert(parent()->is_root());
    set_generation(parent()->generation());
    set_parent(parent()->parent());
  }

  // Gets the root node's generation integer, which is the one used by the tree.
  uint32_t *get_root_generation() const {
    assert(BtreeGenerationsEnabled());
    const btree_node *curr = this;
    for (; !curr->is_root(); curr = curr->parent()) continue;
    return const_cast<uint32_t *>(&curr->GetField<1>()[0]);
  }

  // Returns the generation for iterator validation.
  uint32_t generation() const {
    return BtreeGenerationsEnabled() ? *get_root_generation() : 0;
  }
  // Updates generation. Should only be called on a root node or during node
  // initialization.
  void set_generation(uint32_t generation) {
    if (BtreeGenerationsEnabled()) GetField<1>()[0] = generation;
  }
  // Updates the generation. We do this whenever the node is mutated.
  void next_generation() {
    if (BtreeGenerationsEnabled()) ++*get_root_generation();
  }

  // Getters for the key/value at position i in the node.
  const key_type &key(size_type i) const { return params_type::key(slot(i)); }
  reference value(size_type i) { return params_type::element(slot(i)); }
  const_reference value(size_type i) const {
    return params_type::element(slot(i));
  }

  // Getters/setter for the child at position i in the node.
  btree_node *child(field_type i) const { return GetField<4>()[i]; }
  btree_node *start_child() const { return child(start()); }
  btree_node *&mutable_child(field_type i) { return GetField<4>()[i]; }
  void clear_child(field_type i) {
    absl::container_internal::SanitizerPoisonObject(&mutable_child(i));
  }
  void set_child_noupdate_position(field_type i, btree_node *c) {
    absl::container_internal::SanitizerUnpoisonObject(&mutable_child(i));
    mutable_child(i) = c;
  }
  void set_child(field_type i, btree_node *c) {
    set_child_noupdate_position(i, c);
    c->set_position(i);
  }
  void init_child(field_type i, btree_node *c) {
    set_child(i, c);
    c->set_parent(this);
  }

  // Returns the position of the first value whose key is not less than k.
  template <typename K>
  SearchResult<size_type, is_key_compare_to::value> lower_bound(
      const K &k, const key_compare &comp) const {
    return use_linear_search::value ? linear_search(k, comp)
                                    : binary_search(k, comp);
  }
  // Returns the position of the first value whose key is greater than k.
  template <typename K>
  size_type upper_bound(const K &k, const key_compare &comp) const {
    auto upper_compare = upper_bound_adapter<key_compare>(comp);
    return use_linear_search::value ? linear_search(k, upper_compare).value
                                    : binary_search(k, upper_compare).value;
  }

  template <typename K, typename Compare>
  SearchResult<size_type, btree_is_key_compare_to<Compare, key_type>::value>
  linear_search(const K &k, const Compare &comp) const {
    return linear_search_impl(k, start(), finish(), comp,
                              btree_is_key_compare_to<Compare, key_type>());
  }

  template <typename K, typename Compare>
  SearchResult<size_type, btree_is_key_compare_to<Compare, key_type>::value>
  binary_search(const K &k, const Compare &comp) const {
    return binary_search_impl(k, start(), finish(), comp,
                              btree_is_key_compare_to<Compare, key_type>());
  }

  // Returns the position of the first value whose key is not less than k using
  // linear search performed using plain compare.
  template <typename K, typename Compare>
  SearchResult<size_type, false> linear_search_impl(
      const K &k, size_type s, const size_type e, const Compare &comp,
      std::false_type /* IsCompareTo */) const {
    while (s < e) {
      if (!comp(key(s), k)) {
        break;
      }
      ++s;
    }
    return SearchResult<size_type, false>{s};
  }

  // Returns the position of the first value whose key is not less than k using
  // linear search performed using compare-to.
  template <typename K, typename Compare>
  SearchResult<size_type, true> linear_search_impl(
      const K &k, size_type s, const size_type e, const Compare &comp,
      std::true_type /* IsCompareTo */) const {
    while (s < e) {
      const absl::weak_ordering c = comp(key(s), k);
      if (c == 0) {
        return {s, MatchKind::kEq};
      } else if (c > 0) {
        break;
      }
      ++s;
    }
    return {s, MatchKind::kNe};
  }

  // Returns the position of the first value whose key is not less than k using
  // binary search performed using plain compare.
  template <typename K, typename Compare>
  SearchResult<size_type, false> binary_search_impl(
      const K &k, size_type s, size_type e, const Compare &comp,
      std::false_type /* IsCompareTo */) const {
    while (s != e) {
      const size_type mid = (s + e) >> 1;
      if (comp(key(mid), k)) {
        s = mid + 1;
      } else {
        e = mid;
      }
    }
    return SearchResult<size_type, false>{s};
  }

  // Returns the position of the first value whose key is not less than k using
  // binary search performed using compare-to.
  template <typename K, typename CompareTo>
  SearchResult<size_type, true> binary_search_impl(
      const K &k, size_type s, size_type e, const CompareTo &comp,
      std::true_type /* IsCompareTo */) const {
    if (params_type::template can_have_multiple_equivalent_keys<K>()) {
      MatchKind exact_match = MatchKind::kNe;
      while (s != e) {
        const size_type mid = (s + e) >> 1;
        const absl::weak_ordering c = comp(key(mid), k);
        if (c < 0) {
          s = mid + 1;
        } else {
          e = mid;
          if (c == 0) {
            // Need to return the first value whose key is not less than k,
            // which requires continuing the binary search if there could be
            // multiple equivalent keys.
            exact_match = MatchKind::kEq;
          }
        }
      }
      return {s, exact_match};
    } else {  // Can't have multiple equivalent keys.
      while (s != e) {
        const size_type mid = (s + e) >> 1;
        const absl::weak_ordering c = comp(key(mid), k);
        if (c < 0) {
          s = mid + 1;
        } else if (c > 0) {
          e = mid;
        } else {
          return {mid, MatchKind::kEq};
        }
      }
      return {s, MatchKind::kNe};
    }
  }

  // Returns whether key i is ordered correctly with respect to the other keys
  // in the node. The motivation here is to detect comparators that violate
  // transitivity. Note: we only do comparisons of keys on this node rather than
  // the whole tree so that this is constant time.
  template <typename Compare>
  bool is_ordered_correctly(field_type i, const Compare &comp) const {
    if (std::is_base_of<BtreeTestOnlyCheckedCompareOptOutBase,
                        Compare>::value ||
        params_type::kIsKeyCompareStringAdapted) {
      return true;
    }

    const auto compare = [&](field_type a, field_type b) {
      const absl::weak_ordering cmp =
          compare_internal::do_three_way_comparison(comp, key(a), key(b));
      return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
    };
    int cmp = -1;
    constexpr bool kCanHaveEquivKeys =
        params_type::template can_have_multiple_equivalent_keys<key_type>();
    for (field_type j = start(); j < finish(); ++j) {
      if (j == i) {
        if (cmp > 0) return false;
        continue;
      }
      int new_cmp = compare(j, i);
      if (new_cmp < cmp || (!kCanHaveEquivKeys && new_cmp == 0)) return false;
      cmp = new_cmp;
    }
    return true;
  }

  // Emplaces a value at position i, shifting all existing values and
  // children at positions >= i to the right by 1.
  template <typename... Args>
  void emplace_value(field_type i, allocator_type *alloc, Args &&...args);

  // Removes the values at positions [i, i + to_erase), shifting all existing
  // values and children after that range to the left by to_erase. Clears all
  // children between [i, i + to_erase).
  void remove_values(field_type i, field_type to_erase, allocator_type *alloc);

  // Rebalances a node with its right sibling.
  void rebalance_right_to_left(field_type to_move, btree_node *right,
                               allocator_type *alloc);
  void rebalance_left_to_right(field_type to_move, btree_node *right,
                               allocator_type *alloc);

  // Splits a node, moving a portion of the node's values to its right sibling.
  void split(int insert_position, btree_node *dest, allocator_type *alloc);

  // Merges a node with its right sibling, moving all of the values and the
  // delimiting key in the parent node onto itself, and deleting the src node.
  void merge(btree_node *src, allocator_type *alloc);

  // Node allocation/deletion routines.
  void init_leaf(field_type position, field_type max_count,
                 btree_node *parent) {
    set_generation(0);
    set_parent(parent);
    set_position(position);
    set_start(0);
    set_finish(0);
    set_max_count(max_count);
    absl::container_internal::SanitizerPoisonMemoryRegion(
        start_slot(), max_count * sizeof(slot_type));
  }
  void init_internal(field_type position, btree_node *parent) {
    init_leaf(position, kNodeSlots, parent);
    // Set `max_count` to a sentinel value to indicate that this node is
    // internal.
    set_max_count(kInternalNodeMaxCount);
    absl::container_internal::SanitizerPoisonMemoryRegion(
        &mutable_child(start()), (kNodeSlots + 1) * sizeof(btree_node *));
  }

  static void deallocate(const size_type size, btree_node *node,
                         allocator_type *alloc) {
    absl::container_internal::SanitizerUnpoisonMemoryRegion(node, size);
    absl::container_internal::Deallocate<Alignment()>(alloc, node, size);
  }

  // Deletes a node and all of its children.
  static void clear_and_delete(btree_node *node, allocator_type *alloc);

 private:
  template <typename... Args>
  void value_init(const field_type i, allocator_type *alloc, Args &&...args) {
    next_generation();
    absl::container_internal::SanitizerUnpoisonObject(slot(i));
    params_type::construct(alloc, slot(i), std::forward<Args>(args)...);
  }
  void value_destroy(const field_type i, allocator_type *alloc) {
    next_generation();
    params_type::destroy(alloc, slot(i));
    absl::container_internal::SanitizerPoisonObject(slot(i));
  }
  void value_destroy_n(const field_type i, const field_type n,
                       allocator_type *alloc) {
    next_generation();
    for (slot_type *s = slot(i), *end = slot(i + n); s != end; ++s) {
      params_type::destroy(alloc, s);
      absl::container_internal::SanitizerPoisonObject(s);
    }
  }

  static void transfer(slot_type *dest, slot_type *src, allocator_type *alloc) {
    absl::container_internal::SanitizerUnpoisonObject(dest);
    params_type::transfer(alloc, dest, src);
    absl::container_internal::SanitizerPoisonObject(src);
  }

  // Transfers value from slot `src_i` in `src_node` to slot `dest_i` in `this`.
  void transfer(const size_type dest_i, const size_type src_i,
                btree_node *src_node, allocator_type *alloc) {
    next_generation();
    transfer(slot(dest_i), src_node->slot(src_i), alloc);
  }

  // Transfers `n` values starting at value `src_i` in `src_node` into the
  // values starting at value `dest_i` in `this`.
  void transfer_n(const size_type n, const size_type dest_i,
                  const size_type src_i, btree_node *src_node,
                  allocator_type *alloc) {
    next_generation();
    for (slot_type *src = src_node->slot(src_i), *end = src + n,
                   *dest = slot(dest_i);
         src != end; ++src, ++dest) {
      transfer(dest, src, alloc);
    }
  }

  // Same as above, except that we start at the end and work our way to the
  // beginning.
  void transfer_n_backward(const size_type n, const size_type dest_i,
                           const size_type src_i, btree_node *src_node,
                           allocator_type *alloc) {
    next_generation();
    for (slot_type *src = src_node->slot(src_i + n), *end = src - n,
                   *dest = slot(dest_i + n);
         src != end; --src, --dest) {
      // If we modified the loop index calculations above to avoid the -1s here,
      // it would result in UB in the computation of `end` (and possibly `src`
      // as well, if n == 0), since slot() is effectively an array index and it
      // is UB to compute the address of any out-of-bounds array element except
      // for one-past-the-end.
      transfer(dest - 1, src - 1, alloc);
    }
  }

  template <typename P>
  friend class btree;
  template <typename N, typename R, typename P>
  friend class btree_iterator;
  friend class BtreeNodePeer;
  friend struct btree_access;
};

template <typename Node>
bool AreNodesFromSameContainer(const Node *node_a, const Node *node_b) {
  // If either node is null, then give up on checking whether they're from the
  // same container. (If exactly one is null, then we'll trigger the
  // default-constructed assert in Equals.)
  if (node_a == nullptr || node_b == nullptr) return true;
  while (!node_a->is_root()) node_a = node_a->parent();
  while (!node_b->is_root()) node_b = node_b->parent();
  return node_a == node_b;
}

class btree_iterator_generation_info_enabled {
 public:
  explicit btree_iterator_generation_info_enabled(uint32_t g)
      : generation_(g) {}

  // Updates the generation. For use internally right before we return an
  // iterator to the user.
  template <typename Node>
  void update_generation(const Node *node) {
    if (node != nullptr) generation_ = node->generation();
  }
  uint32_t generation() const { return generation_; }

  template <typename Node>
  void assert_valid_generation(const Node *node) const {
    if (node != nullptr && node->generation() != generation_) {
      ABSL_INTERNAL_LOG(
          FATAL,
          "Attempting to use an invalidated iterator. The corresponding b-tree "
          "container has been mutated since this iterator was constructed.");
    }
  }

 private:
  // Used to check that the iterator hasn't been invalidated.
  uint32_t generation_;
};

class btree_iterator_generation_info_disabled {
 public:
  explicit btree_iterator_generation_info_disabled(uint32_t) {}
  static void update_generation(const void *) {}
  static uint32_t generation() { return 0; }
  static void assert_valid_generation(const void *) {}
};

#ifdef ABSL_BTREE_ENABLE_GENERATIONS
using btree_iterator_generation_info = btree_iterator_generation_info_enabled;
#else
using btree_iterator_generation_info = btree_iterator_generation_info_disabled;
#endif

template <typename Node, typename Reference, typename Pointer>
class btree_iterator : private btree_iterator_generation_info {
  using field_type = typename Node::field_type;
  using key_type = typename Node::key_type;
  using size_type = typename Node::size_type;
  using params_type = typename Node::params_type;
  using is_map_container = typename params_type::is_map_container;

  using node_type = Node;
  using normal_node = typename std::remove_const<Node>::type;
  using const_node = const Node;
  using normal_pointer = typename params_type::pointer;
  using normal_reference = typename params_type::reference;
  using const_pointer = typename params_type::const_pointer;
  using const_reference = typename params_type::const_reference;
  using slot_type = typename params_type::slot_type;

  // In sets, all iterators are const.
  using iterator = absl::conditional_t<
      is_map_container::value,
      btree_iterator<normal_node, normal_reference, normal_pointer>,
      btree_iterator<normal_node, const_reference, const_pointer>>;
  using const_iterator =
      btree_iterator<const_node, const_reference, const_pointer>;

 public:
  // These aliases are public for std::iterator_traits.
  using difference_type = typename Node::difference_type;
  using value_type = typename params_type::value_type;
  using pointer = Pointer;
  using reference = Reference;
  using iterator_category = std::bidirectional_iterator_tag;

  btree_iterator() : btree_iterator(nullptr, -1) {}
  explicit btree_iterator(Node *n) : btree_iterator(n, n->start()) {}
  btree_iterator(Node *n, int p)
      : btree_iterator_generation_info(n != nullptr ? n->generation()
                                                    : ~uint32_t{}),
        node_(n),
        position_(p) {}

  // NOTE: this SFINAE allows for implicit conversions from iterator to
  // const_iterator, but it specifically avoids hiding the copy constructor so
  // that the trivial one will be used when possible.
  template <typename N, typename R, typename P,
            absl::enable_if_t<
                std::is_same<btree_iterator<N, R, P>, iterator>::value &&
                    std::is_same<btree_iterator, const_iterator>::value,
                int> = 0>
  btree_iterator(const btree_iterator<N, R, P> other)  // NOLINT
      : btree_iterator_generation_info(other),
        node_(other.node_),
        position_(other.position_) {}

  bool operator==(const iterator &other) const {
    return Equals(other);
  }
  bool operator==(const const_iterator &other) const {
    return Equals(other);
  }
  bool operator!=(const iterator &other) const {
    return !Equals(other);
  }
  bool operator!=(const const_iterator &other) const {
    return !Equals(other);
  }

  // Returns n such that n calls to ++other yields *this.
  // Precondition: n exists.
  difference_type operator-(const_iterator other) const {
    if (node_ == other.node_) {
      if (node_->is_leaf()) return position_ - other.position_;
      if (position_ == other.position_) return 0;
    }
    return distance_slow(other);
  }

  // Advances the iterator by `n`. Values of `n` must not result in going past
  // the `end` iterator (for a positive `n`) or before the `begin` iterator (for
  // a negative `n`).
  btree_iterator &operator+=(difference_type n) {
    assert_valid_generation(node_);
    if (n == 0) return *this;
    if (n < 0) return decrement_n_slow(-n);
    return increment_n_slow(n);
  }

  // Moves the iterator by `n` positions backwards. Values of `n` must not
  // result in going before the `begin` iterator (for a positive `n`) or past
  // the `end` iterator (for a negative `n`).
  btree_iterator &operator-=(difference_type n) {
    assert_valid_generation(node_);
    if (n == 0) return *this;
    if (n < 0) return increment_n_slow(-n);
    return decrement_n_slow(n);
  }

  // Accessors for the key/value the iterator is pointing at.
  reference operator*() const {
    ABSL_HARDENING_ASSERT(node_ != nullptr);
    assert_valid_generation(node_);
    ABSL_HARDENING_ASSERT(position_ >= node_->start());
    if (position_ >= node_->finish()) {
      ABSL_HARDENING_ASSERT(!IsEndIterator() && "Dereferencing end() iterator");
      ABSL_HARDENING_ASSERT(position_ < node_->finish());
    }
    return node_->value(static_cast<field_type>(position_));
  }
  pointer operator->() const { return &operator*(); }

  btree_iterator &operator++() {
    increment();
    return *this;
  }
  btree_iterator &operator--() {
    decrement();
    return *this;
  }
  btree_iterator operator++(int) {
    btree_iterator tmp = *this;
    ++*this;
    return tmp;
  }
  btree_iterator operator--(int) {
    btree_iterator tmp = *this;
    --*this;
    return tmp;
  }

 private:
  friend iterator;
  friend const_iterator;
  template <typename Params>
  friend class btree;
  template <typename Tree>
  friend class btree_container;
  template <typename Tree>
  friend class btree_set_container;
  template <typename Tree>
  friend class btree_map_container;
  template <typename Tree>
  friend class btree_multiset_container;
  template <typename TreeType, typename CheckerType>
  friend class base_checker;
  friend struct btree_access;

  // This SFINAE allows explicit conversions from const_iterator to
  // iterator, but also avoids hiding the copy constructor.
  // NOTE: the const_cast is safe because this constructor is only called by
  // non-const methods and the container owns the nodes.
  template <typename N, typename R, typename P,
            absl::enable_if_t<
                std::is_same<btree_iterator<N, R, P>, const_iterator>::value &&
                    std::is_same<btree_iterator, iterator>::value,
                int> = 0>
  explicit btree_iterator(const btree_iterator<N, R, P> other)
      : btree_iterator_generation_info(other.generation()),
        node_(const_cast<node_type *>(other.node_)),
        position_(other.position_) {}

  bool Equals(const const_iterator other) const {
    ABSL_HARDENING_ASSERT(((node_ == nullptr && other.node_ == nullptr) ||
                           (node_ != nullptr && other.node_ != nullptr)) &&
                          "Comparing default-constructed iterator with "
                          "non-default-constructed iterator.");
    // Note: we use assert instead of ABSL_HARDENING_ASSERT here because this
    // changes the complexity of Equals from O(1) to O(log(N) + log(M)) where
    // N/M are sizes of the containers containing node_/other.node_.
    assert(AreNodesFromSameContainer(node_, other.node_) &&
           "Comparing iterators from different containers.");
    assert_valid_generation(node_);
    other.assert_valid_generation(other.node_);
    return node_ == other.node_ && position_ == other.position_;
  }

  bool IsEndIterator() const {
    if (position_ != node_->finish()) return false;
    node_type *node = node_;
    while (!node->is_root()) {
      if (node->position() != node->parent()->finish()) return false;
      node = node->parent();
    }
    return true;
  }

  // Returns n such that n calls to ++other yields *this.
  // Precondition: n exists && (this->node_ != other.node_ ||
  // !this->node_->is_leaf() || this->position_ != other.position_).
  difference_type distance_slow(const_iterator other) const;

  // Increment/decrement the iterator.
  void increment() {
    assert_valid_generation(node_);
    if (node_->is_leaf() && ++position_ < node_->finish()) {
      return;
    }
    increment_slow();
  }
  void increment_slow();
  btree_iterator &increment_n_slow(difference_type n);

  void decrement() {
    assert_valid_generation(node_);
    if (node_->is_leaf() && --position_ >= node_->start()) {
      return;
    }
    decrement_slow();
  }
  void decrement_slow();
  btree_iterator &decrement_n_slow(difference_type n);

  const key_type &key() const {
    return node_->key(static_cast<size_type>(position_));
  }
  decltype(std::declval<Node *>()->slot(0)) slot() {
    return node_->slot(static_cast<size_type>(position_));
  }

  void update_generation() {
    btree_iterator_generation_info::update_generation(node_);
  }

  // The node in the tree the iterator is pointing at.
  Node *node_;
  // The position within the node of the tree the iterator is pointing at.
  // NOTE: this is an int rather than a field_type because iterators can point
  // to invalid positions (such as -1) in certain circumstances.
  int position_;
};

template <typename Params>
class btree {
  using node_type = btree_node<Params>;
  using is_key_compare_to = typename Params::is_key_compare_to;
  using field_type = typename node_type::field_type;

  // We use a static empty node for the root/leftmost/rightmost of empty btrees
  // in order to avoid branching in begin()/end().
  struct EmptyNodeType : node_type {
    using field_type = typename node_type::field_type;
    node_type *parent;
#ifdef ABSL_BTREE_ENABLE_GENERATIONS
    uint32_t generation = 0;
#endif
    field_type position = 0;
    field_type start = 0;
    field_type finish = 0;
    // max_count must be != kInternalNodeMaxCount (so that this node is regarded
    // as a leaf node). max_count() is never called when the tree is empty.
    field_type max_count = node_type::kInternalNodeMaxCount + 1;

    constexpr EmptyNodeType() : parent(this) {}
  };

  static node_type *EmptyNode() {
    alignas(node_type::Alignment()) static constexpr EmptyNodeType empty_node;
    return const_cast<EmptyNodeType *>(&empty_node);
  }

  enum : uint32_t {
    kNodeSlots = node_type::kNodeSlots,
    kMinNodeValues = kNodeSlots / 2,
  };

  struct node_stats {
    using size_type = typename Params::size_type;

    node_stats(size_type l, size_type i) : leaf_nodes(l), internal_nodes(i) {}

    node_stats &operator+=(const node_stats &other) {
      leaf_nodes += other.leaf_nodes;
      internal_nodes += other.internal_nodes;
      return *this;
    }

    size_type leaf_nodes;
    size_type internal_nodes;
  };

 public:
  using key_type = typename Params::key_type;
  using value_type = typename Params::value_type;
  using size_type = typename Params::size_type;
  using difference_type = typename Params::difference_type;
  using key_compare = typename Params::key_compare;
  using original_key_compare = typename Params::original_key_compare;
  using value_compare = typename Params::value_compare;
  using allocator_type = typename Params::allocator_type;
  using reference = typename Params::reference;
  using const_reference = typename Params::const_reference;
  using pointer = typename Params::pointer;
  using const_pointer = typename Params::const_pointer;
  using iterator =
      typename btree_iterator<node_type, reference, pointer>::iterator;
  using const_iterator = typename iterator::const_iterator;
  using reverse_iterator = std::reverse_iterator<iterator>;
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  using node_handle_type = node_handle<Params, Params, allocator_type>;

  // Internal types made public for use by btree_container types.
  using params_type = Params;
  using slot_type = typename Params::slot_type;

 private:
  // Copies or moves (depending on the template parameter) the values in
  // other into this btree in their order in other. This btree must be empty
  // before this method is called. This method is used in copy construction,
  // copy assignment, and move assignment.
  template <typename Btree>
  void copy_or_move_values_in_order(Btree &other);

  // Validates that various assumptions/requirements are true at compile time.
  constexpr static bool static_assert_validation();

 public:
  btree(const key_compare &comp, const allocator_type &alloc)
      : root_(EmptyNode()), rightmost_(comp, alloc, EmptyNode()), size_(0) {}

  btree(const btree &other) : btree(other, other.allocator()) {}
  btree(const btree &other, const allocator_type &alloc)
      : btree(other.key_comp(), alloc) {
    copy_or_move_values_in_order(other);
  }
  btree(btree &&other) noexcept
      : root_(std::exchange(other.root_, EmptyNode())),
        rightmost_(std::move(other.rightmost_)),
        size_(std::exchange(other.size_, 0u)) {
    other.mutable_rightmost() = EmptyNode();
  }
  btree(btree &&other, const allocator_type &alloc)
      : btree(other.key_comp(), alloc) {
    if (alloc == other.allocator()) {
      swap(other);
    } else {
      // Move values from `other` one at a time when allocators are different.
      copy_or_move_values_in_order(other);
    }
  }

  ~btree() {
    // Put static_asserts in destructor to avoid triggering them before the type
    // is complete.
    static_assert(static_assert_validation(), "This call must be elided.");
    clear();
  }

  // Assign the contents of other to *this.
  btree &operator=(const btree &other);
  btree &operator=(btree &&other) noexcept;

  iterator begin() { return iterator(leftmost()); }
  const_iterator begin() const { return const_iterator(leftmost()); }
  iterator end() { return iterator(rightmost(), rightmost()->finish()); }
  const_iterator end() const {
    return const_iterator(rightmost(), rightmost()->finish());
  }
  reverse_iterator rbegin() { return reverse_iterator(end()); }
  const_reverse_iterator rbegin() const {
    return const_reverse_iterator(end());
  }
  reverse_iterator rend() { return reverse_iterator(begin()); }
  const_reverse_iterator rend() const {
    return const_reverse_iterator(begin());
  }

  // Finds the first element whose key is not less than `key`.
  template <typename K>
  iterator lower_bound(const K &key) {
    return internal_end(internal_lower_bound(key).value);
  }
  template <typename K>
  const_iterator lower_bound(const K &key) const {
    return internal_end(internal_lower_bound(key).value);
  }

  // Finds the first element whose key is not less than `key` and also returns
  // whether that element is equal to `key`.
  template <typename K>
  std::pair<iterator, bool> lower_bound_equal(const K &key) const;

  // Finds the first element whose key is greater than `key`.
  template <typename K>
  iterator upper_bound(const K &key) {
    return internal_end(internal_upper_bound(key));
  }
  template <typename K>
  const_iterator upper_bound(const K &key) const {
    return internal_end(internal_upper_bound(key));
  }

  // Finds the range of values which compare equal to key. The first member of
  // the returned pair is equal to lower_bound(key). The second member of the
  // pair is equal to upper_bound(key).
  template <typename K>
  std::pair<iterator, iterator> equal_range(const K &key);
  template <typename K>
  std::pair<const_iterator, const_iterator> equal_range(const K &key) const {
    return const_cast<btree *>(this)->equal_range(key);
  }

  // Inserts a value into the btree only if it does not already exist. The
  // boolean return value indicates whether insertion succeeded or failed.
  // Requirement: if `key` already exists in the btree, does not consume `args`.
  // Requirement: `key` is never referenced after consuming `args`.
  template <typename K, typename... Args>
  std::pair<iterator, bool> insert_unique(const K &key, Args &&...args);

  // Inserts with hint. Checks to see if the value should be placed immediately
  // before `position` in the tree. If so, then the insertion will take
  // amortized constant time. If not, the insertion will take amortized
  // logarithmic time as if a call to insert_unique() were made.
  // Requirement: if `key` already exists in the btree, does not consume `args`.
  // Requirement: `key` is never referenced after consuming `args`.
  template <typename K, typename... Args>
  std::pair<iterator, bool> insert_hint_unique(iterator position, const K &key,
                                               Args &&...args);

  // Insert a range of values into the btree.
  // Note: the first overload avoids constructing a value_type if the key
  // already exists in the btree.
  template <typename InputIterator,
            typename = decltype(std::declval<const key_compare &>()(
                params_type::key(*std::declval<InputIterator>()),
                std::declval<const key_type &>()))>
  void insert_iterator_unique(InputIterator b, InputIterator e, int);
  // We need the second overload for cases in which we need to construct a
  // value_type in order to compare it with the keys already in the btree.
  template <typename InputIterator>
  void insert_iterator_unique(InputIterator b, InputIterator e, char);

  // Inserts a value into the btree.
  template <typename ValueType>
  iterator insert_multi(const key_type &key, ValueType &&v);

  // Inserts a value into the btree.
  template <typename ValueType>
  iterator insert_multi(ValueType &&v) {
    return insert_multi(params_type::key(v), std::forward<ValueType>(v));
  }

  // Insert with hint. Check to see if the value should be placed immediately
  // before position in the tree. If it does, then the insertion will take
  // amortized constant time. If not, the insertion will take amortized
  // logarithmic time as if a call to insert_multi(v) were made.
  template <typename ValueType>
  iterator insert_hint_multi(iterator position, ValueType &&v);

  // Insert a range of values into the btree.
  template <typename InputIterator>
  void insert_iterator_multi(InputIterator b,
                             InputIterator e);

  // Erase the specified iterator from the btree. The iterator must be valid
  // (i.e. not equal to end()).  Return an iterator pointing to the node after
  // the one that was erased (or end() if none exists).
  // Requirement: does not read the value at `*iter`.
  iterator erase(iterator iter);

  // Erases range. Returns the number of keys erased and an iterator pointing
  // to the element after the last erased element.
  std::pair<size_type, iterator> erase_range(iterator begin, iterator end);

  // Finds an element with key equivalent to `key` or returns `end()` if `key`
  // is not present.
  template <typename K>
  iterator find(const K &key) {
    return internal_end(internal_find(key));
  }
  template <typename K>
  const_iterator find(const K &key) const {
    return internal_end(internal_find(key));
  }

  // Clear the btree, deleting all of the values it contains.
  void clear();

  // Swaps the contents of `this` and `other`.
  void swap(btree &other);

  const key_compare &key_comp() const noexcept {
    return rightmost_.template get<0>();
  }
  template <typename K1, typename K2>
  bool compare_keys(const K1 &a, const K2 &b) const {
    return compare_internal::compare_result_as_less_than(key_comp()(a, b));
  }

  value_compare value_comp() const {
    return value_compare(original_key_compare(key_comp()));
  }

  // Verifies the structure of the btree.
  void verify() const;

  // Size routines.
  size_type size() const { return size_; }
  size_type max_size() const { return (std::numeric_limits<size_type>::max)(); }
  bool empty() const { return size_ == 0; }

  // The height of the btree. An empty tree will have height 0.
  size_type height() const {
    size_type h = 0;
    if (!empty()) {
      // Count the length of the chain from the leftmost node up to the
      // root. We actually count from the root back around to the level below
      // the root, but the calculation is the same because of the circularity
      // of that traversal.
      const node_type *n = root();
      do {
        ++h;
        n = n->parent();
      } while (n != root());
    }
    return h;
  }

  // The number of internal, leaf and total nodes used by the btree.
  size_type leaf_nodes() const { return internal_stats(root()).leaf_nodes; }
  size_type internal_nodes() const {
    return internal_stats(root()).internal_nodes;
  }
  size_type nodes() const {
    node_stats stats = internal_stats(root());
    return stats.leaf_nodes + stats.internal_nodes;
  }

  // The total number of bytes used by the btree.
  // TODO(b/169338300): update to support node_btree_*.
  size_type bytes_used() const {
    node_stats stats = internal_stats(root());
    if (stats.leaf_nodes == 1 && stats.internal_nodes == 0) {
      return sizeof(*this) + node_type::LeafSize(root()->max_count());
    } else {
      return sizeof(*this) + stats.leaf_nodes * node_type::LeafSize() +
             stats.internal_nodes * node_type::InternalSize();
    }
  }

  // The average number of bytes used per value stored in the btree assuming
  // random insertion order.
  static double average_bytes_per_value() {
    // The expected number of values per node with random insertion order is the
    // average of the maximum and minimum numbers of values per node.
    const double expected_values_per_node = (kNodeSlots + kMinNodeValues) / 2.0;
    return node_type::LeafSize() / expected_values_per_node;
  }

  // The fullness of the btree. Computed as the number of elements in the btree
  // divided by the maximum number of elements a tree with the current number
  // of nodes could hold. A value of 1 indicates perfect space
  // utilization. Smaller values indicate space wastage.
  // Returns 0 for empty trees.
  double fullness() const {
    if (empty()) return 0.0;
    return static_cast<double>(size()) / (nodes() * kNodeSlots);
  }
  // The overhead of the btree structure in bytes per node. Computed as the
  // total number of bytes used by the btree minus the number of bytes used for
  // storing elements divided by the number of elements.
  // Returns 0 for empty trees.
  double overhead() const {
    if (empty()) return 0.0;
    return (bytes_used() - size() * sizeof(value_type)) /
           static_cast<double>(size());
  }

  // The allocator used by the btree.
  allocator_type get_allocator() const { return allocator(); }

 private:
  friend struct btree_access;

  // Internal accessor routines.
  node_type *root() { return root_; }
  const node_type *root() const { return root_; }
  node_type *&mutable_root() noexcept { return root_; }
  node_type *rightmost() { return rightmost_.template get<2>(); }
  const node_type *rightmost() const { return rightmost_.template get<2>(); }
  node_type *&mutable_rightmost() noexcept {
    return rightmost_.template get<2>();
  }
  key_compare *mutable_key_comp() noexcept {
    return &rightmost_.template get<0>();
  }

  // The leftmost node is stored as the parent of the root node.
  node_type *leftmost() { return root()->parent(); }
  const node_type *leftmost() const { return root()->parent(); }

  // Allocator routines.
  allocator_type *mutable_allocator() noexcept {
    return &rightmost_.template get<1>();
  }
  const allocator_type &allocator() const noexcept {
    return rightmost_.template get<1>();
  }

  // Allocates a correctly aligned node of at least size bytes using the
  // allocator.
  node_type *allocate(size_type size) {
    return reinterpret_cast<node_type *>(
        absl::container_internal::Allocate<node_type::Alignment()>(
            mutable_allocator(), size));
  }

  // Node creation/deletion routines.
  node_type *new_internal_node(field_type position, node_type *parent) {
    node_type *n = allocate(node_type::InternalSize());
    n->init_internal(position, parent);
    return n;
  }
  node_type *new_leaf_node(field_type position, node_type *parent) {
    node_type *n = allocate(node_type::LeafSize());
    n->init_leaf(position, kNodeSlots, parent);
    return n;
  }
  node_type *new_leaf_root_node(field_type max_count) {
    node_type *n = allocate(node_type::LeafSize(max_count));
    n->init_leaf(/*position=*/0, max_count, /*parent=*/n);
    return n;
  }

  // Deletion helper routines.
  iterator rebalance_after_delete(iterator iter);

  // Rebalances or splits the node iter points to.
  void rebalance_or_split(iterator *iter);

  // Merges the values of left, right and the delimiting key on their parent
  // onto left, removing the delimiting key and deleting right.
  void merge_nodes(node_type *left, node_type *right);

  // Tries to merge node with its left or right sibling, and failing that,
  // rebalance with its left or right sibling. Returns true if a merge
  // occurred, at which point it is no longer valid to access node. Returns
  // false if no merging took place.
  bool try_merge_or_rebalance(iterator *iter);

  // Tries to shrink the height of the tree by 1.
  void try_shrink();

  iterator internal_end(iterator iter) {
    return iter.node_ != nullptr ? iter : end();
  }
  const_iterator internal_end(const_iterator iter) const {
    return iter.node_ != nullptr ? iter : end();
  }

  // Emplaces a value into the btree immediately before iter. Requires that
  // key(v) <= iter.key() and (--iter).key() <= key(v).
  template <typename... Args>
  iterator internal_emplace(iterator iter, Args &&...args);

  // Returns an iterator pointing to the first value >= the value "iter" is
  // pointing at. Note that "iter" might be pointing to an invalid location such
  // as iter.position_ == iter.node_->finish(). This routine simply moves iter
  // up in the tree to a valid location. Requires: iter.node_ is non-null.
  template <typename IterType>
  static IterType internal_last(IterType iter);

  // Returns an iterator pointing to the leaf position at which key would
  // reside in the tree, unless there is an exact match - in which case, the
  // result may not be on a leaf. When there's a three-way comparator, we can
  // return whether there was an exact match. This allows the caller to avoid a
  // subsequent comparison to determine if an exact match was made, which is
  // important for keys with expensive comparison, such as strings.
  template <typename K>
  SearchResult<iterator, is_key_compare_to::value> internal_locate(
      const K &key) const;

  // Internal routine which implements lower_bound().
  template <typename K>
  SearchResult<iterator, is_key_compare_to::value> internal_lower_bound(
      const K &key) const;

  // Internal routine which implements upper_bound().
  template <typename K>
  iterator internal_upper_bound(const K &key) const;

  // Internal routine which implements find().
  template <typename K>
  iterator internal_find(const K &key) const;

  // Verifies the tree structure of node.
  size_type internal_verify(const node_type *node, const key_type *lo,
                            const key_type *hi) const;

  node_stats internal_stats(const node_type *node) const {
    // The root can be a static empty node.
    if (node == nullptr || (node == root() && empty())) {
      return node_stats(0, 0);
    }
    if (node->is_leaf()) {
      return node_stats(1, 0);
    }
    node_stats res(0, 1);
    for (int i = node->start(); i <= node->finish(); ++i) {
      res += internal_stats(node->child(i));
    }
    return res;
  }

  node_type *root_;

  // A pointer to the rightmost node. Note that the leftmost node is stored as
  // the root's parent. We use compressed tuple in order to save space because
  // key_compare and allocator_type are usually empty.
  absl::container_internal::CompressedTuple<key_compare, allocator_type,
                                            node_type *>
      rightmost_;

  // Number of values.
  size_type size_;
};

////
// btree_node methods
template <typename P>
template <typename... Args>
inline void btree_node<P>::emplace_value(const field_type i,
                                         allocator_type *alloc,
                                         Args &&...args) {
  assert(i >= start());
  assert(i <= finish());
  // Shift old values to create space for new value and then construct it in
  // place.
  if (i < finish()) {
    transfer_n_backward(finish() - i, /*dest_i=*/i + 1, /*src_i=*/i, this,
                        alloc);
  }
  value_init(static_cast<field_type>(i), alloc, std::forward<Args>(args)...);
  set_finish(finish() + 1);

  if (is_internal() && finish() > i + 1) {
    for (field_type j = finish(); j > i + 1; --j) {
      set_child(j, child(j - 1));
    }
    clear_child(i + 1);
  }
}

template <typename P>
inline void btree_node<P>::remove_values(const field_type i,
                                         const field_type to_erase,
                                         allocator_type *alloc) {
  // Transfer values after the removed range into their new places.
  value_destroy_n(i, to_erase, alloc);
  const field_type orig_finish = finish();
  const field_type src_i = i + to_erase;
  transfer_n(orig_finish - src_i, i, src_i, this, alloc);

  if (is_internal()) {
    // Delete all children between begin and end.
    for (field_type j = 0; j < to_erase; ++j) {
      clear_and_delete(child(i + j + 1), alloc);
    }
    // Rotate children after end into new positions.
    for (field_type j = i + to_erase + 1; j <= orig_finish; ++j) {
      set_child(j - to_erase, child(j));
      clear_child(j);
    }
  }
  set_finish(orig_finish - to_erase);
}

template <typename P>
void btree_node<P>::rebalance_right_to_left(field_type to_move,
                                            btree_node *right,
                                            allocator_type *alloc) {
  assert(parent() == right->parent());
  assert(position() + 1 == right->position());
  assert(right->count() >= count());
  assert(to_move >= 1);
  assert(to_move <= right->count());

  // 1) Move the delimiting value in the parent to the left node.
  transfer(finish(), position(), parent(), alloc);

  // 2) Move the (to_move - 1) values from the right node to the left node.
  transfer_n(to_move - 1, finish() + 1, right->start(), right, alloc);

  // 3) Move the new delimiting value to the parent from the right node.
  parent()->transfer(position(), right->start() + to_move - 1, right, alloc);

  // 4) Shift the values in the right node to their correct positions.
  right->transfer_n(right->count() - to_move, right->start(),
                    right->start() + to_move, right, alloc);

  if (is_internal()) {
    // Move the child pointers from the right to the left node.
    for (field_type i = 0; i < to_move; ++i) {
      init_child(finish() + i + 1, right->child(i));
    }
    for (field_type i = right->start(); i <= right->finish() - to_move; ++i) {
      assert(i + to_move <= right->max_count());
      right->init_child(i, right->child(i + to_move));
      right->clear_child(i + to_move);
    }
  }

  // Fixup `finish` on the left and right nodes.
  set_finish(finish() + to_move);
  right->set_finish(right->finish() - to_move);
}

template <typename P>
void btree_node<P>::rebalance_left_to_right(field_type to_move,
                                            btree_node *right,
                                            allocator_type *alloc) {
  assert(parent() == right->parent());
  assert(position() + 1 == right->position());
  assert(count() >= right->count());
  assert(to_move >= 1);
  assert(to_move <= count());

  // Values in the right node are shifted to the right to make room for the
  // new to_move values. Then, the delimiting value in the parent and the
  // other (to_move - 1) values in the left node are moved into the right node.
  // Lastly, a new delimiting value is moved from the left node into the
  // parent, and the remaining empty left node entries are destroyed.

  // 1) Shift existing values in the right node to their correct positions.
  right->transfer_n_backward(right->count(), right->start() + to_move,
                             right->start(), right, alloc);

  // 2) Move the delimiting value in the parent to the right node.
  right->transfer(right->start() + to_move - 1, position(), parent(), alloc);

  // 3) Move the (to_move - 1) values from the left node to the right node.
  right->transfer_n(to_move - 1, right->start(), finish() - (to_move - 1), this,
                    alloc);

  // 4) Move the new delimiting value to the parent from the left node.
  parent()->transfer(position(), finish() - to_move, this, alloc);

  if (is_internal()) {
    // Move the child pointers from the left to the right node.
    for (field_type i = right->finish() + 1; i > right->start(); --i) {
      right->init_child(i - 1 + to_move, right->child(i - 1));
      right->clear_child(i - 1);
    }
    for (field_type i = 1; i <= to_move; ++i) {
      right->init_child(i - 1, child(finish() - to_move + i));
      clear_child(finish() - to_move + i);
    }
  }

  // Fixup the counts on the left and right nodes.
  set_finish(finish() - to_move);
  right->set_finish(right->finish() + to_move);
}

template <typename P>
void btree_node<P>::split(const int insert_position, btree_node *dest,
                          allocator_type *alloc) {
  assert(dest->count() == 0);
  assert(max_count() == kNodeSlots);
  assert(position() + 1 == dest->position());
  assert(parent() == dest->parent());

  // We bias the split based on the position being inserted. If we're
  // inserting at the beginning of the left node then bias the split to put
  // more values on the right node. If we're inserting at the end of the
  // right node then bias the split to put more values on the left node.
  if (insert_position == start()) {
    dest->set_finish(dest->start() + finish() - 1);
  } else if (insert_position == kNodeSlots) {
    dest->set_finish(dest->start());
  } else {
    dest->set_finish(dest->start() + count() / 2);
  }
  set_finish(finish() - dest->count());
  assert(count() >= 1);

  // Move values from the left sibling to the right sibling.
  dest->transfer_n(dest->count(), dest->start(), finish(), this, alloc);

  // The split key is the largest value in the left sibling.
  --mutable_finish();
  parent()->emplace_value(position(), alloc, finish_slot());
  value_destroy(finish(), alloc);
  parent()->set_child_noupdate_position(position() + 1, dest);

  if (is_internal()) {
    for (field_type i = dest->start(), j = finish() + 1; i <= dest->finish();
         ++i, ++j) {
      assert(child(j) != nullptr);
      dest->init_child(i, child(j));
      clear_child(j);
    }
  }
}

template <typename P>
void btree_node<P>::merge(btree_node *src, allocator_type *alloc) {
  assert(parent() == src->parent());
  assert(position() + 1 == src->position());

  // Move the delimiting value to the left node.
  value_init(finish(), alloc, parent()->slot(position()));

  // Move the values from the right to the left node.
  transfer_n(src->count(), finish() + 1, src->start(), src, alloc);

  if (is_internal()) {
    // Move the child pointers from the right to the left node.
    for (field_type i = src->start(), j = finish() + 1; i <= src->finish();
         ++i, ++j) {
      init_child(j, src->child(i));
      src->clear_child(i);
    }
  }

  // Fixup `finish` on the src and dest nodes.
  set_finish(start() + 1 + count() + src->count());
  src->set_finish(src->start());

  // Remove the value on the parent node and delete the src node.
  parent()->remove_values(position(), /*to_erase=*/1, alloc);
}

template <typename P>
void btree_node<P>::clear_and_delete(btree_node *node, allocator_type *alloc) {
  if (node->is_leaf()) {
    node->value_destroy_n(node->start(), node->count(), alloc);
    deallocate(LeafSize(node->max_count()), node, alloc);
    return;
  }
  if (node->count() == 0) {
    deallocate(InternalSize(), node, alloc);
    return;
  }

  // The parent of the root of the subtree we are deleting.
  btree_node *delete_root_parent = node->parent();

  // Navigate to the leftmost leaf under node, and then delete upwards.
  while (node->is_internal()) node = node->start_child();
#ifdef ABSL_BTREE_ENABLE_GENERATIONS
  // When generations are enabled, we delete the leftmost leaf last in case it's
  // the parent of the root and we need to check whether it's a leaf before we
  // can update the root's generation.
  // TODO(ezb): if we change btree_node::is_root to check a bool inside the node
  // instead of checking whether the parent is a leaf, we can remove this logic.
  btree_node *leftmost_leaf = node;
#endif
  // Use `size_type` because `pos` needs to be able to hold `kNodeSlots+1`,
  // which isn't guaranteed to be a valid `field_type`.
  size_type pos = node->position();
  btree_node *parent = node->parent();
  for (;;) {
    // In each iteration of the next loop, we delete one leaf node and go right.
    assert(pos <= parent->finish());
    do {
      node = parent->child(static_cast<field_type>(pos));
      if (node->is_internal()) {
        // Navigate to the leftmost leaf under node.
        while (node->is_internal()) node = node->start_child();
        pos = node->position();
        parent = node->parent();
      }
      node->value_destroy_n(node->start(), node->count(), alloc);
#ifdef ABSL_BTREE_ENABLE_GENERATIONS
      if (leftmost_leaf != node)
#endif
        deallocate(LeafSize(node->max_count()), node, alloc);
      ++pos;
    } while (pos <= parent->finish());

    // Once we've deleted all children of parent, delete parent and go up/right.
    assert(pos > parent->finish());
    do {
      node = parent;
      pos = node->position();
      parent = node->parent();
      node->value_destroy_n(node->start(), node->count(), alloc);
      deallocate(InternalSize(), node, alloc);
      if (parent == delete_root_parent) {
#ifdef ABSL_BTREE_ENABLE_GENERATIONS
        deallocate(LeafSize(leftmost_leaf->max_count()), leftmost_leaf, alloc);
#endif
        return;
      }
      ++pos;
    } while (pos > parent->finish());
  }
}

////
// btree_iterator methods

// Note: the implementation here is based on btree_node::clear_and_delete.
template <typename N, typename R, typename P>
auto btree_iterator<N, R, P>::distance_slow(const_iterator other) const
    -> difference_type {
  const_iterator begin = other;
  const_iterator end = *this;
  assert(begin.node_ != end.node_ || !begin.node_->is_leaf() ||
         begin.position_ != end.position_);

  const node_type *node = begin.node_;
  // We need to compensate for double counting if begin.node_ is a leaf node.
  difference_type count = node->is_leaf() ? -begin.position_ : 0;

  // First navigate to the leftmost leaf node past begin.
  if (node->is_internal()) {
    ++count;
    node = node->child(begin.position_ + 1);
  }
  while (node->is_internal()) node = node->start_child();

  // Use `size_type` because `pos` needs to be able to hold `kNodeSlots+1`,
  // which isn't guaranteed to be a valid `field_type`.
  size_type pos = node->position();
  const node_type *parent = node->parent();
  for (;;) {
    // In each iteration of the next loop, we count one leaf node and go right.
    assert(pos <= parent->finish());
    do {
      node = parent->child(static_cast<field_type>(pos));
      if (node->is_internal()) {
        // Navigate to the leftmost leaf under node.
        while (node->is_internal()) node = node->start_child();
        pos = node->position();
        parent = node->parent();
      }
      if (node == end.node_) return count + end.position_;
      if (parent == end.node_ && pos == static_cast<size_type>(end.position_))
        return count + node->count();
      // +1 is for the next internal node value.
      count += node->count() + 1;
      ++pos;
    } while (pos <= parent->finish());

    // Once we've counted all children of parent, go up/right.
    assert(pos > parent->finish());
    do {
      node = parent;
      pos = node->position();
      parent = node->parent();
      // -1 because we counted the value at end and shouldn't.
      if (parent == end.node_ && pos == static_cast<size_type>(end.position_))
        return count - 1;
      ++pos;
    } while (pos > parent->finish());
  }
}

template <typename N, typename R, typename P>
void btree_iterator<N, R, P>::increment_slow() {
  N* node = node_;
  int position = position_;
  if (node->is_leaf()) {
    assert(position >= node->finish());
    while (position == node->finish() && !node->is_root()) {
      assert(node->parent()->child(node->position()) == node);
      position = node->position();
      node = node->parent();
    }
    // TODO(ezb): assert we aren't incrementing end() instead of handling.
    if (position == node->finish()) {
      return;
    }
  } else {
    assert(position < node->finish());
    node = node->child(static_cast<field_type>(position + 1));
    while (node->is_internal()) {
      node = node->start_child();
    }
    position = node->start();
  }
  *this = {node, position};
}

template <typename N, typename R, typename P>
void btree_iterator<N, R, P>::decrement_slow() {
  N* node = node_;
  int position = position_;
  if (node->is_leaf()) {
    assert(position <= -1);
    while (position < node->start() && !node->is_root()) {
      assert(node->parent()->child(node->position()) == node);
      position = node->position() - 1;
      node = node->parent();
    }
    // TODO(ezb): assert we aren't decrementing begin() instead of handling.
    if (position < node->start()) {
      return;
    }
  } else {
    assert(position >= node->start());
    node = node->child(static_cast<field_type>(position));
    while (node->is_internal()) {
      node = node->child(node->finish());
    }
    position = node->finish() - 1;
  }
  *this = {node, position};
}

template <typename N, typename R, typename P>
btree_iterator<N, R, P> &btree_iterator<N, R, P>::increment_n_slow(
    difference_type n) {
  N *node = node_;
  int position = position_;
  ABSL_ASSUME(n > 0);
  while (n > 0) {
    if (node->is_leaf()) {
      if (position + n < node->finish()) {
        position += n;
        break;
      } else {
        n -= node->finish() - position;
        position = node->finish();
        btree_iterator save = {node, position};
        while (position == node->finish() && !node->is_root()) {
          position = node->position();
          node = node->parent();
        }
        if (position == node->finish()) {
          ABSL_HARDENING_ASSERT(n == 0);
          return *this = save;
        }
      }
    } else {
      --n;
      assert(position < node->finish());
      node = node->child(static_cast<field_type>(position + 1));
      while (node->is_internal()) {
        node = node->start_child();
      }
      position = node->start();
    }
  }
  node_ = node;
  position_ = position;
  return *this;
}

template <typename N, typename R, typename P>
btree_iterator<N, R, P> &btree_iterator<N, R, P>::decrement_n_slow(
    difference_type n) {
  N *node = node_;
  int position = position_;
  ABSL_ASSUME(n > 0);
  while (n > 0) {
    if (node->is_leaf()) {
      if (position - n >= node->start()) {
        position -= n;
        break;
      } else {
        n -= 1 + position - node->start();
        position = node->start() - 1;
        while (position < node->start() && !node->is_root()) {
          position = node->position() - 1;
          node = node->parent();
        }
        ABSL_HARDENING_ASSERT(position >= node->start());
      }
    } else {
      --n;
      assert(position >= node->start());
      node = node->child(static_cast<field_type>(position));
      while (node->is_internal()) {
        node = node->child(node->finish());
      }
      position = node->finish() - 1;
    }
  }
  node_ = node;
  position_ = position;
  return *this;
}

////
// btree methods
template <typename P>
template <typename Btree>
void btree<P>::copy_or_move_values_in_order(Btree &other) {
  static_assert(std::is_same<btree, Btree>::value ||
                    std::is_same<const btree, Btree>::value,
                "Btree type must be same or const.");
  assert(empty());

  // We can avoid key comparisons because we know the order of the
  // values is the same order we'll store them in.
  auto iter = other.begin();
  if (iter == other.end()) return;
  insert_multi(iter.slot());
  ++iter;
  for (; iter != other.end(); ++iter) {
    // If the btree is not empty, we can just insert the new value at the end
    // of the tree.
    internal_emplace(end(), iter.slot());
  }
}

template <typename P>
constexpr bool btree<P>::static_assert_validation() {
  static_assert(std::is_nothrow_copy_constructible<key_compare>::value,
                "Key comparison must be nothrow copy constructible");
  static_assert(std::is_nothrow_copy_constructible<allocator_type>::value,
                "Allocator must be nothrow copy constructible");
  static_assert(std::is_trivially_copyable<iterator>::value,
                "iterator not trivially copyable.");

  // Note: We assert that kTargetValues, which is computed from
  // Params::kTargetNodeSize, must fit the node_type::field_type.
  static_assert(
      kNodeSlots < (1 << (8 * sizeof(typename node_type::field_type))),
      "target node size too large");

  // Verify that key_compare returns an absl::{weak,strong}_ordering or bool.
  static_assert(
      compare_has_valid_result_type<key_compare, key_type>(),
      "key comparison function must return absl::{weak,strong}_ordering or "
      "bool.");

  // Test the assumption made in setting kNodeSlotSpace.
  static_assert(node_type::MinimumOverhead() >= sizeof(void *) + 4,
                "node space assumption incorrect");

  return true;
}

template <typename P>
template <typename K>
auto btree<P>::lower_bound_equal(const K &key) const
    -> std::pair<iterator, bool> {
  const SearchResult<iterator, is_key_compare_to::value> res =
      internal_lower_bound(key);
  const iterator lower = iterator(internal_end(res.value));
  const bool equal = res.HasMatch()
                         ? res.IsEq()
                         : lower != end() && !compare_keys(key, lower.key());
  return {lower, equal};
}

template <typename P>
template <typename K>
auto btree<P>::equal_range(const K &key) -> std::pair<iterator, iterator> {
  const std::pair<iterator, bool> lower_and_equal = lower_bound_equal(key);
  const iterator lower = lower_and_equal.first;
  if (!lower_and_equal.second) {
    return {lower, lower};
  }

  const iterator next = std::next(lower);
  if (!params_type::template can_have_multiple_equivalent_keys<K>()) {
    // The next iterator after lower must point to a key greater than `key`.
    // Note: if this assert fails, then it may indicate that the comparator does
    // not meet the equivalence requirements for Compare
    // (see https://en.cppreference.com/w/cpp/named_req/Compare).
    assert(next == end() || compare_keys(key, next.key()));
    return {lower, next};
  }
  // Try once more to avoid the call to upper_bound() if there's only one
  // equivalent key. This should prevent all calls to upper_bound() in cases of
  // unique-containers with heterogeneous comparators in which all comparison
  // operators have the same equivalence classes.
  if (next == end() || compare_keys(key, next.key())) return {lower, next};

  // In this case, we need to call upper_bound() to avoid worst case O(N)
  // behavior if we were to iterate over equal keys.
  return {lower, upper_bound(key)};
}

template <typename P>
template <typename K, typename... Args>
auto btree<P>::insert_unique(const K &key, Args &&...args)
    -> std::pair<iterator, bool> {
  if (empty()) {
    mutable_root() = mutable_rightmost() = new_leaf_root_node(1);
  }

  SearchResult<iterator, is_key_compare_to::value> res = internal_locate(key);
  iterator iter = res.value;

  if (res.HasMatch()) {
    if (res.IsEq()) {
      // The key already exists in the tree, do nothing.
      return {iter, false};
    }
  } else {
    iterator last = internal_last(iter);
    if (last.node_ && !compare_keys(key, last.key())) {
      // The key already exists in the tree, do nothing.
      return {last, false};
    }
  }
  return {internal_emplace(iter, std::forward<Args>(args)...), true};
}

template <typename P>
template <typename K, typename... Args>
inline auto btree<P>::insert_hint_unique(iterator position, const K &key,
                                         Args &&...args)
    -> std::pair<iterator, bool> {
  if (!empty()) {
    if (position == end() || compare_keys(key, position.key())) {
      if (position == begin() || compare_keys(std::prev(position).key(), key)) {
        // prev.key() < key < position.key()
        return {internal_emplace(position, std::forward<Args>(args)...), true};
      }
    } else if (compare_keys(position.key(), key)) {
      ++position;
      if (position == end() || compare_keys(key, position.key())) {
        // {original `position`}.key() < key < {current `position`}.key()
        return {internal_emplace(position, std::forward<Args>(args)...), true};
      }
    } else {
      // position.key() == key
      return {position, false};
    }
  }
  return insert_unique(key, std::forward<Args>(args)...);
}

template <typename P>
template <typename InputIterator, typename>
void btree<P>::insert_iterator_unique(InputIterator b, InputIterator e, int) {
  for (; b != e; ++b) {
    insert_hint_unique(end(), params_type::key(*b), *b);
  }
}

template <typename P>
template <typename InputIterator>
void btree<P>::insert_iterator_unique(InputIterator b, InputIterator e, char) {
  for (; b != e; ++b) {
    // Use a node handle to manage a temp slot.
    auto node_handle =
        CommonAccess::Construct<node_handle_type>(get_allocator(), *b);
    slot_type *slot = CommonAccess::GetSlot(node_handle);
    insert_hint_unique(end(), params_type::key(slot), slot);
  }
}

template <typename P>
template <typename ValueType>
auto btree<P>::insert_multi(const key_type &key, ValueType &&v) -> iterator {
  if (empty()) {
    mutable_root() = mutable_rightmost() = new_leaf_root_node(1);
  }

  iterator iter = internal_upper_bound(key);
  if (iter.node_ == nullptr) {
    iter = end();
  }
  return internal_emplace(iter, std::forward<ValueType>(v));
}

template <typename P>
template <typename ValueType>
auto btree<P>::insert_hint_multi(iterator position, ValueType &&v) -> iterator {
  if (!empty()) {
    const key_type &key = params_type::key(v);
    if (position == end() || !compare_keys(position.key(), key)) {
      if (position == begin() ||
          !compare_keys(key, std::prev(position).key())) {
        // prev.key() <= key <= position.key()
        return internal_emplace(position, std::forward<ValueType>(v));
      }
    } else {
      ++position;
      if (position == end() || !compare_keys(position.key(), key)) {
        // {original `position`}.key() < key < {current `position`}.key()
        return internal_emplace(position, std::forward<ValueType>(v));
      }
    }
  }
  return insert_multi(std::forward<ValueType>(v));
}

template <typename P>
template <typename InputIterator>
void btree<P>::insert_iterator_multi(InputIterator b, InputIterator e) {
  for (; b != e; ++b) {
    insert_hint_multi(end(), *b);
  }
}

template <typename P>
auto btree<P>::operator=(const btree &other) -> btree & {
  if (this != &other) {
    clear();

    *mutable_key_comp() = other.key_comp();
    if (absl::allocator_traits<
            allocator_type>::propagate_on_container_copy_assignment::value) {
      *mutable_allocator() = other.allocator();
    }

    copy_or_move_values_in_order(other);
  }
  return *this;
}

template <typename P>
auto btree<P>::operator=(btree &&other) noexcept -> btree & {
  if (this != &other) {
    clear();

    using std::swap;
    if (absl::allocator_traits<
            allocator_type>::propagate_on_container_move_assignment::value) {
      swap(root_, other.root_);
      // Note: `rightmost_` also contains the allocator and the key comparator.
      swap(rightmost_, other.rightmost_);
      swap(size_, other.size_);
    } else {
      if (allocator() == other.allocator()) {
        swap(mutable_root(), other.mutable_root());
        swap(*mutable_key_comp(), *other.mutable_key_comp());
        swap(mutable_rightmost(), other.mutable_rightmost());
        swap(size_, other.size_);
      } else {
        // We aren't allowed to propagate the allocator and the allocator is
        // different so we can't take over its memory. We must move each element
        // individually. We need both `other` and `this` to have `other`s key
        // comparator while moving the values so we can't swap the key
        // comparators.
        *mutable_key_comp() = other.key_comp();
        copy_or_move_values_in_order(other);
      }
    }
  }
  return *this;
}

template <typename P>
auto btree<P>::erase(iterator iter) -> iterator {
  iter.node_->value_destroy(static_cast<field_type>(iter.position_),
                            mutable_allocator());
  iter.update_generation();

  const bool internal_delete = iter.node_->is_internal();
  if (internal_delete) {
    // Deletion of a value on an internal node. First, transfer the largest
    // value from our left child here, then erase/rebalance from that position.
    // We can get to the largest value from our left child by decrementing iter.
    iterator internal_iter(iter);
    --iter;
    assert(iter.node_->is_leaf());
    internal_iter.node_->transfer(
        static_cast<size_type>(internal_iter.position_),
        static_cast<size_type>(iter.position_), iter.node_,
        mutable_allocator());
  } else {
    // Shift values after erased position in leaf. In the internal case, we
    // don't need to do this because the leaf position is the end of the node.
    const field_type transfer_from =
        static_cast<field_type>(iter.position_ + 1);
    const field_type num_to_transfer = iter.node_->finish() - transfer_from;
    iter.node_->transfer_n(num_to_transfer,
                           static_cast<size_type>(iter.position_),
                           transfer_from, iter.node_, mutable_allocator());
  }
  // Update node finish and container size.
  iter.node_->set_finish(iter.node_->finish() - 1);
  --size_;

  // We want to return the next value after the one we just erased. If we
  // erased from an internal node (internal_delete == true), then the next
  // value is ++(++iter). If we erased from a leaf node (internal_delete ==
  // false) then the next value is ++iter. Note that ++iter may point to an
  // internal node and the value in the internal node may move to a leaf node
  // (iter.node_) when rebalancing is performed at the leaf level.

  iterator res = rebalance_after_delete(iter);

  // If we erased from an internal node, advance the iterator.
  if (internal_delete) {
    ++res;
  }
  return res;
}

template <typename P>
auto btree<P>::rebalance_after_delete(iterator iter) -> iterator {
  // Merge/rebalance as we walk back up the tree.
  iterator res(iter);
  bool first_iteration = true;
  for (;;) {
    if (iter.node_ == root()) {
      try_shrink();
      if (empty()) {
        return end();
      }
      break;
    }
    if (iter.node_->count() >= kMinNodeValues) {
      break;
    }
    bool merged = try_merge_or_rebalance(&iter);
    // On the first iteration, we should update `res` with `iter` because `res`
    // may have been invalidated.
    if (first_iteration) {
      res = iter;
      first_iteration = false;
    }
    if (!merged) {
      break;
    }
    iter.position_ = iter.node_->position();
    iter.node_ = iter.node_->parent();
  }
  res.update_generation();

  // Adjust our return value. If we're pointing at the end of a node, advance
  // the iterator.
  if (res.position_ == res.node_->finish()) {
    res.position_ = res.node_->finish() - 1;
    ++res;
  }

  return res;
}

// Note: we tried implementing this more efficiently by erasing all of the
// elements in [begin, end) at once and then doing rebalancing once at the end
// (rather than interleaving deletion and rebalancing), but that adds a lot of
// complexity, which seems to outweigh the performance win.
template <typename P>
auto btree<P>::erase_range(iterator begin, iterator end)
    -> std::pair<size_type, iterator> {
  size_type count = static_cast<size_type>(end - begin);
  assert(count >= 0);

  if (count == 0) {
    return {0, begin};
  }

  if (static_cast<size_type>(count) == size_) {
    clear();
    return {count, this->end()};
  }

  if (begin.node_ == end.node_) {
    assert(end.position_ > begin.position_);
    begin.node_->remove_values(
        static_cast<field_type>(begin.position_),
        static_cast<field_type>(end.position_ - begin.position_),
        mutable_allocator());
    size_ -= count;
    return {count, rebalance_after_delete(begin)};
  }

  const size_type target_size = size_ - count;
  while (size_ > target_size) {
    if (begin.node_->is_leaf()) {
      const size_type remaining_to_erase = size_ - target_size;
      const size_type remaining_in_node =
          static_cast<size_type>(begin.node_->finish() - begin.position_);
      const field_type to_erase = static_cast<field_type>(
          (std::min)(remaining_to_erase, remaining_in_node));
      begin.node_->remove_values(static_cast<field_type>(begin.position_),
                                 to_erase, mutable_allocator());
      size_ -= to_erase;
      begin = rebalance_after_delete(begin);
    } else {
      begin = erase(begin);
    }
  }
  begin.update_generation();
  return {count, begin};
}

template <typename P>
void btree<P>::clear() {
  if (!empty()) {
    node_type::clear_and_delete(root(), mutable_allocator());
  }
  mutable_root() = mutable_rightmost() = EmptyNode();
  size_ = 0;
}

template <typename P>
void btree<P>::swap(btree &other) {
  using std::swap;
  if (absl::allocator_traits<
          allocator_type>::propagate_on_container_swap::value) {
    // Note: `rightmost_` also contains the allocator and the key comparator.
    swap(rightmost_, other.rightmost_);
  } else {
    // It's undefined behavior if the allocators are unequal here.
    assert(allocator() == other.allocator());
    swap(mutable_rightmost(), other.mutable_rightmost());
    swap(*mutable_key_comp(), *other.mutable_key_comp());
  }
  swap(mutable_root(), other.mutable_root());
  swap(size_, other.size_);
}

template <typename P>
void btree<P>::verify() const {
  assert(root() != nullptr);
  assert(leftmost() != nullptr);
  assert(rightmost() != nullptr);
  assert(empty() || size() == internal_verify(root(), nullptr, nullptr));
  assert(leftmost() == (++const_iterator(root(), -1)).node_);
  assert(rightmost() == (--const_iterator(root(), root()->finish())).node_);
  assert(leftmost()->is_leaf());
  assert(rightmost()->is_leaf());
}

template <typename P>
void btree<P>::rebalance_or_split(iterator *iter) {
  node_type *&node = iter->node_;
  int &insert_position = iter->position_;
  assert(node->count() == node->max_count());
  assert(kNodeSlots == node->max_count());

  // First try to make room on the node by rebalancing.
  node_type *parent = node->parent();
  if (node != root()) {
    if (node->position() > parent->start()) {
      // Try rebalancing with our left sibling.
      node_type *left = parent->child(node->position() - 1);
      assert(left->max_count() == kNodeSlots);
      if (left->count() < kNodeSlots) {
        // We bias rebalancing based on the position being inserted. If we're
        // inserting at the end of the right node then we bias rebalancing to
        // fill up the left node.
        field_type to_move =
            (kNodeSlots - left->count()) /
            (1 + (static_cast<field_type>(insert_position) < kNodeSlots));
        to_move = (std::max)(field_type{1}, to_move);

        if (static_cast<field_type>(insert_position) - to_move >=
                node->start() ||
            left->count() + to_move < kNodeSlots) {
          left->rebalance_right_to_left(to_move, node, mutable_allocator());

          assert(node->max_count() - node->count() == to_move);
          insert_position = static_cast<int>(
              static_cast<field_type>(insert_position) - to_move);
          if (insert_position < node->start()) {
            insert_position = insert_position + left->count() + 1;
            node = left;
          }

          assert(node->count() < node->max_count());
          return;
        }
      }
    }

    if (node->position() < parent->finish()) {
      // Try rebalancing with our right sibling.
      node_type *right = parent->child(node->position() + 1);
      assert(right->max_count() == kNodeSlots);
      if (right->count() < kNodeSlots) {
        // We bias rebalancing based on the position being inserted. If we're
        // inserting at the beginning of the left node then we bias rebalancing
        // to fill up the right node.
        field_type to_move = (kNodeSlots - right->count()) /
                             (1 + (insert_position > node->start()));
        to_move = (std::max)(field_type{1}, to_move);

        if (static_cast<field_type>(insert_position) <=
                node->finish() - to_move ||
            right->count() + to_move < kNodeSlots) {
          node->rebalance_left_to_right(to_move, right, mutable_allocator());

          if (insert_position > node->finish()) {
            insert_position = insert_position - node->count() - 1;
            node = right;
          }

          assert(node->count() < node->max_count());
          return;
        }
      }
    }

    // Rebalancing failed, make sure there is room on the parent node for a new
    // value.
    assert(parent->max_count() == kNodeSlots);
    if (parent->count() == kNodeSlots) {
      iterator parent_iter(parent, node->position());
      rebalance_or_split(&parent_iter);
      parent = node->parent();
    }
  } else {
    // Rebalancing not possible because this is the root node.
    // Create a new root node and set the current root node as the child of the
    // new root.
    parent = new_internal_node(/*position=*/0, parent);
    parent->set_generation(root()->generation());
    parent->init_child(parent->start(), node);
    mutable_root() = parent;
    // If the former root was a leaf node, then it's now the rightmost node.
    assert(parent->start_child()->is_internal() ||
           parent->start_child() == rightmost());
  }

  // Split the node.
  node_type *split_node;
  if (node->is_leaf()) {
    split_node = new_leaf_node(node->position() + 1, parent);
    node->split(insert_position, split_node, mutable_allocator());
    if (rightmost() == node) mutable_rightmost() = split_node;
  } else {
    split_node = new_internal_node(node->position() + 1, parent);
    node->split(insert_position, split_node, mutable_allocator());
  }

  if (insert_position > node->finish()) {
    insert_position = insert_position - node->count() - 1;
    node = split_node;
  }
}

template <typename P>
void btree<P>::merge_nodes(node_type *left, node_type *right) {
  left->merge(right, mutable_allocator());
  if (rightmost() == right) mutable_rightmost() = left;
}

template <typename P>
bool btree<P>::try_merge_or_rebalance(iterator *iter) {
  node_type *parent = iter->node_->parent();
  if (iter->node_->position() > parent->start()) {
    // Try merging with our left sibling.
    node_type *left = parent->child(iter->node_->position() - 1);
    assert(left->max_count() == kNodeSlots);
    if (1U + left->count() + iter->node_->count() <= kNodeSlots) {
      iter->position_ += 1 + left->count();
      merge_nodes(left, iter->node_);
      iter->node_ = left;
      return true;
    }
  }
  if (iter->node_->position() < parent->finish()) {
    // Try merging with our right sibling.
    node_type *right = parent->child(iter->node_->position() + 1);
    assert(right->max_count() == kNodeSlots);
    if (1U + iter->node_->count() + right->count() <= kNodeSlots) {
      merge_nodes(iter->node_, right);
      return true;
    }
    // Try rebalancing with our right sibling. We don't perform rebalancing if
    // we deleted the first element from iter->node_ and the node is not
    // empty. This is a small optimization for the common pattern of deleting
    // from the front of the tree.
    if (right->count() > kMinNodeValues &&
        (iter->node_->count() == 0 || iter->position_ > iter->node_->start())) {
      field_type to_move = (right->count() - iter->node_->count()) / 2;
      to_move =
          (std::min)(to_move, static_cast<field_type>(right->count() - 1));
      iter->node_->rebalance_right_to_left(to_move, right, mutable_allocator());
      return false;
    }
  }
  if (iter->node_->position() > parent->start()) {
    // Try rebalancing with our left sibling. We don't perform rebalancing if
    // we deleted the last element from iter->node_ and the node is not
    // empty. This is a small optimization for the common pattern of deleting
    // from the back of the tree.
    node_type *left = parent->child(iter->node_->position() - 1);
    if (left->count() > kMinNodeValues &&
        (iter->node_->count() == 0 ||
         iter->position_ < iter->node_->finish())) {
      field_type to_move = (left->count() - iter->node_->count()) / 2;
      to_move = (std::min)(to_move, static_cast<field_type>(left->count() - 1));
      left->rebalance_left_to_right(to_move, iter->node_, mutable_allocator());
      iter->position_ += to_move;
      return false;
    }
  }
  return false;
}

template <typename P>
void btree<P>::try_shrink() {
  node_type *orig_root = root();
  if (orig_root->count() > 0) {
    return;
  }
  // Deleted the last item on the root node, shrink the height of the tree.
  if (orig_root->is_leaf()) {
    assert(size() == 0);
    mutable_root() = mutable_rightmost() = EmptyNode();
  } else {
    node_type *child = orig_root->start_child();
    child->make_root();
    mutable_root() = child;
  }
  node_type::clear_and_delete(orig_root, mutable_allocator());
}

template <typename P>
template <typename IterType>
inline IterType btree<P>::internal_last(IterType iter) {
  assert(iter.node_ != nullptr);
  while (iter.position_ == iter.node_->finish()) {
    iter.position_ = iter.node_->position();
    iter.node_ = iter.node_->parent();
    if (iter.node_->is_leaf()) {
      iter.node_ = nullptr;
      break;
    }
  }
  iter.update_generation();
  return iter;
}

template <typename P>
template <typename... Args>
inline auto btree<P>::internal_emplace(iterator iter, Args &&...args)
    -> iterator {
  if (iter.node_->is_internal()) {
    // We can't insert on an internal node. Instead, we'll insert after the
    // previous value which is guaranteed to be on a leaf node.
    --iter;
    ++iter.position_;
  }
  const field_type max_count = iter.node_->max_count();
  allocator_type *alloc = mutable_allocator();

  const auto transfer_and_delete = [&](node_type *old_node,
                                       node_type *new_node) {
    new_node->transfer_n(old_node->count(), new_node->start(),
                         old_node->start(), old_node, alloc);
    new_node->set_finish(old_node->finish());
    old_node->set_finish(old_node->start());
    new_node->set_generation(old_node->generation());
    node_type::clear_and_delete(old_node, alloc);
  };
  const auto replace_leaf_root_node = [&](field_type new_node_size) {
    assert(iter.node_ == root());
    node_type *old_root = iter.node_;
    node_type *new_root = iter.node_ = new_leaf_root_node(new_node_size);
    transfer_and_delete(old_root, new_root);
    mutable_root() = mutable_rightmost() = new_root;
  };

  bool replaced_node = false;
  if (iter.node_->count() == max_count) {
    // Make room in the leaf for the new item.
    if (max_count < kNodeSlots) {
      // Insertion into the root where the root is smaller than the full node
      // size. Simply grow the size of the root node.
      replace_leaf_root_node(static_cast<field_type>(
          (std::min)(static_cast<int>(kNodeSlots), 2 * max_count)));
      replaced_node = true;
    } else {
      rebalance_or_split(&iter);
    }
  }
  (void)replaced_node;
#if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
    defined(ABSL_HAVE_HWADDRESS_SANITIZER)
  if (!replaced_node) {
    assert(iter.node_->is_leaf());
    if (iter.node_->is_root()) {
      replace_leaf_root_node(max_count);
    } else {
      node_type *old_node = iter.node_;
      const bool was_rightmost = rightmost() == old_node;
      const bool was_leftmost = leftmost() == old_node;
      node_type *parent = old_node->parent();
      const field_type position = old_node->position();
      node_type *new_node = iter.node_ = new_leaf_node(position, parent);
      parent->set_child_noupdate_position(position, new_node);
      transfer_and_delete(old_node, new_node);
      if (was_rightmost) mutable_rightmost() = new_node;
      // The leftmost node is stored as the parent of the root node.
      if (was_leftmost) root()->set_parent(new_node);
    }
  }
#endif
  iter.node_->emplace_value(static_cast<field_type>(iter.position_), alloc,
                            std::forward<Args>(args)...);
  assert(
      iter.node_->is_ordered_correctly(static_cast<field_type>(iter.position_),
                                       original_key_compare(key_comp())) &&
      "If this assert fails, then either (1) the comparator may violate "
      "transitivity, i.e. comp(a,b) && comp(b,c) -> comp(a,c) (see "
      "https://en.cppreference.com/w/cpp/named_req/Compare), or (2) a "
      "key may have been mutated after it was inserted into the tree.");
  ++size_;
  iter.update_generation();
  return iter;
}

template <typename P>
template <typename K>
inline auto btree<P>::internal_locate(const K &key) const
    -> SearchResult<iterator, is_key_compare_to::value> {
  iterator iter(const_cast<node_type *>(root()));
  for (;;) {
    SearchResult<size_type, is_key_compare_to::value> res =
        iter.node_->lower_bound(key, key_comp());
    iter.position_ = static_cast<int>(res.value);
    if (res.IsEq()) {
      return {iter, MatchKind::kEq};
    }
    // Note: in the non-key-compare-to case, we don't need to walk all the way
    // down the tree if the keys are equal, but determining equality would
    // require doing an extra comparison on each node on the way down, and we
    // will need to go all the way to the leaf node in the expected case.
    if (iter.node_->is_leaf()) {
      break;
    }
    iter.node_ = iter.node_->child(static_cast<field_type>(iter.position_));
  }
  // Note: in the non-key-compare-to case, the key may actually be equivalent
  // here (and the MatchKind::kNe is ignored).
  return {iter, MatchKind::kNe};
}

template <typename P>
template <typename K>
auto btree<P>::internal_lower_bound(const K &key) const
    -> SearchResult<iterator, is_key_compare_to::value> {
  if (!params_type::template can_have_multiple_equivalent_keys<K>()) {
    SearchResult<iterator, is_key_compare_to::value> ret = internal_locate(key);
    ret.value = internal_last(ret.value);
    return ret;
  }
  iterator iter(const_cast<node_type *>(root()));
  SearchResult<size_type, is_key_compare_to::value> res;
  bool seen_eq = false;
  for (;;) {
    res = iter.node_->lower_bound(key, key_comp());
    iter.position_ = static_cast<int>(res.value);
    if (iter.node_->is_leaf()) {
      break;
    }
    seen_eq = seen_eq || res.IsEq();
    iter.node_ = iter.node_->child(static_cast<field_type>(iter.position_));
  }
  if (res.IsEq()) return {iter, MatchKind::kEq};
  return {internal_last(iter), seen_eq ? MatchKind::kEq : MatchKind::kNe};
}

template <typename P>
template <typename K>
auto btree<P>::internal_upper_bound(const K &key) const -> iterator {
  iterator iter(const_cast<node_type *>(root()));
  for (;;) {
    iter.position_ = static_cast<int>(iter.node_->upper_bound(key, key_comp()));
    if (iter.node_->is_leaf()) {
      break;
    }
    iter.node_ = iter.node_->child(static_cast<field_type>(iter.position_));
  }
  return internal_last(iter);
}

template <typename P>
template <typename K>
auto btree<P>::internal_find(const K &key) const -> iterator {
  SearchResult<iterator, is_key_compare_to::value> res = internal_locate(key);
  if (res.HasMatch()) {
    if (res.IsEq()) {
      return res.value;
    }
  } else {
    const iterator iter = internal_last(res.value);
    if (iter.node_ != nullptr && !compare_keys(key, iter.key())) {
      return iter;
    }
  }
  return {nullptr, 0};
}

template <typename P>
typename btree<P>::size_type btree<P>::internal_verify(
    const node_type *node, const key_type *lo, const key_type *hi) const {
  assert(node->count() > 0);
  assert(node->count() <= node->max_count());
  if (lo) {
    assert(!compare_keys(node->key(node->start()), *lo));
  }
  if (hi) {
    assert(!compare_keys(*hi, node->key(node->finish() - 1)));
  }
  for (int i = node->start() + 1; i < node->finish(); ++i) {
    assert(!compare_keys(node->key(i), node->key(i - 1)));
  }
  size_type count = node->count();
  if (node->is_internal()) {
    for (field_type i = node->start(); i <= node->finish(); ++i) {
      assert(node->child(i) != nullptr);
      assert(node->child(i)->parent() == node);
      assert(node->child(i)->position() == i);
      count += internal_verify(node->child(i),
                               i == node->start() ? lo : &node->key(i - 1),
                               i == node->finish() ? hi : &node->key(i));
    }
  }
  return count;
}

struct btree_access {
  template <typename BtreeContainer, typename Pred>
  static auto erase_if(BtreeContainer &container, Pred pred) ->
      typename BtreeContainer::size_type {
    const auto initial_size = container.size();
    auto &tree = container.tree_;
    auto *alloc = tree.mutable_allocator();
    for (auto it = container.begin(); it != container.end();) {
      if (!pred(*it)) {
        ++it;
        continue;
      }
      auto *node = it.node_;
      if (node->is_internal()) {
        // Handle internal nodes normally.
        it = container.erase(it);
        continue;
      }
      // If this is a leaf node, then we do all the erases from this node
      // at once before doing rebalancing.

      // The current position to transfer slots to.
      int to_pos = it.position_;
      node->value_destroy(it.position_, alloc);
      while (++it.position_ < node->finish()) {
        it.update_generation();
        if (pred(*it)) {
          node->value_destroy(it.position_, alloc);
        } else {
          node->transfer(node->slot(to_pos++), node->slot(it.position_), alloc);
        }
      }
      const int num_deleted = node->finish() - to_pos;
      tree.size_ -= num_deleted;
      node->set_finish(to_pos);
      it.position_ = to_pos;
      it = tree.rebalance_after_delete(it);
    }
    return initial_size - container.size();
  }
};

#undef ABSL_BTREE_ENABLE_GENERATIONS

}  // namespace container_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_CONTAINER_INTERNAL_BTREE_H_
*õ
‹soong/.intermediates/external/abseil-cpp/absl_strings_str_format_internal_hdrs/gen/my_include_dir/absl/strings/internal/str_format/output.hä// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Output extension hooks for the Format library.
// `internal::InvokeFlush` calls the appropriate flush function for the
// specified output argument.
// `BufferRawSink` is a simple output sink for a char buffer. Used by SnprintF.
// `FILERawSink` is a std::FILE* based sink. Used by PrintF and FprintF.

#ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_OUTPUT_H_
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_OUTPUT_H_

#include <cstdio>
#include <ios>
#include <ostream>
#include <string>

#include "absl/base/port.h"
#include "absl/strings/string_view.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace str_format_internal {

// RawSink implementation that writes into a char* buffer.
// It will not overflow the buffer, but will keep the total count of chars
// that would have been written.
class BufferRawSink {
 public:
  BufferRawSink(char* buffer, size_t size) : buffer_(buffer), size_(size) {}

  size_t total_written() const { return total_written_; }
  void Write(string_view v);

 private:
  char* buffer_;
  size_t size_;
  size_t total_written_ = 0;
};

// RawSink implementation that writes into a FILE*.
// It keeps track of the total number of bytes written and any error encountered
// during the writes.
class FILERawSink {
 public:
  explicit FILERawSink(std::FILE* output) : output_(output) {}

  void Write(string_view v);

  size_t count() const { return count_; }
  int error() const { return error_; }

 private:
  std::FILE* output_;
  int error_ = 0;
  size_t count_ = 0;
};

// Provide RawSink integration with common types from the STL.
inline void AbslFormatFlush(std::string* out, string_view s) {
  out->append(s.data(), s.size());
}
inline void AbslFormatFlush(std::ostream* out, string_view s) {
  out->write(s.data(), static_cast<std::streamsize>(s.size()));
}

inline void AbslFormatFlush(FILERawSink* sink, string_view v) {
  sink->Write(v);
}

inline void AbslFormatFlush(BufferRawSink* sink, string_view v) {
  sink->Write(v);
}

// This is a SFINAE to get a better compiler error message when the type
// is not supported.
template <typename T>
auto InvokeFlush(T* out, string_view s) -> decltype(AbslFormatFlush(out, s)) {
  AbslFormatFlush(out, s);
}

}  // namespace str_format_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_STR_FORMAT_OUTPUT_H_
*¹Ã
‚soong/.intermediates/external/abseil-cpp/absl_strings_cord_internal_hdrs/gen/my_include_dir/absl/strings/internal/cord_rep_btree.h°Â// Copyright 2021 The Abseil Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_H_
#define ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_H_

#include <cassert>
#include <cstdint>
#include <iosfwd>

#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/optimization.h"
#include "absl/strings/internal/cord_data_edge.h"
#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_flat.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {

// `SetCordBtreeExhaustiveValidation()` can be set to force exhaustive
// validation in debug assertions, and code that calls `IsValid()`
// explicitly. By default, assertions should be relatively cheap and
// AssertValid() can easily lead to O(n^2) complexity as recursive / full tree
// validation is O(n).
void SetCordBtreeExhaustiveValidation(bool do_exaustive_validation);
bool IsCordBtreeExhaustiveValidationEnabled();

class CordRepBtreeNavigator;

// CordRepBtree is as the name implies a btree implementation of a Cordrep tree.
// Data is stored at the leaf level only, non leaf nodes contain down pointers
// only. Allowed types of data edges are FLAT, EXTERNAL and SUBSTRINGs of FLAT
// or EXTERNAL nodes. The implementation allows for data to be added to either
// end of the tree only, it does not provide any 'insert' logic. This has the
// benefit that we can expect good fill ratios: all nodes except the outer
// 'legs' will have 100% fill ratios for trees built using Append/Prepend
// methods. Merged trees will typically have a fill ratio well above 50% as in a
// similar fashion, one side of the merged tree will typically have a 100% fill
// ratio, and the 'open' end will average 50%. All operations are O(log(n)) or
// better, and the tree never needs balancing.
//
// All methods accepting a CordRep* or CordRepBtree* adopt a reference on that
// input unless explicitly stated otherwise. All functions returning a CordRep*
// or CordRepBtree* instance transfer a reference back to the caller.
// Simplified, callers both 'donate' and 'consume' a reference count on each
// call, simplifying the API. An example of building a tree:
//
//   CordRepBtree* tree = CordRepBtree::Create(MakeFlat("Hello"));
//   tree = CordRepBtree::Append(tree, MakeFlat("world"));
//
// In the above example, all inputs are consumed, making each call affecting
// `tree` reference count neutral. The returned `tree` value can be different
// from the input if the input is shared with other threads, or if the tree
// grows in height, but callers typically never have to concern themselves with
// that and trust that all methods DTRT at all times.
class CordRepBtree : public CordRep {
 public:
  // EdgeType identifies `front` and `back` enum values.
  // Various implementations in CordRepBtree such as `Add` and `Edge` are
  // generic and templated on operating on either of the boundary edges.
  // For more information on the possible edges contained in a CordRepBtree
  // instance see the documentation for `edges_`.
  enum class EdgeType { kFront, kBack };

  // Convenience constants into `EdgeType`
  static constexpr EdgeType kFront = EdgeType::kFront;
  static constexpr EdgeType kBack = EdgeType::kBack;

  // Maximum number of edges: based on experiments and performance data, we can
  // pick suitable values resulting in optimum cacheline aligned values. The
  // preferred values are based on 64-bit systems where we aim to align this
  // class onto 64 bytes, i.e.:  6 = 64 bytes, 14 = 128 bytes, etc.
  // TODO(b/192061034): experiment with alternative sizes.
  static constexpr size_t kMaxCapacity = 6;

  // Reasonable maximum height of the btree. We can expect a fill ratio of at
  // least 50%: trees are always expanded at the front or back. Concatenating
  // trees will then typically fold at the top most node, where the lower nodes
  // are at least at capacity on one side of joined inputs. At a lower fill
  // rate of 4 edges per node, we have capacity for ~16 million leaf nodes.
  // We will fail / abort if an application ever exceeds this height, which
  // should be extremely rare (near impossible) and be an indication of an
  // application error: we do not assume it reasonable for any application to
  // operate correctly with such monster trees.
  // Another compelling reason for the number `12` is that any contextual stack
  // required for navigation or insertion requires 12 words and 12 bytes, which
  // fits inside 2 cache lines with some room to spare, and is reasonable as a
  // local stack variable compared to Cord's current near 400 bytes stack use.
  // The maximum `height` value of a node is then `kMaxDepth - 1` as node height
  // values start with a value of 0 for leaf nodes.
  static constexpr size_t kMaxDepth = 12;
  // See comments on height() for why this is an int and not a size_t.
  static constexpr int kMaxHeight = static_cast<int>(kMaxDepth - 1);

  // `Action` defines the action for unwinding changes done at the btree's leaf
  // level that need to be propagated up to the parent node(s). Each operation
  // on a node has an effect / action defined as follows:
  // - kSelf
  //   The operation (add / update, etc) was performed directly on the node as
  //   the node is private to the current thread (i.e.: not shared directly or
  //   indirectly through a refcount > 1). Changes can be propagated directly to
  //   all parent nodes as all parent nodes are also then private to the current
  //   thread.
  // - kCopied
  //   The operation (add / update, etc) was performed on a copy of the original
  //   node, as the node is (potentially) directly or indirectly shared with
  //   other threads. Changes need to be propagated into the parent nodes where
  //   the old down pointer must be unreffed and replaced with this new copy.
  //   Such changes to parent nodes may themselves require a copy if the parent
  //   node is also shared. A kCopied action can propagate all the way to the
  //   top node where we then must unref the `tree` input provided by the
  //   caller, and return the new copy.
  // - kPopped
  //   The operation (typically add) could not be satisfied due to insufficient
  //   capacity in the targeted node, and a new 'leg' was created that needs to
  //   be added into the parent node. For example, adding a FLAT inside a leaf
  //   node that is at capacity will create a new leaf node containing that
  //   FLAT, that needs to be 'popped' up the btree. Such 'pop' actions can
  //   cascade up the tree if parent nodes are also at capacity. A 'Popped'
  //   action propagating all the way to the top of the tree will result in
  //   the tree becoming one level higher than the current tree through a final
  //   `CordRepBtree::New(tree, popped)` call, resulting in a new top node
  //   referencing the old tree and the new (fully popped upwards) 'leg'.
  enum Action { kSelf, kCopied, kPopped };

  // Result of an operation on a node. See the `Action` enum for details.
  struct OpResult {
    CordRepBtree* tree;
    Action action;
  };

  // Return value of the CopyPrefix and CopySuffix methods which can
  // return a node or data edge at any height inside the tree.
  // A height of 0 defines the lowest (leaf) node, a height of -1 identifies
  // `edge` as being a plain data node: EXTERNAL / FLAT or SUBSTRING thereof.
  struct CopyResult {
    CordRep* edge;
    int height;
  };

  // Logical position inside a node:
  // - index: index of the edge.
  // - n: size or offset value depending on context.
  struct Position {
    size_t index;
    size_t n;
  };

  // Creates a btree from the given input. Adopts a ref of `rep`.
  // If the input `rep` is itself a btree, i.e., `IsBtree()`, then this
  // function immediately returns `rep->btree()`. If the input is a valid data
  // edge (see IsDataEdge()), then a new leaf node is returned containing `rep`
  // as the sole data edge. Else, the input is assumed to be a (legacy) concat
  // tree, and the input is consumed and transformed into a btree().
  static CordRepBtree* Create(CordRep* rep);

  // Destroys the provided tree. Should only be called by cord internal API's,
  // typically after a ref_count.Decrement() on the last reference count.
  static void Destroy(CordRepBtree* tree);

  // Destruction
  static void Delete(CordRepBtree* tree) { delete tree; }

  // Use CordRep::Unref() as we overload for absl::Span<CordRep* const>.
  using CordRep::Unref;

  // Unrefs all edges in `edges` which are assumed to be 'likely one'.
  static void Unref(absl::Span<CordRep* const> edges);

  // Appends / Prepends an existing CordRep instance to this tree.
  // The below methods accept three types of input:
  // 1) `rep` is a data node (See `IsDataNode` for valid data edges).
  // `rep` is appended or prepended to this tree 'as is'.
  // 2) `rep` is a BTREE.
  // `rep` is merged into `tree` respecting the Append/Prepend order.
  // 3) `rep` is some other (legacy) type.
  // `rep` is converted in place and added to `tree`
  // Requires `tree` and `rep` to be not null.
  static CordRepBtree* Append(CordRepBtree* tree, CordRep* rep);
  static CordRepBtree* Prepend(CordRepBtree* tree, CordRep* rep);

  // Append/Prepend the data in `data` to this tree.
  // The `extra` parameter defines how much extra capacity should be allocated
  // for any additional FLAT being allocated. This is an optimization hint from
  // the caller. For example, a caller may need to add 2 string_views of data
  // "abc" and "defghi" which are not consecutive. The caller can in this case
  // invoke `AddData(tree, "abc", 6)`, and any newly added flat is allocated
  // where possible with at least 6 bytes of extra capacity beyond `length`.
  // This helps avoiding data getting fragmented over multiple flats.
  // There is no limit on the size of `data`. If `data` can not be stored inside
  // a single flat, then the function will iteratively add flats until all data
  // has been consumed and appended or prepended to the tree.
  static CordRepBtree* Append(CordRepBtree* tree, string_view data,
                              size_t extra = 0);
  static CordRepBtree* Prepend(CordRepBtree* tree, string_view data,
                               size_t extra = 0);

  // Returns a new tree, containing `n` bytes of data from this instance
  // starting at offset `offset`. Where possible, the returned tree shares
  // (re-uses) data edges and nodes with this instance to minimize the
  // combined memory footprint of both trees.
  // Requires `offset + n <= length`. Returns `nullptr` if `n` is zero.
  CordRep* SubTree(size_t offset, size_t n);

  // Removes `n` trailing bytes from `tree`, and returns the resulting tree
  // or data edge. Returns `tree` if n is zero, and nullptr if n == length.
  // This function is logically identical to:
  //   result = tree->SubTree(0, tree->length - n);
  //   Unref(tree);
  //   return result;
  // However, the actual implementation will as much as possible perform 'in
  // place' modifications on the tree on all nodes and edges that are mutable.
  // For example, in a fully privately owned tree with the last edge being a
  // flat of length 12, RemoveSuffix(1) will simply set the length of that data
  // edge to 11, and reduce the length of all nodes on the edge path by 1.
  static CordRep* RemoveSuffix(CordRepBtree* tree, size_t n);

  // Returns the character at the given offset.
  char GetCharacter(size_t offset) const;

  // Returns true if this node holds a single data edge, and if so, sets
  // `fragment` to reference the contained data. `fragment` is an optional
  // output parameter and allowed to be null.
  bool IsFlat(absl::string_view* fragment) const;

  // Returns true if the data of `n` bytes starting at offset `offset`
  // is contained in a single data edge, and if so, sets fragment to reference
  // the contained data. `fragment` is an optional output parameter and allowed
  // to be null.
  bool IsFlat(size_t offset, size_t n, absl::string_view* fragment) const;

  // Returns a span (mutable range of bytes) of up to `size` bytes into the
  // last FLAT data edge inside this tree under the following conditions:
  // - none of the nodes down into the FLAT node are shared.
  // - the last data edge in this tree is a non-shared FLAT.
  // - the referenced FLAT has additional capacity available.
  // If all these conditions are met, a non-empty span is returned, and the
  // length of the flat node and involved tree nodes have been increased by
  // `span.length()`. The caller is responsible for immediately assigning values
  // to all uninitialized data reference by the returned span.
  // Requires `this->refcount.IsOne()`: this function forces the caller to do
  // this fast path check on the top level node, as this is the most commonly
  // shared node of a cord tree.
  Span<char> GetAppendBuffer(size_t size);

  // Extracts the right-most data edge from this tree iff:
  // - the tree and all internal edges to the right-most node are not shared.
  // - the right-most node is a FLAT node and not shared.
  // - the right-most node has at least the desired extra capacity.
  //
  // Returns {tree, nullptr} if any of the above conditions are not met.
  // This method effectively removes data from the tree. The intent of this
  // method is to allow applications appending small string data to use
  // pre-existing capacity, and add the modified rep back to the tree.
  //
  // Simplified such code would look similar to this:
  //   void MyTreeBuilder::Append(string_view data) {
  //     ExtractResult result = CordRepBtree::ExtractAppendBuffer(tree_, 1);
  //     if (CordRep* rep = result.extracted) {
  //       size_t available = rep->Capacity() - rep->length;
  //       size_t n = std::min(data.size(), n);
  //       memcpy(rep->Data(), data.data(), n);
  //       rep->length += n;
  //       data.remove_prefix(n);
  //       if (!result.tree->IsBtree()) {
  //         tree_ = CordRepBtree::Create(result.tree);
  //       }
  //       tree_ = CordRepBtree::Append(tree_, rep);
  //     }
  //     ...
  //     // Remaining edge in `result.tree`.
  //   }
  static ExtractResult ExtractAppendBuffer(CordRepBtree* tree,
                                           size_t extra_capacity = 1);

  // Returns the `height` of the tree. The height of a tree is limited to
  // kMaxHeight. `height` is implemented as an `int` as in some places we
  // use negative (-1) values for 'data edges'.
  int height() const { return static_cast<int>(storage[0]); }

  // Properties: begin, back, end, front/back boundary indexes.
  size_t begin() const { return static_cast<size_t>(storage[1]); }
  size_t back() const { return static_cast<size_t>(storage[2]) - 1; }
  size_t end() const { return static_cast<size_t>(storage[2]); }
  size_t index(EdgeType edge) const {
    return edge == kFront ? begin() : back();
  }

  // Properties: size and capacity.
  // `capacity` contains the current capacity of this instance, where
  // `kMaxCapacity` contains the maximum capacity of a btree node.
  // For now, `capacity` and `kMaxCapacity` return the same value, but this may
  // change in the future if we see benefit in dynamically sizing 'small' nodes
  // to 'large' nodes for large data trees.
  size_t size() const { return end() - begin(); }
  size_t capacity() const { return kMaxCapacity; }

  // Edge access
  inline CordRep* Edge(size_t index) const;
  inline CordRep* Edge(EdgeType edge_type) const;
  inline absl::Span<CordRep* const> Edges() const;
  inline absl::Span<CordRep* const> Edges(size_t begin, size_t end) const;

  // Returns reference to the data edge at `index`.
  // Requires this instance to be a leaf node, and `index` to be valid index.
  inline absl::string_view Data(size_t index) const;

  // Diagnostics: returns true if `tree` is valid and internally consistent.
  // If `shallow` is false, then the provided top level node and all child nodes
  // below it are recursively checked. If `shallow` is true, only the provided
  // node in `tree` and the cumulative length, type and height of the direct
  // child nodes of `tree` are checked. The value of `shallow` is ignored if the
  // internal `cord_btree_exhaustive_validation` diagnostics variable is true,
  // in which case the performed validations works as if `shallow` were false.
  // This function is intended for debugging and testing purposes only.
  static bool IsValid(const CordRepBtree* tree, bool shallow = false);

  // Diagnostics: asserts that the provided tree is valid.
  // `AssertValid()` performs a shallow validation by default. `shallow` can be
  // set to false in which case an exhaustive validation is performed. This
  // function is implemented in terms of calling `IsValid()` and asserting the
  // return value to be true. See `IsValid()` for more information.
  // This function is intended for debugging and testing purposes only.
  static CordRepBtree* AssertValid(CordRepBtree* tree, bool shallow = true);
  static const CordRepBtree* AssertValid(const CordRepBtree* tree,
                                         bool shallow = true);

  // Diagnostics: dump the contents of this tree to `stream`.
  // This function is intended for debugging and testing purposes only.
  static void Dump(const CordRep* rep, std::ostream& stream);
  static void Dump(const CordRep* rep, absl::string_view label,
                   std::ostream& stream);
  static void Dump(const CordRep* rep, absl::string_view label,
                   bool include_contents, std::ostream& stream);

  // Adds the edge `edge` to this node if possible. `owned` indicates if the
  // current node is potentially shared or not with other threads. Returns:
  // - {kSelf, <this>}
  //   The edge was directly added to this node.
  // - {kCopied, <node>}
  //   The edge was added to a copy of this node.
  // - {kPopped, New(edge, height())}
  //   A new leg with the edge was created as this node has no extra capacity.
  template <EdgeType edge_type>
  inline OpResult AddEdge(bool owned, CordRep* edge, size_t delta);

  // Replaces the front or back edge with the provided new edge. Returns:
  // - {kSelf, <this>}
  //   The edge was directly set in this node. The old edge is unreffed.
  // - {kCopied, <node>}
  //   A copy of this node was created with the new edge value.
  // In both cases, the function adopts a reference on `edge`.
  template <EdgeType edge_type>
  OpResult SetEdge(bool owned, CordRep* edge, size_t delta);

  // Creates a new empty node at the specified height.
  static CordRepBtree* New(int height = 0);

  // Creates a new node containing `rep`, with the height being computed
  // automatically based on the type of `rep`.
  static CordRepBtree* New(CordRep* rep);

  // Creates a new node containing both `front` and `back` at height
  // `front.height() + 1`. Requires `back.height() == front.height()`.
  static CordRepBtree* New(CordRepBtree* front, CordRepBtree* back);

  // Creates a fully balanced tree from the provided tree by rebuilding a new
  // tree from all data edges in the input. This function is automatically
  // invoked internally when the tree exceeds the maximum height.
  static CordRepBtree* Rebuild(CordRepBtree* tree);

 private:
  CordRepBtree() = default;
  ~CordRepBtree() = default;

  // Initializes the main properties `tag`, `begin`, `end`, `height`.
  inline void InitInstance(int height, size_t begin = 0, size_t end = 0);

  // Direct property access begin / end
  void set_begin(size_t begin) { storage[1] = static_cast<uint8_t>(begin); }
  void set_end(size_t end) { storage[2] = static_cast<uint8_t>(end); }

  // Decreases the value of `begin` by `n`, and returns the new value. Notice
  // how this returns the new value unlike atomic::fetch_add which returns the
  // old value. This is because this is used to prepend edges at 'begin - 1'.
  size_t sub_fetch_begin(size_t n) {
    storage[1] -= static_cast<uint8_t>(n);
    return storage[1];
  }

  // Increases the value of `end` by `n`, and returns the previous value. This
  // function is typically used to append edges at 'end'.
  size_t fetch_add_end(size_t n) {
    const uint8_t current = storage[2];
    storage[2] = static_cast<uint8_t>(current + n);
    return current;
  }

  // Returns the index of the last edge starting on, or before `offset`, with
  // `n` containing the relative offset of `offset` inside that edge.
  // Requires `offset` < length.
  Position IndexOf(size_t offset) const;

  // Returns the index of the last edge starting before `offset`, with `n`
  // containing the relative offset of `offset` inside that edge.
  // This function is useful to find the edges for some span of bytes ending at
  // `offset` (i.e., `n` bytes). For example:
  //
  //   Position pos = IndexBefore(n)
  //   edges = Edges(begin(), pos.index)     // All full edges (may be empty)
  //   last = Sub(Edge(pos.index), 0, pos.n) // Last partial edge (may be empty)
  //
  // Requires 0 < `offset` <= length.
  Position IndexBefore(size_t offset) const;

  // Returns the index of the edge ending at (or on) length `length`, and the
  // number of bytes inside that edge up to `length`. For example, if we have a
  // Node with 2 edges, one of 10 and one of 20 long, then IndexOfLength(27)
  // will return {1, 17}, and IndexOfLength(10) will return {0, 10}.
  Position IndexOfLength(size_t n) const;

  // Identical to the above function except starting from the position `front`.
  // This function is equivalent to `IndexBefore(front.n + offset)`, with
  // the difference that this function is optimized to start at `front.index`.
  Position IndexBefore(Position front, size_t offset) const;

  // Returns the index of the edge directly beyond the edge containing offset
  // `offset`, with `n` containing the distance of that edge from `offset`.
  // This function is useful for iteratively finding suffix nodes and remaining
  // partial bytes in left-most suffix nodes as for example in CopySuffix.
  // Requires `offset` < length.
  Position IndexBeyond(size_t offset) const;

  // Creates a new leaf node containing as much data as possible from `data`.
  // The data is added either forwards or reversed depending on `edge_type`.
  // Callers must check the length of the returned node to determine if all data
  // was copied or not.
  // See the `Append/Prepend` function for the meaning and purpose of `extra`.
  template <EdgeType edge_type>
  static CordRepBtree* NewLeaf(absl::string_view data, size_t extra);

  // Creates a raw copy of this Btree node with the specified length, copying
  // all properties, but without adding any references to existing edges.
  CordRepBtree* CopyRaw(size_t new_length) const;

  // Creates a full copy of this Btree node, adding a reference on all edges.
  CordRepBtree* Copy() const;

  // Creates a partial copy of this Btree node, copying all edges up to `end`,
  // adding a reference on each copied edge, and sets the length of the newly
  // created copy to `new_length`.
  CordRepBtree* CopyBeginTo(size_t end, size_t new_length) const;

  // Returns a tree containing the edges [tree->begin(), end) and length
  // of `new_length`. This method consumes a reference on the provided
  // tree, and logically performs the following operation:
  //   result = tree->CopyBeginTo(end, new_length);
  //   CordRep::Unref(tree);
  //   return result;
  static CordRepBtree* ConsumeBeginTo(CordRepBtree* tree, size_t end,
                                      size_t new_length);

  // Creates a partial copy of this Btree node, copying all edges starting at
  // `begin`, adding a reference on each copied edge, and sets the length of
  // the newly created copy to `new_length`.
  CordRepBtree* CopyToEndFrom(size_t begin, size_t new_length) const;

  // Extracts and returns the front edge from the provided tree.
  // This method consumes a reference on the provided tree, and logically
  // performs the following operation:
  //   edge = CordRep::Ref(tree->Edge(kFront));
  //   CordRep::Unref(tree);
  //   return edge;
  static CordRep* ExtractFront(CordRepBtree* tree);

  // Returns a tree containing the result of appending `right` to `left`.
  static CordRepBtree* MergeTrees(CordRepBtree* left, CordRepBtree* right);

  // Fallback functions for `Create()`, `Append()` and `Prepend()` which
  // deal with legacy / non conforming input, i.e.: CONCAT trees.
  static CordRepBtree* CreateSlow(CordRep* rep);
  static CordRepBtree* AppendSlow(CordRepBtree*, CordRep* rep);
  static CordRepBtree* PrependSlow(CordRepBtree*, CordRep* rep);

  // Recursively rebuilds `tree` into `stack`. If 'consume` is set to true, the
  // function will consume a reference on `tree`. `stack` is a null terminated
  // array containing the new tree's state, with the current leaf node at
  // stack[0], and parent nodes above that, or null for 'top of tree'.
  static void Rebuild(CordRepBtree** stack, CordRepBtree* tree, bool consume);

  // Aligns existing edges to start at index 0, to allow for a new edge to be
  // added to the back of the current edges.
  inline void AlignBegin();

  // Aligns existing edges to end at `capacity`, to allow for a new edge to be
  // added in front of the current edges.
  inline void AlignEnd();

  // Adds the provided edge to this node.
  // Requires this node to have capacity for the edge. Realigns / moves
  // existing edges as needed to prepend or append the new edge.
  template <EdgeType edge_type>
  inline void Add(CordRep* rep);

  // Adds the provided edges to this node.
  // Requires this node to have capacity for the edges. Realigns / moves
  // existing edges as needed to prepend or append the new edges.
  template <EdgeType edge_type>
  inline void Add(absl::Span<CordRep* const>);

  // Adds data from `data` to this node until either all data has been consumed,
  // or there is no more capacity for additional flat nodes inside this node.
  // Requires the current node to be a leaf node, data to be non empty, and the
  // current node to have capacity for at least one more data edge.
  // Returns any remaining data from `data` that was not added, which is
  // depending on the edge type (front / back) either the remaining prefix of
  // suffix of the input.
  // See the `Append/Prepend` function for the meaning and purpose of `extra`.
  template <EdgeType edge_type>
  absl::string_view AddData(absl::string_view data, size_t extra);

  // Replace the front or back edge with the provided value.
  // Adopts a reference on `edge` and unrefs the old edge.
  template <EdgeType edge_type>
  inline void SetEdge(CordRep* edge);

  // Returns a partial copy of the current tree containing the first `n` bytes
  // of data. `CopyResult` contains both the resulting edge and its height. The
  // resulting tree may be less high than the current tree, or even be a single
  // matching data edge if `allow_folding` is set to true.
  // For example, if `n == 1`, then the result will be the single data edge, and
  // height will be set to -1 (one below the owning leaf node). If n == 0, this
  // function returns null. Requires `n <= length`
  CopyResult CopyPrefix(size_t n, bool allow_folding = true);

  // Returns a partial copy of the current tree containing all data starting
  // after `offset`. `CopyResult` contains both the resulting edge and its
  // height. The resulting tree may be less high than the current tree, or even
  // be a single matching data edge. For example, if `n == length - 1`, then the
  // result will be a single data edge, and height will be set to -1 (one below
  // the owning leaf node).
  // Requires `offset < length`
  CopyResult CopySuffix(size_t offset);

  // Returns a OpResult value of {this, kSelf} or {Copy(), kCopied}
  // depending on the value of `owned`.
  inline OpResult ToOpResult(bool owned);

  // Adds `rep` to the specified tree, returning the modified tree.
  template <EdgeType edge_type>
  static CordRepBtree* AddCordRep(CordRepBtree* tree, CordRep* rep);

  // Adds `data` to the specified tree, returning the modified tree.
  // See the `Append/Prepend` function for the meaning and purpose of `extra`.
  template <EdgeType edge_type>
  static CordRepBtree* AddData(CordRepBtree* tree, absl::string_view data,
                               size_t extra = 0);

  // Merges `src` into `dst` with `src` being added either before (kFront) or
  // after (kBack) `dst`. Requires the height of `dst` to be greater than or
  // equal to the height of `src`.
  template <EdgeType edge_type>
  static CordRepBtree* Merge(CordRepBtree* dst, CordRepBtree* src);

  // Fallback version of GetAppendBuffer for large trees: GetAppendBuffer()
  // implements an inlined version for trees of limited height (3 levels),
  // GetAppendBufferSlow implements the logic for large trees.
  Span<char> GetAppendBufferSlow(size_t size);

  // `edges_` contains all edges starting from this instance.
  // These are explicitly `child` edges only, a cord btree (or any cord tree in
  // that respect) does not store `parent` pointers anywhere: multiple trees /
  // parents can reference the same shared child edge. The type of these edges
  // depends on the height of the node. `Leaf nodes` (height == 0) contain `data
  // edges` (external or flat nodes, or sub-strings thereof). All other nodes
  // (height > 0) contain pointers to BTREE nodes with a height of `height - 1`.
  CordRep* edges_[kMaxCapacity];

  friend class CordRepBtreeTestPeer;
  friend class CordRepBtreeNavigator;
};

inline CordRepBtree* CordRep::btree() {
  assert(IsBtree());
  return static_cast<CordRepBtree*>(this);
}

inline const CordRepBtree* CordRep::btree() const {
  assert(IsBtree());
  return static_cast<const CordRepBtree*>(this);
}

inline void CordRepBtree::InitInstance(int height, size_t begin, size_t end) {
  tag = BTREE;
  storage[0] = static_cast<uint8_t>(height);
  storage[1] = static_cast<uint8_t>(begin);
  storage[2] = static_cast<uint8_t>(end);
}

inline CordRep* CordRepBtree::Edge(size_t index) const {
  assert(index >= begin());
  assert(index < end());
  return edges_[index];
}

inline CordRep* CordRepBtree::Edge(EdgeType edge_type) const {
  return edges_[edge_type == kFront ? begin() : back()];
}

inline absl::Span<CordRep* const> CordRepBtree::Edges() const {
  return {edges_ + begin(), size()};
}

inline absl::Span<CordRep* const> CordRepBtree::Edges(size_t begin,
                                                      size_t end) const {
  assert(begin <= end);
  assert(begin >= this->begin());
  assert(end <= this->end());
  return {edges_ + begin, static_cast<size_t>(end - begin)};
}

inline absl::string_view CordRepBtree::Data(size_t index) const {
  assert(height() == 0);
  return EdgeData(Edge(index));
}

inline CordRepBtree* CordRepBtree::New(int height) {
  CordRepBtree* tree = new CordRepBtree;
  tree->length = 0;
  tree->InitInstance(height);
  return tree;
}

inline CordRepBtree* CordRepBtree::New(CordRep* rep) {
  CordRepBtree* tree = new CordRepBtree;
  int height = rep->IsBtree() ? rep->btree()->height() + 1 : 0;
  tree->length = rep->length;
  tree->InitInstance(height, /*begin=*/0, /*end=*/1);
  tree->edges_[0] = rep;
  return tree;
}

inline CordRepBtree* CordRepBtree::New(CordRepBtree* front,
                                       CordRepBtree* back) {
  assert(front->height() == back->height());
  CordRepBtree* tree = new CordRepBtree;
  tree->length = front->length + back->length;
  tree->InitInstance(front->height() + 1, /*begin=*/0, /*end=*/2);
  tree->edges_[0] = front;
  tree->edges_[1] = back;
  return tree;
}

inline void CordRepBtree::Unref(absl::Span<CordRep* const> edges) {
  for (CordRep* edge : edges) {
    if (ABSL_PREDICT_FALSE(!edge->refcount.Decrement())) {
      CordRep::Destroy(edge);
    }
  }
}

inline CordRepBtree* CordRepBtree::CopyRaw(size_t new_length) const {
  CordRepBtree* tree = new CordRepBtree;

  // `length` and `refcount` are the first members of `CordRepBtree`.
  // We initialize `length` using the given length, have `refcount` be set to
  // ref = 1 through its default constructor, and copy all data beyond
  // 'refcount' which starts with `tag` using a single memcpy: all contents
  // except `refcount` is trivially copyable, and the compiler does not
  // efficiently coalesce member-wise copy of these members.
  // See https://gcc.godbolt.org/z/qY8zsca6z
  // LINT.IfChange(copy_raw)
  tree->length = new_length;
  uint8_t* dst = &tree->tag;
  const uint8_t* src = &tag;
  const ptrdiff_t offset = src - reinterpret_cast<const uint8_t*>(this);
  memcpy(dst, src, sizeof(CordRepBtree) - static_cast<size_t>(offset));
  return tree;
  // LINT.ThenChange()
}

inline CordRepBtree* CordRepBtree::Copy() const {
  CordRepBtree* tree = CopyRaw(length);
  for (CordRep* rep : Edges()) CordRep::Ref(rep);
  return tree;
}

inline CordRepBtree* CordRepBtree::CopyToEndFrom(size_t begin,
                                                 size_t new_length) const {
  assert(begin >= this->begin());
  assert(begin <= this->end());
  CordRepBtree* tree = CopyRaw(new_length);
  tree->set_begin(begin);
  for (CordRep* edge : tree->Edges()) CordRep::Ref(edge);
  return tree;
}

inline CordRepBtree* CordRepBtree::CopyBeginTo(size_t end,
                                               size_t new_length) const {
  assert(end <= capacity());
  assert(end >= this->begin());
  CordRepBtree* tree = CopyRaw(new_length);
  tree->set_end(end);
  for (CordRep* edge : tree->Edges()) CordRep::Ref(edge);
  return tree;
}

inline void CordRepBtree::AlignBegin() {
  // The below code itself does not need to be fast as typically we have
  // mono-directional append/prepend calls, and `begin` / `end` are typically
  // adjusted no more than once. But we want to avoid potential register clobber
  // effects, making the compiler emit register save/store/spills, and minimize
  // the size of code.
  const size_t delta = begin();
  if (ABSL_PREDICT_FALSE(delta != 0)) {
    const size_t new_end = end() - delta;
    set_begin(0);
    set_end(new_end);
    // TODO(mvels): we can write this using 2 loads / 2 stores depending on
    // total size for the kMaxCapacity = 6 case. I.e., we can branch (switch) on
    // size, and then do overlapping load/store of up to 4 pointers (inlined as
    // XMM, YMM or ZMM load/store) and up to 2 pointers (XMM / YMM), which is a)
    // compact and b) not clobbering any registers.
    ABSL_ASSUME(new_end <= kMaxCapacity);
#ifdef __clang__
#pragma unroll 1
#endif
    for (size_t i = 0; i < new_end; ++i) {
      edges_[i] = edges_[i + delta];
    }
  }
}

inline void CordRepBtree::AlignEnd() {
  // See comments in `AlignBegin` for motivation on the hand-rolled for loops.
  const size_t delta = capacity() - end();
  if (delta != 0) {
    const size_t new_begin = begin() + delta;
    const size_t new_end = end() + delta;
    set_begin(new_begin);
    set_end(new_end);
    ABSL_ASSUME(new_end <= kMaxCapacity);
#ifdef __clang__
#pragma unroll 1
#endif
    for (size_t i = new_end - 1; i >= new_begin; --i) {
      edges_[i] = edges_[i - delta];
    }
  }
}

template <>
inline void CordRepBtree::Add<CordRepBtree::kBack>(CordRep* rep) {
  AlignBegin();
  edges_[fetch_add_end(1)] = rep;
}

template <>
inline void CordRepBtree::Add<CordRepBtree::kBack>(
    absl::Span<CordRep* const> edges) {
  AlignBegin();
  size_t new_end = end();
  for (CordRep* edge : edges) edges_[new_end++] = edge;
  set_end(new_end);
}

template <>
inline void CordRepBtree::Add<CordRepBtree::kFront>(CordRep* rep) {
  AlignEnd();
  edges_[sub_fetch_begin(1)] = rep;
}

template <>
inline void CordRepBtree::Add<CordRepBtree::kFront>(
    absl::Span<CordRep* const> edges) {
  AlignEnd();
  size_t new_begin = begin() - edges.size();
  set_begin(new_begin);
  for (CordRep* edge : edges) edges_[new_begin++] = edge;
}

template <CordRepBtree::EdgeType edge_type>
inline void CordRepBtree::SetEdge(CordRep* edge) {
  const int idx = edge_type == kFront ? begin() : back();
  CordRep::Unref(edges_[idx]);
  edges_[idx] = edge;
}

inline CordRepBtree::OpResult CordRepBtree::ToOpResult(bool owned) {
  return owned ? OpResult{this, kSelf} : OpResult{Copy(), kCopied};
}

inline CordRepBtree::Position CordRepBtree::IndexOf(size_t offset) const {
  assert(offset < length);
  size_t index = begin();
  while (offset >= edges_[index]->length) offset -= edges_[index++]->length;
  return {index, offset};
}

inline CordRepBtree::Position CordRepBtree::IndexBefore(size_t offset) const {
  assert(offset > 0);
  assert(offset <= length);
  size_t index = begin();
  while (offset > edges_[index]->length) offset -= edges_[index++]->length;
  return {index, offset};
}

inline CordRepBtree::Position CordRepBtree::IndexBefore(Position front,
                                                        size_t offset) const {
  size_t index = front.index;
  offset = offset + front.n;
  while (offset > edges_[index]->length) offset -= edges_[index++]->length;
  return {index, offset};
}

inline CordRepBtree::Position CordRepBtree::IndexOfLength(size_t n) const {
  assert(n <= length);
  size_t index = back();
  size_t strip = length - n;
  while (strip >= edges_[index]->length) strip -= edges_[index--]->length;
  return {index, edges_[index]->length - strip};
}

inline CordRepBtree::Position CordRepBtree::IndexBeyond(
    const size_t offset) const {
  // We need to find the edge which `starting offset` is beyond (>=)`offset`.
  // For this we can't use the `offset -= length` logic of IndexOf. Instead, we
  // track the offset of the `current edge` in `off`, which we increase as we
  // iterate over the edges until we find the matching edge.
  size_t off = 0;
  size_t index = begin();
  while (offset > off) off += edges_[index++]->length;
  return {index, off - offset};
}

inline CordRepBtree* CordRepBtree::Create(CordRep* rep) {
  if (IsDataEdge(rep)) return New(rep);
  return CreateSlow(rep);
}

inline Span<char> CordRepBtree::GetAppendBuffer(size_t size) {
  assert(refcount.IsOne());
  CordRepBtree* tree = this;
  const int height = this->height();
  CordRepBtree* n1 = tree;
  CordRepBtree* n2 = tree;
  CordRepBtree* n3 = tree;
  switch (height) {
    case 3:
      tree = tree->Edge(kBack)->btree();
      if (!tree->refcount.IsOne()) return {};
      n2 = tree;
      ABSL_FALLTHROUGH_INTENDED;
    case 2:
      tree = tree->Edge(kBack)->btree();
      if (!tree->refcount.IsOne()) return {};
      n1 = tree;
      ABSL_FALLTHROUGH_INTENDED;
    case 1:
      tree = tree->Edge(kBack)->btree();
      if (!tree->refcount.IsOne()) return {};
      ABSL_FALLTHROUGH_INTENDED;
    case 0:
      CordRep* edge = tree->Edge(kBack);
      if (!edge->refcount.IsOne()) return {};
      if (edge->tag < FLAT) return {};
      size_t avail = edge->flat()->Capacity() - edge->length;
      if (avail == 0) return {};
      size_t delta = (std::min)(size, avail);
      Span<char> span = {edge->flat()->Data() + edge->length, delta};
      edge->length += delta;
      switch (height) {
        case 3:
          n3->length += delta;
          ABSL_FALLTHROUGH_INTENDED;
        case 2:
          n2->length += delta;
          ABSL_FALLTHROUGH_INTENDED;
        case 1:
          n1->length += delta;
          ABSL_FALLTHROUGH_INTENDED;
        case 0:
          tree->length += delta;
          return span;
      }
      break;
  }
  return GetAppendBufferSlow(size);
}

extern template CordRepBtree* CordRepBtree::AddCordRep<CordRepBtree::kBack>(
    CordRepBtree* tree, CordRep* rep);

extern template CordRepBtree* CordRepBtree::AddCordRep<CordRepBtree::kFront>(
    CordRepBtree* tree, CordRep* rep);

inline CordRepBtree* CordRepBtree::Append(CordRepBtree* tree, CordRep* rep) {
  if (ABSL_PREDICT_TRUE(IsDataEdge(rep))) {
    return CordRepBtree::AddCordRep<kBack>(tree, rep);
  }
  return AppendSlow(tree, rep);
}

inline CordRepBtree* CordRepBtree::Prepend(CordRepBtree* tree, CordRep* rep) {
  if (ABSL_PREDICT_TRUE(IsDataEdge(rep))) {
    return CordRepBtree::AddCordRep<kFront>(tree, rep);
  }
  return PrependSlow(tree, rep);
}

#ifdef NDEBUG

inline CordRepBtree* CordRepBtree::AssertValid(CordRepBtree* tree,
                                               bool /* shallow */) {
  return tree;
}

inline const CordRepBtree* CordRepBtree::AssertValid(const CordRepBtree* tree,
                                                     bool /* shallow */) {
  return tree;
}

#endif

}  // namespace cord_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_H_
*Ð
jsoong/.intermediates/external/abseil-cpp/absl_types_optional_hdrs/gen/my_include_dir/absl/types/optional.há
// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// optional.h
// -----------------------------------------------------------------------------
//
// Historical note: Abseil once provided an implementation of `absl::optional`
// as a polyfill for `std::optional` prior to C++17. Now that C++17 is required,
// `absl::optional` is an alias for `std::optional`.

#ifndef ABSL_TYPES_OPTIONAL_H_
#define ABSL_TYPES_OPTIONAL_H_

#include <optional>

#include "absl/base/config.h"
#include "absl/utility/utility.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
using std::bad_optional_access;
using std::optional;
using std::make_optional;
using std::nullopt_t;
using std::nullopt;
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_TYPES_OPTIONAL_H_
*­
hsoong/.intermediates/external/abseil-cpp/absl_types_variant_hdrs/gen/my_include_dir/absl/types/variant.hÀ// Copyright 2018 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// variant.h
// -----------------------------------------------------------------------------
//
// Historical note: Abseil once provided an implementation of `absl::variant`
// as a polyfill for `std::variant` prior to C++17. Now that C++17 is required,
// `absl::variant` is an alias for `std::variant`.

#ifndef ABSL_TYPES_VARIANT_H_
#define ABSL_TYPES_VARIANT_H_

#include <variant>

#include "absl/base/config.h"
#include "absl/utility/utility.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
using std::bad_variant_access;
using std::get;
using std::get_if;
using std::holds_alternative;
using std::monostate;
using std::variant;
using std::variant_alternative;
using std::variant_alternative_t;
using std::variant_npos;
using std::variant_size;
using std::variant_size_v;
using std::visit;

namespace variant_internal {
// Helper visitor for converting a variant<Ts...>` into another type (mostly
// variant) that can be constructed from any type.
template <typename To>
struct ConversionVisitor {
  template <typename T>
  To operator()(T&& v) const {
    return To(std::forward<T>(v));
  }
};
}  // namespace variant_internal

// ConvertVariantTo()
//
// Helper functions to convert an `absl::variant` to a variant of another set of
// types, provided that the alternative type of the new variant type can be
// converted from any type in the source variant.
//
// Example:
//
//   absl::variant<name1, name2, float> InternalReq(const Req&);
//
//   // name1 and name2 are convertible to name
//   absl::variant<name, float> ExternalReq(const Req& req) {
//     return absl::ConvertVariantTo<absl::variant<name, float>>(
//              InternalReq(req));
//   }
template <typename To, typename Variant>
To ConvertVariantTo(Variant&& variant) {
  return absl::visit(variant_internal::ConversionVisitor<To>{},
                     std::forward<Variant>(variant));
}

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_TYPES_VARIANT_H_
*¢
…soong/.intermediates/external/abseil-cpp/absl_strings_cordz_functions_hdrs/gen/my_include_dir/absl/strings/internal/cordz_functions.h—// Copyright 2019 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_STRINGS_INTERNAL_CORDZ_FUNCTIONS_H_
#define ABSL_STRINGS_INTERNAL_CORDZ_FUNCTIONS_H_

#include <stdint.h>

#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/optimization.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {

// Returns the current sample rate. This represents the average interval
// between samples.
int32_t get_cordz_mean_interval();

// Sets the sample rate with the average interval between samples.
void set_cordz_mean_interval(int32_t mean_interval);

// Cordz is only enabled on Linux with thread_local support.
#if defined(ABSL_INTERNAL_CORDZ_ENABLED)
#error ABSL_INTERNAL_CORDZ_ENABLED cannot be set directly
#elif defined(__linux__) && defined(ABSL_HAVE_THREAD_LOCAL)
#define ABSL_INTERNAL_CORDZ_ENABLED 1
#endif

#ifdef ABSL_INTERNAL_CORDZ_ENABLED

struct SamplingState {
  int64_t next_sample;
  int64_t sample_stride;
};

// cordz_next_sample is the number of events until the next sample event. If
// the value is 1 or less, the code will check on the next event if cordz is
// enabled, and if so, will sample the Cord. cordz is only enabled when we can
// use thread locals.
ABSL_CONST_INIT extern thread_local SamplingState cordz_next_sample;

// Determines if the next sample should be profiled.
// Returns:
//   0: Do not sample
//  >0: Sample with the stride of the last sampling period
int64_t cordz_should_profile_slow(SamplingState& state);

// Determines if the next sample should be profiled.
// Returns:
//   0: Do not sample
//  >0: Sample with the stride of the last sampling period
inline int64_t cordz_should_profile() {
  if (ABSL_PREDICT_TRUE(cordz_next_sample.next_sample > 1)) {
    cordz_next_sample.next_sample--;
    return 0;
  }
  return cordz_should_profile_slow(cordz_next_sample);
}

// Sets the interval until the next sample (for testing only)
void cordz_set_next_sample_for_testing(int64_t next_sample);

#else  // ABSL_INTERNAL_CORDZ_ENABLED

inline int64_t cordz_should_profile() { return 0; }
inline void cordz_set_next_sample_for_testing(int64_t) {}

#endif  // ABSL_INTERNAL_CORDZ_ENABLED

}  // namespace cord_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_CORDZ_FUNCTIONS_H_
*°%
ksoong/.intermediates/external/abseil-cpp/absl_types_span_hdrs/gen/my_include_dir/absl/types/internal/span.hÀ$//
// Copyright 2019 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef ABSL_TYPES_INTERNAL_SPAN_H_
#define ABSL_TYPES_INTERNAL_SPAN_H_

#include <algorithm>
#include <cstddef>
#include <string>
#include <type_traits>

#include "absl/algorithm/algorithm.h"
#include "absl/base/config.h"
#include "absl/base/internal/throw_delegate.h"
#include "absl/meta/type_traits.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

template <typename T>
class Span;

namespace span_internal {
// Wrappers for access to container data pointers.
template <typename C>
constexpr auto GetDataImpl(C& c, char) noexcept  // NOLINT(runtime/references)
    -> decltype(c.data()) {
  return c.data();
}

// Before C++17, std::string::data returns a const char* in all cases.
inline char* GetDataImpl(std::string& s,  // NOLINT(runtime/references)
                         int) noexcept {
  return &s[0];
}

template <typename C>
constexpr auto GetData(C& c) noexcept  // NOLINT(runtime/references)
    -> decltype(GetDataImpl(c, 0)) {
  return GetDataImpl(c, 0);
}

// Detection idioms for size() and data().
template <typename C>
using HasSize =
    std::is_integral<absl::decay_t<decltype(std::declval<C&>().size())>>;

// We want to enable conversion from vector<T*> to Span<const T* const> but
// disable conversion from vector<Derived> to Span<Base>. Here we use
// the fact that U** is convertible to Q* const* if and only if Q is the same
// type or a more cv-qualified version of U.  We also decay the result type of
// data() to avoid problems with classes which have a member function data()
// which returns a reference.
template <typename T, typename C>
using HasData =
    std::is_convertible<absl::decay_t<decltype(GetData(std::declval<C&>()))>*,
                        T* const*>;

// Extracts value type from a Container
template <typename C>
struct ElementType {
  using type = typename absl::remove_reference_t<C>::value_type;
};

template <typename T, size_t N>
struct ElementType<T (&)[N]> {
  using type = T;
};

template <typename C>
using ElementT = typename ElementType<C>::type;

template <typename T>
using EnableIfMutable =
    typename std::enable_if<!std::is_const<T>::value, int>::type;

template <template <typename> class SpanT, typename T>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool EqualImpl(SpanT<T> a, SpanT<T> b) {
  static_assert(std::is_const<T>::value, "");
  return std::equal(a.begin(), a.end(), b.begin(), b.end());
}

template <template <typename> class SpanT, typename T>
ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 bool LessThanImpl(SpanT<T> a, SpanT<T> b) {
  // We can't use value_type since that is remove_cv_t<T>, so we go the long way
  // around.
  static_assert(std::is_const<T>::value, "");
  return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
}

template <typename From, typename To>
using EnableIfConvertibleTo =
    typename std::enable_if<std::is_convertible<From, To>::value>::type;

// IsView is true for types where the return type of .data() is the same for
// mutable and const instances. This isn't foolproof, but it's only used to
// enable a compiler warning.
template <typename T, typename = void, typename = void>
struct IsView {
  static constexpr bool value = false;
};

template <typename T>
struct IsView<
    T, absl::void_t<decltype(span_internal::GetData(std::declval<const T&>()))>,
    absl::void_t<decltype(span_internal::GetData(std::declval<T&>()))>> {
 private:
  using Container = std::remove_const_t<T>;
  using ConstData =
      decltype(span_internal::GetData(std::declval<const Container&>()));
  using MutData = decltype(span_internal::GetData(std::declval<Container&>()));
 public:
  static constexpr bool value = std::is_same<ConstData, MutData>::value;
};

// These enablers result in 'int' so they can be used as typenames or defaults
// in template parameters lists.
template <typename T>
using EnableIfIsView = std::enable_if_t<IsView<T>::value, int>;

template <typename T>
using EnableIfNotIsView = std::enable_if_t<!IsView<T>::value, int>;

}  // namespace span_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_TYPES_INTERNAL_SPAN_H_
*ì
}soong/.intermediates/external/abseil-cpp/absl_base_base_internal_hdrs/gen/my_include_dir/absl/base/internal/scheduling_mode.hê// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Core interfaces and definitions used by by low-level interfaces such as
// SpinLock.

#ifndef ABSL_BASE_INTERNAL_SCHEDULING_MODE_H_
#define ABSL_BASE_INTERNAL_SCHEDULING_MODE_H_

#include "absl/base/config.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {

// Used to describe how a thread may be scheduled.  Typically associated with
// the declaration of a resource supporting synchronized access.
//
// SCHEDULE_COOPERATIVE_AND_KERNEL:
// Specifies that when waiting, a cooperative thread (e.g. a Fiber) may
// reschedule (using base::scheduling semantics); allowing other cooperative
// threads to proceed.
//
// SCHEDULE_KERNEL_ONLY: (Also described as "non-cooperative")
// Specifies that no cooperative scheduling semantics may be used, even if the
// current thread is itself cooperatively scheduled.  This means that
// cooperative threads will NOT allow other cooperative threads to execute in
// their place while waiting for a resource of this type.  Host operating system
// semantics (e.g. a futex) may still be used.
//
// When optional, clients should strongly prefer SCHEDULE_COOPERATIVE_AND_KERNEL
// by default.  SCHEDULE_KERNEL_ONLY should only be used for resources on which
// base::scheduling (e.g. the implementation of a Scheduler) may depend.
//
// NOTE: Cooperative resources may not be nested below non-cooperative ones.
// This means that it is invalid to to acquire a SCHEDULE_COOPERATIVE_AND_KERNEL
// resource if a SCHEDULE_KERNEL_ONLY resource is already held.
enum SchedulingMode {
  SCHEDULE_KERNEL_ONLY = 0,         // Allow scheduling only the host OS.
  SCHEDULE_COOPERATIVE_AND_KERNEL,  // Also allow cooperative scheduling.
};

}  // namespace base_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_BASE_INTERNAL_SCHEDULING_MODE_H_
*Ô&
tsoong/.intermediates/external/abseil-cpp/absl_base_hdrs/gen/my_include_dir/absl/base/internal/low_level_scheduling.hÛ%// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Core interfaces and definitions used by by low-level interfaces such as
// SpinLock.

#ifndef ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_
#define ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_

#include "absl/base/internal/raw_logging.h"
#include "absl/base/internal/scheduling_mode.h"
#include "absl/base/macros.h"

// The following two declarations exist so SchedulingGuard may friend them with
// the appropriate language linkage.  These callbacks allow libc internals, such
// as function level statics, to schedule cooperatively when locking.
extern "C" bool __google_disable_rescheduling(void);
extern "C" void __google_enable_rescheduling(bool disable_result);

namespace absl {
ABSL_NAMESPACE_BEGIN
class CondVar;
class Mutex;

namespace synchronization_internal {
int MutexDelay(int32_t c, int mode);
}  // namespace synchronization_internal

namespace base_internal {

class SchedulingHelper;  // To allow use of SchedulingGuard.
class SpinLock;          // To allow use of SchedulingGuard.

// SchedulingGuard
// Provides guard semantics that may be used to disable cooperative rescheduling
// of the calling thread within specific program blocks.  This is used to
// protect resources (e.g. low-level SpinLocks or Domain code) that cooperative
// scheduling depends on.
//
// Domain implementations capable of rescheduling in reaction to involuntary
// kernel thread actions (e.g blocking due to a pagefault or syscall) must
// guarantee that an annotated thread is not allowed to (cooperatively)
// reschedule until the annotated region is complete.
//
// It is an error to attempt to use a cooperatively scheduled resource (e.g.
// Mutex) within a rescheduling-disabled region.
//
// All methods are async-signal safe.
class SchedulingGuard {
 public:
  // Returns true iff the calling thread may be cooperatively rescheduled.
  static bool ReschedulingIsAllowed();
  SchedulingGuard(const SchedulingGuard&) = delete;
  SchedulingGuard& operator=(const SchedulingGuard&) = delete;

 private:
  // Disable cooperative rescheduling of the calling thread.  It may still
  // initiate scheduling operations (e.g. wake-ups), however, it may not itself
  // reschedule.  Nestable.  The returned result is opaque, clients should not
  // attempt to interpret it.
  // REQUIRES: Result must be passed to a pairing EnableScheduling().
  static bool DisableRescheduling();

  // Marks the end of a rescheduling disabled region, previously started by
  // DisableRescheduling().
  // REQUIRES: Pairs with innermost call (and result) of DisableRescheduling().
  static void EnableRescheduling(bool disable_result);

  // A scoped helper for {Disable, Enable}Rescheduling().
  // REQUIRES: destructor must run in same thread as constructor.
  struct ScopedDisable {
    ScopedDisable() { disabled = SchedulingGuard::DisableRescheduling(); }
    ~ScopedDisable() { SchedulingGuard::EnableRescheduling(disabled); }

    bool disabled;
  };

  // A scoped helper to enable rescheduling temporarily.
  // REQUIRES: destructor must run in same thread as constructor.
  class ScopedEnable {
   public:
    ScopedEnable();
    ~ScopedEnable();

   private:
    int scheduling_disabled_depth_;
  };

  // Access to SchedulingGuard is explicitly permitted.
  friend class absl::CondVar;
  friend class absl::Mutex;
  friend class SchedulingHelper;
  friend class SpinLock;
  friend int absl::synchronization_internal::MutexDelay(int32_t c, int mode);
};

//------------------------------------------------------------------------------
// End of public interfaces.
//------------------------------------------------------------------------------

inline bool SchedulingGuard::ReschedulingIsAllowed() {
  return false;
}

inline bool SchedulingGuard::DisableRescheduling() {
  return false;
}

inline void SchedulingGuard::EnableRescheduling(bool /* disable_result */) {
  return;
}

inline SchedulingGuard::ScopedEnable::ScopedEnable()
    : scheduling_disabled_depth_(0) {}
inline SchedulingGuard::ScopedEnable::~ScopedEnable() {
  ABSL_RAW_CHECK(scheduling_disabled_depth_ == 0, "disable unused warning");
}

}  // namespace base_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_
*¤A
hsoong/.intermediates/external/abseil-cpp/absl_log_log_entry_hdrs/gen/my_include_dir/absl/log/log_entry.h·@// 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/log_entry.h
// -----------------------------------------------------------------------------
//
// This header declares `class absl::LogEntry`, which represents a log record as
// passed to `LogSink::Send`. Data returned by pointer or by reference or by
// `absl::string_view` must be copied if they are needed after the lifetime of
// the `absl::LogEntry`.

#ifndef ABSL_LOG_LOG_ENTRY_H_
#define ABSL_LOG_LOG_ENTRY_H_

#include <cstddef>
#include <string>

#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/log_severity.h"
#include "absl/log/internal/config.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "absl/types/span.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

namespace log_internal {
// Test only friend.
class LogEntryTestPeer;
class LogMessage;
}  // namespace log_internal

// LogEntry
//
// Represents a single entry in a log, i.e., one `LOG` statement or failed
// `CHECK`.
//
// `LogEntry` is thread-compatible.
class LogEntry final {
 public:
  using tid_t = log_internal::Tid;

  // For non-verbose log entries, `verbosity()` returns `kNoVerbosityLevel`.
  static constexpr int kNoVerbosityLevel = -1;
  static constexpr int kNoVerboseLevel = -1;  // TO BE removed

  // Pass `LogEntry` by reference, and do not store it as its state does not
  // outlive the call to `LogSink::Send()`.
  LogEntry(const LogEntry&) = delete;
  LogEntry& operator=(const LogEntry&) = delete;

  // Source file and line where the log message occurred.  Taken from `__FILE__`
  // and `__LINE__` unless overridden by `LOG(...).AtLocation(...)`.
  //
  // Take special care not to use the values returned by `source_filename()` and
  // `source_basename()` after the lifetime of the entry.  This is always
  // incorrect, but it will often work in practice because they usually point
  // into a statically allocated character array obtained from `__FILE__`.
  // Statements like `LOG(INFO).AtLocation(std::string(...), ...)` will expose
  // the bug.  If you need the data later, you must copy them.
  absl::string_view source_filename() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return full_filename_;
  }
  absl::string_view source_basename() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return base_filename_;
  }
  int source_line() const { return line_; }

  // LogEntry::prefix()
  //
  // True unless the metadata prefix was suppressed once by
  // `LOG(...).NoPrefix()` or globally by `absl::EnableLogPrefix(false)`.
  // Implies `text_message_with_prefix() == text_message()`.
  bool prefix() const { return prefix_; }

  // LogEntry::log_severity()
  //
  // Returns this entry's severity.  For `LOG`, taken from the first argument;
  // for `CHECK`, always `absl::LogSeverity::kFatal`.
  absl::LogSeverity log_severity() const { return severity_; }

  // LogEntry::verbosity()
  //
  // Returns this entry's verbosity, or `kNoVerbosityLevel` for a non-verbose
  // entry. Taken from the argument to `VLOG` or from
  // `LOG(...).WithVerbosity(...)`.
  int verbosity() const { return verbose_level_; }

  // LogEntry::timestamp()
  //
  // Returns the time at which this entry was written.  Captured during
  // evaluation of `LOG`, but can be overridden by
  // `LOG(...).WithTimestamp(...)`.
  //
  // Take care not to rely on timestamps increasing monotonically, or even to
  // rely on timestamps having any particular relationship with reality (since
  // they can be overridden).
  absl::Time timestamp() const { return timestamp_; }

  // LogEntry::tid()
  //
  // Returns the ID of the thread that wrote this entry.  Captured during
  // evaluation of `LOG`, but can be overridden by `LOG(...).WithThreadID(...)`.
  //
  // Take care not to *rely* on reported thread IDs as they can be overridden as
  // specified above.
  tid_t tid() const { return tid_; }

  // Text-formatted version of the log message.  An underlying buffer holds
  // these contiguous data:
  //
  // * A prefix formed by formatting metadata (timestamp, filename, line number,
  //   etc.)
  //   The prefix may be empty - see `LogEntry::prefix()` - and may rarely be
  //   truncated if the metadata are very long.
  // * The streamed data
  //   The data may be empty if nothing was streamed, or may be truncated to fit
  //   the buffer.
  // * A newline
  // * A nul terminator
  //
  // The newline and nul terminator will be present even if the prefix and/or
  // data are truncated.
  //
  // These methods give access to the most commonly useful substrings of the
  // buffer's contents.  Other combinations can be obtained with substring
  // arithmetic.
  //
  // The buffer does not outlive the entry; if you need the data later, you must
  // copy them.
  absl::string_view text_message_with_prefix_and_newline() const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return absl::string_view(
        text_message_with_prefix_and_newline_and_nul_.data(),
        text_message_with_prefix_and_newline_and_nul_.size() - 1);
  }
  absl::string_view text_message_with_prefix() const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return absl::string_view(
        text_message_with_prefix_and_newline_and_nul_.data(),
        text_message_with_prefix_and_newline_and_nul_.size() - 2);
  }
  absl::string_view text_message_with_newline() const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return absl::string_view(
        text_message_with_prefix_and_newline_and_nul_.data() + prefix_len_,
        text_message_with_prefix_and_newline_and_nul_.size() - prefix_len_ - 1);
  }
  absl::string_view text_message() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return absl::string_view(
        text_message_with_prefix_and_newline_and_nul_.data() + prefix_len_,
        text_message_with_prefix_and_newline_and_nul_.size() - prefix_len_ - 2);
  }
  const char* text_message_with_prefix_and_newline_c_str() const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return text_message_with_prefix_and_newline_and_nul_.data();
  }

  // Returns a serialized protobuf holding the operands streamed into this
  // log message.  The message definition is not yet published.
  //
  // The buffer does not outlive the entry; if you need the data later, you must
  // copy them.
  absl::string_view encoded_message() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return encoding_;
  }

  // LogEntry::stacktrace()
  //
  // Optional stacktrace, e.g. for `FATAL` logs and failed `CHECK`s.
  //
  // Fatal entries are dispatched to each sink twice: first with all data and
  // metadata but no stacktrace, and then with the stacktrace.  This is done
  // because stacktrace collection is sometimes slow and fallible, and it's
  // critical to log enough information to diagnose the failure even if the
  // stacktrace collection hangs.
  //
  // The buffer does not outlive the entry; if you need the data later, you must
  // copy them.
  absl::string_view stacktrace() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return stacktrace_;
  }

 private:
  LogEntry() = default;

  absl::string_view full_filename_;
  absl::string_view base_filename_;
  int line_;
  bool prefix_;
  absl::LogSeverity severity_;
  int verbose_level_;  // >=0 for `VLOG`, etc.; otherwise `kNoVerbosityLevel`.
  absl::Time timestamp_;
  tid_t tid_;
  absl::Span<const char> text_message_with_prefix_and_newline_and_nul_;
  size_t prefix_len_;
  absl::string_view encoding_;
  std::string stacktrace_;

  friend class log_internal::LogEntryTestPeer;
  friend class log_internal::LogMessage;
};

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_LOG_LOG_ENTRY_H_
*µq
xsoong/.intermediates/external/abseil-cpp/absl_log_internal_log_impl_hdrs/gen/my_include_dir/absl/log/internal/log_impl.h¸p// 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.

#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"

// ABSL_LOG()
#define ABSL_LOG_INTERNAL_LOG_IMPL(severity)             \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, true) \
      ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()

// ABSL_PLOG()
#define ABSL_LOG_INTERNAL_PLOG_IMPL(severity)              \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, true)   \
      ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \
          .WithPerror()

// ABSL_DLOG()
#ifndef NDEBUG
#define ABSL_LOG_INTERNAL_DLOG_IMPL(severity)            \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, true) \
      ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
#else
#define ABSL_LOG_INTERNAL_DLOG_IMPL(severity)             \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, false) \
      ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
#endif

// The `switch` ensures that this expansion is the beginning 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_DLOG_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_DLOG_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()
#define ABSL_LOG_INTERNAL_PLOG_IF_IMPL(severity, condition)   \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, condition) \
      ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()    \
          .WithPerror()

#ifndef NDEBUG
#define ABSL_LOG_INTERNAL_DLOG_IF_IMPL(severity, condition)   \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, condition) \
      ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
#else
#define ABSL_LOG_INTERNAL_DLOG_IF_IMPL(severity, condition)              \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, false && (condition)) \
      ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
#endif

// ABSL_LOG_EVERY_N
#define ABSL_LOG_INTERNAL_LOG_EVERY_N_IMPL(severity, n)            \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryN, n) \
      ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()

// ABSL_LOG_FIRST_N
#define ABSL_LOG_INTERNAL_LOG_FIRST_N_IMPL(severity, n)            \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(FirstN, n) \
      ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()

// ABSL_LOG_EVERY_POW_2
#define ABSL_LOG_INTERNAL_LOG_EVERY_POW_2_IMPL(severity)           \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryPow2) \
      ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()

// ABSL_LOG_EVERY_N_SEC
#define ABSL_LOG_INTERNAL_LOG_EVERY_N_SEC_IMPL(severity, n_seconds)           \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryNSec, n_seconds) \
      ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()

#define ABSL_LOG_INTERNAL_PLOG_EVERY_N_IMPL(severity, n)           \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryN, n) \
      ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()         \
          .WithPerror()

#define ABSL_LOG_INTERNAL_PLOG_FIRST_N_IMPL(severity, n)           \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(FirstN, n) \
      ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()         \
          .WithPerror()

#define ABSL_LOG_INTERNAL_PLOG_EVERY_POW_2_IMPL(severity)          \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryPow2) \
      ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()         \
          .WithPerror()

#define ABSL_LOG_INTERNAL_PLOG_EVERY_N_SEC_IMPL(severity, n_seconds)          \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryNSec, n_seconds) \
      ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()                    \
          .WithPerror()

#ifndef NDEBUG
#define ABSL_LOG_INTERNAL_DLOG_EVERY_N_IMPL(severity, n) \
  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true)       \
  (EveryN, n) ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()

#define ABSL_LOG_INTERNAL_DLOG_FIRST_N_IMPL(severity, n) \
  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true)       \
  (FirstN, n) ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()

#define ABSL_LOG_INTERNAL_DLOG_EVERY_POW_2_IMPL(severity) \
  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true)        \
  (EveryPow2) ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()

#define ABSL_LOG_INTERNAL_DLOG_EVERY_N_SEC_IMPL(severity, n_seconds) \
  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true)                   \
  (EveryNSec, n_seconds) ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()

#else  // def NDEBUG
#define ABSL_LOG_INTERNAL_DLOG_EVERY_N_IMPL(severity, n) \
  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false)      \
  (EveryN, n) ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()

#define ABSL_LOG_INTERNAL_DLOG_FIRST_N_IMPL(severity, n) \
  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false)      \
  (FirstN, n) ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()

#define ABSL_LOG_INTERNAL_DLOG_EVERY_POW_2_IMPL(severity) \
  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false)       \
  (EveryPow2) ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()

#define ABSL_LOG_INTERNAL_DLOG_EVERY_N_SEC_IMPL(severity, n_seconds) \
  ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false)                  \
  (EveryNSec, n_seconds) ABSL_LOGGING_INTERNAL_DLOG##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()

#define ABSL_LOG_INTERNAL_LOG_IF_FIRST_N_IMPL(severity, condition, n)   \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(FirstN, n) \
      ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()

#define ABSL_LOG_INTERNAL_LOG_IF_EVERY_POW_2_IMPL(severity, condition)  \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryPow2) \
      ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()

#define ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_SEC_IMPL(severity, condition,  \
                                                  n_seconds)            \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryNSec, \
                                                             n_seconds) \
      ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()

#define ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_IMPL(severity, condition, n)  \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryN, n) \
      ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()              \
          .WithPerror()

#define ABSL_LOG_INTERNAL_PLOG_IF_FIRST_N_IMPL(severity, condition, n)  \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(FirstN, n) \
      ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()              \
          .WithPerror()

#define ABSL_LOG_INTERNAL_PLOG_IF_EVERY_POW_2_IMPL(severity, condition) \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryPow2) \
      ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()              \
          .WithPerror()

#define ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_SEC_IMPL(severity, condition, \
                                                   n_seconds)           \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryNSec, \
                                                             n_seconds) \
      ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()              \
          .WithPerror()

#ifndef NDEBUG
#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_IMPL(severity, condition, n)  \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryN, n) \
      ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()

#define ABSL_LOG_INTERNAL_DLOG_IF_FIRST_N_IMPL(severity, condition, n)  \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(FirstN, n) \
      ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()

#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_POW_2_IMPL(severity, condition) \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryPow2) \
      ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()

#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_SEC_IMPL(severity, condition, \
                                                   n_seconds)           \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryNSec, \
                                                             n_seconds) \
      ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()

#else  // def NDEBUG
#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_IMPL(severity, condition, n)   \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, false && (condition))( \
      EveryN, n) ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()

#define ABSL_LOG_INTERNAL_DLOG_IF_FIRST_N_IMPL(severity, condition, n)   \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, false && (condition))( \
      FirstN, n) ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()

#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_POW_2_IMPL(severity, condition)  \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, false && (condition))( \
      EveryPow2) ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()

#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_SEC_IMPL(severity, condition,  \
                                                   n_seconds)            \
  ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, false && (condition))( \
      EveryNSec, n_seconds)                                              \
      ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
#endif  // def NDEBUG

#endif  // ABSL_LOG_INTERNAL_LOG_IMPL_H_
*×†
dsoong/.intermediates/external/abseil-cpp/absl_base_config_hdrs/gen/my_include_dir/absl/base/config.hí…//
// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// File: config.h
// -----------------------------------------------------------------------------
//
// This header file defines a set of macros for checking the presence of
// important compiler and platform features. Such macros can be used to
// produce portable code by parameterizing compilation based on the presence or
// lack of a given feature.
//
// We define a "feature" as some interface we wish to program to: for example,
// a library function or system call. A value of `1` indicates support for
// that feature; any other value indicates the feature support is undefined.
//
// Example:
//
// Suppose a programmer wants to write a program that uses the 'mmap()' system
// call. The Abseil macro for that feature (`ABSL_HAVE_MMAP`) allows you to
// selectively include the `mmap.h` header and bracket code using that feature
// in the macro:
//
//   #include "absl/base/config.h"
//
//   #ifdef ABSL_HAVE_MMAP
//   #include "sys/mman.h"
//   #endif  //ABSL_HAVE_MMAP
//
//   ...
//   #ifdef ABSL_HAVE_MMAP
//   void *ptr = mmap(...);
//   ...
//   #endif  // ABSL_HAVE_MMAP

#ifndef ABSL_BASE_CONFIG_H_
#define ABSL_BASE_CONFIG_H_

// Included for the __GLIBC__ macro (or similar macros on other systems).
#include <limits.h>

#ifdef __cplusplus
// Included for __GLIBCXX__, _LIBCPP_VERSION
#include <cstddef>
#endif  // __cplusplus

// ABSL_INTERNAL_CPLUSPLUS_LANG
//
// MSVC does not set the value of __cplusplus correctly, but instead uses
// _MSVC_LANG as a stand-in.
// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros
//
// However, there are reports that MSVC even sets _MSVC_LANG incorrectly at
// times, for example:
// https://github.com/microsoft/vscode-cpptools/issues/1770
// https://reviews.llvm.org/D70996
//
// For this reason, this symbol is considered INTERNAL and code outside of
// Abseil must not use it.
#if defined(_MSVC_LANG)
#define ABSL_INTERNAL_CPLUSPLUS_LANG _MSVC_LANG
#elif defined(__cplusplus)
#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.
#include <Availability.h>
#include <TargetConditionals.h>
#endif

#include "absl/base/options.h"
#include "absl/base/policy_checks.h"

// Abseil long-term support (LTS) releases will define
// `ABSL_LTS_RELEASE_VERSION` to the integer representing the date string of the
// LTS release version, and will define `ABSL_LTS_RELEASE_PATCH_LEVEL` to the
// integer representing the patch-level for that release.
//
// For example, for LTS release version "20300401.2", this would give us
// ABSL_LTS_RELEASE_VERSION == 20300401 && ABSL_LTS_RELEASE_PATCH_LEVEL == 2
//
// These symbols will not be defined in non-LTS code.
//
// Abseil recommends that clients live-at-head. Therefore, if you are using
// these symbols to assert a minimum version requirement, we recommend you do it
// as
//
// #if defined(ABSL_LTS_RELEASE_VERSION) && ABSL_LTS_RELEASE_VERSION < 20300401
// #error Project foo requires Abseil LTS version >= 20300401
// #endif
//
// The `defined(ABSL_LTS_RELEASE_VERSION)` part of the check excludes
// live-at-head clients from the minimum version assertion.
//
// See https://abseil.io/about/releases for more information on Abseil release
// management.
//
// LTS releases can be obtained from
// https://github.com/abseil/abseil-cpp/releases.
#define ABSL_LTS_RELEASE_VERSION 20250512
#define ABSL_LTS_RELEASE_PATCH_LEVEL 1

// Helper macro to convert a CPP variable to a string literal.
#define ABSL_INTERNAL_DO_TOKEN_STR(x) #x
#define ABSL_INTERNAL_TOKEN_STR(x) ABSL_INTERNAL_DO_TOKEN_STR(x)

// -----------------------------------------------------------------------------
// Abseil namespace annotations
// -----------------------------------------------------------------------------

// ABSL_NAMESPACE_BEGIN/ABSL_NAMESPACE_END
//
// An annotation placed at the beginning/end of each `namespace absl` scope.
// This is used to inject an inline namespace.
//
// The proper way to write Abseil code in the `absl` namespace is:
//
// namespace absl {
// ABSL_NAMESPACE_BEGIN
//
// void Foo();  // absl::Foo().
//
// ABSL_NAMESPACE_END
// }  // namespace absl
//
// Users of Abseil should not use these macros, because users of Abseil should
// not write `namespace absl {` in their own code for any reason.  (Abseil does
// not support forward declarations of its own types, nor does it support
// user-provided specialization of Abseil templates.  Code that violates these
// rules may be broken without warning.)
#if !defined(ABSL_OPTION_USE_INLINE_NAMESPACE) || \
    !defined(ABSL_OPTION_INLINE_NAMESPACE_NAME)
#error options.h is misconfigured.
#endif

// Check that ABSL_OPTION_INLINE_NAMESPACE_NAME is neither "head" nor ""
#if defined(__cplusplus) && ABSL_OPTION_USE_INLINE_NAMESPACE == 1

#define ABSL_INTERNAL_INLINE_NAMESPACE_STR \
  ABSL_INTERNAL_TOKEN_STR(ABSL_OPTION_INLINE_NAMESPACE_NAME)

static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != '\0',
              "options.h misconfigured: ABSL_OPTION_INLINE_NAMESPACE_NAME must "
              "not be empty.");
static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
                  ABSL_INTERNAL_INLINE_NAMESPACE_STR[1] != 'e' ||
                  ABSL_INTERNAL_INLINE_NAMESPACE_STR[2] != 'a' ||
                  ABSL_INTERNAL_INLINE_NAMESPACE_STR[3] != 'd' ||
                  ABSL_INTERNAL_INLINE_NAMESPACE_STR[4] != '\0',
              "options.h misconfigured: ABSL_OPTION_INLINE_NAMESPACE_NAME must "
              "be changed to a new, unique identifier name.");

#endif

#if ABSL_OPTION_USE_INLINE_NAMESPACE == 0
#define ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_END
#define ABSL_INTERNAL_C_SYMBOL(x) x
#elif ABSL_OPTION_USE_INLINE_NAMESPACE == 1
#define ABSL_NAMESPACE_BEGIN \
  inline namespace ABSL_OPTION_INLINE_NAMESPACE_NAME {
#define ABSL_NAMESPACE_END }
#define ABSL_INTERNAL_C_SYMBOL_HELPER_2(x, v) x##_##v
#define ABSL_INTERNAL_C_SYMBOL_HELPER_1(x, v) \
  ABSL_INTERNAL_C_SYMBOL_HELPER_2(x, v)
#define ABSL_INTERNAL_C_SYMBOL(x) \
  ABSL_INTERNAL_C_SYMBOL_HELPER_1(x, ABSL_OPTION_INLINE_NAMESPACE_NAME)
#else
#error options.h is misconfigured.
#endif

// -----------------------------------------------------------------------------
// Compiler Feature Checks
// -----------------------------------------------------------------------------

// ABSL_HAVE_BUILTIN()
//
// Checks whether the compiler supports a Clang Feature Checking Macro, and if
// so, checks whether it supports the provided builtin function "x" where x
// is one of the functions noted in
// https://clang.llvm.org/docs/LanguageExtensions.html
//
// Note: Use this macro to avoid an extra level of #ifdef __has_builtin check.
// http://releases.llvm.org/3.3/tools/clang/docs/LanguageExtensions.html
#ifdef __has_builtin
#define ABSL_HAVE_BUILTIN(x) __has_builtin(x)
#else
#define ABSL_HAVE_BUILTIN(x) 0
#endif

#ifdef __has_feature
#define ABSL_HAVE_FEATURE(f) __has_feature(f)
#else
#define ABSL_HAVE_FEATURE(f) 0
#endif

// Portable check for GCC minimum version:
// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
#if defined(__GNUC__) && defined(__GNUC_MINOR__)
#define ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(x, y) \
  (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y))
#else
#define ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(x, y) 0
#endif

#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__)
#define ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(x, y) \
  (__clang_major__ > (x) || __clang_major__ == (x) && __clang_minor__ >= (y))
#else
#define ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(x, y) 0
#endif

// ABSL_HAVE_TLS is defined to 1 when __thread should be supported.
// We assume __thread is supported on Linux when compiled with Clang or
// compiled against libstdc++ with _GLIBCXX_HAVE_TLS defined.
#ifdef ABSL_HAVE_TLS
#error ABSL_HAVE_TLS cannot be directly set
#elif (defined(__linux__)) && (defined(__clang__) || defined(_GLIBCXX_HAVE_TLS))
#define ABSL_HAVE_TLS 1
#endif

// ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
//
// Checks whether `std::is_trivially_destructible<T>` is supported.
#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
#error ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE cannot be directly set
#define ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 1
#endif

// ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
//
// Checks whether `std::is_trivially_default_constructible<T>` and
// `std::is_trivially_copy_constructible<T>` are supported.
#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
#error ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE cannot be directly set
#else
#define ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 1
#endif

// ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
//
// Checks whether `std::is_trivially_copy_assignable<T>` is supported.
#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
#error ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE cannot be directly set
#else
#define ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 1
#endif

// ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE
//
// Checks whether `std::is_trivially_copyable<T>` is supported.
#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE
#error ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE cannot be directly set
#define ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE 1
#endif

// ABSL_HAVE_THREAD_LOCAL
//
// Checks whether the `thread_local` storage duration specifier is supported.
#ifdef ABSL_HAVE_THREAD_LOCAL
#error ABSL_HAVE_THREAD_LOCAL cannot be directly set
#elif !defined(__XTENSA__) && !defined(ANDROID_DISABLE_TLS_FOR_LINKER)
#define ABSL_HAVE_THREAD_LOCAL 1
#endif

// ABSL_HAVE_INTRINSIC_INT128
//
// Checks whether the __int128 compiler extension for a 128-bit integral type is
// supported.
//
// Note: __SIZEOF_INT128__ is defined by Clang and GCC when __int128 is
// supported, but we avoid using it in certain cases:
// * On Clang:
//   * Building using Clang for Windows, where the Clang runtime library has
//     128-bit support only on LP64 architectures, but Windows is LLP64.
// * On Nvidia's nvcc:
//   * nvcc also defines __GNUC__ and __SIZEOF_INT128__, but not all versions
//     actually support __int128.
#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) || \
    (defined(__GNUC__) && !defined(__clang__) && !defined(__CUDACC__))
#define ABSL_HAVE_INTRINSIC_INT128 1
#elif defined(__CUDACC__)
// __CUDACC_VER__ is a full version number before CUDA 9, and is defined to a
// string explaining that it has been removed starting with CUDA 9. We use
// nested #ifs because there is no short-circuiting in the preprocessor.
// NOTE: `__CUDACC__` could be undefined while `__CUDACC_VER__` is defined.
#if __CUDACC_VER__ >= 70000
#define ABSL_HAVE_INTRINSIC_INT128 1
#endif  // __CUDACC_VER__ >= 70000
#endif  // defined(__CUDACC__)
#endif  // ABSL_HAVE_INTRINSIC_INT128

// ABSL_HAVE_EXCEPTIONS
//
// Checks whether the compiler both supports and enables exceptions. Many
// compilers support a "no exceptions" mode that disables exceptions.
//
// Generally, when ABSL_HAVE_EXCEPTIONS is not defined:
//
// * Code using `throw` and `try` may not compile.
// * The `noexcept` specifier will still compile and behave as normal.
// * The `noexcept` operator may still return `false`.
//
// For further details, consult the compiler's documentation.
#ifdef ABSL_HAVE_EXCEPTIONS
#error ABSL_HAVE_EXCEPTIONS cannot be directly set.
#elif ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(3, 6)
// Clang >= 3.6
#if ABSL_HAVE_FEATURE(cxx_exceptions)
#define ABSL_HAVE_EXCEPTIONS 1
#endif  // ABSL_HAVE_FEATURE(cxx_exceptions)
#elif defined(__clang__)
// Clang < 3.6
// http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro
#if defined(__EXCEPTIONS) && ABSL_HAVE_FEATURE(cxx_exceptions)
#define ABSL_HAVE_EXCEPTIONS 1
#endif  // defined(__EXCEPTIONS) && ABSL_HAVE_FEATURE(cxx_exceptions)
// Handle remaining special cases and default to exceptions being supported.
#elif !(defined(__GNUC__) && !defined(__cpp_exceptions)) && \
    !(defined(_MSC_VER) && !defined(_CPPUNWIND))
#define ABSL_HAVE_EXCEPTIONS 1
#endif

// -----------------------------------------------------------------------------
// Platform Feature Checks
// -----------------------------------------------------------------------------

// Currently supported operating systems and associated preprocessor
// symbols:
//
//   Linux and Linux-derived           __linux__
//   Android                           __ANDROID__ (implies __linux__)
//   Linux (non-Android)               __linux__ && !__ANDROID__
//   Darwin (macOS and iOS)            __APPLE__
//   Akaros (http://akaros.org)        __ros__
//   Windows                           _WIN32
//   NaCL                              __native_client__
//   AsmJS                             __asmjs__
//   WebAssembly (Emscripten)          __EMSCRIPTEN__
//   Fuchsia                           __Fuchsia__
//
// Note that since Android defines both __ANDROID__ and __linux__, one
// may probe for either Linux or Android by simply testing for __linux__.

// ABSL_HAVE_MMAP
//
// Checks whether the platform has an mmap(2) implementation as defined in
// 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(__EMSCRIPTEN__) || defined(__Fuchsia__) || \
    defined(__sun) || defined(__myriad2__) || defined(__HAIKU__) ||          \
    defined(__OpenBSD__) || defined(__NetBSD__) || defined(__QNX__) ||       \
    defined(__VXWORKS__) || defined(__hexagon__) || defined(__XTENSA__)
#define ABSL_HAVE_MMAP 1
#endif

// ABSL_HAVE_PTHREAD_GETSCHEDPARAM
//
// Checks whether the platform implements the pthread_(get|set)schedparam(3)
// functions as defined in POSIX.1-2001.
#ifdef ABSL_HAVE_PTHREAD_GETSCHEDPARAM
#error ABSL_HAVE_PTHREAD_GETSCHEDPARAM cannot be directly set
#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
    defined(_AIX) || defined(__ros__) || defined(__OpenBSD__) ||          \
    defined(__NetBSD__) || defined(__VXWORKS__)
#define ABSL_HAVE_PTHREAD_GETSCHEDPARAM 1
#endif

// ABSL_HAVE_SCHED_GETCPU
//
// Checks whether sched_getcpu is available.
#ifdef ABSL_HAVE_SCHED_GETCPU
#error ABSL_HAVE_SCHED_GETCPU cannot be directly set
#elif defined(__linux__)
#define ABSL_HAVE_SCHED_GETCPU 1
#endif

// ABSL_HAVE_SCHED_YIELD
//
// Checks whether the platform implements sched_yield(2) as defined in
// POSIX.1-2001.
#ifdef ABSL_HAVE_SCHED_YIELD
#error ABSL_HAVE_SCHED_YIELD cannot be directly set
#elif defined(__linux__) || defined(__ros__) || defined(__native_client__) || \
    defined(__VXWORKS__)
#define ABSL_HAVE_SCHED_YIELD 1
#endif

// ABSL_HAVE_SEMAPHORE_H
//
// Checks whether the platform supports the <semaphore.h> header and sem_init(3)
// family of functions as standardized in POSIX.1-2001.
//
// Note: While Apple provides <semaphore.h> for both iOS and macOS, it is
// explicitly deprecated and will cause build failures if enabled for those
// platforms.  We side-step the issue by not defining it here for Apple
// platforms.
#ifdef ABSL_HAVE_SEMAPHORE_H
#error ABSL_HAVE_SEMAPHORE_H cannot be directly set
#elif defined(__linux__) || defined(__ros__) || defined(__VXWORKS__)
#define ABSL_HAVE_SEMAPHORE_H 1
#endif

// ABSL_HAVE_ALARM
//
// Checks whether the platform supports the <signal.h> header and alarm(2)
// function as standardized in POSIX.1-2001.
#ifdef ABSL_HAVE_ALARM
#error ABSL_HAVE_ALARM cannot be directly set
#elif defined(__GOOGLE_GRTE_VERSION__)
// feature tests for Google's GRTE
#define ABSL_HAVE_ALARM 1
#elif defined(__GLIBC__)
// feature test for glibc
#define ABSL_HAVE_ALARM 1
#elif defined(_MSC_VER)
// feature tests for Microsoft's library
#elif defined(__MINGW32__)
// mingw32 doesn't provide alarm(2):
// https://osdn.net/projects/mingw/scm/git/mingw-org-wsl/blobs/5.2-trunk/mingwrt/include/unistd.h
// mingw-w64 provides a no-op implementation:
// 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__)
// Signals don't exist on hexagon/QuRT
#elif defined(__hexagon__)
#else
// other standard libraries
#define ABSL_HAVE_ALARM 1
#endif

// ABSL_IS_LITTLE_ENDIAN
// ABSL_IS_BIG_ENDIAN
//
// Checks the endianness of the platform.
//
// Prefer using `std::endian` in C++20, or `absl::endian` from
// absl/numeric/bits.h prior to C++20.
//
// Notes: uses the built in endian macros provided by GCC (since 4.6) and
// Clang (since 3.2); see
// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html.
// Otherwise, if _WIN32, assume little endian. Otherwise, bail with an error.
#if defined(ABSL_IS_BIG_ENDIAN)
#error "ABSL_IS_BIG_ENDIAN cannot be directly set."
#endif
#if defined(ABSL_IS_LITTLE_ENDIAN)
#error "ABSL_IS_LITTLE_ENDIAN cannot be directly set."
#endif

#if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
     __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
#define ABSL_IS_LITTLE_ENDIAN 1
#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
    __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define ABSL_IS_BIG_ENDIAN 1
#elif defined(_WIN32)
#define ABSL_IS_LITTLE_ENDIAN 1
#else
#error "absl endian detection needs to be set up for your compiler"
#endif

// macOS < 10.13 and iOS < 12 don't support <any>, <optional>, or <variant>
// because the libc++ shared library shipped on the system doesn't have the
// requisite exported symbols.  See
// https://github.com/abseil/abseil-cpp/issues/207 and
// https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes
//
// libc++ spells out the availability requirements in the file
// llvm-project/libcxx/include/__config via the #define
// _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS. The set of versions has been
// modified a few times, via
// https://github.com/llvm/llvm-project/commit/7fb40e1569dd66292b647f4501b85517e9247953
// 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__) &&      \
      __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 120000))
#define ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE 1
#else
#define ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE 0
#endif

// Deprecated macros for polyfill detection.
#define ABSL_HAVE_STD_ANY 1
#define ABSL_USES_STD_ANY 1
#define ABSL_HAVE_STD_OPTIONAL 1
#define ABSL_USES_STD_OPTIONAL 1
#define ABSL_HAVE_STD_VARIANT 1
#define ABSL_USES_STD_VARIANT 1

// ABSL_HAVE_STD_STRING_VIEW
//
// Deprecated: always defined to 1.
// std::string_view was added in C++17, which means all versions of C++
// supported by Abseil have it.
#ifdef ABSL_HAVE_STD_STRING_VIEW
#error "ABSL_HAVE_STD_STRING_VIEW cannot be directly set."
#else
#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_STRING_VIEW
//
// Indicates whether absl::string_view is an alias for std::string_view.
#if !defined(ABSL_OPTION_USE_STD_STRING_VIEW)
#error options.h is misconfigured.
#elif ABSL_OPTION_USE_STD_STRING_VIEW == 0
#undef ABSL_USES_STD_STRING_VIEW
#elif ABSL_OPTION_USE_STD_STRING_VIEW == 1 || \
    ABSL_OPTION_USE_STD_STRING_VIEW == 2
#define ABSL_USES_STD_STRING_VIEW 1
#else
#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

// ABSL_INTERNAL_MANGLED_NS
// ABSL_INTERNAL_MANGLED_BACKREFERENCE
//
// Internal macros for building up mangled names in our internal fork of CCTZ.
// This implementation detail is only needed and provided for the MSVC build.
//
// These macros both expand to string literals.  ABSL_INTERNAL_MANGLED_NS is
// the mangled spelling of the `absl` namespace, and
// ABSL_INTERNAL_MANGLED_BACKREFERENCE is a back-reference integer representing
// the proper count to skip past the CCTZ fork namespace names.  (This number
// is one larger when there is an inline namespace name to skip.)
#if defined(_MSC_VER)
#if ABSL_OPTION_USE_INLINE_NAMESPACE == 0
#define ABSL_INTERNAL_MANGLED_NS "absl"
#define ABSL_INTERNAL_MANGLED_BACKREFERENCE "5"
#else
#define ABSL_INTERNAL_MANGLED_NS \
  ABSL_INTERNAL_TOKEN_STR(ABSL_OPTION_INLINE_NAMESPACE_NAME) "@absl"
#define ABSL_INTERNAL_MANGLED_BACKREFERENCE "6"
#endif
#endif

// ABSL_DLL
//
// When building Abseil as a DLL, this macro expands to `__declspec(dllexport)`
// so we can annotate symbols appropriately as being exported. When used in
// headers consuming a DLL, this macro expands to `__declspec(dllimport)` so
// that consumers know the symbol is defined inside the DLL. In all other cases,
// the macro expands to nothing.
#if defined(_MSC_VER)
#if defined(ABSL_BUILD_DLL)
#define ABSL_DLL __declspec(dllexport)
#elif defined(ABSL_CONSUME_DLL)
#define ABSL_DLL __declspec(dllimport)
#else
#define ABSL_DLL
#endif
#else
#define ABSL_DLL
#endif  // defined(_MSC_VER)

#if defined(_MSC_VER)
#if defined(ABSL_BUILD_TEST_DLL)
#define ABSL_TEST_DLL __declspec(dllexport)
#elif defined(ABSL_CONSUME_TEST_DLL)
#define ABSL_TEST_DLL __declspec(dllimport)
#else
#define ABSL_TEST_DLL
#endif
#else
#define ABSL_TEST_DLL
#endif  // defined(_MSC_VER)

// ABSL_HAVE_MEMORY_SANITIZER
//
// MemorySanitizer (MSan) is a detector of uninitialized reads. It consists of
// a compiler instrumentation module and a run-time library.
#ifdef ABSL_HAVE_MEMORY_SANITIZER
#error "ABSL_HAVE_MEMORY_SANITIZER cannot be directly set."
#elif !defined(__native_client__) && ABSL_HAVE_FEATURE(memory_sanitizer)
#define ABSL_HAVE_MEMORY_SANITIZER 1
#endif

// ABSL_HAVE_THREAD_SANITIZER
//
// ThreadSanitizer (TSan) is a fast data race detector.
#ifdef ABSL_HAVE_THREAD_SANITIZER
#error "ABSL_HAVE_THREAD_SANITIZER cannot be directly set."
#elif defined(__SANITIZE_THREAD__)
#define ABSL_HAVE_THREAD_SANITIZER 1
#elif ABSL_HAVE_FEATURE(thread_sanitizer)
#define ABSL_HAVE_THREAD_SANITIZER 1
#endif

// ABSL_HAVE_ADDRESS_SANITIZER
//
// AddressSanitizer (ASan) is a fast memory error detector.
#ifdef ABSL_HAVE_ADDRESS_SANITIZER
#error "ABSL_HAVE_ADDRESS_SANITIZER cannot be directly set."
#elif defined(__SANITIZE_ADDRESS__)
#define ABSL_HAVE_ADDRESS_SANITIZER 1
#elif ABSL_HAVE_FEATURE(address_sanitizer)
#define ABSL_HAVE_ADDRESS_SANITIZER 1
#endif

// ABSL_HAVE_HWADDRESS_SANITIZER
//
// Hardware-Assisted AddressSanitizer (or HWASAN) is even faster than asan
// memory error detector which can use CPU features like ARM TBI, Intel LAM or
// AMD UAI.
#ifdef ABSL_HAVE_HWADDRESS_SANITIZER
#error "ABSL_HAVE_HWADDRESS_SANITIZER cannot be directly set."
#elif defined(__SANITIZE_HWADDRESS__)
#define ABSL_HAVE_HWADDRESS_SANITIZER 1
#elif ABSL_HAVE_FEATURE(hwaddress_sanitizer)
#define ABSL_HAVE_HWADDRESS_SANITIZER 1
#endif

// ABSL_HAVE_DATAFLOW_SANITIZER
//
// Dataflow Sanitizer (or DFSAN) is a generalised dynamic data flow analysis.
#ifdef ABSL_HAVE_DATAFLOW_SANITIZER
#error "ABSL_HAVE_DATAFLOW_SANITIZER cannot be directly set."
#elif defined(DATAFLOW_SANITIZER)
// GCC provides no method for detecting the presence of the standalone
// DataFlowSanitizer (-fsanitize=dataflow), so GCC users of -fsanitize=dataflow
// should also use -DDATAFLOW_SANITIZER.
#define ABSL_HAVE_DATAFLOW_SANITIZER 1
#elif ABSL_HAVE_FEATURE(dataflow_sanitizer)
#define ABSL_HAVE_DATAFLOW_SANITIZER 1
#endif

// ABSL_HAVE_LEAK_SANITIZER
//
// LeakSanitizer (or lsan) is a detector of memory leaks.
// https://clang.llvm.org/docs/LeakSanitizer.html
// https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer
//
// The macro ABSL_HAVE_LEAK_SANITIZER can be used to detect at compile-time
// whether the LeakSanitizer is potentially available. However, just because the
// LeakSanitizer is available does not mean it is active. Use the
// always-available run-time interface in //absl/debugging/leak_check.h for
// interacting with LeakSanitizer.
#ifdef ABSL_HAVE_LEAK_SANITIZER
#error "ABSL_HAVE_LEAK_SANITIZER cannot be directly set."
#elif defined(LEAK_SANITIZER)
// GCC provides no method for detecting the presence of the standalone
// LeakSanitizer (-fsanitize=leak), so GCC users of -fsanitize=leak should also
// use -DLEAK_SANITIZER.
#define ABSL_HAVE_LEAK_SANITIZER 1
// Clang standalone LeakSanitizer (-fsanitize=leak)
#elif ABSL_HAVE_FEATURE(leak_sanitizer)
#define ABSL_HAVE_LEAK_SANITIZER 1
#elif defined(ABSL_HAVE_ADDRESS_SANITIZER)
// GCC or Clang using the LeakSanitizer integrated into AddressSanitizer.
#define ABSL_HAVE_LEAK_SANITIZER 1
#endif

// ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
//
// Deprecated: always defined to 1.
// Class template argument deduction is a language feature added in C++17,
// which means all versions of C++ supported by Abseil have it.
#ifdef ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
#error "ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION cannot be directly set."
#else
#define ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION 1
#endif

// `ABSL_INTERNAL_HAS_RTTI` determines whether abseil is being compiled with
// RTTI support.
#ifdef ABSL_INTERNAL_HAS_RTTI
#error ABSL_INTERNAL_HAS_RTTI cannot be directly set
#elif ABSL_HAVE_FEATURE(cxx_rtti)
#define ABSL_INTERNAL_HAS_RTTI 1
#elif defined(__GNUC__) && defined(__GXX_RTTI)
#define ABSL_INTERNAL_HAS_RTTI 1
#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__)
#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
// which architectures support the various x86 instruction sets.
#ifdef ABSL_INTERNAL_HAVE_SSE
#error ABSL_INTERNAL_HAVE_SSE cannot be directly set
#elif defined(__SSE__)
#define ABSL_INTERNAL_HAVE_SSE 1
#elif (defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1)) && \
    !defined(_M_ARM64EC)
// MSVC only defines _M_IX86_FP for x86 32-bit code, and _M_IX86_FP >= 1
// indicates that at least SSE was targeted with the /arch:SSE option.
// All x86-64 processors support SSE, so support can be assumed.
// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros
#define ABSL_INTERNAL_HAVE_SSE 1
#endif

// ABSL_INTERNAL_HAVE_SSE2 is used for compile-time detection of SSE2 support.
// See https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html for an overview of
// which architectures support the various x86 instruction sets.
#ifdef ABSL_INTERNAL_HAVE_SSE2
#error ABSL_INTERNAL_HAVE_SSE2 cannot be directly set
#elif defined(__SSE2__)
#define ABSL_INTERNAL_HAVE_SSE2 1
#elif (defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2)) && \
    !defined(_M_ARM64EC)
// MSVC only defines _M_IX86_FP for x86 32-bit code, and _M_IX86_FP >= 2
// indicates that at least SSE2 was targeted with the /arch:SSE2 option.
// All x86-64 processors support SSE2, so support can be assumed.
// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros
#define ABSL_INTERNAL_HAVE_SSE2 1
#endif

// ABSL_INTERNAL_HAVE_SSSE3 is used for compile-time detection of SSSE3 support.
// See https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html for an overview of
// which architectures support the various x86 instruction sets.
//
// MSVC does not have a mode that targets SSSE3 at compile-time. To use SSSE3
// with MSVC requires either assuming that the code will only every run on CPUs
// that support SSSE3, otherwise __cpuid() can be used to detect support at
// runtime and fallback to a non-SSSE3 implementation when SSSE3 is unsupported
// by the CPU.
#ifdef ABSL_INTERNAL_HAVE_SSSE3
#error ABSL_INTERNAL_HAVE_SSSE3 cannot be directly set
#elif defined(__SSSE3__)
#define ABSL_INTERNAL_HAVE_SSSE3 1
#endif

// ABSL_INTERNAL_HAVE_ARM_NEON is used for compile-time detection of NEON (ARM
// SIMD).
//
// If __CUDA_ARCH__ is defined, then we are compiling CUDA code in device mode.
// In device mode, NEON intrinsics are not available, regardless of host
// platform.
// https://llvm.org/docs/CompileCudaWithLLVM.html#detecting-clang-vs-nvcc-from-code
#ifdef ABSL_INTERNAL_HAVE_ARM_NEON
#error ABSL_INTERNAL_HAVE_ARM_NEON cannot be directly set
#elif defined(__ARM_NEON) && !(defined(__NVCC__) && defined(__CUDACC__))
#define ABSL_INTERNAL_HAVE_ARM_NEON 1
#endif

// ABSL_HAVE_CONSTANT_EVALUATED is used for compile-time detection of
// constant evaluation support through `absl::is_constant_evaluated`.
#ifdef ABSL_HAVE_CONSTANT_EVALUATED
#error ABSL_HAVE_CONSTANT_EVALUATED cannot be directly set
#endif
#ifdef __cpp_lib_is_constant_evaluated
#define ABSL_HAVE_CONSTANT_EVALUATED 1
#elif ABSL_HAVE_BUILTIN(__builtin_is_constant_evaluated)
#define ABSL_HAVE_CONSTANT_EVALUATED 1
#endif

// ABSL_INTERNAL_CONSTEXPR_SINCE_CXXYY is used to conditionally define constexpr
// for different C++ versions.
//
// These macros are an implementation detail and will be unconditionally removed
// once the minimum supported C++ version catches up to a given version.
//
// For this reason, this symbol is considered INTERNAL and code outside of
// Abseil must not use it.
#if defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
    ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
#define ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17 constexpr
#else
#define ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17
#endif
#if defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
    ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
#define ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 constexpr
#else
#define ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20
#endif

// ABSL_INTERNAL_EMSCRIPTEN_VERSION combines Emscripten's three version macros
// into an integer that can be compared against.
#ifdef ABSL_INTERNAL_EMSCRIPTEN_VERSION
#error ABSL_INTERNAL_EMSCRIPTEN_VERSION cannot be directly set
#endif
#ifdef __EMSCRIPTEN__
#include <emscripten/version.h>
#ifdef __EMSCRIPTEN_major__
#if __EMSCRIPTEN_minor__ >= 1000
#error __EMSCRIPTEN_minor__ is too big to fit in ABSL_INTERNAL_EMSCRIPTEN_VERSION
#endif
#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 + \
   (__EMSCRIPTEN_tiny__))
#endif
#endif

#endif  // ABSL_BASE_CONFIG_H_
*·

tsoong/.intermediates/external/abseil-cpp/absl_log_internal_config_hdrs/gen/my_include_dir/absl/log/internal/config.h¾	// 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/internal/config.h
// -----------------------------------------------------------------------------
//

#ifndef ABSL_LOG_INTERNAL_CONFIG_H_
#define ABSL_LOG_INTERNAL_CONFIG_H_

#include "absl/base/config.h"

#ifdef _WIN32
#include <cstdint>
#else
#include <sys/types.h>
#endif

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace log_internal {

#ifdef _WIN32
using Tid = uint32_t;
#else
using Tid = pid_t;
#endif

}  // namespace log_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_LOG_INTERNAL_CONFIG_H_
*ê
‚soong/.intermediates/external/abseil-cpp/absl_strings_cord_internal_hdrs/gen/my_include_dir/absl/strings/internal/cord_data_edge.hâ// 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.

#ifndef ABSL_STRINGS_INTERNAL_CORD_DATA_EDGE_H_
#define ABSL_STRINGS_INTERNAL_CORD_DATA_EDGE_H_

#include <cassert>
#include <cstddef>

#include "absl/base/config.h"
#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_flat.h"
#include "absl/strings/string_view.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {

// Returns true if the provided rep is a FLAT, EXTERNAL or a SUBSTRING node
// holding a FLAT or EXTERNAL child rep. Requires `rep != nullptr`.
inline bool IsDataEdge(const CordRep* edge) {
  assert(edge != nullptr);

  // The fast path is that `edge` is an EXTERNAL or FLAT node, making the below
  // if a single, well predicted branch. We then repeat the FLAT or EXTERNAL
  // check in the slow path of the SUBSTRING check to optimize for the hot path.
  if (edge->tag == EXTERNAL || edge->tag >= FLAT) return true;
  if (edge->tag == SUBSTRING) edge = edge->substring()->child;
  return edge->tag == EXTERNAL || edge->tag >= FLAT;
}

// Returns the `absl::string_view` data reference for the provided data edge.
// Requires 'IsDataEdge(edge) == true`.
inline absl::string_view EdgeData(const CordRep* edge) {
  assert(IsDataEdge(edge));

  size_t offset = 0;
  const size_t length = edge->length;
  if (edge->IsSubstring()) {
    offset = edge->substring()->start;
    edge = edge->substring()->child;
  }
  return edge->tag >= FLAT
             ? absl::string_view{edge->flat()->Data() + offset, length}
             : absl::string_view{edge->external()->base + offset, length};
}

}  // namespace cord_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_CORD_DATA_EDGE_H_
*ƒA
¶soong/.intermediates/build/make/tools/ide_query/prober_scripts/cpp/ide_query_proberscript_cc/android_arm_armv7-a-neon/gen/proto/build/make/tools/ide_query/prober_scripts/cpp/foo.pb.hÇ?// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: build/make/tools/ide_query/prober_scripts/cpp/foo.proto

#ifndef GOOGLE_PROTOBUF_INCLUDED_build_2fmake_2ftools_2fide_5fquery_2fprober_5fscripts_2fcpp_2ffoo_2eproto_2epb_2eh
#define GOOGLE_PROTOBUF_INCLUDED_build_2fmake_2ftools_2fide_5fquery_2fprober_5fscripts_2fcpp_2ffoo_2eproto_2epb_2eh

#include <cstdint>
#include <limits>
#include <string>
#include <type_traits>

#include "google/protobuf/port_def.inc"
#if PROTOBUF_VERSION < 4022000
#error "This file was generated by a newer version of protoc which is"
#error "incompatible with your Protocol Buffer headers. Please update"
#error "your headers."
#endif  // PROTOBUF_VERSION

#if 4022005 < PROTOBUF_MIN_PROTOC_VERSION
#error "This file was generated by an older version of protoc which is"
#error "incompatible with your Protocol Buffer headers. Please"
#error "regenerate this file with a newer version of protoc."
#endif  // PROTOBUF_MIN_PROTOC_VERSION
#include "google/protobuf/port_undef.inc"
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/arena.h"
#include "google/protobuf/arenastring.h"
#include "google/protobuf/generated_message_util.h"
#include "google/protobuf/metadata_lite.h"
#include "google/protobuf/message_lite.h"
#include "google/protobuf/repeated_field.h"  // IWYU pragma: export
#include "google/protobuf/extension_set.h"  // IWYU pragma: export
// @@protoc_insertion_point(includes)

// Must be included last.
#include "google/protobuf/port_def.inc"

#define PROTOBUF_INTERNAL_EXPORT_build_2fmake_2ftools_2fide_5fquery_2fprober_5fscripts_2fcpp_2ffoo_2eproto

PROTOBUF_NAMESPACE_OPEN
namespace internal {
class AnyMetadata;
}  // namespace internal
PROTOBUF_NAMESPACE_CLOSE

// Internal implementation detail -- do not use these members.
struct TableStruct_build_2fmake_2ftools_2fide_5fquery_2fprober_5fscripts_2fcpp_2ffoo_2eproto {
  static const ::uint32_t offsets[];
};
namespace ide_query {
namespace prober_scripts {
class ProtoMsg;
struct ProtoMsgDefaultTypeInternal;
extern ProtoMsgDefaultTypeInternal _ProtoMsg_default_instance_;
}  // namespace prober_scripts
}  // namespace ide_query
PROTOBUF_NAMESPACE_OPEN
template <>
::ide_query::prober_scripts::ProtoMsg* Arena::CreateMaybeMessage<::ide_query::prober_scripts::ProtoMsg>(Arena*);
PROTOBUF_NAMESPACE_CLOSE

namespace ide_query {
namespace prober_scripts {

// ===================================================================


// -------------------------------------------------------------------

class ProtoMsg final :
    public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:ide_query.prober_scripts.ProtoMsg) */ {
 public:
  inline ProtoMsg() : ProtoMsg(nullptr) {}
  ~ProtoMsg() override;
  explicit PROTOBUF_CONSTEXPR ProtoMsg(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  ProtoMsg(const ProtoMsg& from);
  ProtoMsg(ProtoMsg&& from) noexcept
    : ProtoMsg() {
    *this = ::std::move(from);
  }

  inline ProtoMsg& operator=(const ProtoMsg& from) {
    if (this == &from) return *this;
    CopyFrom(from);
    return *this;
  }
  inline ProtoMsg& operator=(ProtoMsg&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  static const ProtoMsg& default_instance() {
    return *internal_default_instance();
  }
  static inline const ProtoMsg* internal_default_instance() {
    return reinterpret_cast<const ProtoMsg*>(
               &_ProtoMsg_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    0;

  friend void swap(ProtoMsg& a, ProtoMsg& b) {
    a.Swap(&b);
  }
  inline void Swap(ProtoMsg* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(ProtoMsg* other) {
    if (other == this) return;
    ABSL_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  ProtoMsg* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<ProtoMsg>(arena);
  }
  ProtoMsg* New() const {
    return New(nullptr);
  }
  void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from)  final;
  void CopyFrom(const ProtoMsg& from);
  void MergeFrom(const ProtoMsg& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  ::size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::uint8_t* _InternalSerialize(
      ::uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  void SharedDtor();
  void SetCachedSize(int size) const;
  void InternalSwap(ProtoMsg* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() {
    return "ide_query.prober_scripts.ProtoMsg";
  }
  protected:
  explicit ProtoMsg(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  std::string GetTypeName() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kSomeFieldFieldNumber = 1,
  };
  // int64 some_field = 1;
  void clear_some_field() ;
  ::int64_t some_field() const;
  void set_some_field(::int64_t value);

  private:
  ::int64_t _internal_some_field() const;
  void _internal_set_some_field(::int64_t value);

  public:
  // @@protoc_insertion_point(class_scope:ide_query.prober_scripts.ProtoMsg)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::int64_t some_field_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_build_2fmake_2ftools_2fide_5fquery_2fprober_5fscripts_2fcpp_2ffoo_2eproto;
};

// ===================================================================




// ===================================================================


#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif  // __GNUC__
// -------------------------------------------------------------------

// ProtoMsg

// int64 some_field = 1;
inline void ProtoMsg::clear_some_field() {
  _impl_.some_field_ = ::int64_t{0};
}
inline ::int64_t ProtoMsg::some_field() const {
  // @@protoc_insertion_point(field_get:ide_query.prober_scripts.ProtoMsg.some_field)
  return _internal_some_field();
}
inline void ProtoMsg::set_some_field(::int64_t value) {
  _internal_set_some_field(value);
  // @@protoc_insertion_point(field_set:ide_query.prober_scripts.ProtoMsg.some_field)
}
inline ::int64_t ProtoMsg::_internal_some_field() const {
  return _impl_.some_field_;
}
inline void ProtoMsg::_internal_set_some_field(::int64_t value) {
  ;
  _impl_.some_field_ = value;
}

#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif  // __GNUC__

// @@protoc_insertion_point(namespace_scope)
}  // namespace prober_scripts
}  // namespace ide_query


// @@protoc_insertion_point(global_scope)

#include "google/protobuf/port_undef.inc"

#endif  // GOOGLE_PROTOBUF_INCLUDED_build_2fmake_2ftools_2fide_5fquery_2fprober_5fscripts_2fcpp_2ffoo_2eproto_2epb_2eh
*‰^
vsoong/.intermediates/external/abseil-cpp/absl_base_core_headers_hdrs/gen/my_include_dir/absl/base/thread_annotations.hŽ]// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// File: 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_THREAD_ANNOTATIONS_H_
#define ABSL_BASE_THREAD_ANNOTATIONS_H_

#include "absl/base/attributes.h"
#include "absl/base/config.h"

// ABSL_GUARDED_BY()
//
// Documents if a shared field or global variable needs to be protected by a
// mutex. ABSL_GUARDED_BY() allows the user to specify a particular mutex that
// should be held when accessing the annotated variable.
//
// Although this annotation (and ABSL_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_ ABSL_GUARDED_BY(mu_);
//     ...
//   };
#if ABSL_HAVE_ATTRIBUTE(guarded_by)
#define ABSL_GUARDED_BY(x) __attribute__((guarded_by(x)))
#else
#define ABSL_GUARDED_BY(x)
#endif

// ABSL_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_ ABSL_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_ ABSL_GUARDED_BY(mu1_) ABSL_PT_GUARDED_BY(mu2_);
#if ABSL_HAVE_ATTRIBUTE(pt_guarded_by)
#define ABSL_PT_GUARDED_BY(x) __attribute__((pt_guarded_by(x)))
#else
#define ABSL_PT_GUARDED_BY(x)
#endif

// ABSL_ACQUIRED_AFTER() / ABSL_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 ABSL_ACQUIRED_AFTER
// and ABSL_ACQUIRED_BEFORE.)
//
// As with ABSL_GUARDED_BY, this is only applicable to mutexes that are shared
// fields or global variables.
//
// Example:
//
//   Mutex m1_;
//   Mutex m2_ ABSL_ACQUIRED_AFTER(m1_);
#if ABSL_HAVE_ATTRIBUTE(acquired_after)
#define ABSL_ACQUIRED_AFTER(...) __attribute__((acquired_after(__VA_ARGS__)))
#else
#define ABSL_ACQUIRED_AFTER(...)
#endif

#if ABSL_HAVE_ATTRIBUTE(acquired_before)
#define ABSL_ACQUIRED_BEFORE(...) __attribute__((acquired_before(__VA_ARGS__)))
#else
#define ABSL_ACQUIRED_BEFORE(...)
#endif

// ABSL_EXCLUSIVE_LOCKS_REQUIRED() / ABSL_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
// ABSL_EXCLUSIVE_LOCKS_REQUIRED, while const methods should be annotated with
// ABSL_SHARED_LOCKS_REQUIRED.
//
// Example:
//
//   Mutex mu1, mu2;
//   int a ABSL_GUARDED_BY(mu1);
//   int b ABSL_GUARDED_BY(mu2);
//
//   void foo() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2) { ... }
//   void bar() const ABSL_SHARED_LOCKS_REQUIRED(mu1, mu2) { ... }
#if ABSL_HAVE_ATTRIBUTE(exclusive_locks_required)
#define ABSL_EXCLUSIVE_LOCKS_REQUIRED(...) \
  __attribute__((exclusive_locks_required(__VA_ARGS__)))
#else
#define ABSL_EXCLUSIVE_LOCKS_REQUIRED(...)
#endif

#if ABSL_HAVE_ATTRIBUTE(shared_locks_required)
#define ABSL_SHARED_LOCKS_REQUIRED(...) \
  __attribute__((shared_locks_required(__VA_ARGS__)))
#else
#define ABSL_SHARED_LOCKS_REQUIRED(...)
#endif

// ABSL_LOCKS_EXCLUDED()
//
// Documents the locks that cannot be held by callers of this function, as they
// might be acquired by this function (Abseil's `Mutex` locks are
// non-reentrant).
#if ABSL_HAVE_ATTRIBUTE(locks_excluded)
#define ABSL_LOCKS_EXCLUDED(...) __attribute__((locks_excluded(__VA_ARGS__)))
#else
#define ABSL_LOCKS_EXCLUDED(...)
#endif

// ABSL_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 ABSL_LOCK_RETURNED.
#if ABSL_HAVE_ATTRIBUTE(lock_returned)
#define ABSL_LOCK_RETURNED(x) __attribute__((lock_returned(x)))
#else
#define ABSL_LOCK_RETURNED(x)
#endif

// ABSL_LOCKABLE
//
// Documents if a class/type is a lockable type (such as the `Mutex` class).
#if ABSL_HAVE_ATTRIBUTE(lockable)
#define ABSL_LOCKABLE __attribute__((lockable))
#else
#define ABSL_LOCKABLE
#endif

// ABSL_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.
#if ABSL_HAVE_ATTRIBUTE(scoped_lockable)
#define ABSL_SCOPED_LOCKABLE __attribute__((scoped_lockable))
#else
#define ABSL_SCOPED_LOCKABLE
#endif

// ABSL_EXCLUSIVE_LOCK_FUNCTION()
//
// Documents functions that acquire a lock in the body of a function, and do
// not release it.
#if ABSL_HAVE_ATTRIBUTE(exclusive_lock_function)
#define ABSL_EXCLUSIVE_LOCK_FUNCTION(...) \
  __attribute__((exclusive_lock_function(__VA_ARGS__)))
#else
#define ABSL_EXCLUSIVE_LOCK_FUNCTION(...)
#endif

// ABSL_SHARED_LOCK_FUNCTION()
//
// Documents functions that acquire a shared (reader) lock in the body of a
// function, and do not release it.
#if ABSL_HAVE_ATTRIBUTE(shared_lock_function)
#define ABSL_SHARED_LOCK_FUNCTION(...) \
  __attribute__((shared_lock_function(__VA_ARGS__)))
#else
#define ABSL_SHARED_LOCK_FUNCTION(...)
#endif

// ABSL_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.
#if ABSL_HAVE_ATTRIBUTE(unlock_function)
#define ABSL_UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__)))
#else
#define ABSL_UNLOCK_FUNCTION(...)
#endif

// ABSL_EXCLUSIVE_TRYLOCK_FUNCTION() / ABSL_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`.
#if ABSL_HAVE_ATTRIBUTE(exclusive_trylock_function)
#define ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(...) \
  __attribute__((exclusive_trylock_function(__VA_ARGS__)))
#else
#define ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(...)
#endif

#if ABSL_HAVE_ATTRIBUTE(shared_trylock_function)
#define ABSL_SHARED_TRYLOCK_FUNCTION(...) \
  __attribute__((shared_trylock_function(__VA_ARGS__)))
#else
#define ABSL_SHARED_TRYLOCK_FUNCTION(...)
#endif

// ABSL_ASSERT_EXCLUSIVE_LOCK() / ABSL_ASSERT_SHARED_LOCK()
//
// Documents functions that dynamically check to see if a lock is held, and fail
// if it is not held.
#if ABSL_HAVE_ATTRIBUTE(assert_exclusive_lock)
#define ABSL_ASSERT_EXCLUSIVE_LOCK(...) \
  __attribute__((assert_exclusive_lock(__VA_ARGS__)))
#else
#define ABSL_ASSERT_EXCLUSIVE_LOCK(...)
#endif

#if ABSL_HAVE_ATTRIBUTE(assert_shared_lock)
#define ABSL_ASSERT_SHARED_LOCK(...) \
  __attribute__((assert_shared_lock(__VA_ARGS__)))
#else
#define ABSL_ASSERT_SHARED_LOCK(...)
#endif

// ABSL_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.
#if ABSL_HAVE_ATTRIBUTE(no_thread_safety_analysis)
#define ABSL_NO_THREAD_SAFETY_ANALYSIS \
  __attribute__((no_thread_safety_analysis))
#else
#define ABSL_NO_THREAD_SAFETY_ANALYSIS
#endif

//------------------------------------------------------------------------------
// Tool-Supplied Annotations
//------------------------------------------------------------------------------

// ABSL_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 ABSL_TS_UNCHECKED(x) ""

// ABSL_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 ABSL_TS_UNCHECKED.
#define ABSL_TS_FIXME(x) ""

// Like ABSL_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 ABSL_NO_THREAD_SAFETY_ANALYSIS_FIXME ABSL_NO_THREAD_SAFETY_ANALYSIS

// Similar to ABSL_NO_THREAD_SAFETY_ANALYSIS_FIXME, this macro marks a
// ABSL_GUARDED_BY annotation that needs to be fixed, because it is producing
// thread safety warning. It disables the ABSL_GUARDED_BY.
#define ABSL_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 ABSL_TS_UNCHECKED_READ(x) absl::base_internal::ts_unchecked_read(x)

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {

// Takes a reference to a guarded data member, and returns an unguarded
// reference.
// Do not use this function directly, use ABSL_TS_UNCHECKED_READ instead.
template <typename T>
inline const T& ts_unchecked_read(const T& v) ABSL_NO_THREAD_SAFETY_ANALYSIS {
  return v;
}

template <typename T>
inline T& ts_unchecked_read(T& v) ABSL_NO_THREAD_SAFETY_ANALYSIS {
  return v;
}

}  // namespace base_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_BASE_THREAD_ANNOTATIONS_H_
*Î�
rsoong/.intermediates/external/abseil-cpp/absl_synchronization_hdrs/gen/my_include_dir/absl/synchronization/mutex.hÖŒ// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// mutex.h
// -----------------------------------------------------------------------------
//
// This header file defines a `Mutex` -- a mutually exclusive lock -- and the
// most common type of synchronization primitive for facilitating locks on
// shared resources. A mutex is used to prevent multiple threads from accessing
// and/or writing to a shared resource concurrently.
//
// Unlike a `std::mutex`, the Abseil `Mutex` provides the following additional
// features:
//   * Conditional predicates intrinsic to the `Mutex` object
//   * Shared/reader locks, in addition to standard exclusive/writer locks
//   * Deadlock detection and debug support.
//
// The following helper classes are also defined within this file:
//
//  MutexLock - An RAII wrapper to acquire and release a `Mutex` for exclusive/
//              write access within the current scope.
//
//  ReaderMutexLock
//            - An RAII wrapper to acquire and release a `Mutex` for shared/read
//              access within the current scope.
//
//  WriterMutexLock
//            - Effectively an alias for `MutexLock` above, designed for use in
//              distinguishing reader and writer locks within code.
//
// In addition to simple mutex locks, this file also defines ways to perform
// locking under certain conditions.
//
//  Condition - (Preferred) Used to wait for a particular predicate that
//              depends on state protected by the `Mutex` to become true.
//  CondVar   - A lower-level variant of `Condition` that relies on
//              application code to explicitly signal the `CondVar` when
//              a condition has been met.
//
// See below for more information on using `Condition` or `CondVar`.
//
// Mutexes and mutex behavior can be quite complicated. The information within
// this header file is limited, as a result. Please consult the Mutex guide for
// more complete information and examples.

#ifndef ABSL_SYNCHRONIZATION_MUTEX_H_
#define ABSL_SYNCHRONIZATION_MUTEX_H_

#include <atomic>
#include <cstdint>
#include <cstring>
#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"
#include "absl/base/internal/thread_identity.h"
#include "absl/base/internal/tsan_mutex_interface.h"
#include "absl/base/nullability.h"
#include "absl/base/port.h"
#include "absl/base/thread_annotations.h"
#include "absl/synchronization/internal/kernel_timeout.h"
#include "absl/synchronization/internal/per_thread_sem.h"
#include "absl/time/time.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

class Condition;
struct SynchWaitParams;

// -----------------------------------------------------------------------------
// Mutex
// -----------------------------------------------------------------------------
//
// A `Mutex` is a non-reentrant (aka non-recursive) Mutually Exclusive lock
// on some resource, typically a variable or data structure with associated
// invariants. Proper usage of mutexes prevents concurrent access by different
// threads to the same resource.
//
// A `Mutex` has two basic operations: `Mutex::Lock()` and `Mutex::Unlock()`.
// The `Lock()` operation *acquires* a `Mutex` (in a state known as an
// *exclusive* -- or *write* -- lock), and the `Unlock()` operation *releases* a
// Mutex. During the span of time between the Lock() and Unlock() operations,
// a mutex is said to be *held*. By design, all mutexes support exclusive/write
// locks, as this is the most common way to use a mutex.
//
// Mutex operations are only allowed under certain conditions; otherwise an
// operation is "invalid", and disallowed by the API. The conditions concern
// both the current state of the mutex and the identity of the threads that
// are performing the operations.
//
// The `Mutex` state machine for basic lock/unlock operations is quite simple:
//
// |                | Lock()                 | Unlock() |
// |----------------+------------------------+----------|
// | Free           | Exclusive              | invalid  |
// | Exclusive      | blocks, then exclusive | Free     |
//
// The full conditions are as follows.
//
// * Calls to `Unlock()` require that the mutex be held, and must be made in the
//   same thread that performed the corresponding `Lock()` operation which
//   acquired the mutex; otherwise the call is invalid.
//
// * The mutex being non-reentrant (or non-recursive) means that a call to
//   `Lock()` or `TryLock()` must not be made in a thread that already holds the
//   mutex; such a call is invalid.
//
// * In other words, the state of being "held" has both a temporal component
//   (from `Lock()` until `Unlock()`) as well as a thread identity component:
//   the mutex is held *by a particular thread*.
//
// An "invalid" operation has undefined behavior. The `Mutex` implementation
// is allowed to do anything on an invalid call, including, but not limited to,
// crashing with a useful error message, silently succeeding, or corrupting
// data structures. In debug mode, the implementation may crash with a useful
// error message.
//
// `Mutex` is not guaranteed to be "fair" in prioritizing waiting threads; it
// is, however, approximately fair over long periods, and starvation-free for
// threads at the same priority.
//
// The lock/unlock primitives are now annotated with lock annotations
// defined in (base/thread_annotations.h). When writing multi-threaded code,
// you should use lock annotations whenever possible to document your lock
// synchronization policy. Besides acting as documentation, these annotations
// also help compilers or static analysis tools to identify and warn about
// issues that could potentially result in race conditions and deadlocks.
//
// For more information about the lock annotations, please see
// [Thread Safety
// Analysis](http://clang.llvm.org/docs/ThreadSafetyAnalysis.html) in the Clang
// documentation.
//
// See also `MutexLock`, below, for scoped `Mutex` acquisition.

class ABSL_LOCKABLE ABSL_ATTRIBUTE_WARN_UNUSED Mutex {
 public:
  // Creates a `Mutex` that is not held by anyone. This constructor is
  // typically used for Mutexes allocated on the heap or the stack.
  //
  // To create `Mutex` instances with static storage duration
  // (e.g. a namespace-scoped or global variable), see
  // `Mutex::Mutex(absl::kConstInit)` below instead.
  Mutex();

  // Creates a mutex with static storage duration.  A global variable
  // constructed this way avoids the lifetime issues that can occur on program
  // startup and shutdown.  (See absl/base/const_init.h.)
  //
  // For Mutexes allocated on the heap and stack, instead use the default
  // constructor, which can interact more fully with the thread sanitizer.
  //
  // Example usage:
  //   namespace foo {
  //   ABSL_CONST_INIT absl::Mutex mu(absl::kConstInit);
  //   }
  explicit constexpr Mutex(absl::ConstInitType);

  ~Mutex();

  // Mutex::Lock()
  //
  // Blocks the calling thread, if necessary, until this `Mutex` is free, and
  // then acquires it exclusively. (This lock is also known as a "write lock.")
  void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION();

  // Mutex::Unlock()
  //
  // Releases this `Mutex` and returns it from the exclusive/write state to the
  // free state. Calling thread must hold the `Mutex` exclusively.
  void Unlock() ABSL_UNLOCK_FUNCTION();

  // Mutex::TryLock()
  //
  // If the mutex can be acquired without blocking, does so exclusively and
  // returns `true`. Otherwise, returns `false`. Returns `true` with high
  // probability if the `Mutex` was free.
  [[nodiscard]] bool TryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true);

  // Mutex::AssertHeld()
  //
  // Require that the mutex be held exclusively (write mode) by this thread.
  //
  // If the mutex is not currently held by this thread, this function may report
  // an error (typically by crashing with a diagnostic) or it may do nothing.
  // This function is intended only as a tool to assist debugging; it doesn't
  // guarantee correctness.
  void AssertHeld() const ABSL_ASSERT_EXCLUSIVE_LOCK();

  // ---------------------------------------------------------------------------
  // Reader-Writer Locking
  // ---------------------------------------------------------------------------

  // A Mutex can also be used as a starvation-free reader-writer lock.
  // Neither read-locks nor write-locks are reentrant/recursive to avoid
  // potential client programming errors.
  //
  // The Mutex API provides `Writer*()` aliases for the existing `Lock()`,
  // `Unlock()` and `TryLock()` methods for use within applications mixing
  // reader/writer locks. Using `Reader*()` and `Writer*()` operations in this
  // manner can make locking behavior clearer when mixing read and write modes.
  //
  // Introducing reader locks necessarily complicates the `Mutex` state
  // machine somewhat. The table below illustrates the allowed state transitions
  // of a mutex in such cases. Note that ReaderLock() may block even if the lock
  // is held in shared mode; this occurs when another thread is blocked on a
  // call to WriterLock().
  //
  // ---------------------------------------------------------------------------
  //     Operation: WriterLock() Unlock()  ReaderLock()           ReaderUnlock()
  // ---------------------------------------------------------------------------
  // State
  // ---------------------------------------------------------------------------
  // Free           Exclusive    invalid   Shared(1)              invalid
  // Shared(1)      blocks       invalid   Shared(2) or blocks    Free
  // Shared(n) n>1  blocks       invalid   Shared(n+1) or blocks  Shared(n-1)
  // Exclusive      blocks       Free      blocks                 invalid
  // ---------------------------------------------------------------------------
  //
  // In comments below, "shared" refers to a state of Shared(n) for any n > 0.

  // Mutex::ReaderLock()
  //
  // Blocks the calling thread, if necessary, until this `Mutex` is either free,
  // or in shared mode, and then acquires a share of it. Note that
  // `ReaderLock()` will block if some other thread has an exclusive/writer lock
  // on the mutex.

  void ReaderLock() ABSL_SHARED_LOCK_FUNCTION();

  // Mutex::ReaderUnlock()
  //
  // Releases a read share of this `Mutex`. `ReaderUnlock` may return a mutex to
  // the free state if this thread holds the last reader lock on the mutex. Note
  // that you cannot call `ReaderUnlock()` on a mutex held in write mode.
  void ReaderUnlock() ABSL_UNLOCK_FUNCTION();

  // Mutex::ReaderTryLock()
  //
  // If the mutex can be acquired without blocking, acquires this mutex for
  // shared access and returns `true`. Otherwise, returns `false`. Returns
  // `true` with high probability if the `Mutex` was free or shared.
  [[nodiscard]] bool ReaderTryLock() ABSL_SHARED_TRYLOCK_FUNCTION(true);

  // Mutex::AssertReaderHeld()
  //
  // Require that the mutex be held at least in shared mode (read mode) by this
  // thread.
  //
  // If the mutex is not currently held by this thread, this function may report
  // an error (typically by crashing with a diagnostic) or it may do nothing.
  // This function is intended only as a tool to assist debugging; it doesn't
  // guarantee correctness.
  void AssertReaderHeld() const ABSL_ASSERT_SHARED_LOCK();

  // Mutex::WriterLock()
  // Mutex::WriterUnlock()
  // Mutex::WriterTryLock()
  //
  // Aliases for `Mutex::Lock()`, `Mutex::Unlock()`, and `Mutex::TryLock()`.
  //
  // These methods may be used (along with the complementary `Reader*()`
  // methods) to distinguish simple exclusive `Mutex` usage (`Lock()`,
  // etc.) from reader/writer lock usage.
  void WriterLock() ABSL_EXCLUSIVE_LOCK_FUNCTION() { this->Lock(); }

  void WriterUnlock() ABSL_UNLOCK_FUNCTION() { this->Unlock(); }

  [[nodiscard]] bool WriterTryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true) {
    return this->TryLock();
  }

  // ---------------------------------------------------------------------------
  // Conditional Critical Regions
  // ---------------------------------------------------------------------------

  // Conditional usage of a `Mutex` can occur using two distinct paradigms:
  //
  //   * Use of `Mutex` member functions with `Condition` objects.
  //   * Use of the separate `CondVar` abstraction.
  //
  // In general, prefer use of `Condition` and the `Mutex` member functions
  // listed below over `CondVar`. When there are multiple threads waiting on
  // distinctly different conditions, however, a battery of `CondVar`s may be
  // more efficient. This section discusses use of `Condition` objects.
  //
  // `Mutex` contains member functions for performing lock operations only under
  // certain conditions, of class `Condition`. For correctness, the `Condition`
  // must return a boolean that is a pure function, only of state protected by
  // the `Mutex`. The condition must be invariant w.r.t. environmental state
  // such as thread, cpu id, or time, and must be `noexcept`. The condition will
  // always be invoked with the mutex held in at least read mode, so you should
  // not block it for long periods or sleep it on a timer.
  //
  // Since a condition must not depend directly on the current time, use
  // `*WithTimeout()` member function variants to make your condition
  // effectively true after a given duration, or `*WithDeadline()` variants to
  // make your condition effectively true after a given time.
  //
  // The condition function should have no side-effects aside from debug
  // logging; as a special exception, the function may acquire other mutexes
  // provided it releases all those that it acquires.  (This exception was
  // required to allow logging.)

  // Mutex::Await()
  //
  // Unlocks this `Mutex` and blocks until simultaneously both `cond` is `true`
  // and this `Mutex` can be reacquired, then reacquires this `Mutex` in the
  // same mode in which it was previously held. If the condition is initially
  // `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) {
    AwaitCommon(cond, synchronization_internal::KernelTimeout::Never());
  }

  // Mutex::LockWhen()
  // Mutex::ReaderLockWhen()
  // Mutex::WriterLockWhen()
  //
  // Blocks until simultaneously both `cond` is `true` and this `Mutex` can
  // 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() {
    LockWhenCommon(cond, synchronization_internal::KernelTimeout::Never(),
                   true);
  }

  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);
  }

  // ---------------------------------------------------------------------------
  // Mutex Variants with Timeouts/Deadlines
  // ---------------------------------------------------------------------------

  // Mutex::AwaitWithTimeout()
  // Mutex::AwaitWithDeadline()
  //
  // Unlocks this `Mutex` and blocks until simultaneously:
  //   - either `cond` is true or the {timeout has expired, deadline has passed}
  //     and
  //   - this `Mutex` can be reacquired,
  // then reacquire this `Mutex` in the same mode in which it was previously
  // held, returning `true` iff `cond` is `true` on return.
  //
  // If the condition is initially `true`, the implementation *may* skip the
  // release/re-acquire step and return immediately.
  //
  // Deadlines in the past are equivalent to an immediate deadline.
  // 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) {
    return AwaitCommon(cond, synchronization_internal::KernelTimeout{timeout});
  }

  bool AwaitWithDeadline(const Condition& cond, absl::Time deadline) {
    return AwaitCommon(cond, synchronization_internal::KernelTimeout{deadline});
  }

  // Mutex::LockWhenWithTimeout()
  // Mutex::ReaderLockWhenWithTimeout()
  // Mutex::WriterLockWhenWithTimeout()
  //
  // Blocks until simultaneously both:
  //   - either `cond` is `true` or the timeout has expired, and
  //   - this `Mutex` can be acquired,
  // then atomically acquires this `Mutex`, returning `true` iff `cond` is
  // `true` on return.
  //
  // Negative timeouts are equivalent to a zero timeout.
  bool LockWhenWithTimeout(const Condition& cond, absl::Duration timeout)
      ABSL_EXCLUSIVE_LOCK_FUNCTION() {
    return LockWhenCommon(
        cond, synchronization_internal::KernelTimeout{timeout}, true);
  }
  bool ReaderLockWhenWithTimeout(const Condition& cond, absl::Duration timeout)
      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);
  }

  // Mutex::LockWhenWithDeadline()
  // Mutex::ReaderLockWhenWithDeadline()
  // Mutex::WriterLockWhenWithDeadline()
  //
  // Blocks until simultaneously both:
  //   - either `cond` is `true` or the deadline has been passed, and
  //   - this `Mutex` can be acquired,
  // then atomically acquires this Mutex, returning `true` iff `cond` is `true`
  // on return.
  //
  // Deadlines in the past are equivalent to an immediate deadline.
  bool LockWhenWithDeadline(const Condition& cond, absl::Time deadline)
      ABSL_EXCLUSIVE_LOCK_FUNCTION() {
    return LockWhenCommon(
        cond, synchronization_internal::KernelTimeout{deadline}, true);
  }
  bool ReaderLockWhenWithDeadline(const Condition& cond, absl::Time deadline)
      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);
  }

  // ---------------------------------------------------------------------------
  // Debug Support: Invariant Checking, Deadlock Detection, Logging.
  // ---------------------------------------------------------------------------

  // Mutex::EnableInvariantDebugging()
  //
  // If `invariant`!=null and if invariant debugging has been enabled globally,
  // cause `(*invariant)(arg)` to be called at moments when the invariant for
  // this `Mutex` should hold (for example: just after acquire, just before
  // release).
  //
  // The routine `invariant` should have no side-effects since it is not
  // guaranteed how many times it will be called; it should check the invariant
  // and crash if it does not hold. Enabling global invariant debugging may
  // substantially reduce `Mutex` performance; it should be set only for
  // non-production runs.  Optimization options may also disable invariant
  // checks.
  void EnableInvariantDebugging(
      void (*absl_nullable invariant)(void* absl_nullability_unknown),
      void* absl_nullability_unknown arg);

  // Mutex::EnableDebugLog()
  //
  // Cause all subsequent uses of this `Mutex` to be logged via
  // `ABSL_RAW_LOG(INFO)`. Log entries are tagged with `name` if no previous
  // call to `EnableInvariantDebugging()` or `EnableDebugLog()` has been made.
  //
  // Note: This method substantially reduces `Mutex` performance.
  void EnableDebugLog(const char* absl_nullable name);

  // Deadlock detection

  // Mutex::ForgetDeadlockInfo()
  //
  // Forget any deadlock-detection information previously gathered
  // about this `Mutex`. Call this method in debug mode when the lock ordering
  // of a `Mutex` changes.
  void ForgetDeadlockInfo();

  // Mutex::AssertNotHeld()
  //
  // Return immediately if this thread does not hold this `Mutex` in any
  // mode; otherwise, may report an error (typically by crashing with a
  // diagnostic), or may return immediately.
  //
  // Currently this check is performed only if all of:
  //    - in debug mode
  //    - SetMutexDeadlockDetectionMode() has been set to kReport or kAbort
  //    - number of locks concurrently held by this thread is not large.
  // are true.
  void AssertNotHeld() const;

  // Special cases.

  // A `MuHow` is a constant that indicates how a lock should be acquired.
  // Internal implementation detail.  Clients should ignore.
  typedef const struct MuHowS* MuHow;

  // Mutex::InternalAttemptToUseMutexInFatalSignalHandler()
  //
  // Causes the `Mutex` implementation to prepare itself for re-entry caused by
  // future use of `Mutex` within a fatal signal handler. This method is
  // intended for use only for last-ditch attempts to log crash information.
  // It does not guarantee that attempts to use Mutexes within the handler will
  // not deadlock; it merely makes other faults less likely.
  //
  // WARNING:  This routine must be invoked from a signal handler, and the
  // signal handler must either loop forever or terminate the process.
  // Attempts to return from (or `longjmp` out of) the signal handler once this
  // call has been made may cause arbitrary program behaviour including
  // crashes and deadlocks.
  static void InternalAttemptToUseMutexInFatalSignalHandler();

 private:
  std::atomic<intptr_t> mu_;  // The Mutex state.

  // Post()/Wait() versus associated PerThreadSem; in class for required
  // friendship with PerThreadSem.
  static void IncrementSynchSem(Mutex* absl_nonnull mu,
                                base_internal::PerThreadSynch* absl_nonnull w);
  static bool DecrementSynchSem(Mutex* absl_nonnull mu,
                                base_internal::PerThreadSynch* absl_nonnull w,
                                synchronization_internal::KernelTimeout t);

  // slow path acquire
  void LockSlowLoop(SynchWaitParams* absl_nonnull waitp, int flags);
  // wrappers around LockSlowLoop()
  bool LockSlowWithDeadline(MuHow absl_nonnull how,
                            const Condition* absl_nullable cond,
                            synchronization_internal::KernelTimeout t,
                            int flags);
  void LockSlow(MuHow absl_nonnull how, const Condition* absl_nullable cond,
                int flags) ABSL_ATTRIBUTE_COLD;
  // slow path release
  void UnlockSlow(SynchWaitParams* absl_nullable 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* absl_nonnull s);
  // Block a thread on mutex.
  void Block(base_internal::PerThreadSynch* absl_nonnull s);
  // Wake a thread; return successor.
  base_internal::PerThreadSynch* absl_nullable Wakeup(
      base_internal::PerThreadSynch* absl_nonnull w);
  void Dtor();

  friend class CondVar;   // for access to Trans()/Fer().
  void Trans(MuHow absl_nonnull how);  // used for CondVar->Mutex transfer
  void Fer(base_internal::PerThreadSynch* absl_nonnull
           w);  // used for CondVar->Mutex transfer

  // Catch the error of writing Mutex when intending MutexLock.
  explicit Mutex(const volatile Mutex* absl_nullable /*ignored*/) {}

  Mutex(const Mutex&) = delete;
  Mutex& operator=(const Mutex&) = delete;
};

// -----------------------------------------------------------------------------
// Mutex RAII Wrappers
// -----------------------------------------------------------------------------

// MutexLock
//
// `MutexLock` is a helper class, which acquires and releases a `Mutex` via
// RAII.
//
// Example:
//
// Class Foo {
//  public:
//   Foo::Bar* Baz() {
//     MutexLock lock(&mu_);
//     ...
//     return bar;
//   }
//
// private:
//   Mutex mu_;
// };
class ABSL_SCOPED_LOCKABLE MutexLock {
 public:
  // Constructors

  // Calls `mu->Lock()` and returns when that call returns. That is, `*mu` is
  // guaranteed to be locked when this object is constructed. Requires that
  // `mu` be dereferenceable.
  explicit MutexLock(Mutex* absl_nonnull mu) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu)
      : mu_(mu) {
    this->mu_->Lock();
  }

  // Like above, but calls `mu->LockWhen(cond)` instead. That is, in addition to
  // the above, the condition given by `cond` is also guaranteed to hold when
  // this object is constructed.
  explicit MutexLock(Mutex* absl_nonnull mu, const Condition& cond)
      ABSL_EXCLUSIVE_LOCK_FUNCTION(mu)
      : mu_(mu) {
    this->mu_->LockWhen(cond);
  }

  MutexLock(const MutexLock&) = delete;  // NOLINT(runtime/mutex)
  MutexLock(MutexLock&&) = delete;       // NOLINT(runtime/mutex)
  MutexLock& operator=(const MutexLock&) = delete;
  MutexLock& operator=(MutexLock&&) = delete;

  ~MutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_->Unlock(); }

 private:
  Mutex* absl_nonnull const mu_;
};

// ReaderMutexLock
//
// The `ReaderMutexLock` is a helper class, like `MutexLock`, which acquires and
// releases a shared lock on a `Mutex` via RAII.
class ABSL_SCOPED_LOCKABLE ReaderMutexLock {
 public:
  explicit ReaderMutexLock(Mutex* absl_nonnull mu) ABSL_SHARED_LOCK_FUNCTION(mu)
      : mu_(mu) {
    mu->ReaderLock();
  }

  explicit ReaderMutexLock(Mutex* absl_nonnull mu, const Condition& cond)
      ABSL_SHARED_LOCK_FUNCTION(mu)
      : mu_(mu) {
    mu->ReaderLockWhen(cond);
  }

  ReaderMutexLock(const ReaderMutexLock&) = delete;
  ReaderMutexLock(ReaderMutexLock&&) = delete;
  ReaderMutexLock& operator=(const ReaderMutexLock&) = delete;
  ReaderMutexLock& operator=(ReaderMutexLock&&) = delete;

  ~ReaderMutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_->ReaderUnlock(); }

 private:
  Mutex* absl_nonnull const mu_;
};

// WriterMutexLock
//
// The `WriterMutexLock` is a helper class, like `MutexLock`, which acquires and
// releases a write (exclusive) lock on a `Mutex` via RAII.
class ABSL_SCOPED_LOCKABLE WriterMutexLock {
 public:
  explicit WriterMutexLock(Mutex* absl_nonnull mu)
      ABSL_EXCLUSIVE_LOCK_FUNCTION(mu)
      : mu_(mu) {
    mu->WriterLock();
  }

  explicit WriterMutexLock(Mutex* absl_nonnull mu, const Condition& cond)
      ABSL_EXCLUSIVE_LOCK_FUNCTION(mu)
      : mu_(mu) {
    mu->WriterLockWhen(cond);
  }

  WriterMutexLock(const WriterMutexLock&) = delete;
  WriterMutexLock(WriterMutexLock&&) = delete;
  WriterMutexLock& operator=(const WriterMutexLock&) = delete;
  WriterMutexLock& operator=(WriterMutexLock&&) = delete;

  ~WriterMutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_->WriterUnlock(); }

 private:
  Mutex* absl_nonnull const mu_;
};

// -----------------------------------------------------------------------------
// Condition
// -----------------------------------------------------------------------------
//
// `Mutex` contains a number of member functions which take a `Condition` as an
// argument; clients can wait for conditions to become `true` before attempting
// to acquire the mutex. These sections are known as "condition critical"
// sections. To use a `Condition`, you simply need to construct it, and use
// within an appropriate `Mutex` member function; everything else in the
// `Condition` class is an implementation detail.
//
// A `Condition` is specified as a function pointer which returns a boolean.
// `Condition` functions should be pure functions -- their results should depend
// only on passed arguments, should not consult any external state (such as
// clocks), and should have no side-effects, aside from debug logging. Any
// objects that the function may access should be limited to those which are
// constant while the mutex is blocked on the condition (e.g. a stack variable),
// or objects of state protected explicitly by the mutex.
//
// No matter which construction is used for `Condition`, the underlying
// function pointer / functor / callable must not throw any
// exceptions. Correctness of `Mutex` / `Condition` is not guaranteed in
// the face of a throwing `Condition`. (When Abseil is allowed to depend
// on C++17, these function pointers will be explicitly marked
// `noexcept`; until then this requirement cannot be enforced in the
// type system.)
//
// Note: to use a `Condition`, you need only construct it and pass it to a
// suitable `Mutex' member function, such as `Mutex::Await()`, or to the
// constructor of one of the scope guard classes.
//
// Example using LockWhen/Unlock:
//
//   // assume count_ is not internal reference count
//   int count_ ABSL_GUARDED_BY(mu_);
//   Condition count_is_zero(+[](int *count) { return *count == 0; }, &count_);
//
//   mu_.LockWhen(count_is_zero);
//   // ...
//   mu_.Unlock();
//
// Example using a scope guard:
//
//   {
//     MutexLock lock(&mu_, count_is_zero);
//     // ...
//   }
//
// When multiple threads are waiting on exactly the same condition, make sure
// that they are constructed with the same parameters (same pointer to function
// + arg, or same pointer to object + method), so that the mutex implementation
// can avoid redundantly evaluating the same condition for each thread.
class Condition {
 public:
  // A Condition that returns the result of "(*func)(arg)"
  Condition(bool (*absl_nonnull func)(void* absl_nullability_unknown),
            void* absl_nullability_unknown arg);

  // Templated version for people who are averse to casts.
  //
  // To use a lambda, prepend it with unary plus, which converts the lambda
  // into a function pointer:
  //     Condition(+[](T* t) { return ...; }, arg).
  //
  // Note: lambdas in this case must contain no bound variables.
  //
  // See class comment for performance advice.
  template <typename T>
  Condition(bool (*absl_nonnull func)(T* absl_nullability_unknown),
            T* absl_nullability_unknown arg);

  // Same as above, but allows for cases where `arg` comes from a pointer that
  // is convertible to the function parameter type `T*` but not an exact match.
  //
  // For example, the argument might be `X*` but the function takes `const X*`,
  // or the argument might be `Derived*` while the function takes `Base*`, and
  // so on for cases where the argument pointer can be implicitly converted.
  //
  // Implementation notes: This constructor overload is required in addition to
  // the one above to allow deduction of `T` from `arg` for cases such as where
  // 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 (*absl_nonnull func)(T* absl_nullability_unknown),
      typename absl::internal::type_identity<T>::type* absl_nullability_unknown
      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::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* absl_nonnull object,
      bool (absl::internal::type_identity<T>::type::* absl_nonnull method)());

  // Same as above, for const members
  template <typename T>
  Condition(
      const T* absl_nonnull object,
      bool (absl::internal::type_identity<T>::type::* absl_nonnull method)()
          const);

  // A Condition that returns the value of `*cond`
  explicit Condition(const bool* absl_nonnull cond);

  // Templated version for invoking a functor that returns a `bool`.
  // This approach accepts pointers to non-mutable lambdas, `std::function`,
  // the result of` std::bind` and user-defined functors that define
  // `bool F::operator()() const`.
  //
  // Example:
  //
  //   auto reached = [this, current]() {
  //     mu_.AssertReaderHeld();                // For annotalysis.
  //     return processed_ >= current;
  //   };
  //   mu_.Await(Condition(&reached));
  //
  // NOTE: never use "mu_.AssertHeld()" instead of "mu_.AssertReaderHeld()" in
  // the lambda as it may be called when the mutex is being unlocked from a
  // scope holding only a reader lock, which will make the assertion not
  // fulfilled and crash the binary.

  // See class comment for performance advice. In particular, if there
  // might be more than one waiter for the same condition, make sure
  // that all waiters construct the condition with the same pointers.

  // Implementation note: The second template parameter ensures that this
  // constructor doesn't participate in overload resolution if T doesn't have
  // `bool operator() const`.
  template <typename T, typename E = decltype(static_cast<bool (T::*)() const>(
                            &T::operator()))>
  explicit Condition(const T* absl_nonnull obj)
      : Condition(obj, static_cast<bool (T::*)() const>(&T::operator())) {}

  // A Condition that always returns `true`.
  // kTrue is only useful in a narrow set of circumstances, mostly when
  // it's passed conditionally. For example:
  //
  //   mu.LockWhen(some_flag ? kTrue : SomeOtherCondition);
  //
  // Note: {LockWhen,Await}With{Deadline,Timeout} methods with kTrue condition
  // don't return immediately when the timeout happens, they still block until
  // the Mutex becomes available. The return value of these methods does
  // not indicate if the timeout was reached; rather it indicates whether or
  // not the condition is true.
  ABSL_CONST_INIT static const Condition kTrue;

  // Evaluates the condition.
  bool Eval() const;

  // Returns `true` if the two conditions are guaranteed to return the same
  // value if evaluated at the same time, `false` if the evaluation *may* return
  // different results.
  //
  // Two `Condition` values are guaranteed equal if both their `func` and `arg`
  // components are the same. A null pointer is equivalent to a `true`
  // condition.
  static bool GuaranteedEqual(const Condition* absl_nullable a,
                              const Condition* absl_nullable b);

 private:
  // Sizing an allocation for a method pointer can be subtle. In the Itanium
  // specifications, a method pointer has a predictable, uniform size. On the
  // other hand, MSVC ABI, method pointer sizes vary based on the
  // inheritance of the class. Specifically, method pointers from classes with
  // multiple inheritance are bigger than those of classes with single
  // inheritance. Other variations also exist.

#ifndef _MSC_VER
  // Allocation for a function pointer or method pointer.
  // The {0} initializer ensures that all unused bytes of this buffer are
  // always zeroed out.  This is necessary, because GuaranteedEqual() compares
  // all of the bytes, unaware of which bytes are relevant to a given `eval_`.
  using MethodPtr = bool (Condition::*)();
  char callback_[sizeof(MethodPtr)] = {0};
#else
  // It is well known that the larget MSVC pointer-to-member is 24 bytes. This
  // may be the largest known pointer-to-member of any platform. For this
  // reason we will allocate 24 bytes for MSVC platform toolchains.
  char callback_[24] = {0};
#endif

  // Function with which to evaluate callbacks and/or arguments.
  bool (*absl_nullable eval_)(const Condition* absl_nonnull) = nullptr;

  // Either an argument for a function call or an object for a method call.
  void* absl_nullable arg_ = nullptr;

  // Various functions eval_ can point to:
  static bool CallVoidPtrFunction(const Condition* absl_nonnull c);
  template <typename T>
  static bool CastAndCallFunction(const Condition* absl_nonnull c);
  template <typename T, typename ConditionMethodPtr>
  static bool CastAndCallMethod(const Condition* absl_nonnull c);

  // Helper methods for storing, validating, and reading callback arguments.
  template <typename T>
  inline void StoreCallback(T callback) {
    static_assert(
        sizeof(callback) <= sizeof(callback_),
        "An overlarge pointer was passed as a callback to Condition.");
    std::memcpy(callback_, &callback, sizeof(callback));
  }

  template <typename T>
  inline void ReadCallback(T* absl_nonnull callback) const {
    std::memcpy(callback, callback_, sizeof(*callback));
  }

  static bool AlwaysTrue(const Condition* absl_nullable) { return true; }

  // Used only to create kTrue.
  constexpr Condition() : eval_(AlwaysTrue), arg_(nullptr) {}
};

// -----------------------------------------------------------------------------
// CondVar
// -----------------------------------------------------------------------------
//
// A condition variable, reflecting state evaluated separately outside of the
// `Mutex` object, which can be signaled to wake callers.
// This class is not normally needed; use `Mutex` member functions such as
// `Mutex::Await()` and intrinsic `Condition` abstractions. In rare cases
// with many threads and many conditions, `CondVar` may be faster.
//
// The implementation may deliver signals to any condition variable at
// any time, even when no call to `Signal()` or `SignalAll()` is made; as a
// result, upon being awoken, you must check the logical condition you have
// been waiting upon.
//
// Examples:
//
// Usage for a thread waiting for some condition C protected by mutex mu:
//       mu.Lock();
//       while (!C) { cv->Wait(&mu); }        // releases and reacquires mu
//       //  C holds; process data
//       mu.Unlock();
//
// Usage to wake T is:
//       mu.Lock();
//       // process data, possibly establishing C
//       if (C) { cv->Signal(); }
//       mu.Unlock();
//
// If C may be useful to more than one waiter, use `SignalAll()` instead of
// `Signal()`.
//
// With this implementation it is efficient to use `Signal()/SignalAll()` inside
// the locked region; this usage can make reasoning about your program easier.
//
class CondVar {
 public:
  // A `CondVar` allocated on the heap or on the stack can use the this
  // constructor.
  CondVar();

  // CondVar::Wait()
  //
  // Atomically releases a `Mutex` and blocks on this condition variable.
  // Waits until awakened by a call to `Signal()` or `SignalAll()` (or a
  // spurious wakeup), then reacquires the `Mutex` and returns.
  //
  // Requires and ensures that the current thread holds the `Mutex`.
  void Wait(Mutex* absl_nonnull mu) {
    WaitCommon(mu, synchronization_internal::KernelTimeout::Never());
  }

  // CondVar::WaitWithTimeout()
  //
  // Atomically releases a `Mutex` and blocks on this condition variable.
  // Waits until awakened by a call to `Signal()` or `SignalAll()` (or a
  // spurious wakeup), or until the timeout has expired, then reacquires
  // the `Mutex` and returns.
  //
  // Returns true if the timeout has expired without this `CondVar`
  // being signalled in any manner. If both the timeout has expired
  // and this `CondVar` has been signalled, the implementation is free
  // to return `true` or `false`.
  //
  // Requires and ensures that the current thread holds the `Mutex`.
  bool WaitWithTimeout(Mutex* absl_nonnull mu, absl::Duration timeout) {
    return WaitCommon(mu, synchronization_internal::KernelTimeout(timeout));
  }

  // CondVar::WaitWithDeadline()
  //
  // Atomically releases a `Mutex` and blocks on this condition variable.
  // Waits until awakened by a call to `Signal()` or `SignalAll()` (or a
  // spurious wakeup), or until the deadline has passed, then reacquires
  // the `Mutex` and returns.
  //
  // Deadlines in the past are equivalent to an immediate deadline.
  //
  // Returns true if the deadline has passed without this `CondVar`
  // being signalled in any manner. If both the deadline has passed
  // and this `CondVar` has been signalled, the implementation is free
  // to return `true` or `false`.
  //
  // Requires and ensures that the current thread holds the `Mutex`.
  bool WaitWithDeadline(Mutex* absl_nonnull mu, absl::Time deadline) {
    return WaitCommon(mu, synchronization_internal::KernelTimeout(deadline));
  }

  // CondVar::Signal()
  //
  // Signal this `CondVar`; wake at least one waiter if one exists.
  void Signal();

  // CondVar::SignalAll()
  //
  // Signal this `CondVar`; wake all waiters.
  void SignalAll();

  // CondVar::EnableDebugLog()
  //
  // Causes all subsequent uses of this `CondVar` to be logged via
  // `ABSL_RAW_LOG(INFO)`. Log entries are tagged with `name` if `name != 0`.
  // Note: this method substantially reduces `CondVar` performance.
  void EnableDebugLog(const char* absl_nullable name);

 private:
  bool WaitCommon(Mutex* absl_nonnull mutex,
                  synchronization_internal::KernelTimeout t);
  void Remove(base_internal::PerThreadSynch* absl_nonnull s);
  std::atomic<intptr_t> cv_;  // Condition variable state.
  CondVar(const CondVar&) = delete;
  CondVar& operator=(const CondVar&) = delete;
};

// Variants of MutexLock.
//
// If you find yourself using one of these, consider instead using
// Mutex::Unlock() and/or if-statements for clarity.

// MutexLockMaybe
//
// MutexLockMaybe is like MutexLock, but is a no-op when mu is null.
class ABSL_SCOPED_LOCKABLE MutexLockMaybe {
 public:
  explicit MutexLockMaybe(Mutex* absl_nullable mu)
      ABSL_EXCLUSIVE_LOCK_FUNCTION(mu)
      : mu_(mu) {
    if (this->mu_ != nullptr) {
      this->mu_->Lock();
    }
  }

  explicit MutexLockMaybe(Mutex* absl_nullable mu, const Condition& cond)
      ABSL_EXCLUSIVE_LOCK_FUNCTION(mu)
      : mu_(mu) {
    if (this->mu_ != nullptr) {
      this->mu_->LockWhen(cond);
    }
  }

  ~MutexLockMaybe() ABSL_UNLOCK_FUNCTION() {
    if (this->mu_ != nullptr) {
      this->mu_->Unlock();
    }
  }

 private:
  Mutex* absl_nullable const mu_;
  MutexLockMaybe(const MutexLockMaybe&) = delete;
  MutexLockMaybe(MutexLockMaybe&&) = delete;
  MutexLockMaybe& operator=(const MutexLockMaybe&) = delete;
  MutexLockMaybe& operator=(MutexLockMaybe&&) = delete;
};

// ReleasableMutexLock
//
// ReleasableMutexLock is like MutexLock, but permits `Release()` of its
// mutex before destruction. `Release()` may be called at most once.
class ABSL_SCOPED_LOCKABLE ReleasableMutexLock {
 public:
  explicit ReleasableMutexLock(Mutex* absl_nonnull mu)
      ABSL_EXCLUSIVE_LOCK_FUNCTION(mu)
      : mu_(mu) {
    this->mu_->Lock();
  }

  explicit ReleasableMutexLock(Mutex* absl_nonnull mu, const Condition& cond)
      ABSL_EXCLUSIVE_LOCK_FUNCTION(mu)
      : mu_(mu) {
    this->mu_->LockWhen(cond);
  }

  ~ReleasableMutexLock() ABSL_UNLOCK_FUNCTION() {
    if (this->mu_ != nullptr) {
      this->mu_->Unlock();
    }
  }

  void Release() ABSL_UNLOCK_FUNCTION();

 private:
  Mutex* absl_nonnull mu_;
  ReleasableMutexLock(const ReleasableMutexLock&) = delete;
  ReleasableMutexLock(ReleasableMutexLock&&) = delete;
  ReleasableMutexLock& operator=(const ReleasableMutexLock&) = delete;
  ReleasableMutexLock& operator=(ReleasableMutexLock&&) = delete;
};

inline Mutex::Mutex() : mu_(0) {
  ABSL_TSAN_MUTEX_CREATE(this, __tsan_mutex_not_static);
}

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, typename ConditionMethodPtr>
bool Condition::CastAndCallMethod(const Condition* absl_nonnull c) {
  T* object = static_cast<T*>(c->arg_);
  ConditionMethodPtr condition_method_pointer;
  c->ReadCallback(&condition_method_pointer);
  return (object->*condition_method_pointer)();
}

// static
template <typename T>
bool Condition::CastAndCallFunction(const Condition* absl_nonnull c) {
  bool (*function)(T*);
  c->ReadCallback(&function);
  T* argument = static_cast<T*>(c->arg_);
  return (*function)(argument);
}

template <typename T>
inline Condition::Condition(
    bool (*absl_nonnull func)(T* absl_nullability_unknown),
    T* absl_nullability_unknown arg)
    : eval_(&CastAndCallFunction<T>),
      arg_(const_cast<void*>(static_cast<const void*>(arg))) {
  static_assert(sizeof(&func) <= sizeof(callback_),
                "An overlarge function pointer was passed to Condition.");
  StoreCallback(func);
}

template <typename T, typename>
inline Condition::Condition(
    bool (*absl_nonnull func)(T* absl_nullability_unknown),
    typename absl::internal::type_identity<T>::type* absl_nullability_unknown
    arg)
    // Just delegate to the overload above.
    : Condition(func, arg) {}

template <typename T>
inline Condition::Condition(
    T* absl_nonnull object,
    bool (absl::internal::type_identity<T>::type::* absl_nonnull 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* absl_nonnull object,
    bool (absl::internal::type_identity<T>::type::* absl_nonnull method)()
        const)
    : eval_(&CastAndCallMethod<const T, decltype(method)>),
      arg_(reinterpret_cast<void*>(const_cast<T*>(object))) {
  StoreCallback(method);
}

// Register hooks for profiling support.
//
// The function pointer registered here will be called whenever a mutex is
// contended.  The callback is given the cycles for which waiting happened (as
// measured by //absl/base/internal/cycleclock.h, and which may not
// be real "cycle" counts.)
//
// There is no ordering guarantee between when the hook is registered and when
// callbacks will begin.  Only a single profiler can be installed in a running
// binary; if this function is called a second time with a different function
// pointer, the value is ignored (and will cause an assertion failure in debug
// mode.)
void RegisterMutexProfiler(void (*absl_nonnull fn)(int64_t wait_cycles));

// Register a hook for Mutex tracing.
//
// The function pointer registered here will be called whenever a mutex is
// contended.  The callback is given an opaque handle to the contended mutex,
// an event name, and the number of wait cycles (as measured by
// //absl/base/internal/cycleclock.h, and which may not be real
// "cycle" counts.)
//
// The only event name currently sent is "slow release".
//
// This has the same ordering and single-use limitations as
// RegisterMutexProfiler() above.
void RegisterMutexTracer(void (*absl_nonnull fn)(const char* absl_nonnull msg,
                                                 const void* absl_nonnull obj,
                                                 int64_t wait_cycles));

// Register a hook for CondVar tracing.
//
// The function pointer registered here will be called here on various CondVar
// events.  The callback is given an opaque handle to the CondVar object and
// a string identifying the event.  This is thread-safe, but only a single
// tracer can be registered.
//
// Events that can be sent are "Wait", "Unwait", "Signal wakeup", and
// "SignalAll wakeup".
//
// This has the same ordering and single-use limitations as
// RegisterMutexProfiler() above.
void RegisterCondVarTracer(void (*absl_nonnull fn)(
    const char* absl_nonnull msg, const void* absl_nonnull cv));

// EnableMutexInvariantDebugging()
//
// Enable or disable global support for Mutex invariant debugging.  If enabled,
// then invariant predicates can be registered per-Mutex for debug checking.
// See Mutex::EnableInvariantDebugging().
void EnableMutexInvariantDebugging(bool enabled);

// When in debug mode, and when the feature has been enabled globally, the
// implementation will keep track of lock ordering and complain (or optionally
// crash) if a cycle is detected in the acquired-before graph.

// Possible modes of operation for the deadlock detector in debug mode.
enum class OnDeadlockCycle {
  kIgnore,  // Neither report on nor attempt to track cycles in lock ordering
  kReport,  // Report lock cycles to stderr when detected
  kAbort,   // Report lock cycles to stderr when detected, then abort
};

// SetMutexDeadlockDetectionMode()
//
// Enable or disable global support for detection of potential deadlocks
// due to Mutex lock ordering inversions.  When set to 'kIgnore', tracking of
// lock ordering is disabled.  Otherwise, in debug builds, a lock ordering graph
// will be maintained internally, and detected cycles will be reported in
// the manner chosen here.
void SetMutexDeadlockDetectionMode(OnDeadlockCycle mode);

ABSL_NAMESPACE_END
}  // namespace absl

// In some build configurations we pass --detect-odr-violations to the
// gold linker.  This causes it to flag weak symbol overrides as ODR
// violations.  Because ODR only applies to C++ and not C,
// --detect-odr-violations ignores symbols not mangled with C++ names.
// By changing our extension points to be extern "C", we dodge this
// check.
extern "C" {
void ABSL_INTERNAL_C_SYMBOL(AbslInternalMutexYield)();
}  // extern "C"

#endif  // ABSL_SYNCHRONIZATION_MUTEX_H_
*õ»
jsoong/.intermediates/external/abseil-cpp/absl_numeric_int128_hdrs/gen/my_include_dir/absl/numeric/int128.h…»//
// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// File: int128.h
// -----------------------------------------------------------------------------
//
// This header file defines 128-bit integer types, `uint128` and `int128`.
//
// TODO(absl-team): This module is inconsistent as many inline `uint128` methods
// are defined in this file, while many inline `int128` methods are defined in
// the `int128_*_intrinsic.inc` files.

#ifndef ABSL_NUMERIC_INT128_H_
#define ABSL_NUMERIC_INT128_H_

#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstring>
#include <iosfwd>
#include <limits>
#include <string>
#include <utility>

#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/base/port.h"
#include "absl/types/compare.h"

#if defined(_MSC_VER)
// In very old versions of MSVC and when the /Zc:wchar_t flag is off, wchar_t is
// a typedef for unsigned short.  Otherwise wchar_t is mapped to the __wchar_t
// builtin type.  We need to make sure not to define operator wchar_t()
// alongside operator unsigned short() in these instances.
#define ABSL_INTERNAL_WCHAR_T __wchar_t
#if defined(_M_X64) && !defined(_M_ARM64EC)
#include <intrin.h>
#pragma intrinsic(_umul128)
#endif  // defined(_M_X64)
#else   // defined(_MSC_VER)
#define ABSL_INTERNAL_WCHAR_T wchar_t
#endif  // defined(_MSC_VER)

namespace absl {
ABSL_NAMESPACE_BEGIN

class int128;

// uint128
//
// An unsigned 128-bit integer type. The API is meant to mimic an intrinsic type
// as closely as is practical, including exhibiting undefined behavior in
// analogous cases (e.g. division by zero). This type is intended to be a
// drop-in replacement once C++ supports an intrinsic `uint128_t` type; when
// that occurs, existing well-behaved uses of `uint128` will continue to work
// using that new type.
//
// Note: code written with this type will continue to compile once `uint128_t`
// is introduced, provided the replacement helper functions
// `Uint128(Low|High)64()` and `MakeUint128()` are made.
//
// A `uint128` supports the following:
//
//   * Implicit construction from integral types
//   * Explicit conversion to integral types
//
// Additionally, if your compiler supports `__int128`, `uint128` is
// interoperable with that type. (Abseil checks for this compatibility through
// the `ABSL_HAVE_INTRINSIC_INT128` macro.)
//
// However, a `uint128` differs from intrinsic integral types in the following
// ways:
//
//   * Errors on implicit conversions that do not preserve value (such as
//     loss of precision when converting to float values).
//   * Requires explicit construction from and conversion to floating point
//     types.
//   * Conversion to integral types requires an explicit static_cast() to
//     mimic use of the `-Wnarrowing` compiler flag.
//   * The alignment requirement of `uint128` may differ from that of an
//     intrinsic 128-bit integer type depending on platform and build
//     configuration.
//
// Example:
//
//     float y = absl::Uint128Max();  // Error. uint128 cannot be implicitly
//                                    // converted to float.
//
//     absl::uint128 v;
//     uint64_t i = v;                         // Error
//     uint64_t i = static_cast<uint64_t>(v);  // OK
//
class
#if defined(ABSL_HAVE_INTRINSIC_INT128)
    alignas(unsigned __int128)
#endif  // ABSL_HAVE_INTRINSIC_INT128
        uint128 {
 public:
  uint128() = default;

  // Constructors from arithmetic types
  constexpr uint128(int v);                 // NOLINT(runtime/explicit)
  constexpr uint128(unsigned int v);        // NOLINT(runtime/explicit)
  constexpr uint128(long v);                // NOLINT(runtime/int)
  constexpr uint128(unsigned long v);       // NOLINT(runtime/int)
  constexpr uint128(long long v);           // NOLINT(runtime/int)
  constexpr uint128(unsigned long long v);  // NOLINT(runtime/int)
#ifdef ABSL_HAVE_INTRINSIC_INT128
  constexpr uint128(__int128 v);           // NOLINT(runtime/explicit)
  constexpr uint128(unsigned __int128 v);  // NOLINT(runtime/explicit)
#endif                                     // ABSL_HAVE_INTRINSIC_INT128
  constexpr uint128(int128 v);             // NOLINT(runtime/explicit)
  explicit uint128(float v);
  explicit uint128(double v);
  explicit uint128(long double v);

  // Assignment operators from arithmetic types
  uint128& operator=(int v);
  uint128& operator=(unsigned int v);
  uint128& operator=(long v);                // NOLINT(runtime/int)
  uint128& operator=(unsigned long v);       // NOLINT(runtime/int)
  uint128& operator=(long long v);           // NOLINT(runtime/int)
  uint128& operator=(unsigned long long v);  // NOLINT(runtime/int)
#ifdef ABSL_HAVE_INTRINSIC_INT128
  uint128& operator=(__int128 v);
  uint128& operator=(unsigned __int128 v);
#endif  // ABSL_HAVE_INTRINSIC_INT128
  uint128& operator=(int128 v);

  // Conversion operators to other arithmetic types
  constexpr explicit operator bool() const;
  constexpr explicit operator char() const;
  constexpr explicit operator signed char() const;
  constexpr explicit operator unsigned char() const;
  constexpr explicit operator char16_t() const;
  constexpr explicit operator char32_t() const;
  constexpr explicit operator ABSL_INTERNAL_WCHAR_T() const;
  constexpr explicit operator short() const;  // NOLINT(runtime/int)
  // NOLINTNEXTLINE(runtime/int)
  constexpr explicit operator unsigned short() const;
  constexpr explicit operator int() const;
  constexpr explicit operator unsigned int() const;
  constexpr explicit operator long() const;  // NOLINT(runtime/int)
  // NOLINTNEXTLINE(runtime/int)
  constexpr explicit operator unsigned long() const;
  // NOLINTNEXTLINE(runtime/int)
  constexpr explicit operator long long() const;
  // NOLINTNEXTLINE(runtime/int)
  constexpr explicit operator unsigned long long() const;
#ifdef ABSL_HAVE_INTRINSIC_INT128
  constexpr explicit operator __int128() const;
  constexpr explicit operator unsigned __int128() const;
#endif  // ABSL_HAVE_INTRINSIC_INT128
  explicit operator float() const;
  explicit operator double() const;
  explicit operator long double() const;

  // Trivial copy constructor, assignment operator and destructor.

  // Arithmetic operators.
  uint128& operator+=(uint128 other);
  uint128& operator-=(uint128 other);
  uint128& operator*=(uint128 other);
  // Long division/modulo for uint128.
  uint128& operator/=(uint128 other);
  uint128& operator%=(uint128 other);
  uint128 operator++(int);
  uint128 operator--(int);
  uint128& operator<<=(int);
  uint128& operator>>=(int);
  uint128& operator&=(uint128 other);
  uint128& operator|=(uint128 other);
  uint128& operator^=(uint128 other);
  uint128& operator++();
  uint128& operator--();

  // Uint128Low64()
  //
  // Returns the lower 64-bit value of a `uint128` value.
  friend constexpr uint64_t Uint128Low64(uint128 v);

  // Uint128High64()
  //
  // Returns the higher 64-bit value of a `uint128` value.
  friend constexpr uint64_t Uint128High64(uint128 v);

  // MakeUInt128()
  //
  // Constructs a `uint128` numeric value from two 64-bit unsigned integers.
  // Note that this factory function is the only way to construct a `uint128`
  // from integer values greater than 2^64.
  //
  // Example:
  //
  //   absl::uint128 big = absl::MakeUint128(1, 0);
  friend constexpr uint128 MakeUint128(uint64_t high, uint64_t low);

  // Uint128Max()
  //
  // Returns the highest value for a 128-bit unsigned integer.
  friend constexpr uint128 Uint128Max();

  // Support for absl::Hash.
  template <typename H>
  friend H AbslHashValue(H h, uint128 v) {
#if defined(ABSL_HAVE_INTRINSIC_INT128)
    return H::combine(std::move(h), static_cast<unsigned __int128>(v));
#else
    return H::combine(std::move(h), Uint128High64(v), Uint128Low64(v));
#endif
  }

  // Support for absl::StrCat() etc.
  template <typename Sink>
  friend void AbslStringify(Sink& sink, uint128 v) {
    sink.Append(v.ToString());
  }

 private:
  constexpr uint128(uint64_t high, uint64_t low);

  std::string ToString() const;

  // TODO(strel) Update implementation to use __int128 once all users of
  // uint128 are fixed to not depend on alignof(uint128) == 8. Also add
  // alignas(16) to class definition to keep alignment consistent across
  // platforms.
#if defined(ABSL_IS_LITTLE_ENDIAN)
  uint64_t lo_;
  uint64_t hi_;
#elif defined(ABSL_IS_BIG_ENDIAN)
  uint64_t hi_;
  uint64_t lo_;
#else  // byte order
#error "Unsupported byte order: must be little-endian or big-endian."
#endif  // byte order
};

// allow uint128 to be logged
std::ostream& operator<<(std::ostream& os, uint128 v);

// TODO(strel) add operator>>(std::istream&, uint128)

constexpr uint128 Uint128Max() {
  return uint128((std::numeric_limits<uint64_t>::max)(),
                 (std::numeric_limits<uint64_t>::max)());
}

ABSL_NAMESPACE_END
}  // namespace absl

// Specialized numeric_limits for uint128.
namespace std {
template <>
class numeric_limits<absl::uint128> {
 public:
  static constexpr bool is_specialized = true;
  static constexpr bool is_signed = false;
  static constexpr bool is_integer = true;
  static constexpr bool is_exact = true;
  static constexpr bool has_infinity = false;
  static constexpr bool has_quiet_NaN = false;
  static constexpr bool has_signaling_NaN = false;
  ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
  static constexpr float_denorm_style has_denorm = denorm_absent;
  ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
  static constexpr bool has_denorm_loss = false;
  static constexpr float_round_style round_style = round_toward_zero;
  static constexpr bool is_iec559 = false;
  static constexpr bool is_bounded = true;
  static constexpr bool is_modulo = true;
  static constexpr int digits = 128;
  static constexpr int digits10 = 38;
  static constexpr int max_digits10 = 0;
  static constexpr int radix = 2;
  static constexpr int min_exponent = 0;
  static constexpr int min_exponent10 = 0;
  static constexpr int max_exponent = 0;
  static constexpr int max_exponent10 = 0;
#ifdef ABSL_HAVE_INTRINSIC_INT128
  static constexpr bool traps = numeric_limits<unsigned __int128>::traps;
#else   // ABSL_HAVE_INTRINSIC_INT128
  static constexpr bool traps = numeric_limits<uint64_t>::traps;
#endif  // ABSL_HAVE_INTRINSIC_INT128
  static constexpr bool tinyness_before = false;

  static constexpr absl::uint128(min)() { return 0; }
  static constexpr absl::uint128 lowest() { return 0; }
  static constexpr absl::uint128(max)() { return absl::Uint128Max(); }
  static constexpr absl::uint128 epsilon() { return 0; }
  static constexpr absl::uint128 round_error() { return 0; }
  static constexpr absl::uint128 infinity() { return 0; }
  static constexpr absl::uint128 quiet_NaN() { return 0; }
  static constexpr absl::uint128 signaling_NaN() { return 0; }
  static constexpr absl::uint128 denorm_min() { return 0; }
};
}  // namespace std

namespace absl {
ABSL_NAMESPACE_BEGIN

// int128
//
// A signed 128-bit integer type. The API is meant to mimic an intrinsic
// integral type as closely as is practical, including exhibiting undefined
// behavior in analogous cases (e.g. division by zero).
//
// An `int128` supports the following:
//
//   * Implicit construction from integral types
//   * Explicit conversion to integral types
//
// However, an `int128` differs from intrinsic integral types in the following
// ways:
//
//   * It is not implicitly convertible to other integral types.
//   * Requires explicit construction from and conversion to floating point
//     types.

// Additionally, if your compiler supports `__int128`, `int128` is
// interoperable with that type. (Abseil checks for this compatibility through
// the `ABSL_HAVE_INTRINSIC_INT128` macro.)
//
// The design goal for `int128` is that it will be compatible with a future
// `int128_t`, if that type becomes a part of the standard.
//
// Example:
//
//     float y = absl::int128(17);  // Error. int128 cannot be implicitly
//                                  // converted to float.
//
//     absl::int128 v;
//     int64_t i = v;                        // Error
//     int64_t i = static_cast<int64_t>(v);  // OK
//
class int128 {
 public:
  int128() = default;

  // Constructors from arithmetic types
  constexpr int128(int v);                 // NOLINT(runtime/explicit)
  constexpr int128(unsigned int v);        // NOLINT(runtime/explicit)
  constexpr int128(long v);                // NOLINT(runtime/int)
  constexpr int128(unsigned long v);       // NOLINT(runtime/int)
  constexpr int128(long long v);           // NOLINT(runtime/int)
  constexpr int128(unsigned long long v);  // NOLINT(runtime/int)
#ifdef ABSL_HAVE_INTRINSIC_INT128
  constexpr int128(__int128 v);  // NOLINT(runtime/explicit)
  constexpr explicit int128(unsigned __int128 v);
#endif  // ABSL_HAVE_INTRINSIC_INT128
  constexpr explicit int128(uint128 v);
  explicit int128(float v);
  explicit int128(double v);
  explicit int128(long double v);

  // Assignment operators from arithmetic types
  int128& operator=(int v);
  int128& operator=(unsigned int v);
  int128& operator=(long v);                // NOLINT(runtime/int)
  int128& operator=(unsigned long v);       // NOLINT(runtime/int)
  int128& operator=(long long v);           // NOLINT(runtime/int)
  int128& operator=(unsigned long long v);  // NOLINT(runtime/int)
#ifdef ABSL_HAVE_INTRINSIC_INT128
  int128& operator=(__int128 v);
#endif  // ABSL_HAVE_INTRINSIC_INT128

  // Conversion operators to other arithmetic types
  constexpr explicit operator bool() const;
  constexpr explicit operator char() const;
  constexpr explicit operator signed char() const;
  constexpr explicit operator unsigned char() const;
  constexpr explicit operator char16_t() const;
  constexpr explicit operator char32_t() const;
  constexpr explicit operator ABSL_INTERNAL_WCHAR_T() const;
  constexpr explicit operator short() const;  // NOLINT(runtime/int)
  // NOLINTNEXTLINE(runtime/int)
  constexpr explicit operator unsigned short() const;
  constexpr explicit operator int() const;
  constexpr explicit operator unsigned int() const;
  constexpr explicit operator long() const;  // NOLINT(runtime/int)
  // NOLINTNEXTLINE(runtime/int)
  constexpr explicit operator unsigned long() const;
  // NOLINTNEXTLINE(runtime/int)
  constexpr explicit operator long long() const;
  // NOLINTNEXTLINE(runtime/int)
  constexpr explicit operator unsigned long long() const;
#ifdef ABSL_HAVE_INTRINSIC_INT128
  constexpr explicit operator __int128() const;
  constexpr explicit operator unsigned __int128() const;
#endif  // ABSL_HAVE_INTRINSIC_INT128
  explicit operator float() const;
  explicit operator double() const;
  explicit operator long double() const;

  // Trivial copy constructor, assignment operator and destructor.

  // Arithmetic operators
  int128& operator+=(int128 other);
  int128& operator-=(int128 other);
  int128& operator*=(int128 other);
  int128& operator/=(int128 other);
  int128& operator%=(int128 other);
  int128 operator++(int);  // postfix increment: i++
  int128 operator--(int);  // postfix decrement: i--
  int128& operator++();    // prefix increment:  ++i
  int128& operator--();    // prefix decrement:  --i
  int128& operator&=(int128 other);
  int128& operator|=(int128 other);
  int128& operator^=(int128 other);
  int128& operator<<=(int amount);
  int128& operator>>=(int amount);

  // Int128Low64()
  //
  // Returns the lower 64-bit value of a `int128` value.
  friend constexpr uint64_t Int128Low64(int128 v);

  // Int128High64()
  //
  // Returns the higher 64-bit value of a `int128` value.
  friend constexpr int64_t Int128High64(int128 v);

  // MakeInt128()
  //
  // Constructs a `int128` numeric value from two 64-bit integers. Note that
  // signedness is conveyed in the upper `high` value.
  //
  //   (absl::int128(1) << 64) * high + low
  //
  // Note that this factory function is the only way to construct a `int128`
  // from integer values greater than 2^64 or less than -2^64.
  //
  // Example:
  //
  //   absl::int128 big = absl::MakeInt128(1, 0);
  //   absl::int128 big_n = absl::MakeInt128(-1, 0);
  friend constexpr int128 MakeInt128(int64_t high, uint64_t low);

  // Int128Max()
  //
  // Returns the maximum value for a 128-bit signed integer.
  friend constexpr int128 Int128Max();

  // Int128Min()
  //
  // Returns the minimum value for a 128-bit signed integer.
  friend constexpr int128 Int128Min();

  // Support for absl::Hash.
  template <typename H>
  friend H AbslHashValue(H h, int128 v) {
#if defined(ABSL_HAVE_INTRINSIC_INT128)
    return H::combine(std::move(h), v.v_);
#else
    return H::combine(std::move(h), Int128High64(v), Int128Low64(v));
#endif
  }

  // Support for absl::StrCat() etc.
  template <typename Sink>
  friend void AbslStringify(Sink& sink, int128 v) {
    sink.Append(v.ToString());
  }

 private:
  constexpr int128(int64_t high, uint64_t low);

  std::string ToString() const;

#if defined(ABSL_HAVE_INTRINSIC_INT128)
  __int128 v_;
#else  // ABSL_HAVE_INTRINSIC_INT128
#if defined(ABSL_IS_LITTLE_ENDIAN)
  uint64_t lo_;
  int64_t hi_;
#elif defined(ABSL_IS_BIG_ENDIAN)
  int64_t hi_;
  uint64_t lo_;
#else  // byte order
#error "Unsupported byte order: must be little-endian or big-endian."
#endif  // byte order
#endif  // ABSL_HAVE_INTRINSIC_INT128
};

std::ostream& operator<<(std::ostream& os, int128 v);

// TODO(absl-team) add operator>>(std::istream&, int128)

constexpr int128 Int128Max() {
  return int128((std::numeric_limits<int64_t>::max)(),
                (std::numeric_limits<uint64_t>::max)());
}

constexpr int128 Int128Min() {
  return int128((std::numeric_limits<int64_t>::min)(), 0);
}

ABSL_NAMESPACE_END
}  // namespace absl

// Specialized numeric_limits for int128.
namespace std {
template <>
class numeric_limits<absl::int128> {
 public:
  static constexpr bool is_specialized = true;
  static constexpr bool is_signed = true;
  static constexpr bool is_integer = true;
  static constexpr bool is_exact = true;
  static constexpr bool has_infinity = false;
  static constexpr bool has_quiet_NaN = false;
  static constexpr bool has_signaling_NaN = false;
  ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
  static constexpr float_denorm_style has_denorm = denorm_absent;
  ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
  static constexpr bool has_denorm_loss = false;
  static constexpr float_round_style round_style = round_toward_zero;
  static constexpr bool is_iec559 = false;
  static constexpr bool is_bounded = true;
  static constexpr bool is_modulo = false;
  static constexpr int digits = 127;
  static constexpr int digits10 = 38;
  static constexpr int max_digits10 = 0;
  static constexpr int radix = 2;
  static constexpr int min_exponent = 0;
  static constexpr int min_exponent10 = 0;
  static constexpr int max_exponent = 0;
  static constexpr int max_exponent10 = 0;
#ifdef ABSL_HAVE_INTRINSIC_INT128
  static constexpr bool traps = numeric_limits<__int128>::traps;
#else   // ABSL_HAVE_INTRINSIC_INT128
  static constexpr bool traps = numeric_limits<uint64_t>::traps;
#endif  // ABSL_HAVE_INTRINSIC_INT128
  static constexpr bool tinyness_before = false;

  static constexpr absl::int128(min)() { return absl::Int128Min(); }
  static constexpr absl::int128 lowest() { return absl::Int128Min(); }
  static constexpr absl::int128(max)() { return absl::Int128Max(); }
  static constexpr absl::int128 epsilon() { return 0; }
  static constexpr absl::int128 round_error() { return 0; }
  static constexpr absl::int128 infinity() { return 0; }
  static constexpr absl::int128 quiet_NaN() { return 0; }
  static constexpr absl::int128 signaling_NaN() { return 0; }
  static constexpr absl::int128 denorm_min() { return 0; }
};
}  // namespace std

// --------------------------------------------------------------------------
//                      Implementation details follow
// --------------------------------------------------------------------------
namespace absl {
ABSL_NAMESPACE_BEGIN

constexpr uint128 MakeUint128(uint64_t high, uint64_t low) {
  return uint128(high, low);
}

// Assignment from integer types.

inline uint128& uint128::operator=(int v) { return *this = uint128(v); }

inline uint128& uint128::operator=(unsigned int v) {
  return *this = uint128(v);
}

inline uint128& uint128::operator=(long v) {  // NOLINT(runtime/int)
  return *this = uint128(v);
}

// NOLINTNEXTLINE(runtime/int)
inline uint128& uint128::operator=(unsigned long v) {
  return *this = uint128(v);
}

// NOLINTNEXTLINE(runtime/int)
inline uint128& uint128::operator=(long long v) { return *this = uint128(v); }

// NOLINTNEXTLINE(runtime/int)
inline uint128& uint128::operator=(unsigned long long v) {
  return *this = uint128(v);
}

#ifdef ABSL_HAVE_INTRINSIC_INT128
inline uint128& uint128::operator=(__int128 v) { return *this = uint128(v); }

inline uint128& uint128::operator=(unsigned __int128 v) {
  return *this = uint128(v);
}
#endif  // ABSL_HAVE_INTRINSIC_INT128

inline uint128& uint128::operator=(int128 v) { return *this = uint128(v); }

// Arithmetic operators.

constexpr uint128 operator<<(uint128 lhs, int amount);
constexpr uint128 operator>>(uint128 lhs, int amount);
constexpr uint128 operator+(uint128 lhs, uint128 rhs);
constexpr uint128 operator-(uint128 lhs, uint128 rhs);
uint128 operator*(uint128 lhs, uint128 rhs);
uint128 operator/(uint128 lhs, uint128 rhs);
uint128 operator%(uint128 lhs, uint128 rhs);

inline uint128& uint128::operator<<=(int amount) {
  *this = *this << amount;
  return *this;
}

inline uint128& uint128::operator>>=(int amount) {
  *this = *this >> amount;
  return *this;
}

inline uint128& uint128::operator+=(uint128 other) {
  *this = *this + other;
  return *this;
}

inline uint128& uint128::operator-=(uint128 other) {
  *this = *this - other;
  return *this;
}

inline uint128& uint128::operator*=(uint128 other) {
  *this = *this * other;
  return *this;
}

inline uint128& uint128::operator/=(uint128 other) {
  *this = *this / other;
  return *this;
}

inline uint128& uint128::operator%=(uint128 other) {
  *this = *this % other;
  return *this;
}

constexpr uint64_t Uint128Low64(uint128 v) { return v.lo_; }

constexpr uint64_t Uint128High64(uint128 v) { return v.hi_; }

// Constructors from integer types.

#if defined(ABSL_IS_LITTLE_ENDIAN)

constexpr uint128::uint128(uint64_t high, uint64_t low) : lo_{low}, hi_{high} {}

constexpr uint128::uint128(int v)
    : lo_{static_cast<uint64_t>(v)},
      hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0} {}
constexpr uint128::uint128(long v)  // NOLINT(runtime/int)
    : lo_{static_cast<uint64_t>(v)},
      hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0} {}
constexpr uint128::uint128(long long v)  // NOLINT(runtime/int)
    : lo_{static_cast<uint64_t>(v)},
      hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0} {}

constexpr uint128::uint128(unsigned int v) : lo_{v}, hi_{0} {}
// NOLINTNEXTLINE(runtime/int)
constexpr uint128::uint128(unsigned long v) : lo_{v}, hi_{0} {}
// NOLINTNEXTLINE(runtime/int)
constexpr uint128::uint128(unsigned long long v) : lo_{v}, hi_{0} {}

#ifdef ABSL_HAVE_INTRINSIC_INT128
constexpr uint128::uint128(__int128 v)
    : lo_{static_cast<uint64_t>(v & ~uint64_t{0})},
      hi_{static_cast<uint64_t>(static_cast<unsigned __int128>(v) >> 64)} {}
constexpr uint128::uint128(unsigned __int128 v)
    : lo_{static_cast<uint64_t>(v & ~uint64_t{0})},
      hi_{static_cast<uint64_t>(v >> 64)} {}
#endif  // ABSL_HAVE_INTRINSIC_INT128

constexpr uint128::uint128(int128 v)
    : lo_{Int128Low64(v)}, hi_{static_cast<uint64_t>(Int128High64(v))} {}

#elif defined(ABSL_IS_BIG_ENDIAN)

constexpr uint128::uint128(uint64_t high, uint64_t low) : hi_{high}, lo_{low} {}

constexpr uint128::uint128(int v)
    : hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0},
      lo_{static_cast<uint64_t>(v)} {}
constexpr uint128::uint128(long v)  // NOLINT(runtime/int)
    : hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0},
      lo_{static_cast<uint64_t>(v)} {}
constexpr uint128::uint128(long long v)  // NOLINT(runtime/int)
    : hi_{v < 0 ? (std::numeric_limits<uint64_t>::max)() : 0},
      lo_{static_cast<uint64_t>(v)} {}

constexpr uint128::uint128(unsigned int v) : hi_{0}, lo_{v} {}
// NOLINTNEXTLINE(runtime/int)
constexpr uint128::uint128(unsigned long v) : hi_{0}, lo_{v} {}
// NOLINTNEXTLINE(runtime/int)
constexpr uint128::uint128(unsigned long long v) : hi_{0}, lo_{v} {}

#ifdef ABSL_HAVE_INTRINSIC_INT128
constexpr uint128::uint128(__int128 v)
    : hi_{static_cast<uint64_t>(static_cast<unsigned __int128>(v) >> 64)},
      lo_{static_cast<uint64_t>(v & ~uint64_t{0})} {}
constexpr uint128::uint128(unsigned __int128 v)
    : hi_{static_cast<uint64_t>(v >> 64)},
      lo_{static_cast<uint64_t>(v & ~uint64_t{0})} {}
#endif  // ABSL_HAVE_INTRINSIC_INT128

constexpr uint128::uint128(int128 v)
    : hi_{static_cast<uint64_t>(Int128High64(v))}, lo_{Int128Low64(v)} {}

#else  // byte order
#error "Unsupported byte order: must be little-endian or big-endian."
#endif  // byte order

// Conversion operators to integer types.

constexpr uint128::operator bool() const { return lo_ || hi_; }

constexpr uint128::operator char() const { return static_cast<char>(lo_); }

constexpr uint128::operator signed char() const {
  return static_cast<signed char>(lo_);
}

constexpr uint128::operator unsigned char() const {
  return static_cast<unsigned char>(lo_);
}

constexpr uint128::operator char16_t() const {
  return static_cast<char16_t>(lo_);
}

constexpr uint128::operator char32_t() const {
  return static_cast<char32_t>(lo_);
}

constexpr uint128::operator ABSL_INTERNAL_WCHAR_T() const {
  return static_cast<ABSL_INTERNAL_WCHAR_T>(lo_);
}

// NOLINTNEXTLINE(runtime/int)
constexpr uint128::operator short() const { return static_cast<short>(lo_); }

constexpr uint128::operator unsigned short() const {  // NOLINT(runtime/int)
  return static_cast<unsigned short>(lo_);            // NOLINT(runtime/int)
}

constexpr uint128::operator int() const { return static_cast<int>(lo_); }

constexpr uint128::operator unsigned int() const {
  return static_cast<unsigned int>(lo_);
}

// NOLINTNEXTLINE(runtime/int)
constexpr uint128::operator long() const { return static_cast<long>(lo_); }

constexpr uint128::operator unsigned long() const {  // NOLINT(runtime/int)
  return static_cast<unsigned long>(lo_);            // NOLINT(runtime/int)
}

constexpr uint128::operator long long() const {  // NOLINT(runtime/int)
  return static_cast<long long>(lo_);            // NOLINT(runtime/int)
}

constexpr uint128::operator unsigned long long() const {  // NOLINT(runtime/int)
  return static_cast<unsigned long long>(lo_);            // NOLINT(runtime/int)
}

#ifdef ABSL_HAVE_INTRINSIC_INT128
constexpr uint128::operator __int128() const {
  return (static_cast<__int128>(hi_) << 64) + lo_;
}

constexpr uint128::operator unsigned __int128() const {
  return (static_cast<unsigned __int128>(hi_) << 64) + lo_;
}
#endif  // ABSL_HAVE_INTRINSIC_INT128

// Conversion operators to floating point types.

inline uint128::operator float() const {
  // Note: This method might return Inf.
  constexpr float pow_2_64 = 18446744073709551616.0f;
  return static_cast<float>(lo_) + static_cast<float>(hi_) * pow_2_64;
}

inline uint128::operator double() const {
  constexpr double pow_2_64 = 18446744073709551616.0;
  return static_cast<double>(lo_) + static_cast<double>(hi_) * pow_2_64;
}

inline uint128::operator long double() const {
  constexpr long double pow_2_64 = 18446744073709551616.0L;
  return static_cast<long double>(lo_) +
         static_cast<long double>(hi_) * pow_2_64;
}

// Comparison operators.

constexpr bool operator==(uint128 lhs, uint128 rhs) {
#if defined(ABSL_HAVE_INTRINSIC_INT128)
  return static_cast<unsigned __int128>(lhs) ==
         static_cast<unsigned __int128>(rhs);
#else
  return (Uint128Low64(lhs) == Uint128Low64(rhs) &&
          Uint128High64(lhs) == Uint128High64(rhs));
#endif
}

constexpr bool operator!=(uint128 lhs, uint128 rhs) { return !(lhs == rhs); }

constexpr bool operator<(uint128 lhs, uint128 rhs) {
#ifdef ABSL_HAVE_INTRINSIC_INT128
  return static_cast<unsigned __int128>(lhs) <
         static_cast<unsigned __int128>(rhs);
#else
  return (Uint128High64(lhs) == Uint128High64(rhs))
             ? (Uint128Low64(lhs) < Uint128Low64(rhs))
             : (Uint128High64(lhs) < Uint128High64(rhs));
#endif
}

constexpr bool operator>(uint128 lhs, uint128 rhs) { return rhs < lhs; }

constexpr bool operator<=(uint128 lhs, uint128 rhs) { return !(rhs < lhs); }

constexpr bool operator>=(uint128 lhs, uint128 rhs) { return !(lhs < rhs); }

#ifdef __cpp_impl_three_way_comparison
constexpr absl::strong_ordering operator<=>(uint128 lhs, uint128 rhs) {
#if defined(ABSL_HAVE_INTRINSIC_INT128)
  if (auto lhs_128 = static_cast<unsigned __int128>(lhs),
      rhs_128 = static_cast<unsigned __int128>(rhs);
      lhs_128 < rhs_128) {
    return absl::strong_ordering::less;
  } else if (lhs_128 > rhs_128) {
    return absl::strong_ordering::greater;
  } else {
    return absl::strong_ordering::equal;
  }
#else
  if (uint64_t lhs_high = Uint128High64(lhs), rhs_high = Uint128High64(rhs);
      lhs_high < rhs_high) {
    return absl::strong_ordering::less;
  } else if (lhs_high > rhs_high) {
    return absl::strong_ordering::greater;
  } else if (uint64_t lhs_low = Uint128Low64(lhs), rhs_low = Uint128Low64(rhs);
             lhs_low < rhs_low) {
    return absl::strong_ordering::less;
  } else if (lhs_low > rhs_low) {
    return absl::strong_ordering::greater;
  } else {
    return absl::strong_ordering::equal;
  }
#endif
}
#endif

// Unary operators.

constexpr inline uint128 operator+(uint128 val) { return val; }

constexpr inline int128 operator+(int128 val) { return val; }

constexpr uint128 operator-(uint128 val) {
#if defined(ABSL_HAVE_INTRINSIC_INT128)
  return -static_cast<unsigned __int128>(val);
#else
  return MakeUint128(
      ~Uint128High64(val) + static_cast<unsigned long>(Uint128Low64(val) == 0),
      ~Uint128Low64(val) + 1);
#endif
}

constexpr inline bool operator!(uint128 val) {
#if defined(ABSL_HAVE_INTRINSIC_INT128)
  return !static_cast<unsigned __int128>(val);
#else
  return !Uint128High64(val) && !Uint128Low64(val);
#endif
}

// Logical operators.

constexpr inline uint128 operator~(uint128 val) {
#if defined(ABSL_HAVE_INTRINSIC_INT128)
  return ~static_cast<unsigned __int128>(val);
#else
  return MakeUint128(~Uint128High64(val), ~Uint128Low64(val));
#endif
}

constexpr inline uint128 operator|(uint128 lhs, uint128 rhs) {
#if defined(ABSL_HAVE_INTRINSIC_INT128)
  return static_cast<unsigned __int128>(lhs) |
         static_cast<unsigned __int128>(rhs);
#else
  return MakeUint128(Uint128High64(lhs) | Uint128High64(rhs),
                     Uint128Low64(lhs) | Uint128Low64(rhs));
#endif
}

constexpr inline uint128 operator&(uint128 lhs, uint128 rhs) {
#if defined(ABSL_HAVE_INTRINSIC_INT128)
  return static_cast<unsigned __int128>(lhs) &
         static_cast<unsigned __int128>(rhs);
#else
  return MakeUint128(Uint128High64(lhs) & Uint128High64(rhs),
                     Uint128Low64(lhs) & Uint128Low64(rhs));
#endif
}

constexpr inline uint128 operator^(uint128 lhs, uint128 rhs) {
#if defined(ABSL_HAVE_INTRINSIC_INT128)
  return static_cast<unsigned __int128>(lhs) ^
         static_cast<unsigned __int128>(rhs);
#else
  return MakeUint128(Uint128High64(lhs) ^ Uint128High64(rhs),
                     Uint128Low64(lhs) ^ Uint128Low64(rhs));
#endif
}

inline uint128& uint128::operator|=(uint128 other) {
  *this = *this | other;
  return *this;
}

inline uint128& uint128::operator&=(uint128 other) {
  *this = *this & other;
  return *this;
}

inline uint128& uint128::operator^=(uint128 other) {
  *this = *this ^ other;
  return *this;
}

// Arithmetic operators.

constexpr uint128 operator<<(uint128 lhs, int amount) {
#ifdef ABSL_HAVE_INTRINSIC_INT128
  return static_cast<unsigned __int128>(lhs) << amount;
#else
  // uint64_t shifts of >= 64 are undefined, so we will need some
  // special-casing.
  return amount >= 64  ? MakeUint128(Uint128Low64(lhs) << (amount - 64), 0)
         : amount == 0 ? lhs
                       : MakeUint128((Uint128High64(lhs) << amount) |
                                         (Uint128Low64(lhs) >> (64 - amount)),
                                     Uint128Low64(lhs) << amount);
#endif
}

constexpr uint128 operator>>(uint128 lhs, int amount) {
#ifdef ABSL_HAVE_INTRINSIC_INT128
  return static_cast<unsigned __int128>(lhs) >> amount;
#else
  // uint64_t shifts of >= 64 are undefined, so we will need some
  // special-casing.
  return amount >= 64  ? MakeUint128(0, Uint128High64(lhs) >> (amount - 64))
         : amount == 0 ? lhs
                       : MakeUint128(Uint128High64(lhs) >> amount,
                                     (Uint128Low64(lhs) >> amount) |
                                         (Uint128High64(lhs) << (64 - amount)));
#endif
}

#if !defined(ABSL_HAVE_INTRINSIC_INT128)
namespace int128_internal {
constexpr uint128 AddResult(uint128 result, uint128 lhs) {
  // check for carry
  return (Uint128Low64(result) < Uint128Low64(lhs))
             ? MakeUint128(Uint128High64(result) + 1, Uint128Low64(result))
             : result;
}
}  // namespace int128_internal
#endif

constexpr uint128 operator+(uint128 lhs, uint128 rhs) {
#if defined(ABSL_HAVE_INTRINSIC_INT128)
  return static_cast<unsigned __int128>(lhs) +
         static_cast<unsigned __int128>(rhs);
#else
  return int128_internal::AddResult(
      MakeUint128(Uint128High64(lhs) + Uint128High64(rhs),
                  Uint128Low64(lhs) + Uint128Low64(rhs)),
      lhs);
#endif
}

#if !defined(ABSL_HAVE_INTRINSIC_INT128)
namespace int128_internal {
constexpr uint128 SubstructResult(uint128 result, uint128 lhs, uint128 rhs) {
  // check for carry
  return (Uint128Low64(lhs) < Uint128Low64(rhs))
             ? MakeUint128(Uint128High64(result) - 1, Uint128Low64(result))
             : result;
}
}  // namespace int128_internal
#endif

constexpr uint128 operator-(uint128 lhs, uint128 rhs) {
#if defined(ABSL_HAVE_INTRINSIC_INT128)
  return static_cast<unsigned __int128>(lhs) -
         static_cast<unsigned __int128>(rhs);
#else
  return int128_internal::SubstructResult(
      MakeUint128(Uint128High64(lhs) - Uint128High64(rhs),
                  Uint128Low64(lhs) - Uint128Low64(rhs)),
      lhs, rhs);
#endif
}

inline uint128 operator*(uint128 lhs, uint128 rhs) {
#if defined(ABSL_HAVE_INTRINSIC_INT128)
  // TODO(strel) Remove once alignment issues are resolved and unsigned __int128
  // can be used for uint128 storage.
  return static_cast<unsigned __int128>(lhs) *
         static_cast<unsigned __int128>(rhs);
#elif defined(_MSC_VER) && defined(_M_X64) && !defined(_M_ARM64EC)
  uint64_t carry;
  uint64_t low = _umul128(Uint128Low64(lhs), Uint128Low64(rhs), &carry);
  return MakeUint128(Uint128Low64(lhs) * Uint128High64(rhs) +
                         Uint128High64(lhs) * Uint128Low64(rhs) + carry,
                     low);
#else   // ABSL_HAVE_INTRINSIC128
  uint64_t a32 = Uint128Low64(lhs) >> 32;
  uint64_t a00 = Uint128Low64(lhs) & 0xffffffff;
  uint64_t b32 = Uint128Low64(rhs) >> 32;
  uint64_t b00 = Uint128Low64(rhs) & 0xffffffff;
  uint128 result =
      MakeUint128(Uint128High64(lhs) * Uint128Low64(rhs) +
                      Uint128Low64(lhs) * Uint128High64(rhs) + a32 * b32,
                  a00 * b00);
  result += uint128(a32 * b00) << 32;
  result += uint128(a00 * b32) << 32;
  return result;
#endif  // ABSL_HAVE_INTRINSIC128
}

#if defined(ABSL_HAVE_INTRINSIC_INT128)
inline uint128 operator/(uint128 lhs, uint128 rhs) {
  return static_cast<unsigned __int128>(lhs) /
         static_cast<unsigned __int128>(rhs);
}

inline uint128 operator%(uint128 lhs, uint128 rhs) {
  return static_cast<unsigned __int128>(lhs) %
         static_cast<unsigned __int128>(rhs);
}
#endif

// Increment/decrement operators.

inline uint128 uint128::operator++(int) {
  uint128 tmp(*this);
  *this += 1;
  return tmp;
}

inline uint128 uint128::operator--(int) {
  uint128 tmp(*this);
  *this -= 1;
  return tmp;
}

inline uint128& uint128::operator++() {
  *this += 1;
  return *this;
}

inline uint128& uint128::operator--() {
  *this -= 1;
  return *this;
}

constexpr int128 MakeInt128(int64_t high, uint64_t low) {
  return int128(high, low);
}

// Assignment from integer types.
inline int128& int128::operator=(int v) { return *this = int128(v); }

inline int128& int128::operator=(unsigned int v) { return *this = int128(v); }

inline int128& int128::operator=(long v) {  // NOLINT(runtime/int)
  return *this = int128(v);
}

// NOLINTNEXTLINE(runtime/int)
inline int128& int128::operator=(unsigned long v) { return *this = int128(v); }

// NOLINTNEXTLINE(runtime/int)
inline int128& int128::operator=(long long v) { return *this = int128(v); }

// NOLINTNEXTLINE(runtime/int)
inline int128& int128::operator=(unsigned long long v) {
  return *this = int128(v);
}

// Arithmetic operators.
constexpr int128 operator-(int128 v);
constexpr int128 operator+(int128 lhs, int128 rhs);
constexpr int128 operator-(int128 lhs, int128 rhs);
int128 operator*(int128 lhs, int128 rhs);
int128 operator/(int128 lhs, int128 rhs);
int128 operator%(int128 lhs, int128 rhs);
constexpr int128 operator|(int128 lhs, int128 rhs);
constexpr int128 operator&(int128 lhs, int128 rhs);
constexpr int128 operator^(int128 lhs, int128 rhs);
constexpr int128 operator<<(int128 lhs, int amount);
constexpr int128 operator>>(int128 lhs, int amount);

inline int128& int128::operator+=(int128 other) {
  *this = *this + other;
  return *this;
}

inline int128& int128::operator-=(int128 other) {
  *this = *this - other;
  return *this;
}

inline int128& int128::operator*=(int128 other) {
  *this = *this * other;
  return *this;
}

inline int128& int128::operator/=(int128 other) {
  *this = *this / other;
  return *this;
}

inline int128& int128::operator%=(int128 other) {
  *this = *this % other;
  return *this;
}

inline int128& int128::operator|=(int128 other) {
  *this = *this | other;
  return *this;
}

inline int128& int128::operator&=(int128 other) {
  *this = *this & other;
  return *this;
}

inline int128& int128::operator^=(int128 other) {
  *this = *this ^ other;
  return *this;
}

inline int128& int128::operator<<=(int amount) {
  *this = *this << amount;
  return *this;
}

inline int128& int128::operator>>=(int amount) {
  *this = *this >> amount;
  return *this;
}

// Forward declaration for comparison operators.
constexpr bool operator!=(int128 lhs, int128 rhs);

namespace int128_internal {

// Casts from unsigned to signed while preserving the underlying binary
// representation.
constexpr int64_t BitCastToSigned(uint64_t v) {
  // Casting an unsigned integer to a signed integer of the same
  // width is implementation defined behavior if the source value would not fit
  // in the destination type. We step around it with a roundtrip bitwise not
  // operation to make sure this function remains constexpr. Clang, GCC, and
  // MSVC optimize this to a no-op on x86-64.
  return v & (uint64_t{1} << 63) ? ~static_cast<int64_t>(~v)
                                 : static_cast<int64_t>(v);
}

}  // namespace int128_internal

#if defined(ABSL_HAVE_INTRINSIC_INT128)
#include "absl/numeric/int128_have_intrinsic.inc"  // IWYU pragma: export
#else  // ABSL_HAVE_INTRINSIC_INT128
#include "absl/numeric/int128_no_intrinsic.inc"  // IWYU pragma: export
#endif  // ABSL_HAVE_INTRINSIC_INT128

ABSL_NAMESPACE_END
}  // namespace absl

#undef ABSL_INTERNAL_WCHAR_T

#endif  // ABSL_NUMERIC_INT128_H_
*—8
psoong/.intermediates/external/abseil-cpp/absl_base_log_severity_hdrs/gen/my_include_dir/absl/base/log_severity.h¢7// 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.

#ifndef ABSL_BASE_LOG_SEVERITY_H_
#define ABSL_BASE_LOG_SEVERITY_H_

#include <array>
#include <ostream>

#include "absl/base/attributes.h"
#include "absl/base/config.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

// absl::LogSeverity
//
// Four severity levels are defined. Logging APIs should terminate the program
// when a message is logged at severity `kFatal`; the other levels have no
// special semantics.
//
// Values other than the four defined levels (e.g. produced by `static_cast`)
// are valid, but their semantics when passed to a function, macro, or flag
// depend on the function, macro, or flag. The usual behavior is to normalize
// such values to a defined severity level, however in some cases values other
// than the defined levels are useful for comparison.
//
// Example:
//
//   // Effectively disables all logging:
//   SetMinLogLevel(static_cast<absl::LogSeverity>(100));
//
// Abseil flags may be defined with type `LogSeverity`. Dependency layering
// constraints require that the `AbslParseFlag()` overload be declared and
// defined in the flags library itself rather than here. The `AbslUnparseFlag()`
// overload is defined there as well for consistency.
//
// absl::LogSeverity Flag String Representation
//
// An `absl::LogSeverity` has a string representation used for parsing
// command-line flags based on the enumerator name (e.g. `kFatal`) or
// its unprefixed name (without the `k`) in any case-insensitive form. (E.g.
// "FATAL", "fatal" or "Fatal" are all valid.) Unparsing such flags produces an
// unprefixed string representation in all caps (e.g. "FATAL") or an integer.
//
// Additionally, the parser accepts arbitrary integers (as if the type were
// `int`).
//
// Examples:
//
//   --my_log_level=kInfo
//   --my_log_level=INFO
//   --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 {
  kInfo = 0,
  kWarning = 1,
  kError = 2,
  kFatal = 3,
};

// LogSeverities()
//
// Returns an iterable of all standard `absl::LogSeverity` values, ordered from
// least to most severe.
constexpr std::array<absl::LogSeverity, 4> LogSeverities() {
  return {{absl::LogSeverity::kInfo, absl::LogSeverity::kWarning,
           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) {
  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()
//
// Values less than `kInfo` normalize to `kInfo`; values greater than `kFatal`
// normalize to `kError` (**NOT** `kFatal`).
constexpr absl::LogSeverity NormalizeLogSeverity(absl::LogSeverity 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));
}

// operator<<
//
// The exact representation of a streamed `absl::LogSeverity` is deliberately
// unspecified; do not rely on it.
std::ostream& operator<<(std::ostream& os, absl::LogSeverity s);

// Enums representing a lower bound for LogSeverity. APIs that only operate on
// messages of at least a certain level (for example, `SetMinLogLevel()`) use
// this type to specify that level. absl::LogSeverityAtLeast::kInfinity is
// a level above all threshold levels and therefore no log message will
// ever meet this threshold.
enum class LogSeverityAtLeast : int {
  kInfo = static_cast<int>(absl::LogSeverity::kInfo),
  kWarning = static_cast<int>(absl::LogSeverity::kWarning),
  kError = static_cast<int>(absl::LogSeverity::kError),
  kFatal = static_cast<int>(absl::LogSeverity::kFatal),
  kInfinity = 1000,
};

std::ostream& operator<<(std::ostream& os, absl::LogSeverityAtLeast s);

// Enums representing an upper bound for LogSeverity. APIs that only operate on
// messages of at most a certain level (for example, buffer all messages at or
// below a certain level) use this type to specify that level.
// absl::LogSeverityAtMost::kNegativeInfinity is a level below all threshold
// levels and therefore will exclude all log messages.
enum class LogSeverityAtMost : int {
  kNegativeInfinity = -1000,
  kInfo = static_cast<int>(absl::LogSeverity::kInfo),
  kWarning = static_cast<int>(absl::LogSeverity::kWarning),
  kError = static_cast<int>(absl::LogSeverity::kError),
  kFatal = static_cast<int>(absl::LogSeverity::kFatal),
};

std::ostream& operator<<(std::ostream& os, absl::LogSeverityAtMost s);

#define COMPOP(op1, op2, T)                                         \
  constexpr bool operator op1(absl::T lhs, absl::LogSeverity rhs) { \
    return static_cast<absl::LogSeverity>(lhs) op1 rhs;             \
  }                                                                 \
  constexpr bool operator op2(absl::LogSeverity lhs, absl::T rhs) { \
    return lhs op2 static_cast<absl::LogSeverity>(rhs);             \
  }

// Comparisons between `LogSeverity` and `LogSeverityAtLeast`/
// `LogSeverityAtMost` are only supported in one direction.
// Valid checks are:
//   LogSeverity >= LogSeverityAtLeast
//   LogSeverity < LogSeverityAtLeast
//   LogSeverity <= LogSeverityAtMost
//   LogSeverity > LogSeverityAtMost
COMPOP(>, <, LogSeverityAtLeast)
COMPOP(<=, >=, LogSeverityAtLeast)
COMPOP(<, >, LogSeverityAtMost)
COMPOP(>=, <=, LogSeverityAtMost)
#undef COMPOP

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_BASE_LOG_SEVERITY_H_
*úÑ
nsoong/.intermediates/external/abseil-cpp/absl_base_core_headers_hdrs/gen/my_include_dir/absl/base/attributes.h†Ñ// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// This header file defines macros for declaring attributes for functions,
// types, and variables.
//
// These macros are used within Abseil and allow the compiler to optimize, where
// applicable, certain function calls.
//
// Most macros here are exposing GCC or Clang features, and are stubbed out for
// other compilers.
//
// GCC attributes documentation:
//   https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Attributes.html
//   https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Variable-Attributes.html
//   https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Type-Attributes.html
//
// Most attributes in this file are already supported by GCC 4.7. However, some
// of them are not supported in older version of Clang. Thus, we check
// `__has_attribute()` first. If the check fails, we check if we are on GCC and
// assume the attribute exists on GCC (which is verified on GCC 4.7).

// SKIP_ABSL_INLINE_NAMESPACE_CHECK

#ifndef ABSL_BASE_ATTRIBUTES_H_
#define ABSL_BASE_ATTRIBUTES_H_

#include "absl/base/config.h"

// ABSL_HAVE_ATTRIBUTE
//
// A function-like feature checking macro that is a wrapper around
// `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a
// nonzero constant integer if the attribute is supported or 0 if not.
//
// It evaluates to zero if `__has_attribute` is not defined by the compiler.
//
// GCC: https://gcc.gnu.org/gcc-5/changes.html
// Clang: https://clang.llvm.org/docs/LanguageExtensions.html
#ifdef __has_attribute
#define ABSL_HAVE_ATTRIBUTE(x) __has_attribute(x)
#else
#define ABSL_HAVE_ATTRIBUTE(x) 0
#endif

// ABSL_HAVE_CPP_ATTRIBUTE
//
// A function-like feature checking macro that accepts C++11 style attributes.
// It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6
// (https://en.cppreference.com/w/cpp/experimental/feature_test). If we don't
// find `__has_cpp_attribute`, will evaluate to 0.
#if defined(__cplusplus) && defined(__has_cpp_attribute)
// NOTE: requiring __cplusplus above should not be necessary, but
// works around https://bugs.llvm.org/show_bug.cgi?id=23435.
#define ABSL_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
#else
#define ABSL_HAVE_CPP_ATTRIBUTE(x) 0
#endif

// -----------------------------------------------------------------------------
// Function Attributes
// -----------------------------------------------------------------------------
//
// GCC: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
// Clang: https://clang.llvm.org/docs/AttributeReference.html

// ABSL_PRINTF_ATTRIBUTE
// ABSL_SCANF_ATTRIBUTE
//
// Tells the compiler to perform `printf` format string checking if the
// compiler supports it; see the 'format' attribute in
// <https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Attributes.html>.
//
// Note: As the GCC manual states, "[s]ince non-static C++ methods
// have an implicit 'this' argument, the arguments of such methods
// should be counted from two, not one."
#if ABSL_HAVE_ATTRIBUTE(format) || (defined(__GNUC__) && !defined(__clang__))
#define ABSL_PRINTF_ATTRIBUTE(string_index, first_to_check) \
  __attribute__((__format__(__printf__, string_index, first_to_check)))
#define ABSL_SCANF_ATTRIBUTE(string_index, first_to_check) \
  __attribute__((__format__(__scanf__, string_index, first_to_check)))
#else
#define ABSL_PRINTF_ATTRIBUTE(string_index, first_to_check)
#define ABSL_SCANF_ATTRIBUTE(string_index, first_to_check)
#endif

// ABSL_ATTRIBUTE_ALWAYS_INLINE
// ABSL_ATTRIBUTE_NOINLINE
//
// Forces functions to either inline or not inline. Introduced in gcc 3.1.
#if ABSL_HAVE_ATTRIBUTE(always_inline) || \
    (defined(__GNUC__) && !defined(__clang__))
#define ABSL_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline))
#define ABSL_HAVE_ATTRIBUTE_ALWAYS_INLINE 1
#else
#define ABSL_ATTRIBUTE_ALWAYS_INLINE
#endif

#if ABSL_HAVE_ATTRIBUTE(noinline) || (defined(__GNUC__) && !defined(__clang__))
#define ABSL_ATTRIBUTE_NOINLINE __attribute__((noinline))
#define ABSL_HAVE_ATTRIBUTE_NOINLINE 1
#else
#define ABSL_ATTRIBUTE_NOINLINE
#endif

// ABSL_ATTRIBUTE_NO_TAIL_CALL
//
// Prevents the compiler from optimizing away stack frames for functions which
// end in a call to another function.
#if ABSL_HAVE_ATTRIBUTE(disable_tail_calls)
#define ABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 1
#define ABSL_ATTRIBUTE_NO_TAIL_CALL __attribute__((disable_tail_calls))
#elif defined(__GNUC__) && !defined(__clang__) && !defined(__e2k__)
#define ABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 1
#define ABSL_ATTRIBUTE_NO_TAIL_CALL \
  __attribute__((optimize("no-optimize-sibling-calls")))
#else
#define ABSL_ATTRIBUTE_NO_TAIL_CALL
#define ABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 0
#endif

// ABSL_ATTRIBUTE_WEAK
//
// Tags a function as weak for the purposes of compilation and linking.
// Weak attributes did not work properly in LLVM's Windows backend before
// 9.0.0, so disable them there. See https://bugs.llvm.org/show_bug.cgi?id=37598
// for further information. Weak attributes do not work across DLL boundary.
// The MinGW compiler doesn't complain about the weak attribute until the link
// step, presumably because Windows doesn't use ELF binaries.
#if (ABSL_HAVE_ATTRIBUTE(weak) ||                                 \
     (defined(__GNUC__) && !defined(__clang__))) &&               \
    (!defined(_WIN32) ||                                          \
     (defined(__clang__) && __clang_major__ >= 9 &&               \
      !defined(ABSL_BUILD_DLL) && !defined(ABSL_CONSUME_DLL))) && \
    !defined(__MINGW32__)
#undef ABSL_ATTRIBUTE_WEAK
#define ABSL_ATTRIBUTE_WEAK __attribute__((weak))
#define ABSL_HAVE_ATTRIBUTE_WEAK 1
#else
#define ABSL_ATTRIBUTE_WEAK
#define ABSL_HAVE_ATTRIBUTE_WEAK 0
#endif

// ABSL_ATTRIBUTE_NONNULL
//
// Tells the compiler either (a) that a particular function parameter
// should be a non-null pointer, or (b) that all pointer arguments should
// be non-null.
//
// Note: As the GCC manual states, "[s]ince non-static C++ methods
// have an implicit 'this' argument, the arguments of such methods
// should be counted from two, not one."
//
// Args are indexed starting at 1.
//
// For non-static class member functions, the implicit `this` argument
// is arg 1, and the first explicit argument is arg 2. For static class member
// functions, there is no implicit `this`, and the first explicit argument is
// arg 1.
//
// Example:
//
//   /* arg_a cannot be null, but arg_b can */
//   void Function(void* arg_a, void* arg_b) ABSL_ATTRIBUTE_NONNULL(1);
//
//   class C {
//     /* arg_a cannot be null, but arg_b can */
//     void Method(void* arg_a, void* arg_b) ABSL_ATTRIBUTE_NONNULL(2);
//
//     /* arg_a cannot be null, but arg_b can */
//     static void StaticMethod(void* arg_a, void* arg_b)
//     ABSL_ATTRIBUTE_NONNULL(1);
//   };
//
// If no arguments are provided, then all pointer arguments should be non-null.
//
//  /* No pointer arguments may be null. */
//  void Function(void* arg_a, void* arg_b, int arg_c) ABSL_ATTRIBUTE_NONNULL();
//
// NOTE: The GCC nonnull attribute actually accepts a list of arguments, but
// ABSL_ATTRIBUTE_NONNULL does not.
#if ABSL_HAVE_ATTRIBUTE(nonnull) || (defined(__GNUC__) && !defined(__clang__))
#define ABSL_ATTRIBUTE_NONNULL(arg_index) __attribute__((nonnull(arg_index)))
#else
#define ABSL_ATTRIBUTE_NONNULL(...)
#endif

// ABSL_ATTRIBUTE_NORETURN
//
// Tells the compiler that a given function never returns.
//
// Deprecated: Prefer the `[[noreturn]]` attribute standardized by C++11 over
// this macro.
#if ABSL_HAVE_ATTRIBUTE(noreturn) || (defined(__GNUC__) && !defined(__clang__))
#define ABSL_ATTRIBUTE_NORETURN __attribute__((noreturn))
#elif defined(_MSC_VER)
#define ABSL_ATTRIBUTE_NORETURN __declspec(noreturn)
#else
#define ABSL_ATTRIBUTE_NORETURN
#endif

// ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS
//
// Tells the AddressSanitizer (or other memory testing tools) to ignore a given
// function. Useful for cases when a function reads random locations on stack,
// calls _exit from a cloned subprocess, deliberately accesses buffer
// out of bounds or does other scary things with memory.
// NOTE: GCC supports AddressSanitizer(asan) since 4.8.
// https://gcc.gnu.org/gcc-4.8/changes.html
#if defined(ABSL_HAVE_ADDRESS_SANITIZER) && \
    ABSL_HAVE_ATTRIBUTE(no_sanitize_address)
#define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
#elif defined(ABSL_HAVE_ADDRESS_SANITIZER) && defined(_MSC_VER) && \
    _MSC_VER >= 1928
// https://docs.microsoft.com/en-us/cpp/cpp/no-sanitize-address
#define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS __declspec(no_sanitize_address)
#elif defined(ABSL_HAVE_HWADDRESS_SANITIZER) && ABSL_HAVE_ATTRIBUTE(no_sanitize)
// HWAddressSanitizer is a sanitizer similar to AddressSanitizer, which uses CPU
// features to detect similar bugs with less CPU and memory overhead.
// NOTE: GCC supports HWAddressSanitizer(hwasan) since 11.
// https://gcc.gnu.org/gcc-11/changes.html
#define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS \
  __attribute__((no_sanitize("hwaddress")))
#else
#define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS
#endif

// ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY
//
// Tells the MemorySanitizer to relax the handling of a given function. All "Use
// of uninitialized value" warnings from such functions will be suppressed, and
// all values loaded from memory will be considered fully initialized.  This
// attribute is similar to the ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS attribute
// above, but deals with initialized-ness rather than addressability issues.
// NOTE: MemorySanitizer(msan) is supported by Clang but not GCC.
#if ABSL_HAVE_ATTRIBUTE(no_sanitize_memory)
#define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory))
#else
#define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY
#endif

// ABSL_ATTRIBUTE_NO_SANITIZE_THREAD
//
// Tells the ThreadSanitizer to not instrument a given function.
// NOTE: GCC supports ThreadSanitizer(tsan) since 4.8.
// https://gcc.gnu.org/gcc-4.8/changes.html
#if ABSL_HAVE_ATTRIBUTE(no_sanitize_thread)
#define ABSL_ATTRIBUTE_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread))
#else
#define ABSL_ATTRIBUTE_NO_SANITIZE_THREAD
#endif

// ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED
//
// Tells the UndefinedSanitizer to ignore a given function. Useful for cases
// where certain behavior (eg. division by zero) is being used intentionally.
// NOTE: GCC supports UndefinedBehaviorSanitizer(ubsan) since 4.9.
// https://gcc.gnu.org/gcc-4.9/changes.html
#if ABSL_HAVE_ATTRIBUTE(no_sanitize_undefined)
#define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED \
  __attribute__((no_sanitize_undefined))
#elif ABSL_HAVE_ATTRIBUTE(no_sanitize)
#define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED \
  __attribute__((no_sanitize("undefined")))
#else
#define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED
#endif

// ABSL_ATTRIBUTE_NO_SANITIZE_CFI
//
// Tells the ControlFlowIntegrity sanitizer to not instrument a given function.
// See https://clang.llvm.org/docs/ControlFlowIntegrity.html for details.
#if ABSL_HAVE_ATTRIBUTE(no_sanitize) && defined(__llvm__)
#define ABSL_ATTRIBUTE_NO_SANITIZE_CFI __attribute__((no_sanitize("cfi")))
#else
#define ABSL_ATTRIBUTE_NO_SANITIZE_CFI
#endif

// ABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK
//
// Tells the SafeStack to not instrument a given function.
// See https://clang.llvm.org/docs/SafeStack.html for details.
#if ABSL_HAVE_ATTRIBUTE(no_sanitize)
#define ABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK \
  __attribute__((no_sanitize("safe-stack")))
#else
#define ABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK
#endif

// ABSL_ATTRIBUTE_RETURNS_NONNULL
//
// Tells the compiler that a particular function never returns a null pointer.
#if ABSL_HAVE_ATTRIBUTE(returns_nonnull)
#define ABSL_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull))
#else
#define ABSL_ATTRIBUTE_RETURNS_NONNULL
#endif

// ABSL_HAVE_ATTRIBUTE_SECTION
//
// Indicates whether labeled sections are supported. Weak symbol support is
// a prerequisite. Labeled sections are not supported on Darwin/iOS.
#ifdef ABSL_HAVE_ATTRIBUTE_SECTION
#error ABSL_HAVE_ATTRIBUTE_SECTION cannot be directly set
#elif (ABSL_HAVE_ATTRIBUTE(section) ||                \
       (defined(__GNUC__) && !defined(__clang__))) && \
    !defined(__APPLE__) && ABSL_HAVE_ATTRIBUTE_WEAK
#define ABSL_HAVE_ATTRIBUTE_SECTION 1

// ABSL_ATTRIBUTE_SECTION
//
// Tells the compiler/linker to put a given function into a section and define
// `__start_ ## name` and `__stop_ ## name` symbols to bracket the section.
// This functionality is supported by GNU linker.  Any function annotated with
// `ABSL_ATTRIBUTE_SECTION` must not be inlined, or it will be placed into
// whatever section its caller is placed into.
//
#ifndef ABSL_ATTRIBUTE_SECTION
#define ABSL_ATTRIBUTE_SECTION(name) \
  __attribute__((section(#name))) __attribute__((noinline))
#endif

// ABSL_ATTRIBUTE_SECTION_VARIABLE
//
// Tells the compiler/linker to put a given variable into a section and define
// `__start_ ## name` and `__stop_ ## name` symbols to bracket the section.
// This functionality is supported by GNU linker.
#ifndef ABSL_ATTRIBUTE_SECTION_VARIABLE
#ifdef _AIX
// __attribute__((section(#name))) on AIX is achieved by using the `.csect`
// pseudo op which includes an additional integer as part of its syntax
// indicating alignment. If data fall under different alignments then you might
// get a compilation error indicating a `Section type conflict`.
#define ABSL_ATTRIBUTE_SECTION_VARIABLE(name)
#else
#define ABSL_ATTRIBUTE_SECTION_VARIABLE(name) __attribute__((section(#name)))
#endif
#endif

// ABSL_DECLARE_ATTRIBUTE_SECTION_VARS
//
// A weak section declaration to be used as a global declaration
// for ABSL_ATTRIBUTE_SECTION_START|STOP(name) to compile and link
// even without functions with ABSL_ATTRIBUTE_SECTION(name).
// ABSL_DEFINE_ATTRIBUTE_SECTION should be in the exactly one file; it's
// a no-op on ELF but not on Mach-O.
//
#ifndef ABSL_DECLARE_ATTRIBUTE_SECTION_VARS
#define ABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name)   \
  extern char __start_##name[] ABSL_ATTRIBUTE_WEAK; \
  extern char __stop_##name[] ABSL_ATTRIBUTE_WEAK
#endif
#ifndef ABSL_DEFINE_ATTRIBUTE_SECTION_VARS
#define ABSL_INIT_ATTRIBUTE_SECTION_VARS(name)
#define ABSL_DEFINE_ATTRIBUTE_SECTION_VARS(name)
#endif

// ABSL_ATTRIBUTE_SECTION_START
//
// Returns `void*` pointers to start/end of a section of code with
// functions having ABSL_ATTRIBUTE_SECTION(name).
// Returns 0 if no such functions exist.
// One must ABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) for this to compile and
// link.
//
#define ABSL_ATTRIBUTE_SECTION_START(name) \
  (reinterpret_cast<void *>(__start_##name))
#define ABSL_ATTRIBUTE_SECTION_STOP(name) \
  (reinterpret_cast<void *>(__stop_##name))

#else  // !ABSL_HAVE_ATTRIBUTE_SECTION

#define ABSL_HAVE_ATTRIBUTE_SECTION 0

// provide dummy definitions
#define ABSL_ATTRIBUTE_SECTION(name)
#define ABSL_ATTRIBUTE_SECTION_VARIABLE(name)
#define ABSL_INIT_ATTRIBUTE_SECTION_VARS(name)
#define ABSL_DEFINE_ATTRIBUTE_SECTION_VARS(name)
#define ABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name)
#define ABSL_ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void *>(0))
#define ABSL_ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void *>(0))

#endif  // ABSL_ATTRIBUTE_SECTION

// ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC
//
// Support for aligning the stack on 32-bit x86.
#if ABSL_HAVE_ATTRIBUTE(force_align_arg_pointer) || \
    (defined(__GNUC__) && !defined(__clang__))
#if defined(__i386__)
#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC \
  __attribute__((force_align_arg_pointer))
#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0)
#elif defined(__x86_64__)
#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (1)
#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC
#else  // !__i386__ && !__x86_64
#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0)
#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC
#endif  // __i386__
#else
#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC
#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0)
#endif

// ABSL_MUST_USE_RESULT
//
// Tells the compiler to warn about unused results.
//
// For code or headers that are assured to only build with C++17 and up, prefer
// just using the standard `[[nodiscard]]` directly over this macro.
//
// When annotating a function, it must appear as the first part of the
// declaration or definition. The compiler will warn if the return value from
// such a function is unused:
//
//   ABSL_MUST_USE_RESULT Sprocket* AllocateSprocket();
//   AllocateSprocket();  // Triggers a warning.
//
// When annotating a class, it is equivalent to annotating every function which
// returns an instance.
//
//   class ABSL_MUST_USE_RESULT Sprocket {};
//   Sprocket();  // Triggers a warning.
//
//   Sprocket MakeSprocket();
//   MakeSprocket();  // Triggers a warning.
//
// Note that references and pointers are not instances:
//
//   Sprocket* SprocketPointer();
//   SprocketPointer();  // Does *not* trigger a warning.
//
// ABSL_MUST_USE_RESULT allows using cast-to-void to suppress the unused result
// warning. For that, warn_unused_result is used only for clang but not for gcc.
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425
//
// Note: past advice was to place the macro after the argument list.
//
// TODO(b/176172494): Use ABSL_HAVE_CPP_ATTRIBUTE(nodiscard) when all code is
// compliant with the stricter [[nodiscard]].
#if defined(__clang__) && ABSL_HAVE_ATTRIBUTE(warn_unused_result)
#define ABSL_MUST_USE_RESULT __attribute__((warn_unused_result))
#else
#define ABSL_MUST_USE_RESULT
#endif

// ABSL_ATTRIBUTE_HOT, ABSL_ATTRIBUTE_COLD
//
// Tells GCC that a function is hot or cold. GCC can use this information to
// improve static analysis, i.e. a conditional branch to a cold function
// is likely to be not-taken.
// This annotation is used for function declarations.
//
// Example:
//
//   int foo() ABSL_ATTRIBUTE_HOT;
#if ABSL_HAVE_ATTRIBUTE(hot) || (defined(__GNUC__) && !defined(__clang__))
#define ABSL_ATTRIBUTE_HOT __attribute__((hot))
#else
#define ABSL_ATTRIBUTE_HOT
#endif

#if ABSL_HAVE_ATTRIBUTE(cold) || (defined(__GNUC__) && !defined(__clang__))
#define ABSL_ATTRIBUTE_COLD __attribute__((cold))
#else
#define ABSL_ATTRIBUTE_COLD
#endif

// ABSL_XRAY_ALWAYS_INSTRUMENT, ABSL_XRAY_NEVER_INSTRUMENT, ABSL_XRAY_LOG_ARGS
//
// We define the ABSL_XRAY_ALWAYS_INSTRUMENT and ABSL_XRAY_NEVER_INSTRUMENT
// macro used as an attribute to mark functions that must always or never be
// instrumented by XRay. Currently, this is only supported in Clang/LLVM.
//
// For reference on the LLVM XRay instrumentation, see
// http://llvm.org/docs/XRay.html.
//
// A function with the XRAY_ALWAYS_INSTRUMENT macro attribute in its declaration
// will always get the XRay instrumentation sleds. These sleds may introduce
// some binary size and runtime overhead and must be used sparingly.
//
// These attributes only take effect when the following conditions are met:
//
//   * The file/target is built in at least C++11 mode, with a Clang compiler
//     that supports XRay attributes.
//   * The file/target is built with the -fxray-instrument flag set for the
//     Clang/LLVM compiler.
//   * The function is defined in the translation unit (the compiler honors the
//     attribute in either the definition or the declaration, and must match).
//
// There are cases when, even when building with XRay instrumentation, users
// might want to control specifically which functions are instrumented for a
// particular build using special-case lists provided to the compiler. These
// special case lists are provided to Clang via the
// -fxray-always-instrument=... and -fxray-never-instrument=... flags. The
// attributes in source take precedence over these special-case lists.
//
// To disable the XRay attributes at build-time, users may define
// ABSL_NO_XRAY_ATTRIBUTES. Do NOT define ABSL_NO_XRAY_ATTRIBUTES on specific
// packages/targets, as this may lead to conflicting definitions of functions at
// link-time.
//
// XRay isn't currently supported on Android:
// https://github.com/android/ndk/issues/368
#if ABSL_HAVE_CPP_ATTRIBUTE(clang::xray_always_instrument) && \
    !defined(ABSL_NO_XRAY_ATTRIBUTES) && !defined(__ANDROID__)
#define ABSL_XRAY_ALWAYS_INSTRUMENT [[clang::xray_always_instrument]]
#define ABSL_XRAY_NEVER_INSTRUMENT [[clang::xray_never_instrument]]
#if ABSL_HAVE_CPP_ATTRIBUTE(clang::xray_log_args)
#define ABSL_XRAY_LOG_ARGS(N) \
  [[clang::xray_always_instrument, clang::xray_log_args(N)]]
#else
#define ABSL_XRAY_LOG_ARGS(N) [[clang::xray_always_instrument]]
#endif
#else
#define ABSL_XRAY_ALWAYS_INSTRUMENT
#define ABSL_XRAY_NEVER_INSTRUMENT
#define ABSL_XRAY_LOG_ARGS(N)
#endif

// ABSL_ATTRIBUTE_REINITIALIZES
//
// Indicates that a member function reinitializes the entire object to a known
// state, independent of the previous state of the object.
//
// The clang-tidy check bugprone-use-after-move allows member functions marked
// with this attribute to be called on objects that have been moved from;
// without the attribute, this would result in a use-after-move warning.
#if ABSL_HAVE_CPP_ATTRIBUTE(clang::reinitializes)
#define ABSL_ATTRIBUTE_REINITIALIZES [[clang::reinitializes]]
#else
#define ABSL_ATTRIBUTE_REINITIALIZES
#endif

// -----------------------------------------------------------------------------
// Variable Attributes
// -----------------------------------------------------------------------------

// ABSL_ATTRIBUTE_UNUSED
//
// Prevents the compiler from complaining about variables that appear unused.
//
// Deprecated: Use the standard C++17 `[[maybe_unused]` instead.
//
// Due to differences in positioning requirements between the old, compiler
// specific __attribute__ syntax and the now standard `[[maybe_unused]]`, this
// macro does not attempt to take advantage of `[[maybe_unused]]`.
#if ABSL_HAVE_ATTRIBUTE(unused) || (defined(__GNUC__) && !defined(__clang__))
#undef ABSL_ATTRIBUTE_UNUSED
#define ABSL_ATTRIBUTE_UNUSED __attribute__((__unused__))
#else
#define ABSL_ATTRIBUTE_UNUSED
#endif

// ABSL_ATTRIBUTE_INITIAL_EXEC
//
// Tells the compiler to use "initial-exec" mode for a thread-local variable.
// See http://people.redhat.com/drepper/tls.pdf for the gory details.
#if ABSL_HAVE_ATTRIBUTE(tls_model) || (defined(__GNUC__) && !defined(__clang__))
#define ABSL_ATTRIBUTE_INITIAL_EXEC __attribute__((tls_model("initial-exec")))
#else
#define ABSL_ATTRIBUTE_INITIAL_EXEC
#endif

// ABSL_ATTRIBUTE_PACKED
//
// Instructs the compiler not to use natural alignment for a tagged data
// structure, but instead to reduce its alignment to 1.
//
// Therefore, DO NOT APPLY THIS ATTRIBUTE TO STRUCTS CONTAINING ATOMICS. Doing
// so can cause atomic variables to be mis-aligned and silently violate
// atomicity on x86.
//
// This attribute can either be applied to members of a structure or to a
// structure in its entirety. Applying this attribute (judiciously) to a
// structure in its entirety to optimize the memory footprint of very
// commonly-used structs is fine. Do not apply this attribute to a structure in
// its entirety if the purpose is to control the offsets of the members in the
// structure. Instead, apply this attribute only to structure members that need
// it.
//
// When applying ABSL_ATTRIBUTE_PACKED only to specific structure members the
// natural alignment of structure members not annotated is preserved. Aligned
// member accesses are faster than non-aligned member accesses even if the
// targeted microprocessor supports non-aligned accesses.
#if ABSL_HAVE_ATTRIBUTE(packed) || (defined(__GNUC__) && !defined(__clang__))
#define ABSL_ATTRIBUTE_PACKED __attribute__((__packed__))
#else
#define ABSL_ATTRIBUTE_PACKED
#endif

// ABSL_ATTRIBUTE_FUNC_ALIGN
//
// Tells the compiler to align the function start at least to certain
// alignment boundary
#if ABSL_HAVE_ATTRIBUTE(aligned) || (defined(__GNUC__) && !defined(__clang__))
#define ABSL_ATTRIBUTE_FUNC_ALIGN(bytes) __attribute__((aligned(bytes)))
#else
#define ABSL_ATTRIBUTE_FUNC_ALIGN(bytes)
#endif

// ABSL_FALLTHROUGH_INTENDED
//
// Annotates implicit fall-through between switch labels, allowing a case to
// indicate intentional fallthrough and turn off warnings about any lack of a
// `break` statement. The ABSL_FALLTHROUGH_INTENDED macro should be followed by
// a semicolon and can be used in most places where `break` can, provided that
// no statements exist between it and the next switch label.
//
// Example:
//
//  switch (x) {
//    case 40:
//    case 41:
//      if (truth_is_out_there) {
//        ++x;
//        ABSL_FALLTHROUGH_INTENDED;  // Use instead of/along with annotations
//                                    // in comments
//      } else {
//        return x;
//      }
//    case 42:
//      ...
//
// Notes: When supported, GCC and Clang can issue a warning on switch labels
// with unannotated fallthrough using the warning `-Wimplicit-fallthrough`. See
// clang documentation on language extensions for details:
// https://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough
//
// When used with unsupported compilers, the ABSL_FALLTHROUGH_INTENDED macro has
// no effect on diagnostics. In any case this macro has no effect on runtime
// behavior and performance of code.

#ifdef ABSL_FALLTHROUGH_INTENDED
#error "ABSL_FALLTHROUGH_INTENDED should not be defined."
#elif ABSL_HAVE_CPP_ATTRIBUTE(fallthrough)
#define ABSL_FALLTHROUGH_INTENDED [[fallthrough]]
#elif ABSL_HAVE_CPP_ATTRIBUTE(clang::fallthrough)
#define ABSL_FALLTHROUGH_INTENDED [[clang::fallthrough]]
#elif ABSL_HAVE_CPP_ATTRIBUTE(gnu::fallthrough)
#define ABSL_FALLTHROUGH_INTENDED [[gnu::fallthrough]]
#else
#define ABSL_FALLTHROUGH_INTENDED \
  do {                            \
  } while (0)
#endif

// ABSL_DEPRECATED()
//
// Marks a deprecated class, struct, enum, function, method and variable
// declarations. The macro argument is used as a custom diagnostic message (e.g.
// suggestion of a better alternative).
//
// For code or headers that are assured to only build with C++14 and up, prefer
// just using the standard `[[deprecated("message")]]` directly over this macro.
//
// Examples:
//
//   class ABSL_DEPRECATED("Use Bar instead") Foo {...};
//
//   ABSL_DEPRECATED("Use Baz() instead") void Bar() {...}
//
//   template <typename T>
//   ABSL_DEPRECATED("Use DoThat() instead")
//   void DoThis();
//
//   enum FooEnum {
//     kBar ABSL_DEPRECATED("Use kBaz instead"),
//   };
//
// Every usage of a deprecated entity will trigger a warning when compiled with
// GCC/Clang's `-Wdeprecated-declarations` option. Google's production toolchain
// turns this warning off by default, instead relying on clang-tidy to report
// new uses of deprecated code.
#if ABSL_HAVE_ATTRIBUTE(deprecated)
#define ABSL_DEPRECATED(message) __attribute__((deprecated(message)))
#else
#define ABSL_DEPRECATED(message)
#endif

// 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 achieve that
// result.
//
// class ABSL_DEPRECATED("Use Bar instead") Foo;
//
// ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
// Baz ComputeBazFromFoo(Foo f);
// ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
#if defined(__GNUC__) || defined(__clang__)
// Clang also supports these GCC pragmas.
#define ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING \
  _Pragma("GCC diagnostic push")             \
  _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
#define ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING \
  _Pragma("GCC diagnostic pop")
#elif defined(_MSC_VER)
#define ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING \
  _Pragma("warning(push)") _Pragma("warning(disable: 4996)")
#define ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING \
  _Pragma("warning(pop)")
#else
#define ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
#define ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
#endif  // defined(__GNUC__) || defined(__clang__)

// ABSL_CONST_INIT
//
// A variable declaration annotated with the `ABSL_CONST_INIT` attribute will
// not compile (on supported platforms) unless the variable has a constant
// initializer. This is useful for variables with static and thread storage
// duration, because it guarantees that they will not suffer from the so-called
// "static init order fiasco".
//
// This attribute must be placed on the initializing declaration of the
// variable. Some compilers will give a -Wmissing-constinit warning when this
// attribute is placed on some other declaration but missing from the
// initializing declaration.
//
// In some cases (notably with thread_local variables), `ABSL_CONST_INIT` can
// also be used in a non-initializing declaration to tell the compiler that a
// variable is already initialized, reducing overhead that would otherwise be
// incurred by a hidden guard variable. Thus annotating all declarations with
// this attribute is recommended to potentially enhance optimization.
//
// Example:
//
//   class MyClass {
//    public:
//     ABSL_CONST_INIT static MyType my_var;
//   };
//
//   ABSL_CONST_INIT MyType MyClass::my_var = MakeMyType(...);
//
// For code or headers that are assured to only build with C++20 and up, prefer
// just using the standard `constinit` keyword directly over this macro.
//
// Note that this attribute is redundant if the variable is declared constexpr.
#if defined(__cpp_constinit) && __cpp_constinit >= 201907L
#define ABSL_CONST_INIT constinit
#elif ABSL_HAVE_CPP_ATTRIBUTE(clang::require_constant_initialization)
#define ABSL_CONST_INIT [[clang::require_constant_initialization]]
#else
#define ABSL_CONST_INIT
#endif

// ABSL_REQUIRE_EXPLICIT_INIT
//
// ABSL_REQUIRE_EXPLICIT_INIT is placed *after* the data members of an aggregate
// type to indicate that the annotated member must be explicitly initialized by
// the user whenever the aggregate is constructed. For example:
//
//   struct Coord {
//     int x ABSL_REQUIRE_EXPLICIT_INIT;
//     int y ABSL_REQUIRE_EXPLICIT_INIT;
//   };
//   Coord coord = {1};  // warning: field 'y' is not explicitly initialized
//
// Note that usage on C arrays is not supported in C++.
// Use a struct (such as std::array) to wrap the array member instead.
//
// Avoid applying this attribute to the members of non-aggregate types.
// The behavior within non-aggregates is unspecified and subject to change.
//
// Do NOT attempt to suppress or demote the error generated by this attribute.
// Just like with a missing function argument, it is a hard error by design.
//
// See the upstream documentation for more details:
// https://clang.llvm.org/docs/AttributeReference.html#require-explicit-initialization
#ifdef __cplusplus
#if ABSL_HAVE_CPP_ATTRIBUTE(clang::require_explicit_initialization)
// clang-format off
#define ABSL_REQUIRE_EXPLICIT_INIT \
  [[clang::require_explicit_initialization]] = \
    AbslInternal_YouForgotToExplicitlyInitializeAField::v
#else
#define ABSL_REQUIRE_EXPLICIT_INIT \
  = AbslInternal_YouForgotToExplicitlyInitializeAField::v
#endif
// clang-format on
#else
// clang-format off
#if ABSL_HAVE_ATTRIBUTE(require_explicit_initialization)
#define ABSL_REQUIRE_EXPLICIT_INIT \
  __attribute__((require_explicit_initialization))
#else
#define ABSL_REQUIRE_EXPLICIT_INIT \
  /* No portable fallback for C is available */
#endif
// clang-format on
#endif

#ifdef __cplusplus
struct AbslInternal_YouForgotToExplicitlyInitializeAField {
  // A portable version of [[clang::require_explicit_initialization]] that
  // never builds, as a last resort for all toolchains.
  // The error messages are poor, so we don't rely on this unless we have to.
  template <class T>
#if !defined(SWIG)
  constexpr
#endif
  operator T() const /* NOLINT */ {
    const void *volatile deliberately_volatile_ptr = nullptr;
    // Infinite loop to prevent constexpr compilation
    for (;;) {
      // This assignment ensures the 'this' pointer is not optimized away, so
      // that linking always fails.
      deliberately_volatile_ptr = this;  // Deliberately not constexpr
      (void)deliberately_volatile_ptr;
    }
  }
  // This is deliberately left undefined to prevent linking
  static AbslInternal_YouForgotToExplicitlyInitializeAField v;
};
#endif

// 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
// annotated function (or, for a parameter of a constructor, in the value of the
// constructed object). This attribute causes warnings to be produced if a
// temporary object does not live long enough.
//
// When applied to a reference parameter, the referenced object is assumed to be
// retained by the return value of the function. When applied to a non-reference
// parameter (for example, a pointer or a class type), all temporaries
// referenced by the parameter are assumed to be retained by the return value of
// the function.
//
// See also the upstream documentation:
// https://clang.llvm.org/docs/AttributeReference.html#lifetimebound
// https://learn.microsoft.com/en-us/cpp/code-quality/c26816?view=msvc-170
#if ABSL_HAVE_CPP_ATTRIBUTE(clang::lifetimebound)
#define ABSL_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]]
#elif ABSL_HAVE_CPP_ATTRIBUTE(msvc::lifetimebound)
#define ABSL_ATTRIBUTE_LIFETIME_BOUND [[msvc::lifetimebound]]
#elif ABSL_HAVE_ATTRIBUTE(lifetimebound)
#define ABSL_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound))
#else
#define ABSL_ATTRIBUTE_LIFETIME_BOUND
#endif

// Internal attribute; name and documentation TBD.
//
// See the upstream documentation:
// https://clang.llvm.org/docs/AttributeReference.html#lifetime_capture_by
#if ABSL_HAVE_CPP_ATTRIBUTE(clang::lifetime_capture_by)
#define ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(Owner) \
  [[clang::lifetime_capture_by(Owner)]]
#else
#define ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(Owner)
#endif

// ABSL_ATTRIBUTE_VIEW indicates that a type is solely a "view" of data that it
// points to, similarly to a span, string_view, or other non-owning reference
// type.
// This enables diagnosing certain lifetime issues similar to those enabled by
// ABSL_ATTRIBUTE_LIFETIME_BOUND, such as:
//
//   struct ABSL_ATTRIBUTE_VIEW StringView {
//     template<class R>
//     StringView(const R&);
//   };
//
//   StringView f(std::string s) {
//     return s;  // warning: address of stack memory returned
//   }
//
// We disable this on Clang versions < 13 because of the following
// false-positive:
//
//   absl::string_view f(absl::optional<absl::string_view> sv) { return *sv; }
//
// See the following links for details:
// https://reviews.llvm.org/D64448
// https://lists.llvm.org/pipermail/cfe-dev/2018-November/060355.html
#if ABSL_HAVE_CPP_ATTRIBUTE(gsl::Pointer) && \
    (!defined(__clang_major__) || __clang_major__ >= 13)
#define ABSL_ATTRIBUTE_VIEW [[gsl::Pointer]]
#else
#define ABSL_ATTRIBUTE_VIEW
#endif

// ABSL_ATTRIBUTE_OWNER indicates that a type is a container, smart pointer, or
// similar class that owns all the data that it points to.
// This enables diagnosing certain lifetime issues similar to those enabled by
// ABSL_ATTRIBUTE_LIFETIME_BOUND, such as:
//
//   struct ABSL_ATTRIBUTE_VIEW StringView {
//     template<class R>
//     StringView(const R&);
//   };
//
//   struct ABSL_ATTRIBUTE_OWNER String {};
//
//   StringView f(String s) {
//     return s;  // warning: address of stack memory returned
//   }
//
// We disable this on Clang versions < 13 because of the following
// false-positive:
//
//   absl::string_view f(absl::optional<absl::string_view> sv) { return *sv; }
//
// See the following links for details:
// https://reviews.llvm.org/D64448
// https://lists.llvm.org/pipermail/cfe-dev/2018-November/060355.html
#if ABSL_HAVE_CPP_ATTRIBUTE(gsl::Owner) && \
    (!defined(__clang_major__) || __clang_major__ >= 13)
#define ABSL_ATTRIBUTE_OWNER [[gsl::Owner]]
#else
#define ABSL_ATTRIBUTE_OWNER
#endif

// ABSL_ATTRIBUTE_TRIVIAL_ABI
// Indicates that a type is "trivially relocatable" -- meaning it can be
// relocated without invoking the constructor/destructor, using a form of move
// elision.
//
// From a memory safety point of view, putting aside destructor ordering, it's
// safe to apply ABSL_ATTRIBUTE_TRIVIAL_ABI if an object's location
// can change over the course of its lifetime: if a constructor can be run one
// place, and then the object magically teleports to another place where some
// methods are run, and then the object teleports to yet another place where it
// is destroyed. This is notably not true for self-referential types, where the
// move-constructor must keep the self-reference up to date. If the type changed
// location without invoking the move constructor, it would have a dangling
// self-reference.
//
// The use of this teleporting machinery means that the number of paired
// move/destroy operations can change, and so it is a bad idea to apply this to
// a type meant to count the number of moves.
//
// Warning: applying this can, rarely, break callers. Objects passed by value
// will be destroyed at the end of the call, instead of the end of the
// full-expression containing the call. In addition, it changes the ABI
// of functions accepting this type by value (e.g. to pass in registers).
//
// See also the upstream documentation:
// https://clang.llvm.org/docs/AttributeReference.html#trivial-abi
//
// 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

// ABSL_ATTRIBUTE_NO_UNIQUE_ADDRESS
//
// Indicates a data member can be optimized to occupy no space (if it is empty)
// and/or its tail padding can be used for other members.
//
// For code that is assured to only build with C++20 or later, prefer using
// the standard attribute `[[no_unique_address]]` directly instead of this
// macro.
//
// https://devblogs.microsoft.com/cppblog/msvc-cpp20-and-the-std-cpp20-switch/#c20-no_unique_address
// Current versions of MSVC have disabled `[[no_unique_address]]` since it
// breaks ABI compatibility, but offers `[[msvc::no_unique_address]]` for
// situations when it can be assured that it is desired. Since Abseil does not
// claim ABI compatibility in mixed builds, we can offer it unconditionally.
#if defined(_MSC_VER) && _MSC_VER >= 1929
#define ABSL_ATTRIBUTE_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
#elif ABSL_HAVE_CPP_ATTRIBUTE(no_unique_address)
#define ABSL_ATTRIBUTE_NO_UNIQUE_ADDRESS [[no_unique_address]]
#else
#define ABSL_ATTRIBUTE_NO_UNIQUE_ADDRESS
#endif

// ABSL_ATTRIBUTE_UNINITIALIZED
//
// GCC and Clang support a flag `-ftrivial-auto-var-init=<option>` (<option>
// can be "zero" or "pattern") that can be used to initialize automatic stack
// variables. Variables with this attribute will be left uninitialized,
// overriding the compiler flag.
//
// See https://clang.llvm.org/docs/AttributeReference.html#uninitialized
// and https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-uninitialized-variable-attribute
#if ABSL_HAVE_CPP_ATTRIBUTE(clang::uninitialized)
#define ABSL_ATTRIBUTE_UNINITIALIZED [[clang::uninitialized]]
#elif ABSL_HAVE_CPP_ATTRIBUTE(gnu::uninitialized)
#define ABSL_ATTRIBUTE_UNINITIALIZED [[gnu::uninitialized]]
#elif ABSL_HAVE_ATTRIBUTE(uninitialized)
#define ABSL_ATTRIBUTE_UNINITIALIZED __attribute__((uninitialized))
#else
#define ABSL_ATTRIBUTE_UNINITIALIZED
#endif

// ABSL_ATTRIBUTE_WARN_UNUSED
//
// Compilers routinely warn about trivial variables that are unused.  For
// non-trivial types, this warning is suppressed since the
// constructor/destructor may be intentional and load-bearing, for example, with
// a RAII scoped lock.
//
// For example:
//
// class ABSL_ATTRIBUTE_WARN_UNUSED MyType {
//  public:
//   MyType();
//   ~MyType();
// };
//
// void foo() {
//   // Warns with ABSL_ATTRIBUTE_WARN_UNUSED attribute present.
//   MyType unused;
// }
//
// See https://clang.llvm.org/docs/AttributeReference.html#warn-unused and
// https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html#index-warn_005funused-type-attribute
#if ABSL_HAVE_CPP_ATTRIBUTE(gnu::warn_unused)
#define ABSL_ATTRIBUTE_WARN_UNUSED [[gnu::warn_unused]]
#else
#define ABSL_ATTRIBUTE_WARN_UNUSED
#endif

#endif  // ABSL_BASE_ATTRIBUTES_H_
*ÿ1
~soong/.intermediates/external/abseil-cpp/absl_log_internal_vlog_config_hdrs/gen/my_include_dir/absl/log/internal/vlog_config.hü0// 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/nullability.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* absl_nonnull 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* absl_nonnull 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* absl_nonnull 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* absl_nonnull 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* absl_nonnull 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* absl_nullable SetVModuleListHeadForTestOnly(
    VLogSite* absl_nullable v);

}  // namespace log_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_LOG_INTERNAL_VLOG_CONFIG_H_
*¯¶
�soong/.intermediates/external/abseil-cpp/absl_container_inlined_vector_internal_hdrs/gen/my_include_dir/absl/container/internal/inlined_vector.h˜µ// Copyright 2019 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_CONTAINER_INTERNAL_INLINED_VECTOR_H_
#define ABSL_CONTAINER_INTERNAL_INLINED_VECTOR_H_

#include <algorithm>
#include <cstddef>
#include <cstring>
#include <iterator>
#include <limits>
#include <memory>
#include <new>
#include <type_traits>
#include <utility>

#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/identity.h"
#include "absl/base/macros.h"
#include "absl/container/internal/compressed_tuple.h"
#include "absl/memory/memory.h"
#include "absl/meta/type_traits.h"
#include "absl/types/span.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace inlined_vector_internal {

// GCC does not deal very well with the below code
#if !defined(__clang__) && defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
#endif

template <typename A>
using AllocatorTraits = std::allocator_traits<A>;
template <typename A>
using ValueType = typename AllocatorTraits<A>::value_type;
template <typename A>
using SizeType = typename AllocatorTraits<A>::size_type;
template <typename A>
using Pointer = typename AllocatorTraits<A>::pointer;
template <typename A>
using ConstPointer = typename AllocatorTraits<A>::const_pointer;
template <typename A>
using SizeType = typename AllocatorTraits<A>::size_type;
template <typename A>
using DifferenceType = typename AllocatorTraits<A>::difference_type;
template <typename A>
using Reference = ValueType<A>&;
template <typename A>
using ConstReference = const ValueType<A>&;
template <typename A>
using Iterator = Pointer<A>;
template <typename A>
using ConstIterator = ConstPointer<A>;
template <typename A>
using ReverseIterator = typename std::reverse_iterator<Iterator<A>>;
template <typename A>
using ConstReverseIterator = typename std::reverse_iterator<ConstIterator<A>>;
template <typename A>
using MoveIterator = typename std::move_iterator<Iterator<A>>;

template <typename A>
using IsMoveAssignOk = std::is_move_assignable<ValueType<A>>;
template <typename A>
using IsSwapOk = absl::type_traits_internal::IsSwappable<ValueType<A>>;

template <typename A,
          bool IsTriviallyDestructible =
              absl::is_trivially_destructible<ValueType<A>>::value &&
              std::is_same<A, std::allocator<ValueType<A>>>::value>
struct DestroyAdapter;

template <typename A>
struct DestroyAdapter<A, /* IsTriviallyDestructible */ false> {
  static void DestroyElements(A& allocator, Pointer<A> destroy_first,
                              SizeType<A> destroy_size) {
    for (SizeType<A> i = destroy_size; i != 0;) {
      --i;
      AllocatorTraits<A>::destroy(allocator, destroy_first + i);
    }
  }
};

template <typename A>
struct DestroyAdapter<A, /* IsTriviallyDestructible */ true> {
  static void DestroyElements(A& allocator, Pointer<A> destroy_first,
                              SizeType<A> destroy_size) {
    static_cast<void>(allocator);
    static_cast<void>(destroy_first);
    static_cast<void>(destroy_size);
  }
};

template <typename A>
struct Allocation {
  Pointer<A> data = nullptr;
  SizeType<A> capacity = 0;
};

template <typename A,
          bool IsOverAligned =
              (alignof(ValueType<A>) > ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT)>
struct MallocAdapter {
  static Allocation<A> Allocate(A& allocator, SizeType<A> requested_capacity) {
    return {AllocatorTraits<A>::allocate(allocator, requested_capacity),
            requested_capacity};
  }

  static void Deallocate(A& allocator, Pointer<A> pointer,
                         SizeType<A> capacity) {
    AllocatorTraits<A>::deallocate(allocator, pointer, capacity);
  }
};

template <typename A, typename ValueAdapter>
void ConstructElements(absl::internal::type_identity_t<A>& allocator,
                       Pointer<A> construct_first, ValueAdapter& values,
                       SizeType<A> construct_size) {
  for (SizeType<A> i = 0; i < construct_size; ++i) {
    ABSL_INTERNAL_TRY { values.ConstructNext(allocator, construct_first + i); }
    ABSL_INTERNAL_CATCH_ANY {
      DestroyAdapter<A>::DestroyElements(allocator, construct_first, i);
      ABSL_INTERNAL_RETHROW;
    }
  }
}

template <typename A, typename ValueAdapter>
void AssignElements(Pointer<A> assign_first, ValueAdapter& values,
                    SizeType<A> assign_size) {
  for (SizeType<A> i = 0; i < assign_size; ++i) {
    values.AssignNext(assign_first + i);
  }
}

template <typename A>
struct StorageView {
  Pointer<A> data;
  SizeType<A> size;
  SizeType<A> capacity;
};

template <typename A, typename Iterator>
class IteratorValueAdapter {
 public:
  explicit IteratorValueAdapter(const Iterator& it) : it_(it) {}

  void ConstructNext(A& allocator, Pointer<A> construct_at) {
    AllocatorTraits<A>::construct(allocator, construct_at, *it_);
    ++it_;
  }

  void AssignNext(Pointer<A> assign_at) {
    *assign_at = *it_;
    ++it_;
  }

 private:
  Iterator it_;
};

template <typename A>
class CopyValueAdapter {
 public:
  explicit CopyValueAdapter(ConstPointer<A> p) : ptr_(p) {}

  void ConstructNext(A& allocator, Pointer<A> construct_at) {
    AllocatorTraits<A>::construct(allocator, construct_at, *ptr_);
  }

  void AssignNext(Pointer<A> assign_at) { *assign_at = *ptr_; }

 private:
  ConstPointer<A> ptr_;
};

template <typename A>
class DefaultValueAdapter {
 public:
  explicit DefaultValueAdapter() {}

  void ConstructNext(A& allocator, Pointer<A> construct_at) {
    AllocatorTraits<A>::construct(allocator, construct_at);
  }

  void AssignNext(Pointer<A> assign_at) { *assign_at = ValueType<A>(); }
};

template <typename A>
class AllocationTransaction {
 public:
  explicit AllocationTransaction(A& allocator)
      : allocator_data_(allocator, nullptr), capacity_(0) {}

  ~AllocationTransaction() {
    if (DidAllocate()) {
      MallocAdapter<A>::Deallocate(GetAllocator(), GetData(), GetCapacity());
    }
  }

  AllocationTransaction(const AllocationTransaction&) = delete;
  void operator=(const AllocationTransaction&) = delete;

  A& GetAllocator() { return allocator_data_.template get<0>(); }
  Pointer<A>& GetData() { return allocator_data_.template get<1>(); }
  SizeType<A>& GetCapacity() { return capacity_; }

  bool DidAllocate() { return GetData() != nullptr; }

  Pointer<A> Allocate(SizeType<A> requested_capacity) {
    Allocation<A> result =
        MallocAdapter<A>::Allocate(GetAllocator(), requested_capacity);
    GetData() = result.data;
    GetCapacity() = result.capacity;
    return result.data;
  }

  [[nodiscard]] Allocation<A> Release() && {
    Allocation<A> result = {GetData(), GetCapacity()};
    Reset();
    return result;
  }

 private:
  void Reset() {
    GetData() = nullptr;
    GetCapacity() = 0;
  }

  container_internal::CompressedTuple<A, Pointer<A>> allocator_data_;
  SizeType<A> capacity_;
};

template <typename A>
class ConstructionTransaction {
 public:
  explicit ConstructionTransaction(A& allocator)
      : allocator_data_(allocator, nullptr), size_(0) {}

  ~ConstructionTransaction() {
    if (DidConstruct()) {
      DestroyAdapter<A>::DestroyElements(GetAllocator(), GetData(), GetSize());
    }
  }

  ConstructionTransaction(const ConstructionTransaction&) = delete;
  void operator=(const ConstructionTransaction&) = delete;

  A& GetAllocator() { return allocator_data_.template get<0>(); }
  Pointer<A>& GetData() { return allocator_data_.template get<1>(); }
  SizeType<A>& GetSize() { return size_; }

  bool DidConstruct() { return GetData() != nullptr; }
  template <typename ValueAdapter>
  void Construct(Pointer<A> data, ValueAdapter& values, SizeType<A> size) {
    ConstructElements<A>(GetAllocator(), data, values, size);
    GetData() = data;
    GetSize() = size;
  }
  void Commit() && {
    GetData() = nullptr;
    GetSize() = 0;
  }

 private:
  container_internal::CompressedTuple<A, Pointer<A>> allocator_data_;
  SizeType<A> size_;
};

template <typename T, size_t N, typename A>
class Storage {
 public:
  struct MemcpyPolicy {};
  struct ElementwiseAssignPolicy {};
  struct ElementwiseSwapPolicy {};
  struct ElementwiseConstructPolicy {};

  using MoveAssignmentPolicy = absl::conditional_t<
      // Fast path: if the value type can be trivially move assigned and
      // destroyed, and we know the allocator doesn't do anything fancy, then
      // it's safe for us to simply adopt the contents of the storage for
      // `other` and remove its own reference to them. It's as if we had
      // individually move-assigned each value and then destroyed the original.
      absl::conjunction<absl::is_trivially_move_assignable<ValueType<A>>,
                        absl::is_trivially_destructible<ValueType<A>>,
                        std::is_same<A, std::allocator<ValueType<A>>>>::value,
      MemcpyPolicy,
      // Otherwise we use move assignment if possible. If not, we simulate
      // move assignment using move construction.
      //
      // Note that this is in contrast to e.g. std::vector and std::optional,
      // which are themselves not move-assignable when their contained type is
      // not.
      absl::conditional_t<IsMoveAssignOk<A>::value, ElementwiseAssignPolicy,
                          ElementwiseConstructPolicy>>;

  // The policy to be used specifically when swapping inlined elements.
  using SwapInlinedElementsPolicy = absl::conditional_t<
      // Fast path: if the value type can be trivially relocated, and we
      // know the allocator doesn't do anything fancy, then it's safe for us
      // to simply swap the bytes in the inline storage. It's as if we had
      // relocated the first vector's elements into temporary storage,
      // relocated the second's elements into the (now-empty) first's,
      // and then relocated from temporary storage into the second.
      absl::conjunction<absl::is_trivially_relocatable<ValueType<A>>,
                        std::is_same<A, std::allocator<ValueType<A>>>>::value,
      MemcpyPolicy,
      absl::conditional_t<IsSwapOk<A>::value, ElementwiseSwapPolicy,
                          ElementwiseConstructPolicy>>;

  static SizeType<A> NextCapacity(SizeType<A> current_capacity) {
    return current_capacity * 2;
  }

  static SizeType<A> ComputeCapacity(SizeType<A> current_capacity,
                                     SizeType<A> requested_capacity) {
    return (std::max)(NextCapacity(current_capacity), requested_capacity);
  }

  // ---------------------------------------------------------------------------
  // Storage Constructors and Destructor
  // ---------------------------------------------------------------------------

  Storage() : metadata_(A(), /* size and is_allocated */ 0u) {}

  explicit Storage(const A& allocator)
      : metadata_(allocator, /* size and is_allocated */ 0u) {}

  ~Storage() {
    // Fast path: if we are empty and not allocated, there's nothing to do.
    if (GetSizeAndIsAllocated() == 0) {
      return;
    }

    // Fast path: if no destructors need to be run and we know the allocator
    // doesn't do anything fancy, then all we need to do is deallocate (and
    // maybe not even that).
    if (absl::is_trivially_destructible<ValueType<A>>::value &&
        std::is_same<A, std::allocator<ValueType<A>>>::value) {
      DeallocateIfAllocated();
      return;
    }

    DestroyContents();
  }

  // ---------------------------------------------------------------------------
  // Storage Member Accessors
  // ---------------------------------------------------------------------------

  SizeType<A>& GetSizeAndIsAllocated() { return metadata_.template get<1>(); }

  const SizeType<A>& GetSizeAndIsAllocated() const {
    return metadata_.template get<1>();
  }

  SizeType<A> GetSize() const { return GetSizeAndIsAllocated() >> 1; }

  bool GetIsAllocated() const { return GetSizeAndIsAllocated() & 1; }

  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;
  }

  // ABSL_ATTRIBUTE_NO_SANITIZE_CFI is used because the memory pointed to may be
  // uninitialized, a common pattern in allocate()+construct() APIs.
  // https://clang.llvm.org/docs/ControlFlowIntegrity.html#bad-cast-checking
  // NOTE: When this was written, LLVM documentation did not explicitly
  // mention that casting `char*` and using `reinterpret_cast` qualifies
  // as a bad cast.
  ABSL_ATTRIBUTE_NO_SANITIZE_CFI Pointer<A> GetInlinedData() {
    return reinterpret_cast<Pointer<A>>(data_.inlined.inlined_data);
  }

  ABSL_ATTRIBUTE_NO_SANITIZE_CFI ConstPointer<A> GetInlinedData() const {
    return reinterpret_cast<ConstPointer<A>>(data_.inlined.inlined_data);
  }

  SizeType<A> GetAllocatedCapacity() const {
    return data_.allocated.allocated_capacity;
  }

  SizeType<A> GetInlinedCapacity() const {
    return static_cast<SizeType<A>>(kOptimalInlinedSize);
  }

  StorageView<A> MakeStorageView() {
    return GetIsAllocated() ? StorageView<A>{GetAllocatedData(), GetSize(),
                                             GetAllocatedCapacity()}
                            : StorageView<A>{GetInlinedData(), GetSize(),
                                             GetInlinedCapacity()};
  }

  A& GetAllocator() { return metadata_.template get<0>(); }

  const A& GetAllocator() const { return metadata_.template get<0>(); }

  // ---------------------------------------------------------------------------
  // Storage Member Mutators
  // ---------------------------------------------------------------------------

  ABSL_ATTRIBUTE_NOINLINE void InitFrom(const Storage& other);

  template <typename ValueAdapter>
  void Initialize(ValueAdapter values, SizeType<A> new_size);

  template <typename ValueAdapter>
  void Assign(ValueAdapter values, SizeType<A> new_size);

  template <typename ValueAdapter>
  void Resize(ValueAdapter values, SizeType<A> new_size);

  template <typename ValueAdapter>
  Iterator<A> Insert(ConstIterator<A> pos, ValueAdapter values,
                     SizeType<A> insert_count);

  template <typename... Args>
  Reference<A> EmplaceBack(Args&&... args);

  Iterator<A> Erase(ConstIterator<A> from, ConstIterator<A> to);

  void Reserve(SizeType<A> requested_capacity);

  void ShrinkToFit();

  void Swap(Storage* other_storage_ptr);

  void SetIsAllocated() {
    GetSizeAndIsAllocated() |= static_cast<SizeType<A>>(1);
  }

  void UnsetIsAllocated() {
    GetSizeAndIsAllocated() &= ((std::numeric_limits<SizeType<A>>::max)() - 1);
  }

  void SetSize(SizeType<A> size) {
    GetSizeAndIsAllocated() =
        (size << 1) | static_cast<SizeType<A>>(GetIsAllocated());
  }

  void SetAllocatedSize(SizeType<A> size) {
    GetSizeAndIsAllocated() = (size << 1) | static_cast<SizeType<A>>(1);
  }

  void SetInlinedSize(SizeType<A> size) {
    GetSizeAndIsAllocated() = size << static_cast<SizeType<A>>(1);
  }

  void AddSize(SizeType<A> count) {
    GetSizeAndIsAllocated() += count << static_cast<SizeType<A>>(1);
  }

  void SubtractSize(SizeType<A> count) {
    ABSL_HARDENING_ASSERT(count <= GetSize());

    GetSizeAndIsAllocated() -= count << static_cast<SizeType<A>>(1);
  }

  void SetAllocation(Allocation<A> allocation) {
    data_.allocated.allocated_data = allocation.data;
    data_.allocated.allocated_capacity = allocation.capacity;
  }

  void MemcpyFrom(const Storage& other_storage) {
    // Assumption check: it doesn't make sense to memcpy inlined elements unless
    // we know the allocator doesn't do anything fancy, and one of the following
    // holds:
    //
    //  *  The elements are trivially relocatable.
    //
    //  *  It's possible to trivially assign the elements and then destroy the
    //     source.
    //
    //  *  It's possible to trivially copy construct/assign the elements.
    //
    {
      using V = ValueType<A>;
      ABSL_HARDENING_ASSERT(
          other_storage.GetIsAllocated() ||
          (std::is_same<A, std::allocator<V>>::value &&
           (
               // First case above
               absl::is_trivially_relocatable<V>::value ||
               // Second case above
               (absl::is_trivially_move_assignable<V>::value &&
                absl::is_trivially_destructible<V>::value) ||
               // Third case above
               (absl::is_trivially_copy_constructible<V>::value ||
                absl::is_trivially_copy_assignable<V>::value))));
    }

    GetSizeAndIsAllocated() = other_storage.GetSizeAndIsAllocated();
    data_ = other_storage.data_;
  }

  void DeallocateIfAllocated() {
    if (GetIsAllocated()) {
      MallocAdapter<A>::Deallocate(GetAllocator(), GetAllocatedData(),
                                   GetAllocatedCapacity());
    }
  }

 private:
  ABSL_ATTRIBUTE_NOINLINE void DestroyContents();

  using Metadata = container_internal::CompressedTuple<A, SizeType<A>>;

  struct Allocated {
    Pointer<A> allocated_data;
    SizeType<A> allocated_capacity;
  };

  // `kOptimalInlinedSize` is an automatically adjusted inlined capacity of the
  // `InlinedVector`. Sometimes, it is possible to increase the capacity (from
  // the user requested `N`) without increasing the size of the `InlinedVector`.
  static constexpr size_t kOptimalInlinedSize =
      (std::max)(N, sizeof(Allocated) / sizeof(ValueType<A>));

  struct Inlined {
    alignas(ValueType<A>) unsigned char inlined_data[sizeof(
        ValueType<A>[kOptimalInlinedSize])];
  };

  union Data {
    Allocated allocated;
    Inlined inlined;
  };

  void SwapN(ElementwiseSwapPolicy, Storage* other, SizeType<A> n);
  void SwapN(ElementwiseConstructPolicy, Storage* other, SizeType<A> n);

  void SwapInlinedElements(MemcpyPolicy, Storage* other);
  template <typename NotMemcpyPolicy>
  void SwapInlinedElements(NotMemcpyPolicy, Storage* other);

  template <typename... Args>
  ABSL_ATTRIBUTE_NOINLINE Reference<A> EmplaceBackSlow(Args&&... args);

  Metadata metadata_;
  Data data_;
};

template <typename T, size_t N, typename A>
void Storage<T, N, A>::DestroyContents() {
  Pointer<A> data = GetIsAllocated() ? GetAllocatedData() : GetInlinedData();
  DestroyAdapter<A>::DestroyElements(GetAllocator(), data, GetSize());
  DeallocateIfAllocated();
}

template <typename T, size_t N, typename A>
void Storage<T, N, A>::InitFrom(const Storage& other) {
  const SizeType<A> n = other.GetSize();
  ABSL_HARDENING_ASSERT(n > 0);  // Empty sources handled handled in caller.
  ConstPointer<A> src;
  Pointer<A> dst;
  if (!other.GetIsAllocated()) {
    dst = GetInlinedData();
    src = other.GetInlinedData();
  } else {
    // Because this is only called from the `InlinedVector` constructors, it's
    // safe to take on the allocation with size `0`. If `ConstructElements(...)`
    // throws, deallocation will be automatically handled by `~Storage()`.
    SizeType<A> requested_capacity = ComputeCapacity(GetInlinedCapacity(), n);
    Allocation<A> allocation =
        MallocAdapter<A>::Allocate(GetAllocator(), requested_capacity);
    SetAllocation(allocation);
    dst = allocation.data;
    src = other.GetAllocatedData();
  }

  // Fast path: if the value type is trivially copy constructible and we know
  // the allocator doesn't do anything fancy, then we know it is legal for us to
  // simply memcpy the other vector's elements.
  if (absl::is_trivially_copy_constructible<ValueType<A>>::value &&
      std::is_same<A, std::allocator<ValueType<A>>>::value) {
    std::memcpy(reinterpret_cast<char*>(dst),
                reinterpret_cast<const char*>(src), n * sizeof(ValueType<A>));
  } else {
    auto values = IteratorValueAdapter<A, ConstPointer<A>>(src);
    ConstructElements<A>(GetAllocator(), dst, values, n);
  }

  GetSizeAndIsAllocated() = other.GetSizeAndIsAllocated();
}

template <typename T, size_t N, typename A>
template <typename ValueAdapter>
auto Storage<T, N, A>::Initialize(ValueAdapter values,
                                  SizeType<A> new_size) -> void {
  // Only callable from constructors!
  ABSL_HARDENING_ASSERT(!GetIsAllocated());
  ABSL_HARDENING_ASSERT(GetSize() == 0);

  Pointer<A> construct_data;
  if (new_size > GetInlinedCapacity()) {
    // Because this is only called from the `InlinedVector` constructors, it's
    // safe to take on the allocation with size `0`. If `ConstructElements(...)`
    // throws, deallocation will be automatically handled by `~Storage()`.
    SizeType<A> requested_capacity =
        ComputeCapacity(GetInlinedCapacity(), new_size);
    Allocation<A> allocation =
        MallocAdapter<A>::Allocate(GetAllocator(), requested_capacity);
    construct_data = allocation.data;
    SetAllocation(allocation);
    SetIsAllocated();
  } else {
    construct_data = GetInlinedData();
  }

  ConstructElements<A>(GetAllocator(), construct_data, values, new_size);

  // Since the initial size was guaranteed to be `0` and the allocated bit is
  // already correct for either case, *adding* `new_size` gives us the correct
  // result faster than setting it directly.
  AddSize(new_size);
}

template <typename T, size_t N, typename A>
template <typename ValueAdapter>
auto Storage<T, N, A>::Assign(ValueAdapter values,
                              SizeType<A> new_size) -> void {
  StorageView<A> storage_view = MakeStorageView();

  AllocationTransaction<A> allocation_tx(GetAllocator());

  absl::Span<ValueType<A>> assign_loop;
  absl::Span<ValueType<A>> construct_loop;
  absl::Span<ValueType<A>> destroy_loop;

  if (new_size > storage_view.capacity) {
    SizeType<A> requested_capacity =
        ComputeCapacity(storage_view.capacity, new_size);
    construct_loop = {allocation_tx.Allocate(requested_capacity), new_size};
    destroy_loop = {storage_view.data, storage_view.size};
  } else if (new_size > storage_view.size) {
    assign_loop = {storage_view.data, storage_view.size};
    construct_loop = {storage_view.data + storage_view.size,
                      new_size - storage_view.size};
  } else {
    assign_loop = {storage_view.data, new_size};
    destroy_loop = {storage_view.data + new_size, storage_view.size - new_size};
  }

  AssignElements<A>(assign_loop.data(), values, assign_loop.size());

  ConstructElements<A>(GetAllocator(), construct_loop.data(), values,
                       construct_loop.size());

  DestroyAdapter<A>::DestroyElements(GetAllocator(), destroy_loop.data(),
                                     destroy_loop.size());

  if (allocation_tx.DidAllocate()) {
    DeallocateIfAllocated();
    SetAllocation(std::move(allocation_tx).Release());
    SetIsAllocated();
  }

  SetSize(new_size);
}

template <typename T, size_t N, typename A>
template <typename ValueAdapter>
auto Storage<T, N, A>::Resize(ValueAdapter values,
                              SizeType<A> new_size) -> void {
  StorageView<A> storage_view = MakeStorageView();
  Pointer<A> const base = storage_view.data;
  const SizeType<A> size = storage_view.size;
  A& alloc = GetAllocator();
  if (new_size <= size) {
    // Destroy extra old elements.
    DestroyAdapter<A>::DestroyElements(alloc, base + new_size, size - new_size);
  } else if (new_size <= storage_view.capacity) {
    // Construct new elements in place.
    ConstructElements<A>(alloc, base + size, values, new_size - size);
  } else {
    // Steps:
    //  a. Allocate new backing store.
    //  b. Construct new elements in new backing store.
    //  c. Move existing elements from old backing store to new backing store.
    //  d. Destroy all elements in old backing store.
    // Use transactional wrappers for the first two steps so we can roll
    // back if necessary due to exceptions.
    AllocationTransaction<A> allocation_tx(alloc);
    SizeType<A> requested_capacity =
        ComputeCapacity(storage_view.capacity, new_size);
    Pointer<A> new_data = allocation_tx.Allocate(requested_capacity);

    ConstructionTransaction<A> construction_tx(alloc);
    construction_tx.Construct(new_data + size, values, new_size - size);

    IteratorValueAdapter<A, MoveIterator<A>> move_values(
        (MoveIterator<A>(base)));
    ConstructElements<A>(alloc, new_data, move_values, size);

    DestroyAdapter<A>::DestroyElements(alloc, base, size);
    std::move(construction_tx).Commit();
    DeallocateIfAllocated();
    SetAllocation(std::move(allocation_tx).Release());
    SetIsAllocated();
  }
  SetSize(new_size);
}

template <typename T, size_t N, typename A>
template <typename ValueAdapter>
auto Storage<T, N, A>::Insert(ConstIterator<A> pos, ValueAdapter values,
                              SizeType<A> insert_count) -> Iterator<A> {
  StorageView<A> storage_view = MakeStorageView();

  auto insert_index = static_cast<SizeType<A>>(
      std::distance(ConstIterator<A>(storage_view.data), pos));
  SizeType<A> insert_end_index = insert_index + insert_count;
  SizeType<A> new_size = storage_view.size + insert_count;

  if (new_size > storage_view.capacity) {
    AllocationTransaction<A> allocation_tx(GetAllocator());
    ConstructionTransaction<A> construction_tx(GetAllocator());
    ConstructionTransaction<A> move_construction_tx(GetAllocator());

    IteratorValueAdapter<A, MoveIterator<A>> move_values(
        MoveIterator<A>(storage_view.data));

    SizeType<A> requested_capacity =
        ComputeCapacity(storage_view.capacity, new_size);
    Pointer<A> new_data = allocation_tx.Allocate(requested_capacity);

    construction_tx.Construct(new_data + insert_index, values, insert_count);

    move_construction_tx.Construct(new_data, move_values, insert_index);

    ConstructElements<A>(GetAllocator(), new_data + insert_end_index,
                         move_values, storage_view.size - insert_index);

    DestroyAdapter<A>::DestroyElements(GetAllocator(), storage_view.data,
                                       storage_view.size);

    std::move(construction_tx).Commit();
    std::move(move_construction_tx).Commit();
    DeallocateIfAllocated();
    SetAllocation(std::move(allocation_tx).Release());

    SetAllocatedSize(new_size);
    return Iterator<A>(new_data + insert_index);
  } else {
    SizeType<A> move_construction_destination_index =
        (std::max)(insert_end_index, storage_view.size);

    ConstructionTransaction<A> move_construction_tx(GetAllocator());

    IteratorValueAdapter<A, MoveIterator<A>> move_construction_values(
        MoveIterator<A>(storage_view.data +
                        (move_construction_destination_index - insert_count)));
    absl::Span<ValueType<A>> move_construction = {
        storage_view.data + move_construction_destination_index,
        new_size - move_construction_destination_index};

    Pointer<A> move_assignment_values = storage_view.data + insert_index;
    absl::Span<ValueType<A>> move_assignment = {
        storage_view.data + insert_end_index,
        move_construction_destination_index - insert_end_index};

    absl::Span<ValueType<A>> insert_assignment = {move_assignment_values,
                                                  move_construction.size()};

    absl::Span<ValueType<A>> insert_construction = {
        insert_assignment.data() + insert_assignment.size(),
        insert_count - insert_assignment.size()};

    move_construction_tx.Construct(move_construction.data(),
                                   move_construction_values,
                                   move_construction.size());

    for (Pointer<A>
             destination = move_assignment.data() + move_assignment.size(),
             last_destination = move_assignment.data(),
             source = move_assignment_values + move_assignment.size();
         ;) {
      --destination;
      --source;
      if (destination < last_destination) break;
      *destination = std::move(*source);
    }

    AssignElements<A>(insert_assignment.data(), values,
                      insert_assignment.size());

    ConstructElements<A>(GetAllocator(), insert_construction.data(), values,
                         insert_construction.size());

    std::move(move_construction_tx).Commit();

    AddSize(insert_count);
    return Iterator<A>(storage_view.data + insert_index);
  }
}

template <typename T, size_t N, typename A>
template <typename... Args>
auto Storage<T, N, A>::EmplaceBack(Args&&... args) -> Reference<A> {
  StorageView<A> storage_view = MakeStorageView();
  const SizeType<A> n = storage_view.size;
  if (ABSL_PREDICT_TRUE(n != storage_view.capacity)) {
    // Fast path; new element fits.
    Pointer<A> last_ptr = storage_view.data + n;
    AllocatorTraits<A>::construct(GetAllocator(), last_ptr,
                                  std::forward<Args>(args)...);
    AddSize(1);
    return *last_ptr;
  }
  // TODO(b/173712035): Annotate with musttail attribute to prevent regression.
  return EmplaceBackSlow(std::forward<Args>(args)...);
}

template <typename T, size_t N, typename A>
template <typename... Args>
auto Storage<T, N, A>::EmplaceBackSlow(Args&&... args) -> Reference<A> {
  StorageView<A> storage_view = MakeStorageView();
  AllocationTransaction<A> allocation_tx(GetAllocator());
  IteratorValueAdapter<A, MoveIterator<A>> move_values(
      MoveIterator<A>(storage_view.data));
  SizeType<A> requested_capacity = NextCapacity(storage_view.capacity);
  Pointer<A> construct_data = allocation_tx.Allocate(requested_capacity);
  Pointer<A> last_ptr = construct_data + storage_view.size;

  // Construct new element.
  AllocatorTraits<A>::construct(GetAllocator(), last_ptr,
                                std::forward<Args>(args)...);
  // Move elements from old backing store to new backing store.
  ABSL_INTERNAL_TRY {
    ConstructElements<A>(GetAllocator(), allocation_tx.GetData(), move_values,
                         storage_view.size);
  }
  ABSL_INTERNAL_CATCH_ANY {
    AllocatorTraits<A>::destroy(GetAllocator(), last_ptr);
    ABSL_INTERNAL_RETHROW;
  }
  // Destroy elements in old backing store.
  DestroyAdapter<A>::DestroyElements(GetAllocator(), storage_view.data,
                                     storage_view.size);

  DeallocateIfAllocated();
  SetAllocation(std::move(allocation_tx).Release());
  SetIsAllocated();
  AddSize(1);
  return *last_ptr;
}

template <typename T, size_t N, typename A>
auto Storage<T, N, A>::Erase(ConstIterator<A> from,
                             ConstIterator<A> to) -> Iterator<A> {
  StorageView<A> storage_view = MakeStorageView();

  auto erase_size = static_cast<SizeType<A>>(std::distance(from, to));
  auto erase_index = static_cast<SizeType<A>>(
      std::distance(ConstIterator<A>(storage_view.data), from));
  SizeType<A> erase_end_index = erase_index + erase_size;

  // Fast path: if the value type is trivially relocatable and we know
  // the allocator doesn't do anything fancy, then we know it is legal for us to
  // simply destroy the elements in the "erasure window" (which cannot throw)
  // and then memcpy downward to close the window.
  if (absl::is_trivially_relocatable<ValueType<A>>::value &&
      std::is_nothrow_destructible<ValueType<A>>::value &&
      std::is_same<A, std::allocator<ValueType<A>>>::value) {
    DestroyAdapter<A>::DestroyElements(
        GetAllocator(), storage_view.data + erase_index, erase_size);
    std::memmove(
        reinterpret_cast<char*>(storage_view.data + erase_index),
        reinterpret_cast<const char*>(storage_view.data + erase_end_index),
        (storage_view.size - erase_end_index) * sizeof(ValueType<A>));
  } else {
    IteratorValueAdapter<A, MoveIterator<A>> move_values(
        MoveIterator<A>(storage_view.data + erase_end_index));

    AssignElements<A>(storage_view.data + erase_index, move_values,
                      storage_view.size - erase_end_index);

    DestroyAdapter<A>::DestroyElements(
        GetAllocator(), storage_view.data + (storage_view.size - erase_size),
        erase_size);
  }
  SubtractSize(erase_size);
  return Iterator<A>(storage_view.data + erase_index);
}

template <typename T, size_t N, typename A>
auto Storage<T, N, A>::Reserve(SizeType<A> requested_capacity) -> void {
  StorageView<A> storage_view = MakeStorageView();

  if (ABSL_PREDICT_FALSE(requested_capacity <= storage_view.capacity)) return;

  AllocationTransaction<A> allocation_tx(GetAllocator());

  IteratorValueAdapter<A, MoveIterator<A>> move_values(
      MoveIterator<A>(storage_view.data));

  SizeType<A> new_requested_capacity =
      ComputeCapacity(storage_view.capacity, requested_capacity);
  Pointer<A> new_data = allocation_tx.Allocate(new_requested_capacity);

  ConstructElements<A>(GetAllocator(), new_data, move_values,
                       storage_view.size);

  DestroyAdapter<A>::DestroyElements(GetAllocator(), storage_view.data,
                                     storage_view.size);

  DeallocateIfAllocated();
  SetAllocation(std::move(allocation_tx).Release());
  SetIsAllocated();
}

template <typename T, size_t N, typename A>
auto Storage<T, N, A>::ShrinkToFit() -> void {
  // May only be called on allocated instances!
  ABSL_HARDENING_ASSERT(GetIsAllocated());

  StorageView<A> storage_view{GetAllocatedData(), GetSize(),
                              GetAllocatedCapacity()};

  if (ABSL_PREDICT_FALSE(storage_view.size == storage_view.capacity)) return;

  AllocationTransaction<A> allocation_tx(GetAllocator());

  IteratorValueAdapter<A, MoveIterator<A>> move_values(
      MoveIterator<A>(storage_view.data));

  Pointer<A> construct_data;
  if (storage_view.size > GetInlinedCapacity()) {
    SizeType<A> requested_capacity = storage_view.size;
    construct_data = allocation_tx.Allocate(requested_capacity);
    if (allocation_tx.GetCapacity() >= storage_view.capacity) {
      // Already using the smallest available heap allocation.
      return;
    }
  } else {
    construct_data = GetInlinedData();
  }

  ABSL_INTERNAL_TRY {
    ConstructElements<A>(GetAllocator(), construct_data, move_values,
                         storage_view.size);
  }
  ABSL_INTERNAL_CATCH_ANY {
    SetAllocation({storage_view.data, storage_view.capacity});
    ABSL_INTERNAL_RETHROW;
  }

  DestroyAdapter<A>::DestroyElements(GetAllocator(), storage_view.data,
                                     storage_view.size);

  MallocAdapter<A>::Deallocate(GetAllocator(), storage_view.data,
                               storage_view.capacity);

  if (allocation_tx.DidAllocate()) {
    SetAllocation(std::move(allocation_tx).Release());
  } else {
    UnsetIsAllocated();
  }
}

template <typename T, size_t N, typename A>
auto Storage<T, N, A>::Swap(Storage* other_storage_ptr) -> void {
  using std::swap;
  ABSL_HARDENING_ASSERT(this != other_storage_ptr);

  if (GetIsAllocated() && other_storage_ptr->GetIsAllocated()) {
    swap(data_.allocated, other_storage_ptr->data_.allocated);
  } else if (!GetIsAllocated() && !other_storage_ptr->GetIsAllocated()) {
    SwapInlinedElements(SwapInlinedElementsPolicy{}, other_storage_ptr);
  } else {
    Storage* allocated_ptr = this;
    Storage* inlined_ptr = other_storage_ptr;
    if (!allocated_ptr->GetIsAllocated()) swap(allocated_ptr, inlined_ptr);

    StorageView<A> allocated_storage_view{
        allocated_ptr->GetAllocatedData(), allocated_ptr->GetSize(),
        allocated_ptr->GetAllocatedCapacity()};

    IteratorValueAdapter<A, MoveIterator<A>> move_values(
        MoveIterator<A>(inlined_ptr->GetInlinedData()));

    ABSL_INTERNAL_TRY {
      ConstructElements<A>(inlined_ptr->GetAllocator(),
                           allocated_ptr->GetInlinedData(), move_values,
                           inlined_ptr->GetSize());
    }
    ABSL_INTERNAL_CATCH_ANY {
      allocated_ptr->SetAllocation(Allocation<A>{
          allocated_storage_view.data, allocated_storage_view.capacity});
      ABSL_INTERNAL_RETHROW;
    }

    DestroyAdapter<A>::DestroyElements(inlined_ptr->GetAllocator(),
                                       inlined_ptr->GetInlinedData(),
                                       inlined_ptr->GetSize());

    inlined_ptr->SetAllocation(Allocation<A>{allocated_storage_view.data,
                                             allocated_storage_view.capacity});
  }

  swap(GetSizeAndIsAllocated(), other_storage_ptr->GetSizeAndIsAllocated());
  swap(GetAllocator(), other_storage_ptr->GetAllocator());
}

template <typename T, size_t N, typename A>
void Storage<T, N, A>::SwapN(ElementwiseSwapPolicy, Storage* other,
                             SizeType<A> n) {
  std::swap_ranges(GetInlinedData(), GetInlinedData() + n,
                   other->GetInlinedData());
}

template <typename T, size_t N, typename A>
void Storage<T, N, A>::SwapN(ElementwiseConstructPolicy, Storage* other,
                             SizeType<A> n) {
  Pointer<A> a = GetInlinedData();
  Pointer<A> b = other->GetInlinedData();
  // see note on allocators in `SwapInlinedElements`.
  A& allocator_a = GetAllocator();
  A& allocator_b = other->GetAllocator();
  for (SizeType<A> i = 0; i < n; ++i, ++a, ++b) {
    ValueType<A> tmp(std::move(*a));

    AllocatorTraits<A>::destroy(allocator_a, a);
    AllocatorTraits<A>::construct(allocator_b, a, std::move(*b));

    AllocatorTraits<A>::destroy(allocator_b, b);
    AllocatorTraits<A>::construct(allocator_a, b, std::move(tmp));
  }
}

template <typename T, size_t N, typename A>
void Storage<T, N, A>::SwapInlinedElements(MemcpyPolicy, Storage* other) {
  Data tmp = data_;
  data_ = other->data_;
  other->data_ = tmp;
}

template <typename T, size_t N, typename A>
template <typename NotMemcpyPolicy>
void Storage<T, N, A>::SwapInlinedElements(NotMemcpyPolicy policy,
                                           Storage* other) {
  // Note: `destroy` needs to use pre-swap allocator while `construct` -
  // post-swap allocator. Allocators will be swapped later on outside of
  // `SwapInlinedElements`.
  Storage* small_ptr = this;
  Storage* large_ptr = other;
  if (small_ptr->GetSize() > large_ptr->GetSize()) {
    std::swap(small_ptr, large_ptr);
  }

  auto small_size = small_ptr->GetSize();
  auto diff = large_ptr->GetSize() - small_size;
  SwapN(policy, other, small_size);

  IteratorValueAdapter<A, MoveIterator<A>> move_values(
      MoveIterator<A>(large_ptr->GetInlinedData() + small_size));

  ConstructElements<A>(large_ptr->GetAllocator(),
                       small_ptr->GetInlinedData() + small_size, move_values,
                       diff);

  DestroyAdapter<A>::DestroyElements(large_ptr->GetAllocator(),
                                     large_ptr->GetInlinedData() + small_size,
                                     diff);
}

// End ignore "array-bounds"
#if !defined(__clang__) && defined(__GNUC__)
#pragma GCC diagnostic pop
#endif

}  // namespace inlined_vector_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_CONTAINER_INTERNAL_INLINED_VECTOR_H_
*áZ
osoong/.intermediates/external/abseil-cpp/absl_base_hdrs/gen/my_include_dir/absl/base/internal/thread_identity.híY// 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.
//
// Each active thread has an ThreadIdentity that may represent the thread in
// various level interfaces.  ThreadIdentity objects are never deallocated.
// When a thread terminates, its ThreadIdentity object may be reused for a
// thread created later.

#ifndef ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_
#define ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_

#ifndef _WIN32
#include <pthread.h>
// Defines __GOOGLE_GRTE_VERSION__ (via glibc-specific features.h) when
// supported.
#include <unistd.h>
#endif

#include <atomic>
#include <cstdint>

#include "absl/base/config.h"
#include "absl/base/internal/per_thread_tls.h"
#include "absl/base/optimization.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

struct SynchLocksHeld;
struct SynchWaitParams;

namespace base_internal {

class SpinLock;
struct ThreadIdentity;

// Used by the implementation of absl::Mutex and absl::CondVar.
struct PerThreadSynch {
  // The internal representation of absl::Mutex and absl::CondVar rely
  // on the alignment of PerThreadSynch. Both store the address of the
  // PerThreadSynch in the high-order bits of their internal state,
  // which means the low kLowZeroBits of the address of PerThreadSynch
  // must be zero.
  static constexpr int kLowZeroBits = 8;
  static constexpr int kAlignment = 1 << kLowZeroBits;

  // Returns the associated ThreadIdentity.
  // This can be implemented as a cast because we guarantee
  // PerThreadSynch is the first element of ThreadIdentity.
  ThreadIdentity* thread_identity() {
    return reinterpret_cast<ThreadIdentity*>(this);
  }

  PerThreadSynch* next;  // Circular waiter queue; initialized to 0.
  PerThreadSynch* skip;  // If non-zero, all entries in Mutex queue
                         // up to and including "skip" have same
                         // condition as this, and will be woken later
  bool may_skip;         // if false while on mutex queue, a mutex unlocker
                         // is using this PerThreadSynch as a terminator.  Its
                         // skip field must not be filled in because the loop
                         // might then skip over the terminator.
  bool wake;             // This thread is to be woken from a Mutex.
  // If "x" is on a waiter list for a mutex, "x->cond_waiter" is true iff the
  // waiter is waiting on the mutex as part of a CV Wait or Mutex Await.
  //
  // The value of "x->cond_waiter" is meaningless if "x" is not on a
  // Mutex waiter list.
  bool cond_waiter;
  bool maybe_unlocking;  // Valid at head of Mutex waiter queue;
                         // true if UnlockSlow could be searching
                         // for a waiter to wake.  Used for an optimization
                         // in Enqueue().  true is always a valid value.
                         // Can be reset to false when the unlocker or any
                         // writer releases the lock, or a reader fully
                         // releases the lock.  It may not be set to false
                         // by a reader that decrements the count to
                         // non-zero. protected by mutex spinlock
  bool suppress_fatal_errors;  // If true, try to proceed even in the face
                               // of broken invariants.  This is used within
                               // fatal signal handlers to improve the
                               // chances of debug logging information being
                               // output successfully.
  int priority;                // Priority of thread (updated every so often).

  // State values:
  //   kAvailable: This PerThreadSynch is available.
  //   kQueued: This PerThreadSynch is unavailable, it's currently queued on a
  //            Mutex or CondVar waistlist.
  //
  // Transitions from kQueued to kAvailable require a release
  // barrier. This is needed as a waiter may use "state" to
  // independently observe that it's no longer queued.
  //
  // Transitions from kAvailable to kQueued require no barrier, they
  // are externally ordered by the Mutex.
  enum State { kAvailable, kQueued };
  std::atomic<State> state;

  // The wait parameters of the current wait.  waitp is null if the
  // thread is not waiting. Transitions from null to non-null must
  // occur before the enqueue commit point (state = kQueued in
  // Enqueue() and CondVarEnqueue()). Transitions from non-null to
  // null must occur after the wait is finished (state = kAvailable in
  // Mutex::Block() and CondVar::WaitCommon()). This field may be
  // changed only by the thread that describes this PerThreadSynch.  A
  // special case is Fer(), which calls Enqueue() on another thread,
  // but with an identical SynchWaitParams pointer, thus leaving the
  // pointer unchanged.
  SynchWaitParams* waitp;

  intptr_t readers;  // Number of readers in mutex.

  // When priority will next be read (cycles).
  int64_t next_priority_read_cycles;

  // Locks held; used during deadlock detection.
  // Allocated in Synch_GetAllLocks() and freed in ReclaimThreadIdentity().
  SynchLocksHeld* all_locks;
};

// The instances of this class are allocated in NewThreadIdentity() with an
// alignment of PerThreadSynch::kAlignment and never destroyed. Initialization
// should happen in OneTimeInitThreadIdentity().
//
// Instances may be reused by new threads - fields should be reset in
// ResetThreadIdentityBetweenReuse().
//
// NOTE: The layout of fields in this structure is critical, please do not
//       add, remove, or modify the field placements without fully auditing the
//       layout.
struct ThreadIdentity {
  // Must be the first member.  The Mutex implementation requires that
  // the PerThreadSynch object associated with each thread is
  // PerThreadSynch::kAlignment aligned.  We provide this alignment on
  // ThreadIdentity itself.
  PerThreadSynch per_thread_synch;

  // Private: Reserved for absl::synchronization_internal::Waiter.
  struct WaiterState {
    alignas(void*) char data[256];
  } waiter_state;

  // Used by PerThreadSem::{Get,Set}ThreadBlockedCounter().
  std::atomic<int>* blocked_count_ptr;

  // The following variables are mostly read/written just by the
  // thread itself.  The only exception is that these are read by
  // a ticker thread as a hint.
  std::atomic<int> ticker;      // Tick counter, incremented once per second.
  std::atomic<int> wait_start;  // Ticker value when thread started waiting.
  std::atomic<bool> is_idle;    // Has thread become idle yet?

  ThreadIdentity* next;
};

// Returns the ThreadIdentity object representing the calling thread; guaranteed
// to be unique for its lifetime.  The returned object will remain valid for the
// program's lifetime; although it may be re-assigned to a subsequent thread.
// If one does not exist, return nullptr instead.
//
// Does not malloc(*), and is async-signal safe.
// [*] Technically pthread_setspecific() does malloc on first use; however this
// is handled internally within tcmalloc's initialization already. Note that
// darwin does *not* use tcmalloc, so this can catch you if using MallocHooks
// on Apple platforms. Whatever function is calling your MallocHooks will need
// to watch for recursion on Apple platforms.
//
// New ThreadIdentity objects can be constructed and associated with a thread
// by calling GetOrCreateCurrentThreadIdentity() in per-thread-sem.h.
ThreadIdentity* CurrentThreadIdentityIfPresent();

using ThreadIdentityReclaimerFunction = void (*)(void*);

// Sets the current thread identity to the given value.  'reclaimer' is a
// pointer to the global function for cleaning up instances on thread
// destruction.
void SetCurrentThreadIdentity(ThreadIdentity* identity,
                              ThreadIdentityReclaimerFunction reclaimer);

// Removes the currently associated ThreadIdentity from the running thread.
// This must be called from inside the ThreadIdentityReclaimerFunction, and only
// from that function.
void ClearCurrentThreadIdentity();

// May be chosen at compile time via: -DABSL_FORCE_THREAD_IDENTITY_MODE=<mode
// index>
#ifdef ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC
#error ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC cannot be directly set
#else
#define ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC 0
#endif

#ifdef ABSL_THREAD_IDENTITY_MODE_USE_TLS
#error ABSL_THREAD_IDENTITY_MODE_USE_TLS cannot be directly set
#else
#define ABSL_THREAD_IDENTITY_MODE_USE_TLS 1
#endif

#ifdef ABSL_THREAD_IDENTITY_MODE_USE_CPP11
#error ABSL_THREAD_IDENTITY_MODE_USE_CPP11 cannot be directly set
#else
#define ABSL_THREAD_IDENTITY_MODE_USE_CPP11 2
#endif

#ifdef ABSL_THREAD_IDENTITY_MODE
#error ABSL_THREAD_IDENTITY_MODE cannot be directly set
#elif defined(ABSL_FORCE_THREAD_IDENTITY_MODE)
#define ABSL_THREAD_IDENTITY_MODE ABSL_FORCE_THREAD_IDENTITY_MODE
#elif defined(_WIN32) && !defined(__MINGW32__)
#define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_CPP11
#elif defined(__APPLE__) && defined(ABSL_HAVE_THREAD_LOCAL)
#define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_CPP11
#elif ABSL_PER_THREAD_TLS && defined(__GOOGLE_GRTE_VERSION__) && \
    (__GOOGLE_GRTE_VERSION__ >= 20140228L)
// Support for async-safe TLS was specifically added in GRTEv4.  It's not
// present in the upstream eglibc.
// Note:  Current default for production systems.
#define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_TLS
#else
#define ABSL_THREAD_IDENTITY_MODE \
  ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC
#endif

#if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \
    ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11

#if ABSL_PER_THREAD_TLS
ABSL_CONST_INIT extern ABSL_PER_THREAD_TLS_KEYWORD ThreadIdentity*
    thread_identity_ptr;
#elif defined(ABSL_HAVE_THREAD_LOCAL)
ABSL_CONST_INIT extern thread_local ThreadIdentity* thread_identity_ptr;
#else
#error Thread-local storage not detected on this platform
#endif

// thread_local variables cannot be in headers exposed by DLLs or in certain
// build configurations on Apple platforms. However, it is important for
// performance reasons in general that `CurrentThreadIdentityIfPresent` be
// inlined. In the other cases we opt to have the function not be inlined. Note
// that `CurrentThreadIdentityIfPresent` is declared above so we can exclude
// this entire inline definition.
#if !defined(__APPLE__) && !defined(ABSL_BUILD_DLL) && \
    !defined(ABSL_CONSUME_DLL)
#define ABSL_INTERNAL_INLINE_CURRENT_THREAD_IDENTITY_IF_PRESENT 1
#endif

#ifdef ABSL_INTERNAL_INLINE_CURRENT_THREAD_IDENTITY_IF_PRESENT
inline ThreadIdentity* CurrentThreadIdentityIfPresent() {
  return thread_identity_ptr;
}
#endif

#elif ABSL_THREAD_IDENTITY_MODE != \
    ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC
#error Unknown ABSL_THREAD_IDENTITY_MODE
#endif

}  // namespace base_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_
*Ñ"
ksoong/.intermediates/external/abseil-cpp/absl_base_config_hdrs/gen/my_include_dir/absl/base/policy_checks.há!// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// File: policy_checks.h
// -----------------------------------------------------------------------------
//
// This header enforces a minimum set of policies at build time, such as the
// supported compiler and library versions. Unsupported configurations are
// reported with `#error`. This enforcement is best effort, so successfully
// compiling this header does not guarantee a supported configuration.

// SKIP_ABSL_INLINE_NAMESPACE_CHECK

#ifndef ABSL_BASE_POLICY_CHECKS_H_
#define ABSL_BASE_POLICY_CHECKS_H_

// Included for the __GLIBC_PREREQ macro used below.
#include <limits.h>

// Included for the _STLPORT_VERSION macro used below.
#if defined(__cplusplus)
#include <cstddef>
#endif

// -----------------------------------------------------------------------------
// Operating System Check
// -----------------------------------------------------------------------------

#if defined(__CYGWIN__)
#error "Cygwin is not supported."
#endif

// -----------------------------------------------------------------------------
// Toolchain Check
// -----------------------------------------------------------------------------

// We support Visual Studio 2019 (MSVC++ 16.0) and later.
// This minimum will go up.
#if defined(_MSC_VER) && _MSC_VER < 1920 && !defined(__clang__)
#error "This package requires Visual Studio 2019 (MSVC++ 16.0) or higher."
#endif

// We support GCC 7 and later.
// This minimum will go up.
#if defined(__GNUC__) && !defined(__clang__)
#if __GNUC__ < 7
#error "This package requires GCC 7 or higher."
#endif
#endif

// We support Apple Xcode clang 4.2.1 (version 421.11.65) and later.
// This corresponds to Apple Xcode version 4.5.
// This minimum will go up.
#if defined(__apple_build_version__) && __apple_build_version__ < 4211165
#error "This package requires __apple_build_version__ of 4211165 or higher."
#endif

// -----------------------------------------------------------------------------
// C++ Version Check
// -----------------------------------------------------------------------------

// Enforce C++17 as the minimum.
#if defined(_MSVC_LANG)
#if _MSVC_LANG < 201703L
#error "C++ versions less than C++17 are not supported."
#endif  // _MSVC_LANG < 201703L
#elif defined(__cplusplus)
#if __cplusplus < 201703L
#error "C++ versions less than C++17 are not supported."
#endif  // __cplusplus < 201703L
#endif

// -----------------------------------------------------------------------------
// Standard Library Check
// -----------------------------------------------------------------------------

#if defined(_STLPORT_VERSION)
#error "STLPort is not supported."
#endif

// -----------------------------------------------------------------------------
// `char` Size Check
// -----------------------------------------------------------------------------

// Abseil currently assumes CHAR_BIT == 8. If you would like to use Abseil on a
// platform where this is not the case, please provide us with the details about
// your platform so we can consider relaxing this requirement.
#if CHAR_BIT != 8
#error "Abseil assumes CHAR_BIT == 8."
#endif

// -----------------------------------------------------------------------------
// `int` Size Check
// -----------------------------------------------------------------------------

// Abseil currently assumes that an int is 4 bytes. If you would like to use
// Abseil on a platform where this is not the case, please provide us with the
// details about your platform so we can consider relaxing this requirement.
#if INT_MAX < 2147483647
#error "Abseil assumes that int is at least 4 bytes. "
#endif

#endif  // ABSL_BASE_POLICY_CHECKS_H_
*Äº
~soong/.intermediates/external/abseil-cpp/absl_container_inlined_vector_hdrs/gen/my_include_dir/absl/container/inlined_vector.hÀ¹// Copyright 2019 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// File: inlined_vector.h
// -----------------------------------------------------------------------------
//
// This header file contains the declaration and definition of an "inlined
// vector" which behaves in an equivalent fashion to a `std::vector`, except
// that storage for small sequences of the vector are provided inline without
// requiring any heap allocation.
//
// An `absl::InlinedVector<T, N>` specifies the default capacity `N` as one of
// its template parameters. Instances where `size() <= N` hold contained
// elements in inline space. Typically `N` is very small so that sequences that
// are expected to be short do not require allocations.
//
// An `absl::InlinedVector` does not usually require a specific allocator. If
// the inlined vector grows beyond its initial constraints, it will need to
// allocate (as any normal `std::vector` would). This is usually performed with
// the default allocator (defined as `std::allocator<T>`). Optionally, a custom
// allocator type may be specified as `A` in `absl::InlinedVector<T, N, A>`.

#ifndef ABSL_CONTAINER_INLINED_VECTOR_H_
#define ABSL_CONTAINER_INLINED_VECTOR_H_

#include <algorithm>
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <initializer_list>
#include <iterator>
#include <memory>
#include <type_traits>
#include <utility>

#include "absl/algorithm/algorithm.h"
#include "absl/base/attributes.h"
#include "absl/base/internal/iterator_traits.h"
#include "absl/base/internal/throw_delegate.h"
#include "absl/base/macros.h"
#include "absl/base/optimization.h"
#include "absl/base/port.h"
#include "absl/container/internal/inlined_vector.h"
#include "absl/hash/internal/weakly_mixed_integer.h"
#include "absl/memory/memory.h"
#include "absl/meta/type_traits.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
// -----------------------------------------------------------------------------
// InlinedVector
// -----------------------------------------------------------------------------
//
// An `absl::InlinedVector` is designed to be a drop-in replacement for
// `std::vector` for use cases where the vector's size is sufficiently small
// that it can be inlined. If the inlined vector does grow beyond its estimated
// capacity, it will trigger an initial allocation on the heap, and will behave
// as a `std::vector`. The API of the `absl::InlinedVector` within this file is
// designed to cover the same API footprint as covered by `std::vector`.
template <typename T, size_t N, typename A = std::allocator<T>>
class ABSL_ATTRIBUTE_WARN_UNUSED InlinedVector {
  static_assert(N > 0, "`absl::InlinedVector` requires an inlined capacity.");

  using Storage = inlined_vector_internal::Storage<T, N, A>;

  template <typename TheA>
  using AllocatorTraits = inlined_vector_internal::AllocatorTraits<TheA>;
  template <typename TheA>
  using MoveIterator = inlined_vector_internal::MoveIterator<TheA>;
  template <typename TheA>
  using IsMoveAssignOk = inlined_vector_internal::IsMoveAssignOk<TheA>;

  template <typename TheA, typename Iterator>
  using IteratorValueAdapter =
      inlined_vector_internal::IteratorValueAdapter<TheA, Iterator>;
  template <typename TheA>
  using CopyValueAdapter = inlined_vector_internal::CopyValueAdapter<TheA>;
  template <typename TheA>
  using DefaultValueAdapter =
      inlined_vector_internal::DefaultValueAdapter<TheA>;

  template <typename Iterator>
  using EnableIfAtLeastForwardIterator = std::enable_if_t<
      base_internal::IsAtLeastForwardIterator<Iterator>::value, int>;
  template <typename Iterator>
  using DisableIfAtLeastForwardIterator = std::enable_if_t<
      !base_internal::IsAtLeastForwardIterator<Iterator>::value, int>;

  using MemcpyPolicy = typename Storage::MemcpyPolicy;
  using ElementwiseAssignPolicy = typename Storage::ElementwiseAssignPolicy;
  using ElementwiseConstructPolicy =
      typename Storage::ElementwiseConstructPolicy;
  using MoveAssignmentPolicy = typename Storage::MoveAssignmentPolicy;

 public:
  using allocator_type = A;
  using value_type = inlined_vector_internal::ValueType<A>;
  using pointer = inlined_vector_internal::Pointer<A>;
  using const_pointer = inlined_vector_internal::ConstPointer<A>;
  using size_type = inlined_vector_internal::SizeType<A>;
  using difference_type = inlined_vector_internal::DifferenceType<A>;
  using reference = inlined_vector_internal::Reference<A>;
  using const_reference = inlined_vector_internal::ConstReference<A>;
  using iterator = inlined_vector_internal::Iterator<A>;
  using const_iterator = inlined_vector_internal::ConstIterator<A>;
  using reverse_iterator = inlined_vector_internal::ReverseIterator<A>;
  using const_reverse_iterator =
      inlined_vector_internal::ConstReverseIterator<A>;

  // ---------------------------------------------------------------------------
  // InlinedVector Constructors and Destructor
  // ---------------------------------------------------------------------------

  // Creates an empty inlined vector with a value-initialized allocator.
  InlinedVector() noexcept(noexcept(allocator_type())) : storage_() {}

  // Creates an empty inlined vector with a copy of `allocator`.
  explicit InlinedVector(const allocator_type& allocator) noexcept
      : storage_(allocator) {}

  // Creates an inlined vector with `n` copies of `value_type()`.
  explicit InlinedVector(size_type n,
                         const allocator_type& allocator = allocator_type())
      : storage_(allocator) {
    storage_.Initialize(DefaultValueAdapter<A>(), n);
  }

  // Creates an inlined vector with `n` copies of `v`.
  InlinedVector(size_type n, const_reference v,
                const allocator_type& allocator = allocator_type())
      : storage_(allocator) {
    storage_.Initialize(CopyValueAdapter<A>(std::addressof(v)), n);
  }

  // Creates an inlined vector with copies of the elements of `list`.
  InlinedVector(std::initializer_list<value_type> list,
                const allocator_type& allocator = allocator_type())
      : InlinedVector(list.begin(), list.end(), allocator) {}

  // Creates an inlined vector with elements constructed from the provided
  // forward iterator range [`first`, `last`).
  //
  // NOTE: the `enable_if` prevents ambiguous interpretation between a call to
  // this constructor with two integral arguments and a call to the above
  // `InlinedVector(size_type, const_reference)` constructor.
  template <typename ForwardIterator,
            EnableIfAtLeastForwardIterator<ForwardIterator> = 0>
  InlinedVector(ForwardIterator first, ForwardIterator last,
                const allocator_type& allocator = allocator_type())
      : storage_(allocator) {
    storage_.Initialize(IteratorValueAdapter<A, ForwardIterator>(first),
                        static_cast<size_t>(std::distance(first, last)));
  }

  // Creates an inlined vector with elements constructed from the provided input
  // iterator range [`first`, `last`).
  template <typename InputIterator,
            DisableIfAtLeastForwardIterator<InputIterator> = 0>
  InlinedVector(InputIterator first, InputIterator last,
                const allocator_type& allocator = allocator_type())
      : storage_(allocator) {
    std::copy(first, last, std::back_inserter(*this));
  }

  // Creates an inlined vector by copying the contents of `other` using
  // `other`'s allocator.
  InlinedVector(const InlinedVector& other)
      : InlinedVector(other, other.storage_.GetAllocator()) {}

  // Creates an inlined vector by copying the contents of `other` using the
  // provided `allocator`.
  InlinedVector(const InlinedVector& other, const allocator_type& allocator)
      : storage_(allocator) {
    // Fast path: if the other vector is empty, there's nothing for us to do.
    if (other.empty()) {
      return;
    }

    // Fast path: if the value type is trivially copy constructible, we know the
    // allocator doesn't do anything fancy, and there is nothing on the heap
    // then we know it is legal for us to simply memcpy the other vector's
    // inlined bytes to form our copy of its elements.
    if (absl::is_trivially_copy_constructible<value_type>::value &&
        std::is_same<A, std::allocator<value_type>>::value &&
        !other.storage_.GetIsAllocated()) {
      storage_.MemcpyFrom(other.storage_);
      return;
    }

    storage_.InitFrom(other.storage_);
  }

  // Creates an inlined vector by moving in the contents of `other` without
  // allocating. If `other` contains allocated memory, the newly-created inlined
  // vector will take ownership of that memory. However, if `other` does not
  // contain allocated memory, the newly-created inlined vector will perform
  // element-wise move construction of the contents of `other`.
  //
  // NOTE: since no allocation is performed for the inlined vector in either
  // case, the `noexcept(...)` specification depends on whether moving the
  // underlying objects can throw. It is assumed assumed that...
  //  a) move constructors should only throw due to allocation failure.
  //  b) if `value_type`'s move constructor allocates, it uses the same
  //     allocation function as the inlined vector's allocator.
  // Thus, the move constructor is non-throwing if the allocator is non-throwing
  // or `value_type`'s move constructor is specified as `noexcept`.
  InlinedVector(InlinedVector&& other) noexcept(
      absl::allocator_is_nothrow<allocator_type>::value ||
      std::is_nothrow_move_constructible<value_type>::value)
      : storage_(other.storage_.GetAllocator()) {
    // Fast path: if the value type can be trivially relocated (i.e. moved from
    // and destroyed), and we know the allocator doesn't do anything fancy, then
    // it's safe for us to simply adopt the contents of the storage for `other`
    // and remove its own reference to them. It's as if we had individually
    // move-constructed each value and then destroyed the original.
    if (absl::is_trivially_relocatable<value_type>::value &&
        std::is_same<A, std::allocator<value_type>>::value) {
      storage_.MemcpyFrom(other.storage_);
      other.storage_.SetInlinedSize(0);
      return;
    }

    // Fast path: if the other vector is on the heap, we can simply take over
    // its allocation.
    if (other.storage_.GetIsAllocated()) {
      storage_.SetAllocation({other.storage_.GetAllocatedData(),
                              other.storage_.GetAllocatedCapacity()});
      storage_.SetAllocatedSize(other.storage_.GetSize());

      other.storage_.SetInlinedSize(0);
      return;
    }

    // Otherwise we must move each element individually.
    IteratorValueAdapter<A, MoveIterator<A>> other_values(
        MoveIterator<A>(other.storage_.GetInlinedData()));

    inlined_vector_internal::ConstructElements<A>(
        storage_.GetAllocator(), storage_.GetInlinedData(), other_values,
        other.storage_.GetSize());

    storage_.SetInlinedSize(other.storage_.GetSize());
  }

  // Creates an inlined vector by moving in the contents of `other` with a copy
  // of `allocator`.
  //
  // NOTE: if `other`'s allocator is not equal to `allocator`, even if `other`
  // contains allocated memory, this move constructor will still allocate. Since
  // allocation is performed, this constructor can only be `noexcept` if the
  // specified allocator is also `noexcept`.
  InlinedVector(
      InlinedVector&& other,
      const allocator_type&
          allocator) noexcept(absl::allocator_is_nothrow<allocator_type>::value)
      : storage_(allocator) {
    // Fast path: if the value type can be trivially relocated (i.e. moved from
    // and destroyed), and we know the allocator doesn't do anything fancy, then
    // it's safe for us to simply adopt the contents of the storage for `other`
    // and remove its own reference to them. It's as if we had individually
    // move-constructed each value and then destroyed the original.
    if (absl::is_trivially_relocatable<value_type>::value &&
        std::is_same<A, std::allocator<value_type>>::value) {
      storage_.MemcpyFrom(other.storage_);
      other.storage_.SetInlinedSize(0);
      return;
    }

    // Fast path: if the other vector is on the heap and shared the same
    // allocator, we can simply take over its allocation.
    if ((storage_.GetAllocator() == other.storage_.GetAllocator()) &&
        other.storage_.GetIsAllocated()) {
      storage_.SetAllocation({other.storage_.GetAllocatedData(),
                              other.storage_.GetAllocatedCapacity()});
      storage_.SetAllocatedSize(other.storage_.GetSize());

      other.storage_.SetInlinedSize(0);
      return;
    }

    // Otherwise we must move each element individually.
    storage_.Initialize(
        IteratorValueAdapter<A, MoveIterator<A>>(MoveIterator<A>(other.data())),
        other.size());
  }

  ~InlinedVector() {}

  // ---------------------------------------------------------------------------
  // InlinedVector Member Accessors
  // ---------------------------------------------------------------------------

  // `InlinedVector::empty()`
  //
  // Returns whether the inlined vector contains no elements.
  bool empty() const noexcept { return !size(); }

  // `InlinedVector::size()`
  //
  // Returns the number of elements in the inlined vector.
  size_type size() const noexcept { return storage_.GetSize(); }

  // `InlinedVector::max_size()`
  //
  // Returns the maximum number of elements the inlined vector can hold.
  size_type max_size() const noexcept {
    // One bit of the size storage is used to indicate whether the inlined
    // vector contains allocated memory. As a result, the maximum size that the
    // inlined vector can express is the minimum of the limit of how many
    // objects we can allocate and std::numeric_limits<size_type>::max() / 2.
    return (std::min)(AllocatorTraits<A>::max_size(storage_.GetAllocator()),
                      (std::numeric_limits<size_type>::max)() / 2);
  }

  // `InlinedVector::capacity()`
  //
  // Returns the number of elements that could be stored in the inlined vector
  // without requiring a reallocation.
  //
  // NOTE: for most inlined vectors, `capacity()` should be equal to the
  // template parameter `N`. For inlined vectors which exceed this capacity,
  // they will no longer be inlined and `capacity()` will equal the capactity of
  // the allocated memory.
  size_type capacity() const noexcept {
    return storage_.GetIsAllocated() ? storage_.GetAllocatedCapacity()
                                     : storage_.GetInlinedCapacity();
  }

  // `InlinedVector::data()`
  //
  // Returns a `pointer` to the elements of the inlined vector. This pointer
  // can be used to access and modify the contained elements.
  //
  // NOTE: only elements within [`data()`, `data() + size()`) are valid.
  pointer data() noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return storage_.GetIsAllocated() ? storage_.GetAllocatedData()
                                     : storage_.GetInlinedData();
  }

  // Overload of `InlinedVector::data()` that returns a `const_pointer` to the
  // elements of the inlined vector. This pointer can be used to access but not
  // modify the contained elements.
  //
  // NOTE: only elements within [`data()`, `data() + size()`) are valid.
  const_pointer data() const noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return storage_.GetIsAllocated() ? storage_.GetAllocatedData()
                                     : storage_.GetInlinedData();
  }

  // `InlinedVector::operator[](...)`
  //
  // Returns a `reference` to the `i`th element of the inlined vector.
  reference operator[](size_type i) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    ABSL_HARDENING_ASSERT(i < size());
    return data()[i];
  }

  // Overload of `InlinedVector::operator[](...)` that returns a
  // `const_reference` to the `i`th element of the inlined vector.
  const_reference operator[](size_type i) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    ABSL_HARDENING_ASSERT(i < size());
    return data()[i];
  }

  // `InlinedVector::at(...)`
  //
  // Returns a `reference` to the `i`th element of the inlined vector.
  //
  // NOTE: if `i` is not within the required range of `InlinedVector::at(...)`,
  // in both debug and non-debug builds, `std::out_of_range` will be thrown.
  reference at(size_type i) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    if (ABSL_PREDICT_FALSE(i >= size())) {
      base_internal::ThrowStdOutOfRange(
          "`InlinedVector::at(size_type)` failed bounds check");
    }
    return data()[i];
  }

  // Overload of `InlinedVector::at(...)` that returns a `const_reference` to
  // the `i`th element of the inlined vector.
  //
  // NOTE: if `i` is not within the required range of `InlinedVector::at(...)`,
  // in both debug and non-debug builds, `std::out_of_range` will be thrown.
  const_reference at(size_type i) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    if (ABSL_PREDICT_FALSE(i >= size())) {
      base_internal::ThrowStdOutOfRange(
          "`InlinedVector::at(size_type) const` failed bounds check");
    }
    return data()[i];
  }

  // `InlinedVector::front()`
  //
  // Returns a `reference` to the first element of the inlined vector.
  reference front() ABSL_ATTRIBUTE_LIFETIME_BOUND {
    ABSL_HARDENING_ASSERT(!empty());
    return data()[0];
  }

  // Overload of `InlinedVector::front()` that returns a `const_reference` to
  // the first element of the inlined vector.
  const_reference front() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    ABSL_HARDENING_ASSERT(!empty());
    return data()[0];
  }

  // `InlinedVector::back()`
  //
  // Returns a `reference` to the last element of the inlined vector.
  reference back() ABSL_ATTRIBUTE_LIFETIME_BOUND {
    ABSL_HARDENING_ASSERT(!empty());
    return data()[size() - 1];
  }

  // Overload of `InlinedVector::back()` that returns a `const_reference` to the
  // last element of the inlined vector.
  const_reference back() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    ABSL_HARDENING_ASSERT(!empty());
    return data()[size() - 1];
  }

  // `InlinedVector::begin()`
  //
  // Returns an `iterator` to the beginning of the inlined vector.
  iterator begin() noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND { return data(); }

  // Overload of `InlinedVector::begin()` that returns a `const_iterator` to
  // the beginning of the inlined vector.
  const_iterator begin() const noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return data();
  }

  // `InlinedVector::end()`
  //
  // Returns an `iterator` to the end of the inlined vector.
  iterator end() noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return data() + size();
  }

  // Overload of `InlinedVector::end()` that returns a `const_iterator` to the
  // end of the inlined vector.
  const_iterator end() const noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return data() + size();
  }

  // `InlinedVector::cbegin()`
  //
  // Returns a `const_iterator` to the beginning of the inlined vector.
  const_iterator cbegin() const noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return begin();
  }

  // `InlinedVector::cend()`
  //
  // Returns a `const_iterator` to the end of the inlined vector.
  const_iterator cend() const noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return end();
  }

  // `InlinedVector::rbegin()`
  //
  // Returns a `reverse_iterator` from the end of the inlined vector.
  reverse_iterator rbegin() noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return reverse_iterator(end());
  }

  // Overload of `InlinedVector::rbegin()` that returns a
  // `const_reverse_iterator` from the end of the inlined vector.
  const_reverse_iterator rbegin() const noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return const_reverse_iterator(end());
  }

  // `InlinedVector::rend()`
  //
  // Returns a `reverse_iterator` from the beginning of the inlined vector.
  reverse_iterator rend() noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return reverse_iterator(begin());
  }

  // Overload of `InlinedVector::rend()` that returns a `const_reverse_iterator`
  // from the beginning of the inlined vector.
  const_reverse_iterator rend() const noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return const_reverse_iterator(begin());
  }

  // `InlinedVector::crbegin()`
  //
  // Returns a `const_reverse_iterator` from the end of the inlined vector.
  const_reverse_iterator crbegin() const noexcept
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return rbegin();
  }

  // `InlinedVector::crend()`
  //
  // Returns a `const_reverse_iterator` from the beginning of the inlined
  // vector.
  const_reverse_iterator crend() const noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return rend();
  }

  // `InlinedVector::get_allocator()`
  //
  // Returns a copy of the inlined vector's allocator.
  allocator_type get_allocator() const { return storage_.GetAllocator(); }

  // ---------------------------------------------------------------------------
  // InlinedVector Member Mutators
  // ---------------------------------------------------------------------------

  // `InlinedVector::operator=(...)`
  //
  // Replaces the elements of the inlined vector with copies of the elements of
  // `list`.
  InlinedVector& operator=(std::initializer_list<value_type> list) {
    assign(list.begin(), list.end());

    return *this;
  }

  // Overload of `InlinedVector::operator=(...)` that replaces the elements of
  // the inlined vector with copies of the elements of `other`.
  InlinedVector& operator=(const InlinedVector& other) {
    if (ABSL_PREDICT_TRUE(this != std::addressof(other))) {
      const_pointer other_data = other.data();
      assign(other_data, other_data + other.size());
    }

    return *this;
  }

  // Overload of `InlinedVector::operator=(...)` that moves the elements of
  // `other` into the inlined vector.
  //
  // NOTE: as a result of calling this overload, `other` is left in a valid but
  // unspecified state.
  InlinedVector& operator=(InlinedVector&& other) {
    if (ABSL_PREDICT_TRUE(this != std::addressof(other))) {
      MoveAssignment(MoveAssignmentPolicy{}, std::move(other));
    }

    return *this;
  }

  // `InlinedVector::assign(...)`
  //
  // Replaces the contents of the inlined vector with `n` copies of `v`.
  void assign(size_type n, const_reference v) {
    storage_.Assign(CopyValueAdapter<A>(std::addressof(v)), n);
  }

  // Overload of `InlinedVector::assign(...)` that replaces the contents of the
  // inlined vector with copies of the elements of `list`.
  void assign(std::initializer_list<value_type> list) {
    assign(list.begin(), list.end());
  }

  // Overload of `InlinedVector::assign(...)` to replace the contents of the
  // inlined vector with the range [`first`, `last`).
  //
  // NOTE: this overload is for iterators that are "forward" category or better.
  template <typename ForwardIterator,
            EnableIfAtLeastForwardIterator<ForwardIterator> = 0>
  void assign(ForwardIterator first, ForwardIterator last) {
    storage_.Assign(IteratorValueAdapter<A, ForwardIterator>(first),
                    static_cast<size_t>(std::distance(first, last)));
  }

  // Overload of `InlinedVector::assign(...)` to replace the contents of the
  // inlined vector with the range [`first`, `last`).
  //
  // NOTE: this overload is for iterators that are "input" category.
  template <typename InputIterator,
            DisableIfAtLeastForwardIterator<InputIterator> = 0>
  void assign(InputIterator first, InputIterator last) {
    size_type i = 0;
    for (; i < size() && first != last; ++i, static_cast<void>(++first)) {
      data()[i] = *first;
    }

    erase(data() + i, data() + size());
    std::copy(first, last, std::back_inserter(*this));
  }

  // `InlinedVector::resize(...)`
  //
  // Resizes the inlined vector to contain `n` elements.
  //
  // NOTE: If `n` is smaller than `size()`, extra elements are destroyed. If `n`
  // is larger than `size()`, new elements are value-initialized.
  void resize(size_type n) {
    ABSL_HARDENING_ASSERT(n <= max_size());
    storage_.Resize(DefaultValueAdapter<A>(), n);
  }

  // Overload of `InlinedVector::resize(...)` that resizes the inlined vector to
  // contain `n` elements.
  //
  // NOTE: if `n` is smaller than `size()`, extra elements are destroyed. If `n`
  // is larger than `size()`, new elements are copied-constructed from `v`.
  void resize(size_type n, const_reference v) {
    ABSL_HARDENING_ASSERT(n <= max_size());
    storage_.Resize(CopyValueAdapter<A>(std::addressof(v)), n);
  }

  // `InlinedVector::insert(...)`
  //
  // Inserts a copy of `v` at `pos`, returning an `iterator` to the newly
  // inserted element.
  iterator insert(const_iterator pos,
                  const_reference v) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return emplace(pos, v);
  }

  // Overload of `InlinedVector::insert(...)` that inserts `v` at `pos` using
  // move semantics, returning an `iterator` to the newly inserted element.
  iterator insert(const_iterator pos,
                  value_type&& v) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return emplace(pos, std::move(v));
  }

  // Overload of `InlinedVector::insert(...)` that inserts `n` contiguous copies
  // of `v` starting at `pos`, returning an `iterator` pointing to the first of
  // the newly inserted elements.
  iterator insert(const_iterator pos, size_type n,
                  const_reference v) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    ABSL_HARDENING_ASSERT(pos >= begin());
    ABSL_HARDENING_ASSERT(pos <= end());

    if (ABSL_PREDICT_TRUE(n != 0)) {
      value_type dealias = v;
      // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102329#c2
      // It appears that GCC thinks that since `pos` is a const pointer and may
      // point to uninitialized memory at this point, a warning should be
      // issued. But `pos` is actually only used to compute an array index to
      // write to.
#if !defined(__clang__) && defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
      return storage_.Insert(pos, CopyValueAdapter<A>(std::addressof(dealias)),
                             n);
#if !defined(__clang__) && defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
    } else {
      return const_cast<iterator>(pos);
    }
  }

  // Overload of `InlinedVector::insert(...)` that inserts copies of the
  // elements of `list` starting at `pos`, returning an `iterator` pointing to
  // the first of the newly inserted elements.
  iterator insert(const_iterator pos, std::initializer_list<value_type> list)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return insert(pos, list.begin(), list.end());
  }

  // Overload of `InlinedVector::insert(...)` that inserts the range [`first`,
  // `last`) starting at `pos`, returning an `iterator` pointing to the first
  // of the newly inserted elements.
  //
  // NOTE: this overload is for iterators that are "forward" category or better.
  template <typename ForwardIterator,
            EnableIfAtLeastForwardIterator<ForwardIterator> = 0>
  iterator insert(const_iterator pos, ForwardIterator first,
                  ForwardIterator last) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    ABSL_HARDENING_ASSERT(pos >= begin());
    ABSL_HARDENING_ASSERT(pos <= end());

    if (ABSL_PREDICT_TRUE(first != last)) {
      return storage_.Insert(
          pos, IteratorValueAdapter<A, ForwardIterator>(first),
          static_cast<size_type>(std::distance(first, last)));
    } else {
      return const_cast<iterator>(pos);
    }
  }

  // Overload of `InlinedVector::insert(...)` that inserts the range [`first`,
  // `last`) starting at `pos`, returning an `iterator` pointing to the first
  // of the newly inserted elements.
  //
  // NOTE: this overload is for iterators that are "input" category.
  template <typename InputIterator,
            DisableIfAtLeastForwardIterator<InputIterator> = 0>
  iterator insert(const_iterator pos, InputIterator first,
                  InputIterator last) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    ABSL_HARDENING_ASSERT(pos >= begin());
    ABSL_HARDENING_ASSERT(pos <= end());

    size_type index = static_cast<size_type>(std::distance(cbegin(), pos));
    for (size_type i = index; first != last; ++i, static_cast<void>(++first)) {
      insert(data() + i, *first);
    }

    return iterator(data() + index);
  }

  // `InlinedVector::emplace(...)`
  //
  // Constructs and inserts an element using `args...` in the inlined vector at
  // `pos`, returning an `iterator` pointing to the newly emplaced element.
  template <typename... Args>
  iterator emplace(const_iterator pos,
                   Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    ABSL_HARDENING_ASSERT(pos >= begin());
    ABSL_HARDENING_ASSERT(pos <= end());

    value_type dealias(std::forward<Args>(args)...);
    // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102329#c2
    // It appears that GCC thinks that since `pos` is a const pointer and may
    // point to uninitialized memory at this point, a warning should be
    // issued. But `pos` is actually only used to compute an array index to
    // write to.
#if !defined(__clang__) && defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
    return storage_.Insert(pos,
                           IteratorValueAdapter<A, MoveIterator<A>>(
                               MoveIterator<A>(std::addressof(dealias))),
                           1);
#if !defined(__clang__) && defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
  }

  // `InlinedVector::emplace_back(...)`
  //
  // Constructs and inserts an element using `args...` in the inlined vector at
  // `end()`, returning a `reference` to the newly emplaced element.
  template <typename... Args>
  reference emplace_back(Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return storage_.EmplaceBack(std::forward<Args>(args)...);
  }

  // `InlinedVector::push_back(...)`
  //
  // Inserts a copy of `v` in the inlined vector at `end()`.
  void push_back(const_reference v) { static_cast<void>(emplace_back(v)); }

  // Overload of `InlinedVector::push_back(...)` for inserting `v` at `end()`
  // using move semantics.
  void push_back(value_type&& v) {
    static_cast<void>(emplace_back(std::move(v)));
  }

  // `InlinedVector::pop_back()`
  //
  // Destroys the element at `back()`, reducing the size by `1`.
  void pop_back() noexcept {
    ABSL_HARDENING_ASSERT(!empty());

    AllocatorTraits<A>::destroy(storage_.GetAllocator(), data() + (size() - 1));
    storage_.SubtractSize(1);
  }

  // `InlinedVector::erase(...)`
  //
  // Erases the element at `pos`, returning an `iterator` pointing to where the
  // erased element was located.
  //
  // NOTE: may return `end()`, which is not dereferenceable.
  iterator erase(const_iterator pos) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    ABSL_HARDENING_ASSERT(pos >= begin());
    ABSL_HARDENING_ASSERT(pos < end());

    // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102329#c2
    // It appears that GCC thinks that since `pos` is a const pointer and may
    // point to uninitialized memory at this point, a warning should be
    // issued. But `pos` is actually only used to compute an array index to
    // write to.
#if !defined(__clang__) && defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#pragma GCC diagnostic ignored "-Wuninitialized"
#endif
    return storage_.Erase(pos, pos + 1);
#if !defined(__clang__) && defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
  }

  // Overload of `InlinedVector::erase(...)` that erases every element in the
  // range [`from`, `to`), returning an `iterator` pointing to where the first
  // erased element was located.
  //
  // NOTE: may return `end()`, which is not dereferenceable.
  iterator erase(const_iterator from,
                 const_iterator to) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    ABSL_HARDENING_ASSERT(from >= begin());
    ABSL_HARDENING_ASSERT(from <= to);
    ABSL_HARDENING_ASSERT(to <= end());

    if (ABSL_PREDICT_TRUE(from != to)) {
      return storage_.Erase(from, to);
    } else {
      return const_cast<iterator>(from);
    }
  }

  // `InlinedVector::clear()`
  //
  // Destroys all elements in the inlined vector, setting the size to `0` and
  // deallocating any held memory.
  void clear() noexcept {
    inlined_vector_internal::DestroyAdapter<A>::DestroyElements(
        storage_.GetAllocator(), data(), size());
    storage_.DeallocateIfAllocated();

    storage_.SetInlinedSize(0);
  }

  // `InlinedVector::reserve(...)`
  //
  // Ensures that there is enough room for at least `n` elements.
  void reserve(size_type n) { storage_.Reserve(n); }

  // `InlinedVector::shrink_to_fit()`
  //
  // Attempts to reduce memory usage by moving elements to (or keeping elements
  // in) the smallest available buffer sufficient for containing `size()`
  // elements.
  //
  // If `size()` is sufficiently small, the elements will be moved into (or kept
  // in) the inlined space.
  void shrink_to_fit() {
    if (storage_.GetIsAllocated()) {
      storage_.ShrinkToFit();
    }
  }

  // `InlinedVector::swap(...)`
  //
  // Swaps the contents of the inlined vector with `other`.
  void swap(InlinedVector& other) {
    if (ABSL_PREDICT_TRUE(this != std::addressof(other))) {
      storage_.Swap(std::addressof(other.storage_));
    }
  }

 private:
  template <typename H, typename TheT, size_t TheN, typename TheA>
  friend H AbslHashValue(H h, const absl::InlinedVector<TheT, TheN, TheA>& a);

  void MoveAssignment(MemcpyPolicy, InlinedVector&& other) {
    // Assumption check: we shouldn't be told to use memcpy to implement move
    // assignment unless we have trivially destructible elements and an
    // allocator that does nothing fancy.
    static_assert(absl::is_trivially_destructible<value_type>::value, "");
    static_assert(std::is_same<A, std::allocator<value_type>>::value, "");

    // Throw away our existing heap allocation, if any. There is no need to
    // destroy the existing elements one by one because we know they are
    // trivially destructible.
    storage_.DeallocateIfAllocated();

    // Adopt the other vector's inline elements or heap allocation.
    storage_.MemcpyFrom(other.storage_);
    other.storage_.SetInlinedSize(0);
  }

  // Destroy our existing elements, if any, and adopt the heap-allocated
  // elements of the other vector.
  //
  // REQUIRES: other.storage_.GetIsAllocated()
  void DestroyExistingAndAdopt(InlinedVector&& other) {
    ABSL_HARDENING_ASSERT(other.storage_.GetIsAllocated());

    inlined_vector_internal::DestroyAdapter<A>::DestroyElements(
        storage_.GetAllocator(), data(), size());
    storage_.DeallocateIfAllocated();

    storage_.MemcpyFrom(other.storage_);
    other.storage_.SetInlinedSize(0);
  }

  void MoveAssignment(ElementwiseAssignPolicy, InlinedVector&& other) {
    // Fast path: if the other vector is on the heap then we don't worry about
    // actually move-assigning each element. Instead we only throw away our own
    // existing elements and adopt the heap allocation of the other vector.
    if (other.storage_.GetIsAllocated()) {
      DestroyExistingAndAdopt(std::move(other));
      return;
    }

    storage_.Assign(IteratorValueAdapter<A, MoveIterator<A>>(
                        MoveIterator<A>(other.storage_.GetInlinedData())),
                    other.size());
  }

  void MoveAssignment(ElementwiseConstructPolicy, InlinedVector&& other) {
    // Fast path: if the other vector is on the heap then we don't worry about
    // actually move-assigning each element. Instead we only throw away our own
    // existing elements and adopt the heap allocation of the other vector.
    if (other.storage_.GetIsAllocated()) {
      DestroyExistingAndAdopt(std::move(other));
      return;
    }

    inlined_vector_internal::DestroyAdapter<A>::DestroyElements(
        storage_.GetAllocator(), data(), size());
    storage_.DeallocateIfAllocated();

    IteratorValueAdapter<A, MoveIterator<A>> other_values(
        MoveIterator<A>(other.storage_.GetInlinedData()));
    inlined_vector_internal::ConstructElements<A>(
        storage_.GetAllocator(), storage_.GetInlinedData(), other_values,
        other.storage_.GetSize());
    storage_.SetInlinedSize(other.storage_.GetSize());
  }

  Storage storage_;
};

// -----------------------------------------------------------------------------
// InlinedVector Non-Member Functions
// -----------------------------------------------------------------------------

// `swap(...)`
//
// Swaps the contents of two inlined vectors.
template <typename T, size_t N, typename A>
void swap(absl::InlinedVector<T, N, A>& a,
          absl::InlinedVector<T, N, A>& b) noexcept(noexcept(a.swap(b))) {
  a.swap(b);
}

// `operator==(...)`
//
// Tests for value-equality of two inlined vectors.
template <typename T, size_t N, typename A>
bool operator==(const absl::InlinedVector<T, N, A>& a,
                const absl::InlinedVector<T, N, A>& b) {
  auto a_data = a.data();
  auto b_data = b.data();
  return std::equal(a_data, a_data + a.size(), b_data, b_data + b.size());
}

// `operator!=(...)`
//
// Tests for value-inequality of two inlined vectors.
template <typename T, size_t N, typename A>
bool operator!=(const absl::InlinedVector<T, N, A>& a,
                const absl::InlinedVector<T, N, A>& b) {
  return !(a == b);
}

// `operator<(...)`
//
// Tests whether the value of an inlined vector is less than the value of
// another inlined vector using a lexicographical comparison algorithm.
template <typename T, size_t N, typename A>
bool operator<(const absl::InlinedVector<T, N, A>& a,
               const absl::InlinedVector<T, N, A>& b) {
  auto a_data = a.data();
  auto b_data = b.data();
  return std::lexicographical_compare(a_data, a_data + a.size(), b_data,
                                      b_data + b.size());
}

// `operator>(...)`
//
// Tests whether the value of an inlined vector is greater than the value of
// another inlined vector using a lexicographical comparison algorithm.
template <typename T, size_t N, typename A>
bool operator>(const absl::InlinedVector<T, N, A>& a,
               const absl::InlinedVector<T, N, A>& b) {
  return b < a;
}

// `operator<=(...)`
//
// Tests whether the value of an inlined vector is less than or equal to the
// value of another inlined vector using a lexicographical comparison algorithm.
template <typename T, size_t N, typename A>
bool operator<=(const absl::InlinedVector<T, N, A>& a,
                const absl::InlinedVector<T, N, A>& b) {
  return !(b < a);
}

// `operator>=(...)`
//
// Tests whether the value of an inlined vector is greater than or equal to the
// value of another inlined vector using a lexicographical comparison algorithm.
template <typename T, size_t N, typename A>
bool operator>=(const absl::InlinedVector<T, N, A>& a,
                const absl::InlinedVector<T, N, A>& b) {
  return !(a < b);
}

// `AbslHashValue(...)`
//
// Provides `absl::Hash` support for `absl::InlinedVector`. It is uncommon to
// call this directly.
template <typename H, typename T, size_t N, typename A>
H AbslHashValue(H h, const absl::InlinedVector<T, N, A>& a) {
  auto size = a.size();
  return H::combine(H::combine_contiguous(std::move(h), a.data(), size),
                    hash_internal::WeaklyMixedInteger{size});
}

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_CONTAINER_INLINED_VECTOR_H_
*”C
†soong/.intermediates/external/abseil-cpp/absl_crc_crc_internal_hdrs/gen/my_include_dir/absl/crc/internal/crc32_x86_arm_combined_simd.hˆB// 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.

#ifndef ABSL_CRC_INTERNAL_CRC32_X86_ARM_COMBINED_SIMD_H_
#define ABSL_CRC_INTERNAL_CRC32_X86_ARM_COMBINED_SIMD_H_

#include <cstdint>

#include "absl/base/config.h"

// -------------------------------------------------------------------------
// Many x86 and ARM machines have CRC acceleration hardware.
// We can do a faster version of Extend() on such machines.
// We define a translation layer for both x86 and ARM for the ease of use and
// most performance gains.

// This implementation requires 64-bit CRC instructions (part of SSE 4.2) and
// PCLMULQDQ instructions. 32-bit builds with SSE 4.2 do exist, so the
// __x86_64__ condition is necessary.
#if defined(__x86_64__) && defined(__SSE4_2__) && defined(__PCLMUL__)

#include <x86intrin.h>
#define ABSL_CRC_INTERNAL_HAVE_X86_SIMD

#elif defined(_MSC_VER) && !defined(__clang__) && defined(__AVX__) && \
    defined(_M_AMD64)

// MSVC AVX (/arch:AVX) implies SSE 4.2 and PCLMULQDQ.
#include <intrin.h>
#define ABSL_CRC_INTERNAL_HAVE_X86_SIMD

#elif defined(__aarch64__) && defined(__LITTLE_ENDIAN__) &&                 \
    defined(__ARM_FEATURE_CRC32) && defined(ABSL_INTERNAL_HAVE_ARM_NEON) && \
    defined(__ARM_FEATURE_CRYPTO)

#include <arm_acle.h>
#include <arm_neon.h>
#define ABSL_CRC_INTERNAL_HAVE_ARM_SIMD

#endif

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace crc_internal {

#if defined(ABSL_CRC_INTERNAL_HAVE_ARM_SIMD) || \
    defined(ABSL_CRC_INTERNAL_HAVE_X86_SIMD)

#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

// Starting with the initial value in |crc|, accumulates a CRC32 value for
// unsigned integers of different sizes.
uint32_t CRC32_u8(uint32_t crc, uint8_t v);

uint32_t CRC32_u16(uint32_t crc, uint16_t v);

uint32_t CRC32_u32(uint32_t crc, uint32_t v);

uint32_t CRC32_u64(uint32_t crc, uint64_t v);

// Loads 128 bits of integer data. |src| must be 16-byte aligned.
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);

// Polynomially multiplies the low 64 bits of |l| and |r|.
V128 V128_PMulLow(const V128 l, const V128 r);

// Polynomially multiplies the low 64 bits of |r| and high 64 bits of |l|.
V128 V128_PMul01(const V128 l, const V128 r);

// Polynomially multiplies the low 64 bits of |l| and high 64 bits of |r|.
V128 V128_PMul10(const V128 l, const V128 r);

// Produces a XOR operation of |l| and |r|.
V128 V128_Xor(const V128 l, const V128 r);

// Sets the lower half of a 128 bit register to the given 64-bit value and
// zeroes the upper half.
// dst[63:0] := |r|
// dst[127:64] := |0|
V128 V128_From64WithZeroFill(const uint64_t r);

// Extracts a 32-bit integer from |l|, selected with |imm|.
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);

// Add packed 64-bit integers in |l| and |r|.
V128 V128_Add64(const V128 l, const V128 r);

#endif

#if defined(ABSL_CRC_INTERNAL_HAVE_X86_SIMD)

inline uint32_t CRC32_u8(uint32_t crc, uint8_t v) {
  return _mm_crc32_u8(crc, v);
}

inline uint32_t CRC32_u16(uint32_t crc, uint16_t v) {
  return _mm_crc32_u16(crc, v);
}

inline uint32_t CRC32_u32(uint32_t crc, uint32_t v) {
  return _mm_crc32_u32(crc, v);
}

inline uint32_t CRC32_u64(uint32_t crc, uint64_t v) {
  return static_cast<uint32_t>(_mm_crc32_u64(crc, v));
}

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);
}

inline V128 V128_PMulLow(const V128 l, const V128 r) {
  return _mm_clmulepi64_si128(l, r, 0x00);
}

inline V128 V128_PMul01(const V128 l, const V128 r) {
  return _mm_clmulepi64_si128(l, r, 0x01);
}

inline V128 V128_PMul10(const V128 l, const V128 r) {
  return _mm_clmulepi64_si128(l, r, 0x10);
}

inline V128 V128_Xor(const V128 l, const V128 r) { return _mm_xor_si128(l, r); }

inline V128 V128_From64WithZeroFill(const uint64_t r) {
  return _mm_set_epi64x(static_cast<int64_t>(0), static_cast<int64_t>(r));
}

template <int imm>
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_Add64(const V128 l, const V128 r) {
  return _mm_add_epi64(l, r);
}

#elif defined(ABSL_CRC_INTERNAL_HAVE_ARM_SIMD)

inline uint32_t CRC32_u8(uint32_t crc, uint8_t v) { return __crc32cb(crc, v); }

inline uint32_t CRC32_u16(uint32_t crc, uint16_t v) {
  return __crc32ch(crc, v);
}

inline uint32_t CRC32_u32(uint32_t crc, uint32_t v) {
  return __crc32cw(crc, v);
}

inline uint32_t CRC32_u64(uint32_t crc, uint64_t v) {
  return __crc32cd(crc, v);
}

inline V128 V128_Load(const V128* src) {
  return vld1q_u64(reinterpret_cast<const uint64_t*>(src));
}

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 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"
                       : "=w"(res)
                       : "w"(l), "w"(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) {
  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) {
  return reinterpret_cast<V128>(vmull_p64(
      reinterpret_cast<poly64_t>(vget_high_p64(vreinterpretq_p64_u64(l))),
      reinterpret_cast<poly64_t>(vget_low_p64(vreinterpretq_p64_u64(r)))));
}

inline V128 V128_PMul10(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_high_p64(vreinterpretq_p64_u64(r)))));
}

inline V128 V128_Xor(const V128 l, const V128 r) { return veorq_u64(l, r); }

inline V128 V128_From64WithZeroFill(const uint64_t r){
  constexpr uint64x2_t kZero = {0, 0};
  return vsetq_lane_u64(r, kZero, 0);
}


template <int imm>
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);
}

inline V128 V128_Add64(const V128 l, const V128 r) { return vaddq_u64(l, r); }

#endif

}  // namespace crc_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_CRC_INTERNAL_CRC32_X86_ARM_COMBINED_SIMD_H_
*ô9
bsoong/.intermediates/external/abseil-cpp/absl_crc_crc32c_hdrs/gen/my_include_dir/absl/crc/crc32c.h�9// 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: crc32c.h
// -----------------------------------------------------------------------------
//
// This header file defines the API for computing CRC32C values as checksums
// for arbitrary sequences of bytes provided as a string buffer.
//
// The API includes the basic functions for computing such CRC32C values and
// some utility functions for performing more efficient mathematical
// computations using an existing checksum.
#ifndef ABSL_CRC_CRC32C_H_
#define ABSL_CRC_CRC32C_H_

#include <cstdint>
#include <ostream>

#include "absl/crc/internal/crc32c_inline.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

//-----------------------------------------------------------------------------
// crc32c_t
//-----------------------------------------------------------------------------

// `crc32c_t` defines a strongly-typed integer for holding a CRC32C value.
//
// Some operators are intentionally omitted. Only equality operators are defined
// so that `crc32c_t` can be directly compared. Methods for putting `crc32c_t`
// directly into a set are omitted because this is bug-prone due to checksum
// collisions. Use an explicit conversion to the `uint32_t` space for operations
// that treat `crc32c_t` as an integer.
class crc32c_t final {
 public:
  crc32c_t() = default;
  constexpr explicit crc32c_t(uint32_t crc) : crc_(crc) {}

  crc32c_t(const crc32c_t&) = default;
  crc32c_t& operator=(const crc32c_t&) = default;

  explicit operator uint32_t() const { return crc_; }

  friend bool operator==(crc32c_t lhs, crc32c_t rhs) {
    return static_cast<uint32_t>(lhs) == static_cast<uint32_t>(rhs);
  }

  friend bool operator!=(crc32c_t lhs, crc32c_t rhs) { return !(lhs == rhs); }

  template <typename Sink>
  friend void AbslStringify(Sink& sink, crc32c_t crc) {
    absl::Format(&sink, "%08x", static_cast<uint32_t>(crc));
  }

 private:
  uint32_t crc_;
};


namespace crc_internal {
// Non-inline code path for `absl::ExtendCrc32c()`. Do not call directly.
// Call `absl::ExtendCrc32c()` (defined below) instead.
crc32c_t ExtendCrc32cInternal(crc32c_t initial_crc,
                              absl::string_view buf_to_add);
}  // namespace crc_internal

// -----------------------------------------------------------------------------
// CRC32C Computation Functions
// -----------------------------------------------------------------------------

// ExtendCrc32c()
//
// Computes a CRC32C value from an `initial_crc` CRC32C value including the
// `buf_to_add` bytes of an additional buffer. Using this function is more
// efficient than computing a CRC32C value for the combined buffer from
// scratch.
//
// Note: `ExtendCrc32c` with an initial_crc of 0 is equivalent to
// `ComputeCrc32c`.
//
// This operation has a runtime cost of O(`buf_to_add.size()`)
inline crc32c_t ExtendCrc32c(crc32c_t initial_crc,
                             absl::string_view buf_to_add) {
  // Approximately 75% of calls have size <= 64.
  if (buf_to_add.size() <= 64) {
    uint32_t crc = static_cast<uint32_t>(initial_crc);
    if (crc_internal::ExtendCrc32cInline(&crc, buf_to_add.data(),
                                         buf_to_add.size())) {
      return crc32c_t{crc};
    }
  }
  return crc_internal::ExtendCrc32cInternal(initial_crc, buf_to_add);
}

// ComputeCrc32c()
//
// Returns the CRC32C value of the provided string.
inline crc32c_t ComputeCrc32c(absl::string_view buf) {
  return ExtendCrc32c(crc32c_t{0}, buf);
}

// ExtendCrc32cByZeroes()
//
// Computes a CRC32C value for a buffer with an `initial_crc` CRC32C value,
// where `length` bytes with a value of 0 are appended to the buffer. Using this
// function is more efficient than computing a CRC32C value for the combined
// buffer from scratch.
//
// This operation has a runtime cost of O(log(`length`))
crc32c_t ExtendCrc32cByZeroes(crc32c_t initial_crc, size_t length);

// MemcpyCrc32c()
//
// Copies `src` to `dest` using `memcpy()` semantics, returning the CRC32C
// value of the copied buffer.
//
// Using `MemcpyCrc32c()` is potentially faster than performing the `memcpy()`
// and `ComputeCrc32c()` operations separately.
crc32c_t MemcpyCrc32c(void* dest, const void* src, size_t count,
                      crc32c_t initial_crc = crc32c_t{0});

// -----------------------------------------------------------------------------
// CRC32C Arithmetic Functions
// -----------------------------------------------------------------------------

// The following functions perform arithmetic on CRC32C values, which are
// generally more efficient than recalculating any given result's CRC32C value.

// ConcatCrc32c()
//
// Calculates the CRC32C value of two buffers with known CRC32C values
// concatenated together.
//
// Given a buffer with CRC32C value `crc1` and a buffer with
// CRC32C value `crc2` and length, `crc2_length`, returns the CRC32C value of
// the concatenation of these two buffers.
//
// This operation has a runtime cost of O(log(`crc2_length`)).
crc32c_t ConcatCrc32c(crc32c_t crc1, crc32c_t crc2, size_t crc2_length);

// RemoveCrc32cPrefix()
//
// Calculates the CRC32C value of an existing buffer with a series of bytes
// (the prefix) removed from the beginning of that buffer.
//
// Given the CRC32C value of an existing buffer, `full_string_crc`; The CRC32C
// value of a prefix of that buffer, `prefix_crc`; and the length of the buffer
// with the prefix removed, `remaining_string_length` , return the CRC32C
// value of the buffer with the prefix removed.
//
// This operation has a runtime cost of O(log(`remaining_string_length`)).
crc32c_t RemoveCrc32cPrefix(crc32c_t prefix_crc, crc32c_t full_string_crc,
                            size_t remaining_string_length);
// RemoveCrc32cSuffix()
//
// Calculates the CRC32C value of an existing buffer with a series of bytes
// (the suffix) removed from the end of that buffer.
//
// Given a CRC32C value of an existing buffer `full_string_crc`, the CRC32C
// value of the suffix to remove `suffix_crc`, and the length of that suffix
// `suffix_len`, returns the CRC32C value of the buffer with suffix removed.
//
// This operation has a runtime cost of O(log(`suffix_len`))
crc32c_t RemoveCrc32cSuffix(crc32c_t full_string_crc, crc32c_t suffix_crc,
                            size_t suffix_length);

// operator<<
//
// Streams the CRC32C value `crc` to the stream `os`.
inline std::ostream& operator<<(std::ostream& os, crc32c_t crc) {
  return os << absl::StreamFormat("%08x", static_cast<uint32_t>(crc));
}

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_CRC_CRC32C_H_
*í
hsoong/.intermediates/external/abseil-cpp/absl_base_core_headers_hdrs/gen/my_include_dir/absl/base/port.h€// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// This files is a forwarding header for other headers containing various
// portability macros and functions.

#ifndef ABSL_BASE_PORT_H_
#define ABSL_BASE_PORT_H_

#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/optimization.h"

#endif  // ABSL_BASE_PORT_H_
*År
dsoong/.intermediates/external/abseil-cpp/absl_strings_hdrs/gen/my_include_dir/absl/strings/numbers.hÜq// 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.
//
// -----------------------------------------------------------------------------
// File: numbers.h
// -----------------------------------------------------------------------------
//
// This package contains functions for converting strings to numbers. For
// converting numbers to strings, use `StrCat()` or `StrAppend()` in str_cat.h,
// which automatically detect and convert most number values appropriately.

#ifndef ABSL_STRINGS_NUMBERS_H_
#define ABSL_STRINGS_NUMBERS_H_

#ifdef __SSSE3__
#include <tmmintrin.h>
#endif

#ifdef _MSC_VER
#include <intrin.h>
#endif

#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <limits>
#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/port.h"
#include "absl/numeric/bits.h"
#include "absl/numeric/int128.h"
#include "absl/strings/string_view.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

// SimpleAtoi()
//
// Converts the given string (optionally followed or preceded by ASCII
// whitespace) into an integer value, returning `true` if successful. The string
// must reflect a base-10 integer whose value falls within the range of the
// integer type (optionally preceded by a `+` or `-`). If any errors are
// encountered, this function returns `false`, leaving `out` in an unspecified
// state.
template <typename int_type>
[[nodiscard]] bool SimpleAtoi(absl::string_view str,
                              int_type* absl_nonnull out);

// SimpleAtof()
//
// Converts the given string (optionally followed or preceded by ASCII
// whitespace) into a float, which may be rounded on overflow or underflow,
// returning `true` if successful.
// See https://en.cppreference.com/w/c/string/byte/strtof for details about the
// 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.
[[nodiscard]] bool SimpleAtof(absl::string_view str, float* absl_nonnull out);

// SimpleAtod()
//
// Converts the given string (optionally followed or preceded by ASCII
// whitespace) into a double, which may be rounded on overflow or underflow,
// returning `true` if successful.
// See https://en.cppreference.com/w/c/string/byte/strtof for details about the
// 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.
[[nodiscard]] bool SimpleAtod(absl::string_view str, double* absl_nonnull out);

// SimpleAtob()
//
// Converts the given string into a boolean, returning `true` if successful.
// The following case-insensitive strings are interpreted as boolean `true`:
// "true", "t", "yes", "y", "1". The following case-insensitive strings
// 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.
[[nodiscard]] bool SimpleAtob(absl::string_view str, bool* absl_nonnull out);

// SimpleHexAtoi()
//
// Converts a hexadecimal string (optionally followed or preceded by ASCII
// whitespace) to an integer, returning `true` if successful. Only valid base-16
// hexadecimal integers whose value falls within the range of the integer type
// (optionally preceded by a `+` or `-`) can be converted. A valid hexadecimal
// value may include both upper and lowercase character symbols, and may
// optionally include a leading "0x" (or "0X") number prefix, which is ignored
// by this function. If any errors are encountered, this function returns
// `false`, leaving `out` in an unspecified state.
template <typename int_type>
[[nodiscard]] bool SimpleHexAtoi(absl::string_view str,
                                 int_type* absl_nonnull out);

// Overloads of SimpleHexAtoi() for 128 bit integers.
[[nodiscard]] inline bool SimpleHexAtoi(absl::string_view str,
                                        absl::int128* absl_nonnull out);
[[nodiscard]] inline bool SimpleHexAtoi(absl::string_view str,
                                        absl::uint128* absl_nonnull out);

ABSL_NAMESPACE_END
}  // namespace absl

// End of public API.  Implementation details follow.

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace numbers_internal {

template <typename int_type>
constexpr bool is_signed() {
  if constexpr (std::is_arithmetic<int_type>::value) {
    // Use std::numeric_limits<T>::is_signed where it's defined to work.
    return std::numeric_limits<int_type>::is_signed;
  }
  // TODO(jorg): 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.
  return static_cast<int_type>(1) - 2 < 0;
}

// Digit conversion.
ABSL_DLL extern const char kHexChar[17];  // 0123456789abcdef
ABSL_DLL extern const char
    kHexTable[513];  // 000102030405060708090a0b0c0d0e0f1011...

// Writes a two-character representation of 'i' to 'buf'. 'i' must be in the
// range 0 <= i < 100, and buf must have space for two characters. Example:
//   char buf[2];
//   PutTwoDigits(42, buf);
//   // buf[0] == '4'
//   // buf[1] == '2'
void PutTwoDigits(uint32_t i, char* absl_nonnull buf);

// safe_strto?() functions for implementing SimpleAtoi()

bool safe_strto8_base(absl::string_view text, int8_t* absl_nonnull value,
                      int base);
bool safe_strto16_base(absl::string_view text, int16_t* absl_nonnull value,
                       int base);
bool safe_strto32_base(absl::string_view text, int32_t* absl_nonnull value,
                       int base);
bool safe_strto64_base(absl::string_view text, int64_t* absl_nonnull value,
                       int base);
bool safe_strto128_base(absl::string_view text,
                        absl::int128* absl_nonnull value, int base);
bool safe_strtou8_base(absl::string_view text, uint8_t* absl_nonnull value,
                       int base);
bool safe_strtou16_base(absl::string_view text, uint16_t* absl_nonnull value,
                        int base);
bool safe_strtou32_base(absl::string_view text, uint32_t* absl_nonnull value,
                        int base);
bool safe_strtou64_base(absl::string_view text, uint64_t* absl_nonnull value,
                        int base);
bool safe_strtou128_base(absl::string_view text,
                         absl::uint128* absl_nonnull value, int base);

static const int kFastToBufferSize = 32;
static const int kSixDigitsToBufferSize = 16;

// 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* absl_nonnull buffer);

// WARNING: These functions may write more characters than necessary, because
// they are intended for speed. All 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* absl_nonnull FastIntToBuffer(int32_t i, char* absl_nonnull buffer)
    ABSL_INTERNAL_NEED_MIN_SIZE(buffer, kFastToBufferSize);
char* absl_nonnull FastIntToBuffer(uint32_t n, char* absl_nonnull out_str)
    ABSL_INTERNAL_NEED_MIN_SIZE(out_str, kFastToBufferSize);
char* absl_nonnull FastIntToBuffer(int64_t i, char* absl_nonnull buffer)
    ABSL_INTERNAL_NEED_MIN_SIZE(buffer, kFastToBufferSize);
char* absl_nonnull FastIntToBuffer(uint64_t i, char* absl_nonnull buffer)
    ABSL_INTERNAL_NEED_MIN_SIZE(buffer, kFastToBufferSize);

// 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* absl_nonnull FastIntToBuffer(int_type i, char* absl_nonnull buffer)
    ABSL_INTERNAL_NEED_MIN_SIZE(buffer, kFastToBufferSize) {
  static_assert(sizeof(i) <= 64 / 8,
                "FastIntToBuffer works only with 64-bit-or-less integers.");
  // These conditions are constexpr bools to suppress MSVC warning C4127.
  constexpr bool kIsSigned = is_signed<int_type>();
  constexpr bool kUse64Bit = sizeof(i) > 32 / 8;
  if (kIsSigned) {
    if (kUse64Bit) {
      return FastIntToBuffer(static_cast<int64_t>(i), buffer);
    } else {
      return FastIntToBuffer(static_cast<int32_t>(i), buffer);
    }
  } else {
    if (kUse64Bit) {
      return FastIntToBuffer(static_cast<uint64_t>(i), buffer);
    } else {
      return FastIntToBuffer(static_cast<uint32_t>(i), buffer);
    }
  }
}

// Implementation of SimpleAtoi, generalized to support arbitrary base (used
// with base different from 10 elsewhere in Abseil implementation).
template <typename int_type>
[[nodiscard]] bool safe_strtoi_base(absl::string_view s,
                                    int_type* absl_nonnull out, int base) {
  static_assert(sizeof(*out) == 1 || sizeof(*out) == 2 || sizeof(*out) == 4 ||
                    sizeof(*out) == 8,
                "SimpleAtoi works only with 8, 16, 32, or 64-bit integers.");
  static_assert(!std::is_floating_point<int_type>::value,
                "Use SimpleAtof or SimpleAtod instead.");
  bool parsed;
  // These conditions are constexpr bools to suppress MSVC warning C4127.
  constexpr bool kIsSigned = is_signed<int_type>();
  constexpr int kIntTypeSize = sizeof(*out) * 8;
  if (kIsSigned) {
    if (kIntTypeSize == 64) {
      int64_t val;
      parsed = numbers_internal::safe_strto64_base(s, &val, base);
      *out = static_cast<int_type>(val);
    } else if (kIntTypeSize == 32) {
      int32_t val;
      parsed = numbers_internal::safe_strto32_base(s, &val, base);
      *out = static_cast<int_type>(val);
    } else if (kIntTypeSize == 16) {
      int16_t val;
      parsed = numbers_internal::safe_strto16_base(s, &val, base);
      *out = static_cast<int_type>(val);
    } else if (kIntTypeSize == 8) {
      int8_t val;
      parsed = numbers_internal::safe_strto8_base(s, &val, base);
      *out = static_cast<int_type>(val);
    }
  } else {
    if (kIntTypeSize == 64) {
      uint64_t val;
      parsed = numbers_internal::safe_strtou64_base(s, &val, base);
      *out = static_cast<int_type>(val);
    } else if (kIntTypeSize == 32) {
      uint32_t val;
      parsed = numbers_internal::safe_strtou32_base(s, &val, base);
      *out = static_cast<int_type>(val);
    } else if (kIntTypeSize == 16) {
      uint16_t val;
      parsed = numbers_internal::safe_strtou16_base(s, &val, base);
      *out = static_cast<int_type>(val);
    } else if (kIntTypeSize == 8) {
      uint8_t val;
      parsed = numbers_internal::safe_strtou8_base(s, &val, base);
      *out = static_cast<int_type>(val);
    }
  }
  return parsed;
}

// FastHexToBufferZeroPad16()
//
// Outputs `val` into `out` as if by `snprintf(out, 17, "%016x", val)` but
// 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* absl_nonnull out) {
#ifdef ABSL_INTERNAL_HAVE_SSSE3
  uint64_t be = absl::big_endian::FromHost64(val);
  const auto kNibbleMask = _mm_set1_epi8(0xf);
  const auto kHexDigits = _mm_setr_epi8('0', '1', '2', '3', '4', '5', '6', '7',
                                        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');
  auto v = _mm_loadl_epi64(reinterpret_cast<__m128i*>(&be));  // load lo dword
  auto v4 = _mm_srli_epi64(v, 4);                            // shift 4 right
  auto il = _mm_unpacklo_epi8(v4, v);                        // interleave bytes
  auto m = _mm_and_si128(il, kNibbleMask);                   // mask out nibbles
  auto hexchars = _mm_shuffle_epi8(kHexDigits, m);           // hex chars
  _mm_storeu_si128(reinterpret_cast<__m128i*>(out), hexchars);
#else
  for (int i = 0; i < 8; ++i) {
    auto byte = (val >> (56 - 8 * i)) & 0xFF;
    auto* hex = &absl::numbers_internal::kHexTable[byte * 2];
    std::memcpy(out + 2 * i, hex, 2);
  }
#endif
  // | 0x1 so that even 0 has 1 digit.
  return 16 - static_cast<size_t>(countl_zero(val | 0x1) / 4);
}

}  // namespace numbers_internal

template <typename int_type>
[[nodiscard]] bool SimpleAtoi(absl::string_view str,
                              int_type* absl_nonnull out) {
  return numbers_internal::safe_strtoi_base(str, out, 10);
}

[[nodiscard]] inline bool SimpleAtoi(absl::string_view str,
                                     absl::int128* absl_nonnull out) {
  return numbers_internal::safe_strto128_base(str, out, 10);
}

[[nodiscard]] inline bool SimpleAtoi(absl::string_view str,
                                     absl::uint128* absl_nonnull out) {
  return numbers_internal::safe_strtou128_base(str, out, 10);
}

template <typename int_type>
[[nodiscard]] bool SimpleHexAtoi(absl::string_view str,
                                 int_type* absl_nonnull out) {
  return numbers_internal::safe_strtoi_base(str, out, 16);
}

[[nodiscard]] inline bool SimpleHexAtoi(absl::string_view str,
                                        absl::int128* absl_nonnull out) {
  return numbers_internal::safe_strto128_base(str, out, 16);
}

[[nodiscard]] inline bool SimpleHexAtoi(absl::string_view str,
                                        absl::uint128* absl_nonnull out) {
  return numbers_internal::safe_strtou128_base(str, out, 16);
}

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_NUMBERS_H_
*úC
jsoong/.intermediates/external/abseil-cpp/absl_base_core_headers_hdrs/gen/my_include_dir/absl/base/macros.h‹C//
// 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.
//
// -----------------------------------------------------------------------------
// File: macros.h
// -----------------------------------------------------------------------------
//
// This header file defines the set of language macros used within Abseil code.
// For the set of macros used to determine supported compilers and platforms,
// see absl/base/config.h instead.
//
// This code is compiled directly on many platforms, including client
// platforms like Windows, Mac, and embedded systems.  Before making
// any changes here, make sure that you're not breaking any platforms.

#ifndef ABSL_BASE_MACROS_H_
#define ABSL_BASE_MACROS_H_

#include <cassert>
#include <cstddef>

#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/optimization.h"
#include "absl/base/options.h"
#include "absl/base/port.h"

// ABSL_ARRAYSIZE()
//
// Returns the number of elements in an array as a compile-time constant, which
// can be used in defining new arrays. If you use this macro on a pointer by
// mistake, you will get a compile-time error.
#define ABSL_ARRAYSIZE(array) \
  (sizeof(::absl::macros_internal::ArraySizeHelper(array)))

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace macros_internal {
// Note: this internal template function declaration is used by ABSL_ARRAYSIZE.
// The function doesn't need a definition, as we only use its type.
template <typename T, size_t N>
auto ArraySizeHelper(const T (&array)[N]) -> char (&)[N];
}  // namespace macros_internal
ABSL_NAMESPACE_END
}  // namespace absl

// ABSL_BAD_CALL_IF()
//
// Used on a function overload to trap bad calls: any call that matches the
// overload will cause a compile-time error. This macro uses a clang-specific
// "enable_if" attribute, as described at
// https://clang.llvm.org/docs/AttributeReference.html#enable-if
//
// Overloads which use this macro should be bracketed by
// `#ifdef ABSL_BAD_CALL_IF`.
//
// Example:
//
//   int isdigit(int c);
//   #ifdef ABSL_BAD_CALL_IF
//   int isdigit(int c)
//     ABSL_BAD_CALL_IF(c <= -1 || c > 255,
//                       "'c' must have the value of an unsigned char or EOF");
//   #endif // ABSL_BAD_CALL_IF
#if ABSL_HAVE_ATTRIBUTE(enable_if)
#define ABSL_BAD_CALL_IF(expr, msg) \
  __attribute__((enable_if(expr, "Bad call trap"), unavailable(msg)))
#endif

// ABSL_ASSERT()
//
// In C++11, `assert` can't be used portably within constexpr functions.
// `assert` also generates spurious unused-symbol warnings.
// ABSL_ASSERT functions as a runtime assert but works in C++11 constexpr
// functions, and maintains references to symbols.  Example:
//
// constexpr double Divide(double a, double b) {
//   return ABSL_ASSERT(b != 0), a / b;
// }
//
// This macro is inspired by
// https://akrzemi1.wordpress.com/2017/05/18/asserts-in-constexpr-functions/
#if defined(NDEBUG)
#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
// We use `decltype` here to avoid generating unnecessary code that the
// optimizer then has to optimize away.
// This not only improves compilation performance by reducing codegen bloat
// and optimization work, but also guarantees fast run-time performance without
// having to rely on the optimizer.
#define ABSL_ASSERT(expr) (decltype((expr) ? void() : void())())
#else
// Pre-C++20, lambdas can't be inside unevaluated operands, so we're forced to
// rely on the optimizer.
#define ABSL_ASSERT(expr) (false ? ((expr) ? void() : void()) : void())
#endif
#else
#define ABSL_ASSERT(expr)                           \
  (ABSL_PREDICT_TRUE((expr)) ? static_cast<void>(0) \
                             : [] { assert(false && #expr); }())  // NOLINT
#endif

// `ABSL_INTERNAL_HARDENING_ABORT()` controls how `ABSL_HARDENING_ASSERT()`
// aborts the program in release mode (when NDEBUG is defined). The
// implementation should abort the program as quickly as possible and ideally it
// should not be possible to ignore the abort request.
#define ABSL_INTERNAL_HARDENING_ABORT()   \
  do {                                    \
    ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL(); \
    ABSL_INTERNAL_UNREACHABLE_IMPL();     \
  } while (false)

// ABSL_HARDENING_ASSERT()
//
// `ABSL_HARDENING_ASSERT()` is like `ABSL_ASSERT()`, but used to implement
// runtime assertions that should be enabled in hardened builds even when
// `NDEBUG` is defined.
//
// When `NDEBUG` is not defined, `ABSL_HARDENING_ASSERT()` is identical to
// `ABSL_ASSERT()`.
//
// See `ABSL_OPTION_HARDENED` in `absl/base/options.h` for more information on
// hardened mode.
#if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
#define ABSL_HARDENING_ASSERT(expr)                 \
  (ABSL_PREDICT_TRUE((expr)) ? static_cast<void>(0) \
                             : [] { ABSL_INTERNAL_HARDENING_ABORT(); }())
#else
#define ABSL_HARDENING_ASSERT(expr) ABSL_ASSERT(expr)
#endif

// ABSL_HARDENING_ASSERT_SLOW()
//
// `ABSL_HARDENING_ASSERT()` is like `ABSL_HARDENING_ASSERT()`,
//  but specifically for assertions whose predicates are too slow
//  to be enabled in many applications.
//
// When `NDEBUG` is not defined, `ABSL_HARDENING_ASSERT_SLOW()` is identical to
// `ABSL_ASSERT()`.
//
// See `ABSL_OPTION_HARDENED` in `absl/base/options.h` for more information on
// hardened mode.
#if ABSL_OPTION_HARDENED == 1 && defined(NDEBUG)
#define ABSL_HARDENING_ASSERT_SLOW(expr)            \
  (ABSL_PREDICT_TRUE((expr)) ? static_cast<void>(0) \
                             : [] { ABSL_INTERNAL_HARDENING_ABORT(); }())
#else
#define ABSL_HARDENING_ASSERT_SLOW(expr) ABSL_ASSERT(expr)
#endif

#ifdef ABSL_HAVE_EXCEPTIONS
#define ABSL_INTERNAL_TRY try
#define ABSL_INTERNAL_CATCH_ANY catch (...)
#define ABSL_INTERNAL_RETHROW do { throw; } while (false)
#else  // ABSL_HAVE_EXCEPTIONS
#define ABSL_INTERNAL_TRY if (true)
#define ABSL_INTERNAL_CATCH_ANY else if (false)
#define ABSL_INTERNAL_RETHROW do {} while (false)
#endif  // ABSL_HAVE_EXCEPTIONS

// ABSL_DEPRECATE_AND_INLINE()
//
// Marks a function or type alias as deprecated and tags it to be picked up for
// automated refactoring by go/cpp-inliner. It can added to inline function
// definitions or type aliases. It should only be used within a header file. It
// differs from `ABSL_DEPRECATED` in the following ways:
//
// 1. New uses of the function or type will be discouraged via Tricorder
//    warnings.
// 2. If enabled via `METADATA`, automated changes will be sent out inlining the
//    functions's body or replacing the type where it is used.
//
// For example:
//
// ABSL_DEPRECATE_AND_INLINE() inline int OldFunc(int x) {
//   return NewFunc(x, 0);
// }
//
// will mark `OldFunc` as deprecated, and the go/cpp-inliner service will
// replace calls to `OldFunc(x)` with calls to `NewFunc(x, 0)`. Once all calls
// to `OldFunc` have been replaced, `OldFunc` can be deleted.
//
// See go/cpp-inliner for more information.
//
// Note: go/cpp-inliner is Google-internal service for automated refactoring.
// While open-source users do not have access to this service, the macro is
// provided for compatibility, and so that users receive deprecation warnings.
#if ABSL_HAVE_CPP_ATTRIBUTE(deprecated) && \
    ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate)
#define ABSL_DEPRECATE_AND_INLINE() [[deprecated, clang::annotate("inline-me")]]
#elif ABSL_HAVE_CPP_ATTRIBUTE(deprecated)
#define ABSL_DEPRECATE_AND_INLINE() [[deprecated]]
#else
#define ABSL_DEPRECATE_AND_INLINE()
#endif

// Requires the compiler to prove that the size of the given object is at least
// the expected amount.
#if ABSL_HAVE_ATTRIBUTE(diagnose_if) && ABSL_HAVE_BUILTIN(__builtin_object_size)
#define ABSL_INTERNAL_NEED_MIN_SIZE(Obj, N)                     \
  __attribute__((diagnose_if(__builtin_object_size(Obj, 0) < N, \
                             "object size provably too small "  \
                             "(this would corrupt memory)",     \
                             "error")))
#else
#define ABSL_INTERNAL_NEED_MIN_SIZE(Obj, N)
#endif

#endif  // ABSL_BASE_MACROS_H_
*”
fsoong/.intermediates/external/abseil-cpp/absl_log_log_sink_hdrs/gen/my_include_dir/absl/log/log_sink.h©// 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/log_sink.h
// -----------------------------------------------------------------------------
//
// This header declares the interface class `absl::LogSink`.

#ifndef ABSL_LOG_LOG_SINK_H_
#define ABSL_LOG_LOG_SINK_H_

#include "absl/base/config.h"
#include "absl/log/log_entry.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

// absl::LogSink
//
// `absl::LogSink` is an interface which can be extended to intercept and
// process particular messages (with `LOG.ToSinkOnly()` or
// `LOG.ToSinkAlso()`) or all messages (if registered with
// `absl::AddLogSink`).  Implementations must not take any locks that might be
// held by the `LOG` caller.
class LogSink {
 public:
  virtual ~LogSink() = default;

  // LogSink::Send()
  //
  // `Send` is called synchronously during the log statement.  `Send` must be
  // thread-safe.
  //
  // It is safe to use `LOG` within an implementation of `Send`.  `ToSinkOnly`
  // and `ToSinkAlso` are safe in general but can be used to create an infinite
  // loop if you try.
  virtual void Send(const absl::LogEntry& entry) = 0;

  // LogSink::Flush()
  //
  // Sinks that buffer messages should override this method to flush the buffer
  // and return.  `Flush` must be thread-safe.
  virtual void Flush() {}

 protected:
  LogSink() = default;
  // Implementations may be copyable and/or movable.
  LogSink(const LogSink&) = default;
  LogSink& operator=(const LogSink&) = default;

 private:
  // https://lld.llvm.org/missingkeyfunction.html#missing-key-function
  virtual void KeyFunction() const final;  // NOLINT(readability/inheritance)
};

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_LOG_LOG_SINK_H_
*–Q
€soong/.intermediates/external/abseil-cpp/absl_base_raw_logging_internal_hdrs/gen/my_include_dir/absl/base/internal/raw_logging.h�P// 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.
//
// Thread-safe logging routines that do not allocate any memory or
// acquire any locks, and can therefore be used by low-level memory
// allocation, synchronization, and signal-handling code.

#ifndef ABSL_BASE_INTERNAL_RAW_LOGGING_H_
#define ABSL_BASE_INTERNAL_RAW_LOGGING_H_

#include <string>

#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/atomic_hook.h"
#include "absl/base/log_severity.h"
#include "absl/base/macros.h"
#include "absl/base/optimization.h"
#include "absl/base/port.h"

// This is similar to LOG(severity) << format..., but
// * it is to be used ONLY by low-level modules that can't use normal LOG()
// * it is designed to be a low-level logger that does not allocate any
//   memory and does not need any locks, hence:
// * it logs straight and ONLY to STDERR w/o buffering
// * it uses an explicit printf-format and arguments list
// * it will silently chop off really long message strings
// Usage example:
//   ABSL_RAW_LOG(ERROR, "Failed foo with %i: %s", status, error);
// This will print an almost standard log line like this to stderr only:
//   E0821 211317 file.cc:123] RAW: Failed foo with 22: bad_file

#define ABSL_RAW_LOG(severity, ...)                                            \
  do {                                                                         \
    constexpr const char* absl_raw_log_internal_basename =                     \
        ::absl::raw_log_internal::Basename(__FILE__, sizeof(__FILE__) - 1);    \
    ::absl::raw_log_internal::RawLog(ABSL_RAW_LOG_INTERNAL_##severity,         \
                                     absl_raw_log_internal_basename, __LINE__, \
                                     __VA_ARGS__);                             \
    ABSL_RAW_LOG_INTERNAL_MAYBE_UNREACHABLE_##severity;                        \
  } while (0)

// Similar to CHECK(condition) << message, but for low-level modules:
// we use only ABSL_RAW_LOG that does not allocate memory.
// We do not want to provide args list here to encourage this usage:
//   if (!cond)  ABSL_RAW_LOG(FATAL, "foo ...", hard_to_compute_args);
// so that the args are not computed when not needed.
#define ABSL_RAW_CHECK(condition, message)                             \
  do {                                                                 \
    if (ABSL_PREDICT_FALSE(!(condition))) {                            \
      ABSL_RAW_LOG(FATAL, "Check %s failed: %s", #condition, message); \
    }                                                                  \
  } while (0)

// ABSL_INTERNAL_LOG and ABSL_INTERNAL_CHECK work like the RAW variants above,
// except that if the richer log library is linked into the binary, we dispatch
// to that instead.  This is potentially useful for internal logging and
// assertions, where we are using RAW_LOG neither for its async-signal-safety
// nor for its non-allocating nature, but rather because raw logging has very
// few other dependencies.
//
// The API is a subset of the above: each macro only takes two arguments.  Use
// StrCat if you need to build a richer message.
#define ABSL_INTERNAL_LOG(severity, message)                              \
  do {                                                                    \
    constexpr const char* absl_raw_log_internal_filename = __FILE__;      \
    ::absl::raw_log_internal::internal_log_function(                      \
        ABSL_RAW_LOG_INTERNAL_##severity, absl_raw_log_internal_filename, \
        __LINE__, message);                                               \
    ABSL_RAW_LOG_INTERNAL_MAYBE_UNREACHABLE_##severity;                   \
  } while (0)

#define ABSL_INTERNAL_CHECK(condition, message)                    \
  do {                                                             \
    if (ABSL_PREDICT_FALSE(!(condition))) {                        \
      std::string death_message = "Check " #condition " failed: "; \
      death_message += std::string(message);                       \
      ABSL_INTERNAL_LOG(FATAL, death_message);                     \
    }                                                              \
  } while (0)

#ifndef NDEBUG

#define ABSL_RAW_DLOG(severity, ...) ABSL_RAW_LOG(severity, __VA_ARGS__)
#define ABSL_RAW_DCHECK(condition, message) ABSL_RAW_CHECK(condition, message)

#else  // NDEBUG

#define ABSL_RAW_DLOG(severity, ...)                   \
  while (false) ABSL_RAW_LOG(severity, __VA_ARGS__)
#define ABSL_RAW_DCHECK(condition, message) \
  while (false) ABSL_RAW_CHECK(condition, message)

#endif  // NDEBUG

#define ABSL_RAW_LOG_INTERNAL_INFO ::absl::LogSeverity::kInfo
#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)

#define ABSL_RAW_LOG_INTERNAL_MAYBE_UNREACHABLE_INFO
#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 {
ABSL_NAMESPACE_BEGIN
namespace raw_log_internal {

// Helper function to implement ABSL_RAW_LOG
// Logs format... at "severity" level, reporting it
// as called from file:line.
// This does not allocate memory or acquire locks.
void RawLog(absl::LogSeverity severity, const char* file, int line,
            const char* format, ...) ABSL_PRINTF_ATTRIBUTE(4, 5);

// Writes the provided buffer directly to stderr, in a signal-safe, low-level
// manner.  Preserves errno.
void AsyncSignalSafeWriteError(const char* s, size_t len);

// compile-time function to get the "base" filename, that is, the part of
// a filename after the last "/" or "\" path separator.  The search starts at
// the end of the string; the second parameter is the length of the string.
constexpr const char* Basename(const char* fname, int offset) {
  return offset == 0 || fname[offset - 1] == '/' || fname[offset - 1] == '\\'
             ? fname + offset
             : Basename(fname, offset - 1);
}

// For testing only.
// Returns true if raw logging is fully supported. When it is not
// fully supported, no messages will be emitted, but a log at FATAL
// severity will cause an abort.
//
// TODO(gfalcon): Come up with a better name for this method.
bool RawLoggingFullySupported();

// Function type for a raw_log customization hook for suppressing messages
// by severity, and for writing custom prefixes on non-suppressed messages.
//
// The installed hook is called for every raw log invocation.  The message will
// be logged to stderr only if the hook returns true.  FATAL errors will cause
// the process to abort, even if writing to stderr is suppressed.  The hook is
// also provided with an output buffer, where it can write a custom log message
// prefix.
//
// The raw_log system does not allocate memory or grab locks.  User-provided
// hooks must avoid these operations, and must not throw exceptions.
//
// 'severity' is the severity level of the message being written.
// 'file' and 'line' are the file and line number where the ABSL_RAW_LOG macro
// was located.
// 'buf' and 'buf_size' are pointers to the buffer and buffer size.  If the
// hook writes a prefix, it must increment *buf and decrement *buf_size
// accordingly.
using LogFilterAndPrefixHook = bool (*)(absl::LogSeverity severity,
                                        const char* file, int line, char** buf,
                                        int* buf_size);

// Function type for a raw_log customization hook called to abort a process
// when a FATAL message is logged.  If the provided AbortHook() returns, the
// logging system will call abort().
//
// 'file' and 'line' are the file and line number where the ABSL_RAW_LOG macro
// was located.
// The NUL-terminated logged message lives in the buffer between 'buf_start'
// and 'buf_end'.  'prefix_end' points to the first non-prefix character of the
// buffer (as written by the LogFilterAndPrefixHook.)
//
// The lifetime of the filename and message buffers will not end while the
// process remains alive.
using AbortHook = void (*)(const char* file, int line, const char* buf_start,
                           const char* prefix_end, const char* buf_end);

// Internal logging function for ABSL_INTERNAL_LOG to dispatch to.
//
// TODO(gfalcon): When string_view no longer depends on base, change this
// interface to take its message as a string_view instead.
using InternalLogFunction = void (*)(absl::LogSeverity severity,
                                     const char* file, int line,
                                     const std::string& message);

ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES ABSL_DLL extern base_internal::AtomicHook<
    InternalLogFunction>
    internal_log_function;

// Registers hooks of the above types.  Only a single hook of each type may be
// registered.  It is an error to call these functions multiple times with
// different input arguments.
//
// These functions are safe to call at any point during initialization; they do
// not block or malloc, and are async-signal safe.
void RegisterLogFilterAndPrefixHook(LogFilterAndPrefixHook func);
void RegisterAbortHook(AbortHook func);
void RegisterInternalLogFunction(InternalLogFunction func);

}  // namespace raw_log_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_BASE_INTERNAL_RAW_LOGGING_H_
*³
rsoong/.intermediates/external/abseil-cpp/absl_crc_crc32c_hdrs/gen/my_include_dir/absl/crc/internal/crc32c_inline.h¼// 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.

#ifndef ABSL_CRC_INTERNAL_CRC32C_INLINE_H_
#define ABSL_CRC_INTERNAL_CRC32C_INLINE_H_

#include <cstdint>

#include "absl/base/config.h"
#include "absl/base/internal/endian.h"
#include "absl/crc/internal/crc32_x86_arm_combined_simd.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace crc_internal {

// CRC32C implementation optimized for small inputs.
// Either computes crc and return true, or if there is
// no hardware support does nothing and returns false.
inline bool ExtendCrc32cInline(uint32_t* crc, const char* p, size_t n) {
#if defined(ABSL_CRC_INTERNAL_HAVE_ARM_SIMD) || \
    defined(ABSL_CRC_INTERNAL_HAVE_X86_SIMD)
  constexpr uint32_t kCrc32Xor = 0xffffffffU;
  *crc ^= kCrc32Xor;
  if (n & 1) {
    *crc = CRC32_u8(*crc, static_cast<uint8_t>(*p));
    n--;
    p++;
  }
  if (n & 2) {
    *crc = CRC32_u16(*crc, absl::little_endian::Load16(p));
    n -= 2;
    p += 2;
  }
  if (n & 4) {
    *crc = CRC32_u32(*crc, absl::little_endian::Load32(p));
    n -= 4;
    p += 4;
  }
  while (n) {
    *crc = CRC32_u64(*crc, absl::little_endian::Load64(p));
    n -= 8;
    p += 8;
  }
  *crc ^= kCrc32Xor;
  return true;
#else
  // No hardware support, signal the need to fallback.
  static_cast<void>(crc);
  static_cast<void>(p);
  static_cast<void>(n);
  return false;
#endif  // defined(ABSL_CRC_INTERNAL_HAVE_ARM_SIMD) ||
        // defined(ABSL_CRC_INTERNAL_HAVE_X86_SIMD)
}

}  // namespace crc_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_CRC_INTERNAL_CRC32C_INLINE_H_
*…
}soong/.intermediates/external/abseil-cpp/absl_base_throw_delegate_hdrs/gen/my_include_dir/absl/base/internal/throw_delegate.hƒ//
// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#ifndef ABSL_BASE_INTERNAL_THROW_DELEGATE_H_
#define ABSL_BASE_INTERNAL_THROW_DELEGATE_H_

#include <string>

#include "absl/base/config.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {

// Helper functions that allow throwing exceptions consistently from anywhere.
// The main use case is for header-based libraries (eg templates), as they will
// be built by many different targets with their own compiler options.
// In particular, this will allow a safe way to throw exceptions even if the
// caller is compiled with -fno-exceptions.  This is intended for implementing
// things like map<>::at(), which the standard documents as throwing an
// exception on error.
//
// Using other techniques like #if tricks could lead to ODR violations.
//
// You shouldn't use it unless you're writing code that you know will be built
// both with and without exceptions and you need to conform to an interface
// that uses exceptions.

[[noreturn]] void ThrowStdLogicError(const std::string& what_arg);
[[noreturn]] void ThrowStdLogicError(const char* what_arg);
[[noreturn]] void ThrowStdInvalidArgument(const std::string& what_arg);
[[noreturn]] void ThrowStdInvalidArgument(const char* what_arg);
[[noreturn]] void ThrowStdDomainError(const std::string& what_arg);
[[noreturn]] void ThrowStdDomainError(const char* what_arg);
[[noreturn]] void ThrowStdLengthError(const std::string& what_arg);
[[noreturn]] void ThrowStdLengthError(const char* what_arg);
[[noreturn]] void ThrowStdOutOfRange(const std::string& what_arg);
[[noreturn]] void ThrowStdOutOfRange(const char* what_arg);
[[noreturn]] void ThrowStdRuntimeError(const std::string& what_arg);
[[noreturn]] void ThrowStdRuntimeError(const char* what_arg);
[[noreturn]] void ThrowStdRangeError(const std::string& what_arg);
[[noreturn]] void ThrowStdRangeError(const char* what_arg);
[[noreturn]] void ThrowStdOverflowError(const std::string& what_arg);
[[noreturn]] void ThrowStdOverflowError(const char* what_arg);
[[noreturn]] void ThrowStdUnderflowError(const std::string& what_arg);
[[noreturn]] void ThrowStdUnderflowError(const char* what_arg);

[[noreturn]] void ThrowStdBadFunctionCall();
[[noreturn]] void ThrowStdBadAlloc();

// ThrowStdBadArrayNewLength() cannot be consistently supported because
// std::bad_array_new_length is missing in libstdc++ until 4.9.0.
// https://gcc.gnu.org/onlinedocs/gcc-4.8.3/libstdc++/api/a01379_source.html
// https://gcc.gnu.org/onlinedocs/gcc-4.9.0/libstdc++/api/a01327_source.html
// libcxx (as of 3.2) and msvc (as of 2015) both have it.
// [[noreturn]] void ThrowStdBadArrayNewLength();

}  // namespace base_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_BASE_INTERNAL_THROW_DELEGATE_H_
*«'
„soong/.intermediates/external/abseil-cpp/absl_synchronization_hdrs/gen/my_include_dir/absl/synchronization/internal/per_thread_sem.h¡&// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

// PerThreadSem is a low-level synchronization primitive controlling the
// runnability of a single thread, used internally by Mutex and CondVar.
//
// This is NOT a general-purpose synchronization mechanism, and should not be
// used directly by applications.  Applications should use Mutex and CondVar.
//
// The semantics of PerThreadSem are the same as that of a counting semaphore.
// Each thread maintains an abstract "count" value associated with its identity.

#ifndef ABSL_SYNCHRONIZATION_INTERNAL_PER_THREAD_SEM_H_
#define ABSL_SYNCHRONIZATION_INTERNAL_PER_THREAD_SEM_H_

#include <atomic>

#include "absl/base/internal/thread_identity.h"
#include "absl/synchronization/internal/create_thread_identity.h"
#include "absl/synchronization/internal/kernel_timeout.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

class Mutex;

namespace synchronization_internal {

class PerThreadSem {
 public:
  PerThreadSem() = delete;
  PerThreadSem(const PerThreadSem&) = delete;
  PerThreadSem& operator=(const PerThreadSem&) = delete;

  // Routine invoked periodically (once a second) by a background thread.
  // Has no effect on user-visible state.
  static void Tick(base_internal::ThreadIdentity* identity);

  // ---------------------------------------------------------------------------
  // Routines used by autosizing threadpools to detect when threads are
  // blocked.  Each thread has a counter pointer, initially zero.  If non-zero,
  // the implementation atomically increments the counter when it blocks on a
  // semaphore, a decrements it again when it wakes.  This allows a threadpool
  // to keep track of how many of its threads are blocked.
  // SetThreadBlockedCounter() should be used only by threadpool
  // implementations.  GetThreadBlockedCounter() should be used by modules that
  // block threads; if the pointer returned is non-zero, the location should be
  // incremented before the thread blocks, and decremented after it wakes.
  static void SetThreadBlockedCounter(std::atomic<int> *counter);
  static std::atomic<int> *GetThreadBlockedCounter();

 private:
  // Create the PerThreadSem associated with "identity".  Initializes count=0.
  // REQUIRES: May only be called by ThreadIdentity.
  static inline void Init(base_internal::ThreadIdentity* identity);

  // Increments "identity"'s count.
  static inline void Post(base_internal::ThreadIdentity* identity);

  // Waits until either our count > 0 or t has expired.
  // If count > 0, decrements count and returns true.  Otherwise returns false.
  // !t.has_timeout() => Wait(t) will return true.
  static inline bool Wait(KernelTimeout t);

  // Permitted callers.
  friend class PerThreadSemTest;
  friend class absl::Mutex;
  friend void OneTimeInitThreadIdentity(absl::base_internal::ThreadIdentity*);
};

}  // namespace synchronization_internal
ABSL_NAMESPACE_END
}  // namespace absl

// In some build configurations we pass --detect-odr-violations to the
// gold linker.  This causes it to flag weak symbol overrides as ODR
// violations.  Because ODR only applies to C++ and not C,
// --detect-odr-violations ignores symbols not mangled with C++ names.
// By changing our extension points to be extern "C", we dodge this
// check.
extern "C" {
void ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemInit)(
    absl::base_internal::ThreadIdentity* identity);
void ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemPost)(
    absl::base_internal::ThreadIdentity* identity);
bool ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemWait)(
    absl::synchronization_internal::KernelTimeout t);
void ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemPoke)(
    absl::base_internal::ThreadIdentity* identity);
}  // extern "C"

void absl::synchronization_internal::PerThreadSem::Init(
    absl::base_internal::ThreadIdentity* identity) {
  ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemInit)(identity);
}

void absl::synchronization_internal::PerThreadSem::Post(
    absl::base_internal::ThreadIdentity* identity) {
  ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemPost)(identity);
}

bool absl::synchronization_internal::PerThreadSem::Wait(
    absl::synchronization_internal::KernelTimeout t) {
  return ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemWait)(t);
}

#endif  // ABSL_SYNCHRONIZATION_INTERNAL_PER_THREAD_SEM_H_
*±½
xsoong/.intermediates/external/abseil-cpp/absl_log_internal_check_op_hdrs/gen/my_include_dir/absl/log/internal/check_op.h³¼// 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/internal/check_op.h
// -----------------------------------------------------------------------------
//
// This file declares helpers routines and macros used to implement `CHECK`
// macros.

#ifndef ABSL_LOG_INTERNAL_CHECK_OP_H_
#define ABSL_LOG_INTERNAL_CHECK_OP_H_

#include <stdint.h>

#include <cstddef>
#include <ostream>
#include <sstream>
#include <string>
#include <type_traits>
#include <utility>

#include "absl/base/attributes.h"
#include "absl/base/casts.h"
#include "absl/base/config.h"
#include "absl/base/nullability.h"
#include "absl/base/optimization.h"
#include "absl/log/internal/nullguard.h"
#include "absl/log/internal/nullstream.h"
#include "absl/log/internal/strip.h"
#include "absl/strings/has_absl_stringify.h"
#include "absl/strings/string_view.h"

// `ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL` wraps string literals that
// should be stripped when `ABSL_MIN_LOG_LEVEL` exceeds `kFatal`.
#ifdef ABSL_MIN_LOG_LEVEL
#define ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(literal)         \
  (::absl::LogSeverity::kFatal >=                               \
           static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) \
       ? (literal)                                              \
       : "")
#else
#define ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(literal) (literal)
#endif

#ifdef NDEBUG
// `NDEBUG` is defined, so `DCHECK_EQ(x, y)` and so on do nothing.  However, we
// still want the compiler to parse `x` and `y`, because we don't want to lose
// potentially useful errors and warnings.
#define ABSL_LOG_INTERNAL_DCHECK_NOP(x, y)   \
  while (false && ((void)(x), (void)(y), 0)) \
  ::absl::log_internal::NullStream().InternalStream()
#endif

#define ABSL_LOG_INTERNAL_CHECK_OP(name, op, val1, val1_text, val2, val2_text) \
  while (const char* absl_nullable absl_log_internal_check_op_result           \
         [[maybe_unused]] = ::absl::log_internal::name##Impl(                  \
             ::absl::log_internal::GetReferenceableValue(val1),                \
             ::absl::log_internal::GetReferenceableValue(val2),                \
             ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(val1_text " " #op          \
                                                              " " val2_text))) \
    ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, true)                         \
  ABSL_LOG_INTERNAL_CHECK(::absl::implicit_cast<const char* absl_nonnull>(     \
                              absl_log_internal_check_op_result))              \
      .InternalStream()
#define ABSL_LOG_INTERNAL_QCHECK_OP(name, op, val1, val1_text, val2,        \
                                    val2_text)                              \
  while (const char* absl_nullable absl_log_internal_qcheck_op_result =     \
             ::absl::log_internal::name##Impl(                              \
                 ::absl::log_internal::GetReferenceableValue(val1),         \
                 ::absl::log_internal::GetReferenceableValue(val2),         \
                 ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(                    \
                     val1_text " " #op " " val2_text)))                     \
    ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, true)                     \
  ABSL_LOG_INTERNAL_QCHECK(::absl::implicit_cast<const char* absl_nonnull>( \
                               absl_log_internal_qcheck_op_result))         \
      .InternalStream()
#define ABSL_LOG_INTERNAL_CHECK_STROP(func, op, expected, s1, s1_text, s2,     \
                                      s2_text)                                 \
  while (const char* absl_nullable absl_log_internal_check_strop_result =      \
             ::absl::log_internal::Check##func##expected##Impl(                \
                 (s1), (s2),                                                   \
                 ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(s1_text " " #op        \
                                                                " " s2_text))) \
    ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, true)                         \
  ABSL_LOG_INTERNAL_CHECK(::absl::implicit_cast<const char* absl_nonnull>(     \
                              absl_log_internal_check_strop_result))           \
      .InternalStream()
#define ABSL_LOG_INTERNAL_QCHECK_STROP(func, op, expected, s1, s1_text, s2,    \
                                       s2_text)                                \
  while (const char* absl_nullable absl_log_internal_qcheck_strop_result =     \
             ::absl::log_internal::Check##func##expected##Impl(                \
                 (s1), (s2),                                                   \
                 ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(s1_text " " #op        \
                                                                " " s2_text))) \
    ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, true)                        \
  ABSL_LOG_INTERNAL_QCHECK(::absl::implicit_cast<const char* absl_nonnull>(    \
                               absl_log_internal_qcheck_strop_result))         \
      .InternalStream()

// This one is tricky:
// * We must evaluate `val` exactly once, yet we need to do two things with it:
//   evaluate `.ok()` and (sometimes) `.ToString()`.
// * `val` might be an `absl::Status` or some `absl::StatusOr<T>`.
// * `val` might be e.g. `ATemporary().GetStatus()`, which may return a
//   reference to a member of `ATemporary` that is only valid until the end of
//   the full expression.
// * We don't want this file to depend on `absl::Status` `#include`s or linkage,
//   nor do we want to move the definition to status and introduce a dependency
//   in the other direction.  We can be assured that callers must already have a
//   `Status` and the necessary `#include`s and linkage.
// * Callsites should be small and fast (at least when `val.ok()`): one branch,
//   minimal stack footprint.
//   * In particular, the string concat stuff should be out-of-line and emitted
//     in only one TU to save linker input size
// * We want the `val.ok()` check inline so static analyzers and optimizers can
//   see it.
// * 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* absl_nonnull,                     \
                   const char* absl_nullable>                              \
           absl_log_internal_check_ok_goo;                                 \
       absl_log_internal_check_ok_goo.first =                              \
           ::absl::log_internal::AsStatus(val),                            \
       absl_log_internal_check_ok_goo.second =                             \
           ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok())   \
               ? nullptr                                                   \
               : ::absl::status_internal::MakeCheckFailString(             \
                     absl_log_internal_check_ok_goo.first,                 \
                     ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(val_text       \
                                                            " is OK")),    \
       !ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok());)    \
    ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, true)                     \
  ABSL_LOG_INTERNAL_CHECK(::absl::implicit_cast<const char* absl_nonnull>( \
                              absl_log_internal_check_ok_goo.second))      \
      .InternalStream()
#define ABSL_LOG_INTERNAL_QCHECK_OK(val, val_text)                          \
  for (::std::pair<const ::absl::Status* absl_nonnull,                      \
                   const char* absl_nullable>                               \
           absl_log_internal_qcheck_ok_goo;                                 \
       absl_log_internal_qcheck_ok_goo.first =                              \
           ::absl::log_internal::AsStatus(val),                             \
       absl_log_internal_qcheck_ok_goo.second =                             \
           ABSL_PREDICT_TRUE(absl_log_internal_qcheck_ok_goo.first->ok())   \
               ? nullptr                                                    \
               : ::absl::status_internal::MakeCheckFailString(              \
                     absl_log_internal_qcheck_ok_goo.first,                 \
                     ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(val_text        \
                                                            " is OK")),     \
       !ABSL_PREDICT_TRUE(absl_log_internal_qcheck_ok_goo.first->ok());)    \
    ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, true)                     \
  ABSL_LOG_INTERNAL_QCHECK(::absl::implicit_cast<const char* absl_nonnull>( \
                               absl_log_internal_qcheck_ok_goo.second))     \
      .InternalStream()

namespace absl {
ABSL_NAMESPACE_BEGIN

class Status;
template <typename T>
class StatusOr;

namespace status_internal {
ABSL_ATTRIBUTE_PURE_FUNCTION const char* absl_nonnull MakeCheckFailString(
    const absl::Status* absl_nonnull status, const char* absl_nonnull prefix);
}  // namespace status_internal

namespace log_internal {

// Convert a Status or a StatusOr to its underlying status value.
//
// (This implementation does not require a dep on absl::Status to work.)
inline const absl::Status* absl_nonnull AsStatus(const absl::Status& s) {
  return &s;
}
template <typename T>
const absl::Status* absl_nonnull AsStatus(const absl::StatusOr<T>& s) {
  return &s.status();
}

// A helper class for formatting `expr (V1 vs. V2)` in a `CHECK_XX` statement.
// See `MakeCheckOpString` for sample usage.
class CheckOpMessageBuilder final {
 public:
  // Inserts `exprtext` and ` (` to the stream.
  explicit CheckOpMessageBuilder(const char* absl_nonnull exprtext);
  ~CheckOpMessageBuilder() = default;
  // For inserting the first variable.
  std::ostream& ForVar1() { return stream_; }
  // For inserting the second variable (adds an intermediate ` vs. `).
  std::ostream& ForVar2();
  // Get the result (inserts the closing `)`).
  const char* absl_nonnull NewString();

 private:
  std::ostringstream stream_;
};

// This formats a value for a failing `CHECK_XX` statement.  Ordinarily, it uses
// the definition for `operator<<`, with a few special cases below.
template <typename T>
inline void MakeCheckOpValueString(std::ostream& os, const T& v) {
  os << log_internal::NullGuard<T>::Guard(v);
}

// Overloads for char types provide readable values for unprintable characters.
void MakeCheckOpValueString(std::ostream& os, char v);
void MakeCheckOpValueString(std::ostream& os, signed char v);
void MakeCheckOpValueString(std::ostream& os, unsigned char v);
void MakeCheckOpValueString(std::ostream& os, const void* absl_nullable p);

namespace detect_specialization {

// MakeCheckOpString is being specialized for every T and U pair that is being
// passed to the CHECK_op macros. However, there is a lot of redundancy in these
// specializations that creates unnecessary library and binary bloat.
// The number of instantiations tends to be O(n^2) because we have two
// independent inputs. This technique works by reducing `n`.
//
// Most user-defined types being passed to CHECK_op end up being printed as a
// builtin type. For example, enums tend to be implicitly converted to its
// underlying type when calling operator<<, and pointers are printed with the
// `const void*` overload.
// To reduce the number of instantiations we coerce these values before calling
// MakeCheckOpString instead of inside it.
//
// To detect if this coercion is needed, we duplicate all the relevant
// operator<< overloads as specified in the standard, just in a different
// namespace. If the call to `stream << value` becomes ambiguous, it means that
// one of these overloads is the one selected by overload resolution. We then
// do overload resolution again just with our overload set to see which one gets
// selected. That tells us which type to coerce to.
// If the augmented call was not ambiguous, it means that none of these were
// selected and we can't coerce the input.
//
// As a secondary step to reduce code duplication, we promote integral types to
// their 64-bit variant. This does not change the printed value, but reduces the
// number of instantiations even further. Promoting an integer is very cheap at
// the call site.
int64_t operator<<(std::ostream&, short value);           // NOLINT
int64_t operator<<(std::ostream&, unsigned short value);  // NOLINT
int64_t operator<<(std::ostream&, int value);
int64_t operator<<(std::ostream&, unsigned int value);
int64_t operator<<(std::ostream&, long value);                 // NOLINT
uint64_t operator<<(std::ostream&, unsigned long value);       // NOLINT
int64_t operator<<(std::ostream&, long long value);            // NOLINT
uint64_t operator<<(std::ostream&, unsigned long long value);  // NOLINT
float operator<<(std::ostream&, float value);
double operator<<(std::ostream&, double value);
long double operator<<(std::ostream&, long double value);
bool operator<<(std::ostream&, bool value);
const void* absl_nullable operator<<(std::ostream&,
                                     const void* absl_nullable value);
const void* absl_nullable operator<<(std::ostream&, std::nullptr_t);

// These `char` overloads are specified like this in the standard, so we have to
// write them exactly the same to ensure the call is ambiguous.
// If we wrote it in a different way (eg taking std::ostream instead of the
// template) then one call might have a higher rank than the other and it would
// not be ambiguous.
template <typename Traits>
char operator<<(std::basic_ostream<char, Traits>&, char);
template <typename Traits>
signed char operator<<(std::basic_ostream<char, Traits>&, signed char);
template <typename Traits>
unsigned char operator<<(std::basic_ostream<char, Traits>&, unsigned char);
template <typename Traits>
const char* absl_nonnull operator<<(std::basic_ostream<char, Traits>&,
                                    const char* absl_nonnull);
template <typename Traits>
const signed char* absl_nonnull operator<<(std::basic_ostream<char, Traits>&,
                                           const signed char* absl_nonnull);
template <typename Traits>
const unsigned char* absl_nonnull operator<<(std::basic_ostream<char, Traits>&,
                                             const unsigned char* absl_nonnull);

// This overload triggers when the call is not ambiguous.
// It means that T is being printed with some overload not on this list.
// We keep the value as `const T&`.
template <typename T, typename = decltype(std::declval<std::ostream&>()
                                          << std::declval<const T&>())>
const T& Detect(int);

// This overload triggers when the call is ambiguous.
// It means that T is either one from this list or printed as one from this
// list. Eg an enum that decays to `int` for printing.
// We ask the overload set to give us the type we want to convert it to.
template <typename T>
decltype(detect_specialization::operator<<(std::declval<std::ostream&>(),
                                           std::declval<const T&>()))
Detect(char);

// A sink for AbslStringify which redirects everything to a std::ostream.
class StringifySink {
 public:
  explicit StringifySink(std::ostream& os ABSL_ATTRIBUTE_LIFETIME_BOUND);

  void Append(absl::string_view text);
  void Append(size_t length, char ch);
  friend void AbslFormatFlush(StringifySink* absl_nonnull sink,
                              absl::string_view text);

 private:
  std::ostream& os_;
};

// Wraps a type implementing AbslStringify, and implements operator<<.
template <typename T>
class StringifyToStreamWrapper {
 public:
  explicit StringifyToStreamWrapper(const T& v ABSL_ATTRIBUTE_LIFETIME_BOUND)
      : v_(v) {}

  friend std::ostream& operator<<(std::ostream& os,
                                  const StringifyToStreamWrapper& wrapper) {
    StringifySink sink(os);
    AbslStringify(sink, wrapper.v_);
    return os;
  }

 private:
  const T& v_;
};

// This overload triggers when T implements AbslStringify.
// StringifyToStreamWrapper is used to allow MakeCheckOpString to use
// operator<<.
template <typename T>
std::enable_if_t<HasAbslStringify<T>::value,
                 StringifyToStreamWrapper<T>>
Detect(...);  // Ellipsis has lowest preference when int passed.
}  // namespace detect_specialization

template <typename T>
using CheckOpStreamType = decltype(detect_specialization::Detect<T>(0));

// Build the error message string.  Specify no inlining for code size.
template <typename T1, typename T2>
ABSL_ATTRIBUTE_RETURNS_NONNULL const char* absl_nonnull MakeCheckOpString(
    T1 v1, T2 v2, const char* absl_nonnull exprtext) ABSL_ATTRIBUTE_NOINLINE;

template <typename T1, typename T2>
const char* absl_nonnull MakeCheckOpString(T1 v1, T2 v2,
                                           const char* absl_nonnull exprtext) {
  CheckOpMessageBuilder comb(exprtext);
  MakeCheckOpValueString(comb.ForVar1(), v1);
  MakeCheckOpValueString(comb.ForVar2(), v2);
  return comb.NewString();
}

// Add a few commonly used instantiations as extern to reduce size of objects
// files.
#define ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(x) \
  extern template const char* absl_nonnull MakeCheckOpString(   \
      x, x, const char* absl_nonnull)
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(bool);
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(int64_t);
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(uint64_t);
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(float);
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(double);
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(char);
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(unsigned char);
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const std::string&);
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const absl::string_view&);
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const char* absl_nonnull);
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(
    const signed char* absl_nonnull);
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(
    const unsigned char* absl_nonnull);
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const void* absl_nonnull);
#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)                     \
       : "")
#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
// type.
#define ABSL_LOG_INTERNAL_CHECK_OP_IMPL(name, op)                          \
  template <typename T1, typename T2>                                      \
  inline constexpr const char* absl_nullable name##Impl(                   \
      const T1& v1, const T2& v2, const char* absl_nonnull exprtext) {     \
    using U1 = CheckOpStreamType<T1>;                                      \
    using U2 = CheckOpStreamType<T2>;                                      \
    return ABSL_PREDICT_TRUE(v1 op v2)                                     \
               ? nullptr                                                   \
               : ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT(U1, U2, U1(v1),    \
                                                        U2(v2), exprtext); \
  }                                                                        \
  inline constexpr const char* absl_nullable name##Impl(                   \
      int v1, int v2, const char* absl_nonnull exprtext) {                 \
    return name##Impl<int, int>(v1, v2, exprtext);                         \
  }

ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_EQ, ==)
ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_NE, !=)
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

const char* absl_nullable CheckstrcmptrueImpl(
    const char* absl_nullable s1, const char* absl_nullable s2,
    const char* absl_nonnull exprtext);
const char* absl_nullable CheckstrcmpfalseImpl(
    const char* absl_nullable s1, const char* absl_nullable s2,
    const char* absl_nonnull exprtext);
const char* absl_nullable CheckstrcasecmptrueImpl(
    const char* absl_nullable s1, const char* absl_nullable s2,
    const char* absl_nonnull exprtext);
const char* absl_nullable CheckstrcasecmpfalseImpl(
    const char* absl_nullable s1, const char* absl_nullable s2,
    const char* absl_nonnull exprtext);

// `CHECK_EQ` and friends want to pass their arguments by reference, however
// this winds up exposing lots of cases where people have defined and
// initialized static const data members but never declared them (i.e. in a .cc
// file), meaning they are not referenceable.  This function avoids that problem
// for integers (the most common cases) by overloading for every primitive
// integer type, even the ones we discourage, and returning them by value.
// NOLINTBEGIN(runtime/int)
// NOLINTBEGIN(google-runtime-int)
template <typename T>
inline constexpr const T& GetReferenceableValue(const T& t) {
  return t;
}
inline constexpr char GetReferenceableValue(char t) { return t; }
inline constexpr unsigned char GetReferenceableValue(unsigned char t) {
  return t;
}
inline constexpr signed char GetReferenceableValue(signed char t) { return t; }
inline constexpr short GetReferenceableValue(short t) { return t; }
inline constexpr unsigned short GetReferenceableValue(unsigned short t) {
  return t;
}
inline constexpr int GetReferenceableValue(int t) { return t; }
inline constexpr unsigned int GetReferenceableValue(unsigned int t) {
  return t;
}
inline constexpr long GetReferenceableValue(long t) { return t; }
inline constexpr unsigned long GetReferenceableValue(unsigned long t) {
  return t;
}
inline constexpr long long GetReferenceableValue(long long t) { return t; }
inline constexpr unsigned long long GetReferenceableValue(
    unsigned long long t) {
  return t;
}
// NOLINTEND(google-runtime-int)
// NOLINTEND(runtime/int)

}  // namespace log_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_LOG_INTERNAL_CHECK_OP_H_
*õ²
msoong/.intermediates/external/abseil-cpp/absl_strings_cord_hdrs/gen/my_include_dir/absl/strings/cord_buffer.h‚²// Copyright 2021 The Abseil Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// File: cord_buffer.h
// -----------------------------------------------------------------------------
//
// This file defines an `absl::CordBuffer` data structure to hold data for
// eventual inclusion within an existing `Cord` data structure. Cord buffers are
// useful for building large Cords that may require custom allocation of its
// associated memory.
//
#ifndef ABSL_STRINGS_CORD_BUFFER_H_
#define ABSL_STRINGS_CORD_BUFFER_H_

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <utility>

#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/numeric/bits.h"
#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_flat.h"
#include "absl/types/span.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

class Cord;
class CordBufferTestPeer;

// CordBuffer
//
// CordBuffer manages memory buffers for purposes such as zero-copy APIs as well
// as applications building cords with large data requiring granular control
// over the allocation and size of cord data. For example, a function creating
// a cord of random data could use a CordBuffer as follows:
//
//   absl::Cord CreateRandomCord(size_t length) {
//     absl::Cord cord;
//     while (length > 0) {
//       CordBuffer buffer = CordBuffer::CreateWithDefaultLimit(length);
//       absl::Span<char> data = buffer.available_up_to(length);
//       FillRandomValues(data.data(), data.size());
//       buffer.IncreaseLengthBy(data.size());
//       cord.Append(std::move(buffer));
//       length -= data.size();
//     }
//     return cord;
//   }
//
// CordBuffer instances are by default limited to a capacity of `kDefaultLimit`
// bytes. `kDefaultLimit` is currently just under 4KiB, but this default may
// change in the future and/or for specific architectures. The default limit is
// aimed to provide a good trade-off between performance and memory overhead.
// Smaller buffers typically incur more compute cost while larger buffers are
// more CPU efficient but create significant memory overhead because of such
// allocations being less granular. Using larger buffers may also increase the
// risk of memory fragmentation.
//
// Applications create a buffer using one of the `CreateWithDefaultLimit()` or
// `CreateWithCustomLimit()` methods. The returned instance will have a non-zero
// capacity and a zero length. Applications use the `data()` method to set the
// contents of the managed memory, and once done filling the buffer, use the
// `IncreaseLengthBy()` or 'SetLength()' method to specify the length of the
// initialized data before adding the buffer to a Cord.
//
// The `CreateWithCustomLimit()` method is intended for applications needing
// larger buffers than the default memory limit, allowing the allocation of up
// to a capacity of `kCustomLimit` bytes minus some minimum internal overhead.
// The usage of `CreateWithCustomLimit()` should be limited to only those use
// cases where the distribution of the input is relatively well known, and/or
// where the trade-off between the efficiency gains outweigh the risk of memory
// fragmentation. See the documentation for `CreateWithCustomLimit()` for more
// information on using larger custom limits.
//
// The capacity of a `CordBuffer` returned by one of the `Create` methods may
// be larger than the requested capacity due to rounding, alignment and
// granularity of the memory allocator. Applications should use the `capacity`
// method to obtain the effective capacity of the returned instance as
// demonstrated in the provided example above.
//
// CordBuffer is a move-only class. All references into the managed memory are
// invalidated when an instance is moved into either another CordBuffer instance
// or a Cord. Writing to a location obtained by a previous call to `data()`
// after an instance was moved will lead to undefined behavior.
//
// A `moved from` CordBuffer instance will have a valid, but empty state.
// CordBuffer is thread compatible.
class CordBuffer {
 public:
  // kDefaultLimit
  //
  // Default capacity limits of allocated CordBuffers.
  // See the class comments for more information on allocation limits.
  static constexpr size_t kDefaultLimit = cord_internal::kMaxFlatLength;

  // kCustomLimit
  //
  // Maximum size for CreateWithCustomLimit() allocated buffers.
  // Note that the effective capacity may be slightly less
  // because of internal overhead of internal cord buffers.
  static constexpr size_t kCustomLimit = 64U << 10;

  // Constructors, Destructors and Assignment Operators

  // Creates an empty CordBuffer.
  CordBuffer() = default;

  // Destroys this CordBuffer instance and, if not empty, releases any memory
  // managed by this instance, invalidating previously returned references.
  ~CordBuffer();

  // CordBuffer is move-only
  CordBuffer(CordBuffer&& rhs) noexcept;
  CordBuffer& operator=(CordBuffer&&) noexcept;
  CordBuffer(const CordBuffer&) = delete;
  CordBuffer& operator=(const CordBuffer&) = delete;

  // CordBuffer::MaximumPayload()
  //
  // Returns the guaranteed maximum payload for a CordBuffer returned by the
  // `CreateWithDefaultLimit()` method. While small, each internal buffer inside
  // a Cord incurs an overhead to manage the length, type and reference count
  // for the buffer managed inside the cord tree. Applications can use this
  // method to get approximate number of buffers required for a given byte
  // size, etc.
  //
  // For example:
  //   const size_t payload = absl::CordBuffer::MaximumPayload();
  //   const size_t buffer_count = (total_size + payload - 1) / payload;
  //   buffers.reserve(buffer_count);
  static constexpr size_t MaximumPayload();

  // Overload to the above `MaximumPayload()` except that it returns the
  // maximum payload for a CordBuffer returned by the `CreateWithCustomLimit()`
  // method given the provided `block_size`.
  static constexpr size_t MaximumPayload(size_t block_size);

  // CordBuffer::CreateWithDefaultLimit()
  //
  // Creates a CordBuffer instance of the desired `capacity`, capped at the
  // default limit `kDefaultLimit`. The returned buffer has a guaranteed
  // capacity of at least `min(kDefaultLimit, capacity)`. See the class comments
  // for more information on buffer capacities and intended usage.
  static CordBuffer CreateWithDefaultLimit(size_t capacity);

  // CordBuffer::CreateWithCustomLimit()
  //
  // Creates a CordBuffer instance of the desired `capacity` rounded to an
  // appropriate power of 2 size less than, or equal to `block_size`.
  // Requires `block_size` to be a power of 2.
  //
  // If `capacity` is less than or equal to `kDefaultLimit`, then this method
  // behaves identical to `CreateWithDefaultLimit`, which means that the caller
  // is guaranteed to get a buffer of at least the requested capacity.
  //
  // If `capacity` is greater than or equal to `block_size`, then this method
  // returns a buffer with an `allocated size` of `block_size` bytes. Otherwise,
  // this methods returns a buffer with a suitable smaller power of 2 block size
  // to satisfy the request. The actual size depends on a number of factors, and
  // is typically (but not necessarily) the highest or second highest power of 2
  // value less than or equal to `capacity`.
  //
  // The 'allocated size' includes a small amount of overhead required for
  // internal state, which is currently 13 bytes on 64-bit platforms. For
  // example: a buffer created with `block_size` and `capacity' set to 8KiB
  // will have an allocated size of 8KiB, and an effective internal `capacity`
  // of 8KiB - 13 = 8179 bytes.
  //
  // To demonstrate this in practice, let's assume we want to read data from
  // somewhat larger files using approximately 64KiB buffers:
  //
  //   absl::Cord ReadFromFile(int fd, size_t n) {
  //     absl::Cord cord;
  //     while (n > 0) {
  //       CordBuffer buffer = CordBuffer::CreateWithCustomLimit(64 << 10, n);
  //       absl::Span<char> data = buffer.available_up_to(n);
  //       ReadFileDataOrDie(fd, data.data(), data.size());
  //       buffer.IncreaseLengthBy(data.size());
  //       cord.Append(std::move(buffer));
  //       n -= data.size();
  //     }
  //     return cord;
  //   }
  //
  // If we'd use this function to read a file of 659KiB, we may get the
  // following pattern of allocated cord buffer sizes:
  //
  //   CreateWithCustomLimit(64KiB, 674816) --> ~64KiB (65523)
  //   CreateWithCustomLimit(64KiB, 674816) --> ~64KiB (65523)
  //   ...
  //   CreateWithCustomLimit(64KiB,  19586) --> ~16KiB (16371)
  //   CreateWithCustomLimit(64KiB,   3215) -->   3215 (at least 3215)
  //
  // The reason the method returns a 16K buffer instead of a roughly 19K buffer
  // is to reduce memory overhead and fragmentation risks. Using carefully
  // chosen power of 2 values reduces the entropy of allocated memory sizes.
  //
  // Additionally, let's assume we'd use the above function on files that are
  // generally smaller than 64K. If we'd use 'precise' sized buffers for such
  // files, than we'd get a very wide distribution of allocated memory sizes
  // rounded to 4K page sizes, and we'd end up with a lot of unused capacity.
  //
  // In general, application should only use custom sizes if the data they are
  // consuming or storing is expected to be many times the chosen block size,
  // and be based on objective data and performance metrics. For example, a
  // compress function may work faster and consume less CPU when using larger
  // buffers. Such an application should pick a size offering a reasonable
  // trade-off between expected data size, compute savings with larger buffers,
  // and the cost or fragmentation effect of larger buffers.
  // Applications must pick a reasonable spot on that curve, and make sure their
  // data meets their expectations in size distributions such as "mostly large".
  static CordBuffer CreateWithCustomLimit(size_t block_size, size_t capacity);

  // CordBuffer::available()
  //
  // Returns the span delineating the available capacity in this buffer
  // which is defined as `{ data() + length(), capacity() - length() }`.
  absl::Span<char> available();

  // CordBuffer::available_up_to()
  //
  // Returns the span delineating the available capacity in this buffer limited
  // to `size` bytes. This is equivalent to `available().subspan(0, size)`.
  absl::Span<char> available_up_to(size_t size);

  // CordBuffer::data()
  //
  // Returns a non-null reference to the data managed by this instance.
  // Applications are allowed to write up to `capacity` bytes of instance data.
  // CordBuffer data is uninitialized by default. Reading data from an instance
  // that has not yet been initialized will lead to undefined behavior.
  char* data();
  const char* data() const;

  // CordBuffer::length()
  //
  // Returns the length of this instance. The default length of a CordBuffer is
  // 0, indicating an 'empty' CordBuffer. Applications must specify the length
  // of the data in a CordBuffer before adding it to a Cord.
  size_t length() const;

  // CordBuffer::capacity()
  //
  // Returns the capacity of this instance. All instances have a non-zero
  // capacity: default and `moved from` instances have a small internal buffer.
  size_t capacity() const;

  // CordBuffer::IncreaseLengthBy()
  //
  // Increases the length of this buffer by the specified 'n' bytes.
  // Applications must make sure all data in this buffer up to the new length
  // has been initialized before adding a CordBuffer to a Cord: failure to do so
  // will lead to undefined behavior.  Requires `length() + n <= capacity()`.
  // Typically, applications will use 'available_up_to()` to get a span of the
  // desired capacity, and use `span.size()` to increase the length as in:
  //   absl::Span<char> span = buffer.available_up_to(desired);
  //   buffer.IncreaseLengthBy(span.size());
  //   memcpy(span.data(), src, span.size());
  //   etc...
  void IncreaseLengthBy(size_t n);

  // CordBuffer::SetLength()
  //
  // Sets the data length of this instance. Applications must make sure all data
  // of the specified length has been initialized before adding a CordBuffer to
  // a Cord: failure to do so will lead to undefined behavior.
  // Setting the length to a small value or zero does not release any memory
  // held by this CordBuffer instance. Requires `length <= capacity()`.
  // Applications should preferably use the `IncreaseLengthBy()` method above
  // in combination with the 'available()` or `available_up_to()` methods.
  void SetLength(size_t length);

 private:
  // Make sure we don't accidentally over promise.
  static_assert(kCustomLimit <= cord_internal::kMaxLargeFlatSize, "");

  // Assume the cost of an 'uprounded' allocation to CeilPow2(size) versus
  // the cost of allocating at least 1 extra flat <= 4KB:
  // - Flat overhead = 13 bytes
  // - Btree amortized cost / node =~ 13 bytes
  // - 64 byte granularity of tcmalloc at 4K =~ 32 byte average
  // CPU cost and efficiency requires we should at least 'save' something by
  // splitting, as a poor man's measure, we say the slop needs to be
  // at least double the cost offset to make it worth splitting: ~128 bytes.
  static constexpr size_t kMaxPageSlop = 128;

  // Overhead for allocation a flat.
  static constexpr size_t kOverhead = cord_internal::kFlatOverhead;

  using CordRepFlat = cord_internal::CordRepFlat;

  // `Rep` is the internal data representation of a CordBuffer. The internal
  // representation has an internal small size optimization similar to
  // std::string (SSO).
  struct Rep {
    // Inline SSO size of a CordBuffer
    static constexpr size_t kInlineCapacity = sizeof(intptr_t) * 2 - 1;

    // Creates a default instance with kInlineCapacity.
    Rep() : short_rep{} {}

    // Creates an instance managing an allocated non zero CordRep.
    explicit Rep(cord_internal::CordRepFlat* rep) : long_rep{rep} {
      assert(rep != nullptr);
    }

    // Returns true if this instance manages the SSO internal buffer.
    bool is_short() const {
      constexpr size_t offset = offsetof(Short, raw_size);
      return (reinterpret_cast<const char*>(this)[offset] & 1) != 0;
    }

    // Returns the available area of the internal SSO data
    absl::Span<char> short_available() {
      const size_t length = short_length();
      return absl::Span<char>(short_rep.data + length,
                              kInlineCapacity - length);
    }

    // Returns the available area of the internal SSO data
    absl::Span<char> long_available() const {
      assert(!is_short());
      const size_t length = long_rep.rep->length;
      return absl::Span<char>(long_rep.rep->Data() + length,
                              long_rep.rep->Capacity() - length);
    }

    // Returns the length of the internal SSO data.
    size_t short_length() const {
      assert(is_short());
      return static_cast<size_t>(short_rep.raw_size >> 1);
    }

    // Sets the length of the internal SSO data.
    // Disregards any previously set CordRep instance.
    void set_short_length(size_t length) {
      short_rep.raw_size = static_cast<char>((length << 1) + 1);
    }

    // Adds `n` to the current short length.
    void add_short_length(size_t n) {
      assert(is_short());
      short_rep.raw_size += static_cast<char>(n << 1);
    }

    // Returns reference to the internal SSO data buffer.
    char* data() {
      assert(is_short());
      return short_rep.data;
    }
    const char* data() const {
      assert(is_short());
      return short_rep.data;
    }

    // Returns a pointer the external CordRep managed by this instance.
    cord_internal::CordRepFlat* rep() const {
      assert(!is_short());
      return long_rep.rep;
    }

    // The internal representation takes advantage of the fact that allocated
    // memory is always on an even address, and uses the least significant bit
    // of the first or last byte (depending on endianness) as the inline size
    // indicator overlapping with the least significant byte of the CordRep*.
#if defined(ABSL_IS_BIG_ENDIAN)
    struct Long {
      explicit Long(cord_internal::CordRepFlat* rep_arg) : rep(rep_arg) {}
      void* padding;
      cord_internal::CordRepFlat* rep;
    };
    struct Short {
      char data[sizeof(Long) - 1];
      char raw_size = 1;
    };
#else
    struct Long {
      explicit Long(cord_internal::CordRepFlat* rep_arg) : rep(rep_arg) {}
      cord_internal::CordRepFlat* rep;
      void* padding;
    };
    struct Short {
      char raw_size = 1;
      char data[sizeof(Long) - 1];
    };
#endif

    union {
      Long long_rep;
      Short short_rep;
    };
  };

  // Power2 functions
  static bool IsPow2(size_t size) { return absl::has_single_bit(size); }
  static size_t Log2Floor(size_t size) {
    return static_cast<size_t>(absl::bit_width(size) - 1);
  }
  static size_t Log2Ceil(size_t size) {
    return static_cast<size_t>(absl::bit_width(size - 1));
  }

  // Implementation of `CreateWithCustomLimit()`.
  // This implementation allows for future memory allocation hints to
  // be passed down into the CordRepFlat allocation function.
  template <typename... AllocationHints>
  static CordBuffer CreateWithCustomLimitImpl(size_t block_size,
                                              size_t capacity,
                                              AllocationHints... hints);

  // Consumes the value contained in this instance and resets the instance.
  // This method returns a non-null Cordrep* if the current instances manages a
  // CordRep*, and resets the instance to an empty SSO instance. If the current
  // instance is an SSO instance, then this method returns nullptr and sets
  // `short_value` to the inlined data value. In either case, the current
  // instance length is reset to zero.
  // This method is intended to be used by Cord internal functions only.
  cord_internal::CordRep* ConsumeValue(absl::string_view& short_value) {
    cord_internal::CordRep* rep = nullptr;
    if (rep_.is_short()) {
      short_value = absl::string_view(rep_.data(), rep_.short_length());
    } else {
      rep = rep_.rep();
    }
    rep_.set_short_length(0);
    return rep;
  }

  // Internal constructor.
  explicit CordBuffer(cord_internal::CordRepFlat* rep) : rep_(rep) {
    assert(rep != nullptr);
  }

  Rep rep_;

  friend class Cord;
  friend class CordBufferTestPeer;
};

inline constexpr size_t CordBuffer::MaximumPayload() {
  return cord_internal::kMaxFlatLength;
}

inline constexpr size_t CordBuffer::MaximumPayload(size_t block_size) {
  return (std::min)(kCustomLimit, block_size) - cord_internal::kFlatOverhead;
}

inline CordBuffer CordBuffer::CreateWithDefaultLimit(size_t capacity) {
  if (capacity > Rep::kInlineCapacity) {
    auto* rep = cord_internal::CordRepFlat::New(capacity);
    rep->length = 0;
    return CordBuffer(rep);
  }
  return CordBuffer();
}

template <typename... AllocationHints>
inline CordBuffer CordBuffer::CreateWithCustomLimitImpl(
    size_t block_size, size_t capacity, AllocationHints... hints) {
  assert(IsPow2(block_size));
  capacity = (std::min)(capacity, kCustomLimit);
  block_size = (std::min)(block_size, kCustomLimit);
  if (capacity + kOverhead >= block_size) {
    capacity = block_size;
  } else if (capacity <= kDefaultLimit) {
    capacity = capacity + kOverhead;
  } else if (!IsPow2(capacity)) {
    // Check if rounded up to next power 2 is a good enough fit
    // with limited waste making it an acceptable direct fit.
    const size_t rounded_up = size_t{1} << Log2Ceil(capacity);
    const size_t slop = rounded_up - capacity;
    if (slop >= kOverhead && slop <= kMaxPageSlop + kOverhead) {
      capacity = rounded_up;
    } else {
      // Round down to highest power of 2 <= capacity.
      // Consider a more aggressive step down if that may reduce the
      // risk of fragmentation where 'people are holding it wrong'.
      const size_t rounded_down = size_t{1} << Log2Floor(capacity);
      capacity = rounded_down;
    }
  }
  const size_t length = capacity - kOverhead;
  auto* rep = CordRepFlat::New(CordRepFlat::Large(), length, hints...);
  rep->length = 0;
  return CordBuffer(rep);
}

inline CordBuffer CordBuffer::CreateWithCustomLimit(size_t block_size,
                                                    size_t capacity) {
  return CreateWithCustomLimitImpl(block_size, capacity);
}

inline CordBuffer::~CordBuffer() {
  if (!rep_.is_short()) {
    cord_internal::CordRepFlat::Delete(rep_.rep());
  }
}

inline CordBuffer::CordBuffer(CordBuffer&& rhs) noexcept : rep_(rhs.rep_) {
  rhs.rep_.set_short_length(0);
}

inline CordBuffer& CordBuffer::operator=(CordBuffer&& rhs) noexcept {
  if (!rep_.is_short()) cord_internal::CordRepFlat::Delete(rep_.rep());
  rep_ = rhs.rep_;
  rhs.rep_.set_short_length(0);
  return *this;
}

inline absl::Span<char> CordBuffer::available() {
  return rep_.is_short() ? rep_.short_available() : rep_.long_available();
}

inline absl::Span<char> CordBuffer::available_up_to(size_t size) {
  return available().subspan(0, size);
}

inline char* CordBuffer::data() {
  return rep_.is_short() ? rep_.data() : rep_.rep()->Data();
}

inline const char* CordBuffer::data() const {
  return rep_.is_short() ? rep_.data() : rep_.rep()->Data();
}

inline size_t CordBuffer::capacity() const {
  return rep_.is_short() ? Rep::kInlineCapacity : rep_.rep()->Capacity();
}

inline size_t CordBuffer::length() const {
  return rep_.is_short() ? rep_.short_length() : rep_.rep()->length;
}

inline void CordBuffer::SetLength(size_t length) {
  ABSL_HARDENING_ASSERT(length <= capacity());
  if (rep_.is_short()) {
    rep_.set_short_length(length);
  } else {
    rep_.rep()->length = length;
  }
}

inline void CordBuffer::IncreaseLengthBy(size_t n) {
  ABSL_HARDENING_ASSERT(n <= capacity() && length() + n <= capacity());
  if (rep_.is_short()) {
    rep_.add_short_length(n);
  } else {
    rep_.rep()->length += n;
  }
}

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_CORD_BUFFER_H_
*Ñ
nsoong/.intermediates/external/abseil-cpp/absl_base_hdrs/gen/my_include_dir/absl/base/internal/per_thread_tls.hÞ// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_BASE_INTERNAL_PER_THREAD_TLS_H_
#define ABSL_BASE_INTERNAL_PER_THREAD_TLS_H_

// This header defines two macros:
//
// If the platform supports thread-local storage:
//
// * ABSL_PER_THREAD_TLS_KEYWORD is the C keyword needed to declare a
//   thread-local variable
// * ABSL_PER_THREAD_TLS is 1
//
// Otherwise:
//
// * ABSL_PER_THREAD_TLS_KEYWORD is empty
// * ABSL_PER_THREAD_TLS is 0
//
// Microsoft C supports thread-local storage.
// GCC supports it if the appropriate version of glibc is available,
// which the programmer can indicate by defining ABSL_HAVE_TLS

#include "absl/base/port.h"  // For ABSL_HAVE_TLS

#if defined(ABSL_PER_THREAD_TLS)
#error ABSL_PER_THREAD_TLS cannot be directly set
#elif defined(ABSL_PER_THREAD_TLS_KEYWORD)
#error ABSL_PER_THREAD_TLS_KEYWORD cannot be directly set
#elif defined(ABSL_HAVE_TLS)
#define ABSL_PER_THREAD_TLS_KEYWORD __thread
#define ABSL_PER_THREAD_TLS 1
#elif defined(_MSC_VER)
#define ABSL_PER_THREAD_TLS_KEYWORD __declspec(thread)
#define ABSL_PER_THREAD_TLS 1
#else
#define ABSL_PER_THREAD_TLS_KEYWORD
#define ABSL_PER_THREAD_TLS 0
#endif

#endif  // ABSL_BASE_INTERNAL_PER_THREAD_TLS_H_
*âª
œsoong/.intermediates/external/abseil-cpp/absl_time_internal_cctz_civil_time_hdrs/gen/my_include_dir/absl/time/internal/cctz/include/cctz/civil_time_detail.h¿©// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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_TIME_INTERNAL_CCTZ_CIVIL_TIME_DETAIL_H_
#define ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_DETAIL_H_

#include <cstdint>
#include <limits>
#include <ostream>
#include <type_traits>

#include "absl/base/config.h"

// Disable constexpr support unless we are in C++14 mode.
#if __cpp_constexpr >= 201304 || (defined(_MSC_VER) && _MSC_VER >= 1910)
#define CONSTEXPR_D constexpr  // data
#define CONSTEXPR_F constexpr  // function
#define CONSTEXPR_M constexpr  // member
#else
#define CONSTEXPR_D const
#define CONSTEXPR_F inline
#define CONSTEXPR_M
#endif

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace time_internal {
namespace cctz {

// Support years that at least span the range of 64-bit time_t values.
using year_t = std::int_fast64_t;

// Type alias that indicates an argument is not normalized (e.g., the
// constructor parameters and operands/results of addition/subtraction).
using diff_t = std::int_fast64_t;

namespace detail {

// Type aliases that indicate normalized argument values.
using month_t = std::int_fast8_t;   // [1:12]
using day_t = std::int_fast8_t;     // [1:31]
using hour_t = std::int_fast8_t;    // [0:23]
using minute_t = std::int_fast8_t;  // [0:59]
using second_t = std::int_fast8_t;  // [0:59]

// Normalized civil-time fields: Y-M-D HH:MM:SS.
struct fields {
  CONSTEXPR_M fields(year_t year, month_t month, day_t day, hour_t hour,
                     minute_t minute, second_t second)
      : y(year), m(month), d(day), hh(hour), mm(minute), ss(second) {}
  std::int_least64_t y;
  std::int_least8_t m;
  std::int_least8_t d;
  std::int_least8_t hh;
  std::int_least8_t mm;
  std::int_least8_t ss;
};

struct second_tag {};
struct minute_tag : second_tag {};
struct hour_tag : minute_tag {};
struct day_tag : hour_tag {};
struct month_tag : day_tag {};
struct year_tag : month_tag {};

////////////////////////////////////////////////////////////////////////

// Field normalization (without avoidable overflow).

namespace impl {

CONSTEXPR_F bool is_leap_year(year_t y) noexcept {
  return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0);
}
CONSTEXPR_F int year_index(year_t y, month_t m) noexcept {
  const int yi = static_cast<int>((y + (m > 2)) % 400);
  return yi < 0 ? yi + 400 : yi;
}
CONSTEXPR_F int days_per_century(int yi) noexcept {
  return 36524 + (yi == 0 || yi > 300);
}
CONSTEXPR_F int days_per_4years(int yi) noexcept {
  return 1460 + (yi == 0 || yi > 300 || (yi - 1) % 100 < 96);
}
CONSTEXPR_F int days_per_year(year_t y, month_t m) noexcept {
  return is_leap_year(y + (m > 2)) ? 366 : 365;
}
CONSTEXPR_F int days_per_month(year_t y, month_t m) noexcept {
  CONSTEXPR_D int k_days_per_month[1 + 12] = {
      -1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31  // non leap year
  };
  return k_days_per_month[m] + (m == 2 && is_leap_year(y));
}

CONSTEXPR_F fields n_day(year_t y, month_t m, diff_t d, diff_t cd, hour_t hh,
                         minute_t mm, second_t ss) noexcept {
  year_t ey = y % 400;
  const year_t oey = ey;
  ey += (cd / 146097) * 400;
  cd %= 146097;
  if (cd < 0) {
    ey -= 400;
    cd += 146097;
  }
  ey += (d / 146097) * 400;
  d = d % 146097 + cd;
  if (d > 0) {
    if (d > 146097) {
      ey += 400;
      d -= 146097;
    }
  } else {
    if (d > -365) {
      // We often hit the previous year when stepping a civil time backwards,
      // so special case it to avoid counting up by 100/4/1-year chunks.
      ey -= 1;
      d += days_per_year(ey, m);
    } else {
      ey -= 400;
      d += 146097;
    }
  }
  if (d > 365) {
    int yi = year_index(ey, m);  // Index into Gregorian 400 year cycle.
    for (;;) {
      int n = days_per_century(yi);
      if (d <= n) break;
      d -= n;
      ey += 100;
      yi += 100;
      if (yi >= 400) yi -= 400;
    }
    for (;;) {
      int n = days_per_4years(yi);
      if (d <= n) break;
      d -= n;
      ey += 4;
      yi += 4;
      if (yi >= 400) yi -= 400;
    }
    for (;;) {
      int n = days_per_year(ey, m);
      if (d <= n) break;
      d -= n;
      ++ey;
    }
  }
  if (d > 28) {
    for (;;) {
      int n = days_per_month(ey, m);
      if (d <= n) break;
      d -= n;
      if (++m > 12) {
        ++ey;
        m = 1;
      }
    }
  }
  return fields(y + (ey - oey), m, static_cast<day_t>(d), hh, mm, ss);
}
CONSTEXPR_F fields n_mon(year_t y, diff_t m, diff_t d, diff_t cd, hour_t hh,
                         minute_t mm, second_t ss) noexcept {
  if (m != 12) {
    y += m / 12;
    m %= 12;
    if (m <= 0) {
      y -= 1;
      m += 12;
    }
  }
  return n_day(y, static_cast<month_t>(m), d, cd, hh, mm, ss);
}
CONSTEXPR_F fields n_hour(year_t y, diff_t m, diff_t d, diff_t cd, diff_t hh,
                          minute_t mm, second_t ss) noexcept {
  cd += hh / 24;
  hh %= 24;
  if (hh < 0) {
    cd -= 1;
    hh += 24;
  }
  return n_mon(y, m, d, cd, static_cast<hour_t>(hh), mm, ss);
}
CONSTEXPR_F fields n_min(year_t y, diff_t m, diff_t d, diff_t hh, diff_t ch,
                         diff_t mm, second_t ss) noexcept {
  ch += mm / 60;
  mm %= 60;
  if (mm < 0) {
    ch -= 1;
    mm += 60;
  }
  return n_hour(y, m, d, hh / 24 + ch / 24, hh % 24 + ch % 24,
                static_cast<minute_t>(mm), ss);
}
CONSTEXPR_F fields n_sec(year_t y, diff_t m, diff_t d, diff_t hh, diff_t mm,
                         diff_t ss) noexcept {
  // Optimization for when (non-constexpr) fields are already normalized.
  if (0 <= ss && ss < 60) {
    const second_t nss = static_cast<second_t>(ss);
    if (0 <= mm && mm < 60) {
      const minute_t nmm = static_cast<minute_t>(mm);
      if (0 <= hh && hh < 24) {
        const hour_t nhh = static_cast<hour_t>(hh);
        if (1 <= d && d <= 28 && 1 <= m && m <= 12) {
          const day_t nd = static_cast<day_t>(d);
          const month_t nm = static_cast<month_t>(m);
          return fields(y, nm, nd, nhh, nmm, nss);
        }
        return n_mon(y, m, d, 0, nhh, nmm, nss);
      }
      return n_hour(y, m, d, hh / 24, hh % 24, nmm, nss);
    }
    return n_min(y, m, d, hh, mm / 60, mm % 60, nss);
  }
  diff_t cm = ss / 60;
  ss %= 60;
  if (ss < 0) {
    cm -= 1;
    ss += 60;
  }
  return n_min(y, m, d, hh, mm / 60 + cm / 60, mm % 60 + cm % 60,
               static_cast<second_t>(ss));
}

}  // namespace impl

////////////////////////////////////////////////////////////////////////

// Increments the indicated (normalized) field by "n".
CONSTEXPR_F fields step(second_tag, fields f, diff_t n) noexcept {
  return impl::n_sec(f.y, f.m, f.d, f.hh, f.mm + n / 60, f.ss + n % 60);
}
CONSTEXPR_F fields step(minute_tag, fields f, diff_t n) noexcept {
  return impl::n_min(f.y, f.m, f.d, f.hh + n / 60, 0, f.mm + n % 60, f.ss);
}
CONSTEXPR_F fields step(hour_tag, fields f, diff_t n) noexcept {
  return impl::n_hour(f.y, f.m, f.d + n / 24, 0, f.hh + n % 24, f.mm, f.ss);
}
CONSTEXPR_F fields step(day_tag, fields f, diff_t n) noexcept {
  return impl::n_day(f.y, f.m, f.d, n, f.hh, f.mm, f.ss);
}
CONSTEXPR_F fields step(month_tag, fields f, diff_t n) noexcept {
  return impl::n_mon(f.y + n / 12, f.m + n % 12, f.d, 0, f.hh, f.mm, f.ss);
}
CONSTEXPR_F fields step(year_tag, fields f, diff_t n) noexcept {
  return fields(f.y + n, f.m, f.d, f.hh, f.mm, f.ss);
}

////////////////////////////////////////////////////////////////////////

namespace impl {

// Returns (v * f + a) but avoiding intermediate overflow when possible.
CONSTEXPR_F diff_t scale_add(diff_t v, diff_t f, diff_t a) noexcept {
  return (v < 0) ? ((v + 1) * f + a) - f : ((v - 1) * f + a) + f;
}

// Map a (normalized) Y/M/D to the number of days before/after 1970-01-01.
// Probably overflows for years outside [-292277022656:292277026595].
CONSTEXPR_F diff_t ymd_ord(year_t y, month_t m, day_t d) noexcept {
  const diff_t eyear = (m <= 2) ? y - 1 : y;
  const diff_t era = (eyear >= 0 ? eyear : eyear - 399) / 400;
  const diff_t yoe = eyear - era * 400;
  const diff_t doy = (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + d - 1;
  const diff_t doe = yoe * 365 + yoe / 4 - yoe / 100 + doy;
  return era * 146097 + doe - 719468;
}

// Returns the difference in days between two normalized Y-M-D tuples.
// ymd_ord() will encounter integer overflow given extreme year values,
// yet the difference between two such extreme values may actually be
// small, so we take a little care to avoid overflow when possible by
// exploiting the 146097-day cycle.
CONSTEXPR_F diff_t day_difference(year_t y1, month_t m1, day_t d1, year_t y2,
                                  month_t m2, day_t d2) noexcept {
  const diff_t a_c4_off = y1 % 400;
  const diff_t b_c4_off = y2 % 400;
  diff_t c4_diff = (y1 - a_c4_off) - (y2 - b_c4_off);
  diff_t delta = ymd_ord(a_c4_off, m1, d1) - ymd_ord(b_c4_off, m2, d2);
  if (c4_diff > 0 && delta < 0) {
    delta += 2 * 146097;
    c4_diff -= 2 * 400;
  } else if (c4_diff < 0 && delta > 0) {
    delta -= 2 * 146097;
    c4_diff += 2 * 400;
  }
  return (c4_diff / 400 * 146097) + delta;
}

}  // namespace impl

// Returns the difference between fields structs using the indicated unit.
CONSTEXPR_F diff_t difference(year_tag, fields f1, fields f2) noexcept {
  return f1.y - f2.y;
}
CONSTEXPR_F diff_t difference(month_tag, fields f1, fields f2) noexcept {
  return impl::scale_add(difference(year_tag{}, f1, f2), 12, (f1.m - f2.m));
}
CONSTEXPR_F diff_t difference(day_tag, fields f1, fields f2) noexcept {
  return impl::day_difference(f1.y, f1.m, f1.d, f2.y, f2.m, f2.d);
}
CONSTEXPR_F diff_t difference(hour_tag, fields f1, fields f2) noexcept {
  return impl::scale_add(difference(day_tag{}, f1, f2), 24, (f1.hh - f2.hh));
}
CONSTEXPR_F diff_t difference(minute_tag, fields f1, fields f2) noexcept {
  return impl::scale_add(difference(hour_tag{}, f1, f2), 60, (f1.mm - f2.mm));
}
CONSTEXPR_F diff_t difference(second_tag, fields f1, fields f2) noexcept {
  return impl::scale_add(difference(minute_tag{}, f1, f2), 60, f1.ss - f2.ss);
}

////////////////////////////////////////////////////////////////////////

// Aligns the (normalized) fields struct to the indicated field.
CONSTEXPR_F fields align(second_tag, fields f) noexcept { return f; }
CONSTEXPR_F fields align(minute_tag, fields f) noexcept {
  return fields{f.y, f.m, f.d, f.hh, f.mm, 0};
}
CONSTEXPR_F fields align(hour_tag, fields f) noexcept {
  return fields{f.y, f.m, f.d, f.hh, 0, 0};
}
CONSTEXPR_F fields align(day_tag, fields f) noexcept {
  return fields{f.y, f.m, f.d, 0, 0, 0};
}
CONSTEXPR_F fields align(month_tag, fields f) noexcept {
  return fields{f.y, f.m, 1, 0, 0, 0};
}
CONSTEXPR_F fields align(year_tag, fields f) noexcept {
  return fields{f.y, 1, 1, 0, 0, 0};
}

////////////////////////////////////////////////////////////////////////

namespace impl {

template <typename H>
H AbslHashValueImpl(second_tag, H h, fields f) {
  return H::combine(std::move(h), f.y, f.m, f.d, f.hh, f.mm, f.ss);
}
template <typename H>
H AbslHashValueImpl(minute_tag, H h, fields f) {
  return H::combine(std::move(h), f.y, f.m, f.d, f.hh, f.mm);
}
template <typename H>
H AbslHashValueImpl(hour_tag, H h, fields f) {
  return H::combine(std::move(h), f.y, f.m, f.d, f.hh);
}
template <typename H>
H AbslHashValueImpl(day_tag, H h, fields f) {
  return H::combine(std::move(h), f.y, f.m, f.d);
}
template <typename H>
H AbslHashValueImpl(month_tag, H h, fields f) {
  return H::combine(std::move(h), f.y, f.m);
}
template <typename H>
H AbslHashValueImpl(year_tag, H h, fields f) {
  return H::combine(std::move(h), f.y);
}

}  // namespace impl

////////////////////////////////////////////////////////////////////////

template <typename T>
class civil_time {
 public:
  explicit CONSTEXPR_M civil_time(year_t y, diff_t m = 1, diff_t d = 1,
                                  diff_t hh = 0, diff_t mm = 0,
                                  diff_t ss = 0) noexcept
      : civil_time(impl::n_sec(y, m, d, hh, mm, ss)) {}

  CONSTEXPR_M civil_time() noexcept : f_{1970, 1, 1, 0, 0, 0} {}
  civil_time(const civil_time&) = default;
  civil_time& operator=(const civil_time&) = default;

  // Conversion between civil times of different alignment. Conversion to
  // a more precise alignment is allowed implicitly (e.g., day -> hour),
  // but conversion where information is discarded must be explicit
  // (e.g., second -> minute).
  template <typename U, typename S>
  using preserves_data =
      typename std::enable_if<std::is_base_of<U, S>::value>::type;
  template <typename U>
  CONSTEXPR_M civil_time(const civil_time<U>& ct,
                         preserves_data<T, U>* = nullptr) noexcept
      : civil_time(ct.f_) {}
  template <typename U>
  explicit CONSTEXPR_M civil_time(const civil_time<U>& ct,
                                  preserves_data<U, T>* = nullptr) noexcept
      : civil_time(ct.f_) {}

  // Factories for the maximum/minimum representable civil_time.
  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 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);
  }

  // Field accessors.  Note: All but year() return an int.
  CONSTEXPR_M year_t year() const noexcept { return f_.y; }
  CONSTEXPR_M int month() const noexcept { return f_.m; }
  CONSTEXPR_M int day() const noexcept { return f_.d; }
  CONSTEXPR_M int hour() const noexcept { return f_.hh; }
  CONSTEXPR_M int minute() const noexcept { return f_.mm; }
  CONSTEXPR_M int second() const noexcept { return f_.ss; }

  // Assigning arithmetic.
  CONSTEXPR_M civil_time& operator+=(diff_t n) noexcept {
    return *this = *this + n;
  }
  CONSTEXPR_M civil_time& operator-=(diff_t n) noexcept {
    return *this = *this - n;
  }
  CONSTEXPR_M civil_time& operator++() noexcept { return *this += 1; }
  CONSTEXPR_M civil_time operator++(int) noexcept {
    const civil_time a = *this;
    ++*this;
    return a;
  }
  CONSTEXPR_M civil_time& operator--() noexcept { return *this -= 1; }
  CONSTEXPR_M civil_time operator--(int) noexcept {
    const civil_time a = *this;
    --*this;
    return a;
  }

  // Binary arithmetic operators.
  friend CONSTEXPR_F civil_time operator+(civil_time a, diff_t n) noexcept {
    return civil_time(step(T{}, a.f_, n));
  }
  friend CONSTEXPR_F civil_time operator+(diff_t n, civil_time a) noexcept {
    return a + n;
  }
  friend CONSTEXPR_F civil_time operator-(civil_time a, diff_t n) noexcept {
    return n != (std::numeric_limits<diff_t>::min)()
               ? civil_time(step(T{}, a.f_, -n))
               : civil_time(step(T{}, step(T{}, a.f_, -(n + 1)), 1));
  }
  friend CONSTEXPR_F diff_t operator-(civil_time lhs, civil_time rhs) noexcept {
    return difference(T{}, lhs.f_, rhs.f_);
  }

  template <typename H>
  friend H AbslHashValue(H h, civil_time a) {
    return impl::AbslHashValueImpl(T{}, std::move(h), a.f_);
  }

 private:
  // All instantiations of this template are allowed to call the following
  // private constructor and access the private fields member.
  template <typename U>
  friend class civil_time;

  // The designated constructor that all others eventually call.
  explicit CONSTEXPR_M civil_time(fields f) noexcept : f_(align(T{}, f)) {}

  fields f_;
};

// Disallows difference between differently aligned types.
// auto n = civil_day(...) - civil_hour(...);  // would be confusing.
template <typename T, typename U>
CONSTEXPR_F diff_t operator-(civil_time<T>, civil_time<U>) = delete;

using civil_year = civil_time<year_tag>;
using civil_month = civil_time<month_tag>;
using civil_day = civil_time<day_tag>;
using civil_hour = civil_time<hour_tag>;
using civil_minute = civil_time<minute_tag>;
using civil_second = civil_time<second_tag>;

////////////////////////////////////////////////////////////////////////

// Relational operators that work with differently aligned objects.
// Always compares all six fields.
template <typename T1, typename T2>
CONSTEXPR_F bool operator<(const civil_time<T1>& lhs,
                           const civil_time<T2>& rhs) noexcept {
  return (
      lhs.year() < rhs.year() ||
      (lhs.year() == rhs.year() &&
       (lhs.month() < rhs.month() ||
        (lhs.month() == rhs.month() &&
         (lhs.day() < rhs.day() || (lhs.day() == rhs.day() &&
                                    (lhs.hour() < rhs.hour() ||
                                     (lhs.hour() == rhs.hour() &&
                                      (lhs.minute() < rhs.minute() ||
                                       (lhs.minute() == rhs.minute() &&
                                        (lhs.second() < rhs.second())))))))))));
}
template <typename T1, typename T2>
CONSTEXPR_F bool operator<=(const civil_time<T1>& lhs,
                            const civil_time<T2>& rhs) noexcept {
  return !(rhs < lhs);
}
template <typename T1, typename T2>
CONSTEXPR_F bool operator>=(const civil_time<T1>& lhs,
                            const civil_time<T2>& rhs) noexcept {
  return !(lhs < rhs);
}
template <typename T1, typename T2>
CONSTEXPR_F bool operator>(const civil_time<T1>& lhs,
                           const civil_time<T2>& rhs) noexcept {
  return rhs < lhs;
}
template <typename T1, typename T2>
CONSTEXPR_F bool operator==(const civil_time<T1>& lhs,
                            const civil_time<T2>& rhs) noexcept {
  return lhs.year() == rhs.year() && lhs.month() == rhs.month() &&
         lhs.day() == rhs.day() && lhs.hour() == rhs.hour() &&
         lhs.minute() == rhs.minute() && lhs.second() == rhs.second();
}
template <typename T1, typename T2>
CONSTEXPR_F bool operator!=(const civil_time<T1>& lhs,
                            const civil_time<T2>& rhs) noexcept {
  return !(lhs == rhs);
}

////////////////////////////////////////////////////////////////////////

enum class weekday {
  monday,
  tuesday,
  wednesday,
  thursday,
  friday,
  saturday,
  sunday,
};

CONSTEXPR_F weekday get_weekday(const civil_second& cs) noexcept {
  CONSTEXPR_D weekday k_weekday_by_mon_off[13] = {
      weekday::monday,    weekday::tuesday,  weekday::wednesday,
      weekday::thursday,  weekday::friday,   weekday::saturday,
      weekday::sunday,    weekday::monday,   weekday::tuesday,
      weekday::wednesday, weekday::thursday, weekday::friday,
      weekday::saturday,
  };
  CONSTEXPR_D int k_weekday_offsets[1 + 12] = {
      -1, 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4,
  };
  year_t wd = 2400 + (cs.year() % 400) - (cs.month() < 3);
  wd += wd / 4 - wd / 100 + wd / 400;
  wd += k_weekday_offsets[cs.month()] + cs.day();
  return k_weekday_by_mon_off[wd % 7 + 6];
}

////////////////////////////////////////////////////////////////////////

CONSTEXPR_F civil_day next_weekday(civil_day cd, weekday wd) noexcept {
  CONSTEXPR_D weekday k_weekdays_forw[14] = {
      weekday::monday,    weekday::tuesday,  weekday::wednesday,
      weekday::thursday,  weekday::friday,   weekday::saturday,
      weekday::sunday,    weekday::monday,   weekday::tuesday,
      weekday::wednesday, weekday::thursday, weekday::friday,
      weekday::saturday,  weekday::sunday,
  };
  weekday base = get_weekday(cd);
  for (int i = 0;; ++i) {
    if (base == k_weekdays_forw[i]) {
      for (int j = i + 1;; ++j) {
        if (wd == k_weekdays_forw[j]) {
          return cd + (j - i);
        }
      }
    }
  }
}

CONSTEXPR_F civil_day prev_weekday(civil_day cd, weekday wd) noexcept {
  CONSTEXPR_D weekday k_weekdays_back[14] = {
      weekday::sunday,   weekday::saturday,  weekday::friday,
      weekday::thursday, weekday::wednesday, weekday::tuesday,
      weekday::monday,   weekday::sunday,    weekday::saturday,
      weekday::friday,   weekday::thursday,  weekday::wednesday,
      weekday::tuesday,  weekday::monday,
  };
  weekday base = get_weekday(cd);
  for (int i = 0;; ++i) {
    if (base == k_weekdays_back[i]) {
      for (int j = i + 1;; ++j) {
        if (wd == k_weekdays_back[j]) {
          return cd - (j - i);
        }
      }
    }
  }
}

CONSTEXPR_F int get_yearday(const civil_second& cs) noexcept {
  CONSTEXPR_D int k_month_offsets[1 + 12] = {
      -1, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
  };
  const int feb29 = (cs.month() > 2 && impl::is_leap_year(cs.year()));
  return k_month_offsets[cs.month()] + feb29 + cs.day();
}

////////////////////////////////////////////////////////////////////////

std::ostream& operator<<(std::ostream& os, const civil_year& y);
std::ostream& operator<<(std::ostream& os, const civil_month& m);
std::ostream& operator<<(std::ostream& os, const civil_day& d);
std::ostream& operator<<(std::ostream& os, const civil_hour& h);
std::ostream& operator<<(std::ostream& os, const civil_minute& m);
std::ostream& operator<<(std::ostream& os, const civil_second& s);
std::ostream& operator<<(std::ostream& os, weekday wd);

}  // namespace detail
}  // namespace cctz
}  // namespace time_internal
ABSL_NAMESPACE_END
}  // namespace absl

#undef CONSTEXPR_M
#undef CONSTEXPR_F
#undef CONSTEXPR_D

#endif  // ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_DETAIL_H_
*ÎA
œsoong/.intermediates/external/abseil-cpp/absl_synchronization_kernel_timeout_internal_hdrs/gen/my_include_dir/absl/synchronization/internal/kernel_timeout.h¬@// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_SYNCHRONIZATION_INTERNAL_KERNEL_TIMEOUT_H_
#define ABSL_SYNCHRONIZATION_INTERNAL_KERNEL_TIMEOUT_H_

#ifndef _WIN32
#include <sys/types.h>
#endif

#include <algorithm>
#include <chrono>  // NOLINT(build/c++11)
#include <cstdint>
#include <ctime>
#include <limits>

#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace synchronization_internal {

// An optional timeout, with nanosecond granularity.
//
// This is a private low-level API for use by a handful of low-level
// components. Higher-level components should build APIs based on
// absl::Time and absl::Duration.
class KernelTimeout {
 public:
  // Construct an absolute timeout that should expire at `t`.
  explicit KernelTimeout(absl::Time t);

  // Construct a relative timeout that should expire after `d`.
  explicit KernelTimeout(absl::Duration d);

  // Infinite timeout.
  constexpr KernelTimeout() : rep_(kNoTimeout) {}

  // A more explicit factory for those who prefer it.
  // Equivalent to `KernelTimeout()`.
  static constexpr KernelTimeout Never() { return KernelTimeout(); }

  // Returns true if there is a timeout that will eventually expire.
  // Returns false if the timeout is infinite.
  bool has_timeout() const { return rep_ != kNoTimeout; }

  // If `has_timeout()` is true, returns true if the timeout was provided as an
  // `absl::Time`. The return value is undefined if `has_timeout()` is false
  // because all indefinite timeouts are equivalent.
  bool is_absolute_timeout() const { return (rep_ & 1) == 0; }

  // If `has_timeout()` is true, returns true if the timeout was provided as an
  // `absl::Duration`. The return value is undefined if `has_timeout()` is false
  // because all indefinite timeouts are equivalent.
  bool is_relative_timeout() const { return (rep_ & 1) == 1; }

  // Convert to `struct timespec` for interfaces that expect an absolute
  // timeout. If !has_timeout() or is_relative_timeout(), attempts to convert to
  // a reasonable absolute timeout, but callers should to test has_timeout() and
  // is_relative_timeout() and prefer to use a more appropriate interface.
  struct timespec MakeAbsTimespec() const;

  // Convert to `struct timespec` for interfaces that expect a relative
  // timeout. If !has_timeout() or is_absolute_timeout(), attempts to convert to
  // a reasonable relative timeout, but callers should to test has_timeout() and
  // is_absolute_timeout() and prefer to use a more appropriate interface. Since
  // the return value is a relative duration, it should be recomputed by calling
  // this method in the case of a spurious wakeup.
  struct timespec MakeRelativeTimespec() const;

#ifndef _WIN32
  // Convert to `struct timespec` for interfaces that expect an absolute timeout
  // on a specific clock `c`. This is similar to `MakeAbsTimespec()`, but
  // callers usually want to use this method with `CLOCK_MONOTONIC` when
  // relative timeouts are requested, and when the appropriate interface expects
  // an absolute timeout relative to a specific clock (for example,
  // pthread_cond_clockwait() or sem_clockwait()). If !has_timeout(), attempts
  // to convert to a reasonable absolute timeout, but callers should to test
  // has_timeout() prefer to use a more appropriate interface.
  struct timespec MakeClockAbsoluteTimespec(clockid_t c) const;
#endif

  // Convert to unix epoch nanos for interfaces that expect an absolute timeout
  // in nanoseconds. If !has_timeout() or is_relative_timeout(), attempts to
  // convert to a reasonable absolute timeout, but callers should to test
  // has_timeout() and is_relative_timeout() and prefer to use a more
  // appropriate interface.
  int64_t MakeAbsNanos() const;

  // Converts to milliseconds from now, or INFINITE when
  // !has_timeout(). For use by SleepConditionVariableSRW on
  // Windows. Callers should recognize that the return value is a
  // relative duration (it should be recomputed by calling this method
  // in the case of a spurious wakeup).
  // This header file may be included transitively by public header files,
  // so we define our own DWORD and INFINITE instead of getting them from
  // <intsafe.h> and <WinBase.h>.
  typedef unsigned long DWord;  // NOLINT
  DWord InMillisecondsFromNow() const;

  // Convert to std::chrono::time_point for interfaces that expect an absolute
  // timeout, like std::condition_variable::wait_until(). If !has_timeout() or
  // is_relative_timeout(), attempts to convert to a reasonable absolute
  // timeout, but callers should test has_timeout() and is_relative_timeout()
  // and prefer to use a more appropriate interface.
  std::chrono::time_point<std::chrono::system_clock> ToChronoTimePoint() const;

  // Convert to std::chrono::time_point for interfaces that expect a relative
  // timeout, like std::condition_variable::wait_for(). If !has_timeout() or
  // is_absolute_timeout(), attempts to convert to a reasonable relative
  // timeout, but callers should test has_timeout() and is_absolute_timeout()
  // and prefer to use a more appropriate interface. Since the return value is a
  // relative duration, it should be recomputed by calling this method in the
  // case of a spurious wakeup.
  std::chrono::nanoseconds ToChronoDuration() const;

  // Returns true if steady (aka monotonic) clocks are supported by the system.
  // This method exists because go/btm requires synchronized clocks, and
  // thus requires we use the system (aka walltime) clock.
  static constexpr bool SupportsSteadyClock() { return true; }

 private:
  // Returns the current time, expressed as a count of nanoseconds since the
  // epoch used by an arbitrary clock. The implementation tries to use a steady
  // (monotonic) clock if one is available.
  static int64_t SteadyClockNow();

  // Internal representation.
  //   - If the value is kNoTimeout, then the timeout is infinite, and
  //     has_timeout() will return true.
  //   - If the low bit is 0, then the high 63 bits is the number of nanoseconds
  //     after the unix epoch.
  //   - If the low bit is 1, then the high 63 bits is the number of nanoseconds
  //     after the epoch used by SteadyClockNow().
  //
  // In all cases the time is stored as an absolute time, the only difference is
  // the clock epoch. The use of absolute times is important since in the case
  // of a relative timeout with a spurious wakeup, the program would have to
  // restart the wait, and thus needs a way of recomputing the remaining time.
  uint64_t rep_;

  // Returns the number of nanoseconds stored in the internal representation.
  // When combined with the clock epoch indicated by the low bit (which is
  // accessed through is_absolute_timeout() and is_relative_timeout()), the
  // return value is used to compute when the timeout should occur.
  int64_t RawAbsNanos() const { return static_cast<int64_t>(rep_ >> 1); }

  // Converts to nanoseconds from now. Since the return value is a relative
  // duration, it should be recomputed by calling this method in the case of a
  // spurious wakeup.
  int64_t InNanosecondsFromNow() const;

  // A value that represents no timeout (or an infinite timeout).
  static constexpr uint64_t kNoTimeout = (std::numeric_limits<uint64_t>::max)();

  // The maximum value that can be stored in the high 63 bits.
  static constexpr int64_t kMaxNanos = (std::numeric_limits<int64_t>::max)();
};

}  // namespace synchronization_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_SYNCHRONIZATION_INTERNAL_KERNEL_TIMEOUT_H_
