Export of internal Abseil changes
-- 8bdb2020150ed0fd4a4e520e454dc5f54e33f776 by Eric Fiselier <ericwf@google.com>: Workaround bug in GCC 9.2 and after. PiperOrigin-RevId: 291982551 -- 47ff4820e595f96c082a90d733725f6882d83e3b by Abseil Team <absl-team@google.com>: Improve ABSL_ATTRIBUTE_PACKED documentation Recommend to apply ABSL_ATTRIBUTE_PACKED to structure members instead of to an entire structure because applying this attribute to an entire structure may cause the compiler to generate suboptimal code. It reduces the alignment of the data structure from a value larger than one to one. When applied to a structure, ABSL_ATTRIBUTE_PACKED reduces the alignment of a structure (alignof()) to 1. As a result, the compiler can no longer assume that e.g. uint32 members are aligned on a four byte boundary and hence is forced to use single-byte load and store instructions on CPU architectures that do not support non-aligned loads or stores. PiperOrigin-RevId: 291977920 -- 902b7a86f860da699d3a2e5c738be5ef73ede3b4 by Mark Barolak <mbar@google.com>: Internal change PiperOrigin-RevId: 291963048 -- bb3bd3247e376d53a3080b105f13ec7566d3ae50 by Abseil Team <absl-team@google.com>: Support the C++17 insert_or_assign() API in btree_map. PiperOrigin-RevId: 291945474 -- ff3b3cfcbbc64f086f95501f48d49426bcde356f by Gennadiy Rozental <rogeeff@google.com>: Import of CCTZ from GitHub. PiperOrigin-RevId: 291861110 -- fd465cd9cbbacd3962f67a7346d6462edaddd809 by Derek Mauro <dmauro@google.com>: Add flaky=1 to beta_distribution_test. PiperOrigin-RevId: 291757364 -- 3603adfb59c4128c542b670952cce250d59e1f67 by Derek Mauro <dmauro@google.com>: Separate the initialization of NumCPUs() and NominalCPUFrequency() The OSS version of Abseil never needs to call NominalCPUFrequency(). In some configurations, initializing NominalCPUFrequency() requires spending at least 3ms measuring the CPU frequency. By separating the initialization from NumCPUs(), which is called in most configurations, we can save at least 3ms of program startup time. PiperOrigin-RevId: 291737273 -- bea9e4a6bff5a0351d340deab966641867e08c4d by Abseil Team <absl-team@google.com>: Change the cmake library names not to have a redundant `absl_` prefix. PiperOrigin-RevId: 291640501 -- 501b602ef260cd7c8c527342581ceffb3c5b6d4c by Gennadiy Rozental <rogeeff@google.com>: Introducing benchmark for absl::GetFlag. PiperOrigin-RevId: 291433394 -- 4eeaddc788da4b91c272a8adca77ca6dbbbc1d44 by Xiaoyi Zhang <zhangxy@google.com>: fix: Add support for more ARM processors detection Import of https://github.com/abseil/abseil-cpp/pull/608 PiperOrigin-RevId: 291420397 -- a3087a8e883c5d71de7d9bd4ec8f4db5142dfcf5 by Derek Mauro <dmauro@google.com>: Removes the flaky raw_hash_set prefetch test PiperOrigin-RevId: 291197079 -- aad6c2121c102ac36216e771c83227cf3e3bfd66 by Andy Soffer <asoffer@google.com>: Enable building Abseil as a DLL. This is currently experimental and unsupported. This CL does a few things: 1. Adds the ABSL_DLL macro to any class holding a static data member, or to global constants in headers. 2. Adds a whitelist of all files in the DLL and all the build targets that are conglomerated into the DLL. 3. When BUILD_SHARED_LIBS is specified, any build target that would be in the DLL still exists, but we swap out all of it's dependencies so it just depends on abseil_dll PiperOrigin-RevId: 291192055 -- 5e888cd6f2a7722805d41f872108a03a84e421c7 by Mark Barolak <mbar@google.com>: Move absl/strings/internal/escaping.{cc,h} into internal build targets. This puts absl/strings/internal/escaping.h behind a whitelist and it also resolves https://github.com/abseil/abseil-cpp/issues/604. PiperOrigin-RevId: 291173320 -- 166836d24970da87587c1728036f53f05a28f0af by Eric Fiselier <ericwf@google.com>: Internal Change. PiperOrigin-RevId: 291012718 -- 996ddb3dffda02440fa93f30ca5d71b14b688875 by Abseil Team <absl-team@google.com>: Fix shared libraries log spam for built-in types in absl::GetFlag PiperOrigin-RevId: 290772743 GitOrigin-RevId: 8bdb2020150ed0fd4a4e520e454dc5f54e33f776 Change-Id: I8bf2265dd14ebbace220a1b6b982bb5040ad2a26
This commit is contained in:
parent
4442770261
commit
37dd2562ec
49 changed files with 1202 additions and 300 deletions
492
CMake/AbseilDll.cmake
Normal file
492
CMake/AbseilDll.cmake
Normal file
|
@ -0,0 +1,492 @@
|
||||||
|
include(CMakeParseArguments)
|
||||||
|
|
||||||
|
set(ABSL_INTERNAL_DLL_FILES
|
||||||
|
"algorithm/algorithm.h"
|
||||||
|
"algorithm/container.h"
|
||||||
|
"base/attributes.h"
|
||||||
|
"base/call_once.h"
|
||||||
|
"base/casts.h"
|
||||||
|
"base/config.h"
|
||||||
|
"base/const_init.h"
|
||||||
|
"base/dynamic_annotations.cc"
|
||||||
|
"base/dynamic_annotations.h"
|
||||||
|
"base/internal/atomic_hook.h"
|
||||||
|
"base/internal/bits.h"
|
||||||
|
"base/internal/cycleclock.cc"
|
||||||
|
"base/internal/cycleclock.h"
|
||||||
|
"base/internal/direct_mmap.h"
|
||||||
|
"base/internal/endian.h"
|
||||||
|
"base/internal/exponential_biased.cc"
|
||||||
|
"base/internal/exponential_biased.h"
|
||||||
|
"base/internal/hide_ptr.h"
|
||||||
|
"base/internal/identity.h"
|
||||||
|
"base/internal/invoke.h"
|
||||||
|
"base/internal/inline_variable.h"
|
||||||
|
"base/internal/low_level_alloc.cc"
|
||||||
|
"base/internal/low_level_alloc.h"
|
||||||
|
"base/internal/low_level_scheduling.h"
|
||||||
|
"base/internal/per_thread_tls.h"
|
||||||
|
"base/internal/periodic_sampler.cc"
|
||||||
|
"base/internal/periodic_sampler.h"
|
||||||
|
"base/internal/pretty_function.h"
|
||||||
|
"base/internal/raw_logging.cc"
|
||||||
|
"base/internal/raw_logging.h"
|
||||||
|
"base/internal/scheduling_mode.h"
|
||||||
|
"base/internal/scoped_set_env.cc"
|
||||||
|
"base/internal/scoped_set_env.h"
|
||||||
|
"base/internal/spinlock.cc"
|
||||||
|
"base/internal/spinlock.h"
|
||||||
|
"base/internal/spinlock_wait.cc"
|
||||||
|
"base/internal/spinlock_wait.h"
|
||||||
|
"base/internal/sysinfo.cc"
|
||||||
|
"base/internal/sysinfo.h"
|
||||||
|
"base/internal/thread_annotations.h"
|
||||||
|
"base/internal/thread_identity.cc"
|
||||||
|
"base/internal/thread_identity.h"
|
||||||
|
"base/internal/throw_delegate.cc"
|
||||||
|
"base/internal/throw_delegate.h"
|
||||||
|
"base/internal/tsan_mutex_interface.h"
|
||||||
|
"base/internal/unaligned_access.h"
|
||||||
|
"base/internal/unscaledcycleclock.cc"
|
||||||
|
"base/internal/unscaledcycleclock.h"
|
||||||
|
"base/log_severity.cc"
|
||||||
|
"base/log_severity.h"
|
||||||
|
"base/macros.h"
|
||||||
|
"base/optimization.h"
|
||||||
|
"base/options.h"
|
||||||
|
"base/policy_checks.h"
|
||||||
|
"base/port.h"
|
||||||
|
"base/thread_annotations.h"
|
||||||
|
"container/btree_map.h"
|
||||||
|
"container/btree_set.h"
|
||||||
|
"container/fixed_array.h"
|
||||||
|
"container/flat_hash_map.h"
|
||||||
|
"container/flat_hash_set.h"
|
||||||
|
"container/inlined_vector.h"
|
||||||
|
"container/internal/btree.h"
|
||||||
|
"container/internal/btree_container.h"
|
||||||
|
"container/internal/common.h"
|
||||||
|
"container/internal/compressed_tuple.h"
|
||||||
|
"container/internal/container_memory.h"
|
||||||
|
"container/internal/counting_allocator.h"
|
||||||
|
"container/internal/hash_function_defaults.h"
|
||||||
|
"container/internal/hash_policy_traits.h"
|
||||||
|
"container/internal/hashtable_debug.h"
|
||||||
|
"container/internal/hashtable_debug_hooks.h"
|
||||||
|
"container/internal/hashtablez_sampler.cc"
|
||||||
|
"container/internal/hashtablez_sampler.h"
|
||||||
|
"container/internal/hashtablez_sampler_force_weak_definition.cc"
|
||||||
|
"container/internal/have_sse.h"
|
||||||
|
"container/internal/inlined_vector.h"
|
||||||
|
"container/internal/layout.h"
|
||||||
|
"container/internal/node_hash_policy.h"
|
||||||
|
"container/internal/raw_hash_map.h"
|
||||||
|
"container/internal/raw_hash_set.cc"
|
||||||
|
"container/internal/raw_hash_set.h"
|
||||||
|
"container/internal/tracked.h"
|
||||||
|
"container/node_hash_map.h"
|
||||||
|
"container/node_hash_set.h"
|
||||||
|
"debugging/failure_signal_handler.cc"
|
||||||
|
"debugging/failure_signal_handler.h"
|
||||||
|
"debugging/leak_check.h"
|
||||||
|
"debugging/leak_check_disable.cc"
|
||||||
|
"debugging/stacktrace.cc"
|
||||||
|
"debugging/stacktrace.h"
|
||||||
|
"debugging/symbolize.cc"
|
||||||
|
"debugging/symbolize.h"
|
||||||
|
"debugging/internal/address_is_readable.cc"
|
||||||
|
"debugging/internal/address_is_readable.h"
|
||||||
|
"debugging/internal/demangle.cc"
|
||||||
|
"debugging/internal/demangle.h"
|
||||||
|
"debugging/internal/elf_mem_image.cc"
|
||||||
|
"debugging/internal/elf_mem_image.h"
|
||||||
|
"debugging/internal/examine_stack.cc"
|
||||||
|
"debugging/internal/examine_stack.h"
|
||||||
|
"debugging/internal/stack_consumption.cc"
|
||||||
|
"debugging/internal/stack_consumption.h"
|
||||||
|
"debugging/internal/stacktrace_config.h"
|
||||||
|
"debugging/internal/symbolize.h"
|
||||||
|
"debugging/internal/vdso_support.cc"
|
||||||
|
"debugging/internal/vdso_support.h"
|
||||||
|
"functional/function_ref.h"
|
||||||
|
"functional/internal/function_ref.h"
|
||||||
|
"hash/hash.h"
|
||||||
|
"hash/internal/city.h"
|
||||||
|
"hash/internal/city.cc"
|
||||||
|
"hash/internal/hash.h"
|
||||||
|
"hash/internal/hash.cc"
|
||||||
|
"hash/internal/spy_hash_state.h"
|
||||||
|
"memory/memory.h"
|
||||||
|
"meta/type_traits.h"
|
||||||
|
"numeric/int128.cc"
|
||||||
|
"numeric/int128.h"
|
||||||
|
"random/bernoulli_distribution.h"
|
||||||
|
"random/beta_distribution.h"
|
||||||
|
"random/bit_gen_ref.h"
|
||||||
|
"random/discrete_distribution.cc"
|
||||||
|
"random/discrete_distribution.h"
|
||||||
|
"random/distribution_format_traits.h"
|
||||||
|
"random/distributions.h"
|
||||||
|
"random/exponential_distribution.h"
|
||||||
|
"random/gaussian_distribution.cc"
|
||||||
|
"random/gaussian_distribution.h"
|
||||||
|
"random/internal/distributions.h"
|
||||||
|
"random/internal/distribution_caller.h"
|
||||||
|
"random/internal/fast_uniform_bits.h"
|
||||||
|
"random/internal/fastmath.h"
|
||||||
|
"random/internal/gaussian_distribution_gentables.cc"
|
||||||
|
"random/internal/generate_real.h"
|
||||||
|
"random/internal/iostream_state_saver.h"
|
||||||
|
"random/internal/nonsecure_base.h"
|
||||||
|
"random/internal/pcg_engine.h"
|
||||||
|
"random/internal/platform.h"
|
||||||
|
"random/internal/pool_urbg.cc"
|
||||||
|
"random/internal/pool_urbg.h"
|
||||||
|
"random/internal/randen.cc"
|
||||||
|
"random/internal/randen.h"
|
||||||
|
"random/internal/randen_detect.cc"
|
||||||
|
"random/internal/randen_detect.h"
|
||||||
|
"random/internal/randen_engine.h"
|
||||||
|
"random/internal/randen_hwaes.cc"
|
||||||
|
"random/internal/randen_hwaes.h"
|
||||||
|
"random/internal/randen_slow.cc"
|
||||||
|
"random/internal/randen_slow.h"
|
||||||
|
"random/internal/randen_traits.h"
|
||||||
|
"random/internal/salted_seed_seq.h"
|
||||||
|
"random/internal/seed_material.cc"
|
||||||
|
"random/internal/seed_material.h"
|
||||||
|
"random/internal/sequence_urbg.h"
|
||||||
|
"random/internal/traits.h"
|
||||||
|
"random/internal/uniform_helper.h"
|
||||||
|
"random/internal/wide_multiply.h"
|
||||||
|
"random/log_uniform_int_distribution.h"
|
||||||
|
"random/poisson_distribution.h"
|
||||||
|
"random/random.h"
|
||||||
|
"random/seed_gen_exception.cc"
|
||||||
|
"random/seed_gen_exception.h"
|
||||||
|
"random/seed_sequences.cc"
|
||||||
|
"random/seed_sequences.h"
|
||||||
|
"random/uniform_int_distribution.h"
|
||||||
|
"random/uniform_real_distribution.h"
|
||||||
|
"random/zipf_distribution.h"
|
||||||
|
"strings/ascii.cc"
|
||||||
|
"strings/ascii.h"
|
||||||
|
"strings/charconv.cc"
|
||||||
|
"strings/charconv.h"
|
||||||
|
"strings/escaping.cc"
|
||||||
|
"strings/escaping.h"
|
||||||
|
"strings/internal/charconv_bigint.cc"
|
||||||
|
"strings/internal/charconv_bigint.h"
|
||||||
|
"strings/internal/charconv_parse.cc"
|
||||||
|
"strings/internal/charconv_parse.h"
|
||||||
|
"strings/internal/escaping.cc"
|
||||||
|
"strings/internal/escaping.h"
|
||||||
|
"strings/internal/stl_type_traits.h"
|
||||||
|
"strings/match.cc"
|
||||||
|
"strings/match.h"
|
||||||
|
"strings/numbers.cc"
|
||||||
|
"strings/numbers.h"
|
||||||
|
"strings/str_format.h"
|
||||||
|
"strings/str_cat.cc"
|
||||||
|
"strings/str_cat.h"
|
||||||
|
"strings/str_join.h"
|
||||||
|
"strings/str_replace.cc"
|
||||||
|
"strings/str_replace.h"
|
||||||
|
"strings/str_split.cc"
|
||||||
|
"strings/str_split.h"
|
||||||
|
"strings/string_view.cc"
|
||||||
|
"strings/string_view.h"
|
||||||
|
"strings/strip.h"
|
||||||
|
"strings/substitute.cc"
|
||||||
|
"strings/substitute.h"
|
||||||
|
"strings/internal/char_map.h"
|
||||||
|
"strings/internal/memutil.cc"
|
||||||
|
"strings/internal/memutil.h"
|
||||||
|
"strings/internal/ostringstream.cc"
|
||||||
|
"strings/internal/ostringstream.h"
|
||||||
|
"strings/internal/pow10_helper.cc"
|
||||||
|
"strings/internal/pow10_helper.h"
|
||||||
|
"strings/internal/resize_uninitialized.h"
|
||||||
|
"strings/internal/str_format/arg.cc"
|
||||||
|
"strings/internal/str_format/arg.h"
|
||||||
|
"strings/internal/str_format/bind.cc"
|
||||||
|
"strings/internal/str_format/bind.h"
|
||||||
|
"strings/internal/str_format/checker.h"
|
||||||
|
"strings/internal/str_format/extension.cc"
|
||||||
|
"strings/internal/str_format/extension.h"
|
||||||
|
"strings/internal/str_format/float_conversion.cc"
|
||||||
|
"strings/internal/str_format/float_conversion.h"
|
||||||
|
"strings/internal/str_format/output.cc"
|
||||||
|
"strings/internal/str_format/output.h"
|
||||||
|
"strings/internal/str_format/parser.cc"
|
||||||
|
"strings/internal/str_format/parser.h"
|
||||||
|
"strings/internal/str_join_internal.h"
|
||||||
|
"strings/internal/str_split_internal.h"
|
||||||
|
"strings/internal/utf8.cc"
|
||||||
|
"strings/internal/utf8.h"
|
||||||
|
"synchronization/barrier.cc"
|
||||||
|
"synchronization/barrier.h"
|
||||||
|
"synchronization/blocking_counter.cc"
|
||||||
|
"synchronization/blocking_counter.h"
|
||||||
|
"synchronization/mutex.cc"
|
||||||
|
"synchronization/mutex.h"
|
||||||
|
"synchronization/notification.cc"
|
||||||
|
"synchronization/notification.h"
|
||||||
|
"synchronization/internal/create_thread_identity.cc"
|
||||||
|
"synchronization/internal/create_thread_identity.h"
|
||||||
|
"synchronization/internal/graphcycles.cc"
|
||||||
|
"synchronization/internal/graphcycles.h"
|
||||||
|
"synchronization/internal/kernel_timeout.h"
|
||||||
|
"synchronization/internal/per_thread_sem.cc"
|
||||||
|
"synchronization/internal/per_thread_sem.h"
|
||||||
|
"synchronization/internal/thread_pool.h"
|
||||||
|
"synchronization/internal/waiter.cc"
|
||||||
|
"synchronization/internal/waiter.h"
|
||||||
|
"time/civil_time.cc"
|
||||||
|
"time/civil_time.h"
|
||||||
|
"time/clock.cc"
|
||||||
|
"time/clock.h"
|
||||||
|
"time/duration.cc"
|
||||||
|
"time/format.cc"
|
||||||
|
"time/time.cc"
|
||||||
|
"time/time.h"
|
||||||
|
"time/internal/cctz/include/cctz/civil_time.h"
|
||||||
|
"time/internal/cctz/include/cctz/civil_time_detail.h"
|
||||||
|
"time/internal/cctz/include/cctz/time_zone.h"
|
||||||
|
"time/internal/cctz/include/cctz/zone_info_source.h"
|
||||||
|
"time/internal/cctz/src/civil_time_detail.cc"
|
||||||
|
"time/internal/cctz/src/time_zone_fixed.cc"
|
||||||
|
"time/internal/cctz/src/time_zone_fixed.h"
|
||||||
|
"time/internal/cctz/src/time_zone_format.cc"
|
||||||
|
"time/internal/cctz/src/time_zone_if.cc"
|
||||||
|
"time/internal/cctz/src/time_zone_if.h"
|
||||||
|
"time/internal/cctz/src/time_zone_impl.cc"
|
||||||
|
"time/internal/cctz/src/time_zone_impl.h"
|
||||||
|
"time/internal/cctz/src/time_zone_info.cc"
|
||||||
|
"time/internal/cctz/src/time_zone_info.h"
|
||||||
|
"time/internal/cctz/src/time_zone_libc.cc"
|
||||||
|
"time/internal/cctz/src/time_zone_libc.h"
|
||||||
|
"time/internal/cctz/src/time_zone_lookup.cc"
|
||||||
|
"time/internal/cctz/src/time_zone_posix.cc"
|
||||||
|
"time/internal/cctz/src/time_zone_posix.h"
|
||||||
|
"time/internal/cctz/src/tzfile.h"
|
||||||
|
"time/internal/cctz/src/zone_info_source.cc"
|
||||||
|
"types/any.h"
|
||||||
|
"types/bad_any_cast.cc"
|
||||||
|
"types/bad_any_cast.h"
|
||||||
|
"types/bad_optional_access.cc"
|
||||||
|
"types/bad_optional_access.h"
|
||||||
|
"types/bad_variant_access.cc"
|
||||||
|
"types/bad_variant_access.h"
|
||||||
|
"types/compare.h"
|
||||||
|
"types/internal/conformance_aliases.h"
|
||||||
|
"types/internal/conformance_archetype.h"
|
||||||
|
"types/internal/conformance_profile.h"
|
||||||
|
"types/internal/variant.h"
|
||||||
|
"types/optional.h"
|
||||||
|
"types/internal/optional.h"
|
||||||
|
"types/span.h"
|
||||||
|
"types/internal/span.h"
|
||||||
|
"types/variant.h"
|
||||||
|
"utility/utility.h"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(ABSL_INTERNAL_DLL_TARGETS
|
||||||
|
"stacktrace"
|
||||||
|
"symbolize"
|
||||||
|
"examine_stack"
|
||||||
|
"failure_signal_handler"
|
||||||
|
"debugging_internal"
|
||||||
|
"demangle_internal"
|
||||||
|
"leak_check"
|
||||||
|
"leak_check_disable"
|
||||||
|
"stack_consumption"
|
||||||
|
"debugging"
|
||||||
|
"hash"
|
||||||
|
"spy_hash_state"
|
||||||
|
"city"
|
||||||
|
"memory"
|
||||||
|
"strings"
|
||||||
|
"strings_internal"
|
||||||
|
"str_format"
|
||||||
|
"str_format_internal"
|
||||||
|
"pow10_helper"
|
||||||
|
"int128"
|
||||||
|
"numeric"
|
||||||
|
"utility"
|
||||||
|
"any"
|
||||||
|
"bad_any_cast"
|
||||||
|
"bad_any_cast_impl"
|
||||||
|
"span"
|
||||||
|
"optional"
|
||||||
|
"bad_optional_access"
|
||||||
|
"bad_variant_access"
|
||||||
|
"variant"
|
||||||
|
"compare"
|
||||||
|
"algorithm"
|
||||||
|
"algorithm_container"
|
||||||
|
"graphcycles_internal"
|
||||||
|
"kernel_timeout_internal"
|
||||||
|
"synchronization"
|
||||||
|
"thread_pool"
|
||||||
|
"bind_front"
|
||||||
|
"function_ref"
|
||||||
|
"atomic_hook"
|
||||||
|
"log_severity"
|
||||||
|
"raw_logging_internal"
|
||||||
|
"spinlock_wait"
|
||||||
|
"config"
|
||||||
|
"dynamic_annotations"
|
||||||
|
"core_headers"
|
||||||
|
"malloc_internal"
|
||||||
|
"base_internal"
|
||||||
|
"base"
|
||||||
|
"throw_delegate"
|
||||||
|
"pretty_function"
|
||||||
|
"endian"
|
||||||
|
"bits"
|
||||||
|
"exponential_biased"
|
||||||
|
"periodic_sampler"
|
||||||
|
"scoped_set_env"
|
||||||
|
"type_traits"
|
||||||
|
"meta"
|
||||||
|
"random_random"
|
||||||
|
"random_bit_gen_ref"
|
||||||
|
"random_distributions"
|
||||||
|
"random_seed_gen_exception"
|
||||||
|
"random_seed_sequences"
|
||||||
|
"random_internal_traits"
|
||||||
|
"random_internal_distribution_caller"
|
||||||
|
"random_internal_distributions"
|
||||||
|
"random_internal_fast_uniform_bits"
|
||||||
|
"random_internal_seed_material"
|
||||||
|
"random_internal_pool_urbg"
|
||||||
|
"random_internal_explicit_seed_seq"
|
||||||
|
"random_internal_sequence_urbg"
|
||||||
|
"random_internal_salted_seed_seq"
|
||||||
|
"random_internal_iostream_state_saver"
|
||||||
|
"random_internal_generate_real"
|
||||||
|
"random_internal_wide_multiply"
|
||||||
|
"random_internal_fastmath"
|
||||||
|
"random_internal_nonsecure_base"
|
||||||
|
"random_internal_pcg_engine"
|
||||||
|
"random_internal_randen_engine"
|
||||||
|
"random_internal_platform"
|
||||||
|
"random_internal_randen"
|
||||||
|
"random_internal_randen_slow"
|
||||||
|
"random_internal_randen_hwaes"
|
||||||
|
"random_internal_randen_hwaes_impl"
|
||||||
|
"random_internal_uniform_helper"
|
||||||
|
"time"
|
||||||
|
"civil_time"
|
||||||
|
"time_zone"
|
||||||
|
"container"
|
||||||
|
"btree"
|
||||||
|
"compressed_tuple"
|
||||||
|
"fixed_array"
|
||||||
|
"inlined_vector_internal"
|
||||||
|
"inlined_vector"
|
||||||
|
"counting_allocator"
|
||||||
|
"flat_hash_map"
|
||||||
|
"flat_hash_set"
|
||||||
|
"node_hash_map"
|
||||||
|
"node_hash_set"
|
||||||
|
"container_memory"
|
||||||
|
"hash_function_defaults"
|
||||||
|
"hash_policy_traits"
|
||||||
|
"hashtablez_sampler"
|
||||||
|
"hashtable_debug"
|
||||||
|
"hashtable_debug_hooks"
|
||||||
|
"have_sse"
|
||||||
|
"node_hash_policy"
|
||||||
|
"raw_hash_map"
|
||||||
|
"container_common"
|
||||||
|
"raw_hash_set"
|
||||||
|
"layout"
|
||||||
|
"tracked"
|
||||||
|
)
|
||||||
|
|
||||||
|
function(absl_internal_dll_contains)
|
||||||
|
cmake_parse_arguments(ABSL_INTERNAL_DLL
|
||||||
|
""
|
||||||
|
"OUTPUT;TARGET"
|
||||||
|
""
|
||||||
|
${ARGN}
|
||||||
|
)
|
||||||
|
|
||||||
|
STRING(REGEX REPLACE "^absl::" "" _target ${ABSL_INTERNAL_DLL_TARGET})
|
||||||
|
|
||||||
|
list(FIND
|
||||||
|
ABSL_INTERNAL_DLL_TARGETS
|
||||||
|
"${_target}"
|
||||||
|
_index)
|
||||||
|
|
||||||
|
if (${_index} GREATER -1)
|
||||||
|
set(${ABSL_INTERNAL_DLL_OUTPUT} 1 PARENT_SCOPE)
|
||||||
|
else()
|
||||||
|
set(${ABSL_INTERNAL_DLL_OUTPUT} 0 PARENT_SCOPE)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(absl_internal_dll_targets)
|
||||||
|
cmake_parse_arguments(ABSL_INTERNAL_DLL
|
||||||
|
""
|
||||||
|
"OUTPUT"
|
||||||
|
"DEPS"
|
||||||
|
${ARGN}
|
||||||
|
)
|
||||||
|
|
||||||
|
set(_deps "")
|
||||||
|
foreach(dep IN LISTS ABSL_INTERNAL_DLL_DEPS)
|
||||||
|
absl_internal_dll_contains(TARGET ${dep} OUTPUT _contains)
|
||||||
|
if (_contains)
|
||||||
|
list(APPEND _deps abseil_dll)
|
||||||
|
else()
|
||||||
|
list(APPEND _deps ${dep})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# Because we may have added the DLL multiple times
|
||||||
|
list(REMOVE_DUPLICATES _deps)
|
||||||
|
set(${ABSL_INTERNAL_DLL_OUTPUT} "${_deps}" PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(absl_make_dll)
|
||||||
|
add_library(
|
||||||
|
abseil_dll
|
||||||
|
SHARED
|
||||||
|
"${ABSL_INTERNAL_DLL_FILES}"
|
||||||
|
)
|
||||||
|
target_link_libraries(
|
||||||
|
abseil_dll
|
||||||
|
PRIVATE
|
||||||
|
${ABSL_DEFAULT_LINKOPTS}
|
||||||
|
)
|
||||||
|
set_property(TARGET abseil_dll PROPERTY LINKER_LANGUAGE "CXX")
|
||||||
|
target_include_directories(
|
||||||
|
abseil_dll
|
||||||
|
PUBLIC
|
||||||
|
"$<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>"
|
||||||
|
$<INSTALL_INTERFACE:${ABSL_INSTALL_INCLUDEDIR}>
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_options(
|
||||||
|
abseil_dll
|
||||||
|
PRIVATE
|
||||||
|
${ABSL_DEFAULT_COPTS}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_definitions(
|
||||||
|
abseil_dll
|
||||||
|
PRIVATE
|
||||||
|
ABSL_BUILD_DLL
|
||||||
|
NOMINMAX
|
||||||
|
INTERFACE
|
||||||
|
${ABSL_CC_LIB_DEFINES}
|
||||||
|
)
|
||||||
|
install(TARGETS abseil_dll EXPORT ${PROJECT_NAME}Targets
|
||||||
|
RUNTIME DESTINATION ${ABSL_INSTALL_BINDIR}
|
||||||
|
LIBRARY DESTINATION ${ABSL_INSTALL_LIBDIR}
|
||||||
|
ARCHIVE DESTINATION ${ABSL_INSTALL_LIBDIR}
|
||||||
|
)
|
||||||
|
endfunction()
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
include(CMakeParseArguments)
|
include(CMakeParseArguments)
|
||||||
include(AbseilConfigureCopts)
|
include(AbseilConfigureCopts)
|
||||||
|
include(AbseilDll)
|
||||||
include(AbseilInstallDirs)
|
include(AbseilInstallDirs)
|
||||||
|
|
||||||
# The IDE folder for Abseil that will be used if Abseil is included in a CMake
|
# The IDE folder for Abseil that will be used if Abseil is included in a CMake
|
||||||
|
@ -80,7 +81,10 @@ function(absl_cc_library)
|
||||||
${ARGN}
|
${ARGN}
|
||||||
)
|
)
|
||||||
|
|
||||||
if(NOT ABSL_CC_LIB_TESTONLY OR ABSL_RUN_TESTS)
|
if(ABSL_CC_LIB_TESTONLY AND NOT ABSL_RUN_TESTS)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
if(ABSL_ENABLE_INSTALL)
|
if(ABSL_ENABLE_INSTALL)
|
||||||
set(_NAME "${ABSL_CC_LIB_NAME}")
|
set(_NAME "${ABSL_CC_LIB_NAME}")
|
||||||
else()
|
else()
|
||||||
|
@ -97,18 +101,86 @@ function(absl_cc_library)
|
||||||
list(REMOVE_ITEM ABSL_CC_SRCS "${src_file}")
|
list(REMOVE_ITEM ABSL_CC_SRCS "${src_file}")
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
if("${ABSL_CC_SRCS}" STREQUAL "")
|
if("${ABSL_CC_SRCS}" STREQUAL "")
|
||||||
set(ABSL_CC_LIB_IS_INTERFACE 1)
|
set(ABSL_CC_LIB_IS_INTERFACE 1)
|
||||||
else()
|
else()
|
||||||
set(ABSL_CC_LIB_IS_INTERFACE 0)
|
set(ABSL_CC_LIB_IS_INTERFACE 0)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Determine this build target's relationship to the DLL. It's one of three things:
|
||||||
|
# 1. "dll" -- This target is part of the DLL
|
||||||
|
# 2. "dll_dep" -- This target is not part of the DLL, but depends on the DLL.
|
||||||
|
# Note that we assume any target not in the DLL depends on the
|
||||||
|
# DLL. This is not a technical necessity but a convenience
|
||||||
|
# which happens to be true, because nearly every target is
|
||||||
|
# part of the DLL.
|
||||||
|
# 3. "static" -- This target does not depend on the DLL and should be built
|
||||||
|
# statically.
|
||||||
|
if (${ABSL_BUILD_DLL})
|
||||||
|
absl_internal_dll_contains(TARGET ${_NAME} OUTPUT _in_dll)
|
||||||
|
if (${_in_dll})
|
||||||
|
# This target should be replaced by the DLL
|
||||||
|
set(_build_type "dll")
|
||||||
|
set(ABSL_CC_LIB_IS_INTERFACE 1)
|
||||||
|
else()
|
||||||
|
# Building a DLL, but this target is not part of the DLL
|
||||||
|
set(_build_type "dll_dep")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(_build_type "static")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(NOT ABSL_CC_LIB_IS_INTERFACE)
|
if(NOT ABSL_CC_LIB_IS_INTERFACE)
|
||||||
# CMake creates static libraries by default. Users can specify
|
if(${_build_type} STREQUAL "dll_dep")
|
||||||
# -DBUILD_SHARED_LIBS=ON during initial configuration to build shared
|
# This target depends on the DLL. When adding dependencies to this target,
|
||||||
# libraries instead.
|
# any depended-on-target which is contained inside the DLL is replaced
|
||||||
add_library(${_NAME} "")
|
# with a dependency on the DLL.
|
||||||
|
add_library(${_NAME} STATIC "")
|
||||||
target_sources(${_NAME} PRIVATE ${ABSL_CC_LIB_SRCS} ${ABSL_CC_LIB_HDRS})
|
target_sources(${_NAME} PRIVATE ${ABSL_CC_LIB_SRCS} ${ABSL_CC_LIB_HDRS})
|
||||||
|
absl_internal_dll_targets(
|
||||||
|
DEPS ${ABSL_CC_LIB_DEPS}
|
||||||
|
OUTPUT _dll_deps
|
||||||
|
)
|
||||||
|
target_link_libraries(${_NAME}
|
||||||
|
PUBLIC ${_dll_deps}
|
||||||
|
PRIVATE
|
||||||
|
${ABSL_CC_LIB_LINKOPTS}
|
||||||
|
${ABSL_DEFAULT_LINKOPTS}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (ABSL_CC_LIB_TESTONLY)
|
||||||
|
set(_gtest_link_define "GTEST_LINKED_AS_SHARED_LIBRARY=1")
|
||||||
|
else()
|
||||||
|
set(_gtest_link_define)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_compile_definitions(${_NAME}
|
||||||
|
PUBLIC
|
||||||
|
ABSL_CONSUME_DLL
|
||||||
|
"${_gtest_link_define}"
|
||||||
|
)
|
||||||
|
|
||||||
|
elseif(${_build_type} STREQUAL "static")
|
||||||
|
add_library(${_NAME} STATIC "")
|
||||||
|
target_sources(${_NAME} PRIVATE ${ABSL_CC_LIB_SRCS} ${ABSL_CC_LIB_HDRS})
|
||||||
|
target_link_libraries(${_NAME}
|
||||||
|
PUBLIC ${ABSL_CC_LIB_DEPS}
|
||||||
|
PRIVATE
|
||||||
|
${ABSL_CC_LIB_LINKOPTS}
|
||||||
|
${ABSL_DEFAULT_LINKOPTS}
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Invalid build type: ${_build_type}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Linker language can be inferred from sources, but in the case of DLLs we
|
||||||
|
# don't have any .cc files so it would be ambiguous. We could set it
|
||||||
|
# explicitly only in the case of DLLs but, because "CXX" is always the
|
||||||
|
# correct linker language for static or for shared libraries, we set it
|
||||||
|
# unconditionally.
|
||||||
|
set_property(TARGET ${_NAME} PROPERTY LINKER_LANGUAGE "CXX")
|
||||||
|
|
||||||
target_include_directories(${_NAME}
|
target_include_directories(${_NAME}
|
||||||
PUBLIC
|
PUBLIC
|
||||||
"$<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>"
|
"$<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>"
|
||||||
|
@ -116,12 +188,6 @@ function(absl_cc_library)
|
||||||
)
|
)
|
||||||
target_compile_options(${_NAME}
|
target_compile_options(${_NAME}
|
||||||
PRIVATE ${ABSL_CC_LIB_COPTS})
|
PRIVATE ${ABSL_CC_LIB_COPTS})
|
||||||
target_link_libraries(${_NAME}
|
|
||||||
PUBLIC ${ABSL_CC_LIB_DEPS}
|
|
||||||
PRIVATE
|
|
||||||
${ABSL_CC_LIB_LINKOPTS}
|
|
||||||
${ABSL_DEFAULT_LINKOPTS}
|
|
||||||
)
|
|
||||||
target_compile_definitions(${_NAME} PUBLIC ${ABSL_CC_LIB_DEFINES})
|
target_compile_definitions(${_NAME} PUBLIC ${ABSL_CC_LIB_DEFINES})
|
||||||
|
|
||||||
# Add all Abseil targets to a a folder in the IDE for organization.
|
# Add all Abseil targets to a a folder in the IDE for organization.
|
||||||
|
@ -140,9 +206,11 @@ function(absl_cc_library)
|
||||||
# When being installed, we lose the absl_ prefix. We want to put it back
|
# When being installed, we lose the absl_ prefix. We want to put it back
|
||||||
# to have properly named lib files. This is a no-op when we are not being
|
# to have properly named lib files. This is a no-op when we are not being
|
||||||
# installed.
|
# installed.
|
||||||
|
if(ABSL_ENABLE_INSTALL)
|
||||||
set_target_properties(${_NAME} PROPERTIES
|
set_target_properties(${_NAME} PROPERTIES
|
||||||
OUTPUT_NAME "absl_${_NAME}"
|
OUTPUT_NAME "absl_${_NAME}"
|
||||||
)
|
)
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
# Generating header-only library
|
# Generating header-only library
|
||||||
add_library(${_NAME} INTERFACE)
|
add_library(${_NAME} INTERFACE)
|
||||||
|
@ -151,6 +219,11 @@ function(absl_cc_library)
|
||||||
"$<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>"
|
"$<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>"
|
||||||
$<INSTALL_INTERFACE:${ABSL_INSTALL_INCLUDEDIR}>
|
$<INSTALL_INTERFACE:${ABSL_INSTALL_INCLUDEDIR}>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (${_build_type} STREQUAL "dll")
|
||||||
|
set(ABSL_CC_LIB_DEPS abseil_dll)
|
||||||
|
endif()
|
||||||
|
|
||||||
target_link_libraries(${_NAME}
|
target_link_libraries(${_NAME}
|
||||||
INTERFACE
|
INTERFACE
|
||||||
${ABSL_CC_LIB_DEPS}
|
${ABSL_CC_LIB_DEPS}
|
||||||
|
@ -171,7 +244,6 @@ function(absl_cc_library)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(absl::${ABSL_CC_LIB_NAME} ALIAS ${_NAME})
|
add_library(absl::${ABSL_CC_LIB_NAME} ALIAS ${_NAME})
|
||||||
endif()
|
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# absl_cc_test()
|
# absl_cc_test()
|
||||||
|
@ -224,23 +296,42 @@ function(absl_cc_test)
|
||||||
)
|
)
|
||||||
|
|
||||||
set(_NAME "absl_${ABSL_CC_TEST_NAME}")
|
set(_NAME "absl_${ABSL_CC_TEST_NAME}")
|
||||||
|
|
||||||
add_executable(${_NAME} "")
|
add_executable(${_NAME} "")
|
||||||
target_sources(${_NAME} PRIVATE ${ABSL_CC_TEST_SRCS})
|
target_sources(${_NAME} PRIVATE ${ABSL_CC_TEST_SRCS})
|
||||||
target_include_directories(${_NAME}
|
target_include_directories(${_NAME}
|
||||||
PUBLIC ${ABSL_COMMON_INCLUDE_DIRS}
|
PUBLIC ${ABSL_COMMON_INCLUDE_DIRS}
|
||||||
PRIVATE ${GMOCK_INCLUDE_DIRS} ${GTEST_INCLUDE_DIRS}
|
PRIVATE ${GMOCK_INCLUDE_DIRS} ${GTEST_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (${ABSL_BUILD_DLL})
|
||||||
target_compile_definitions(${_NAME}
|
target_compile_definitions(${_NAME}
|
||||||
PUBLIC ${ABSL_CC_TEST_DEFINES}
|
PUBLIC
|
||||||
|
${ABSL_CC_TEST_DEFINES}
|
||||||
|
ABSL_CONSUME_DLL
|
||||||
|
GTEST_LINKED_AS_SHARED_LIBRARY=1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Replace dependencies on targets inside the DLL with abseil_dll itself.
|
||||||
|
absl_internal_dll_targets(
|
||||||
|
DEPS ${ABSL_CC_TEST_DEPS}
|
||||||
|
OUTPUT ABSL_CC_TEST_DEPS
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
target_compile_definitions(${_NAME}
|
||||||
|
PUBLIC
|
||||||
|
${ABSL_CC_TEST_DEFINES}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
target_compile_options(${_NAME}
|
target_compile_options(${_NAME}
|
||||||
PRIVATE ${ABSL_CC_TEST_COPTS}
|
PRIVATE ${ABSL_CC_TEST_COPTS}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(${_NAME}
|
target_link_libraries(${_NAME}
|
||||||
PUBLIC ${ABSL_CC_TEST_DEPS}
|
PUBLIC ${ABSL_CC_TEST_DEPS}
|
||||||
PRIVATE ${ABSL_CC_TEST_LINKOPTS}
|
PRIVATE ${ABSL_CC_TEST_LINKOPTS}
|
||||||
)
|
)
|
||||||
# Add all Abseil targets to a a folder in the IDE for organization.
|
# Add all Abseil targets to a folder in the IDE for organization.
|
||||||
set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/test)
|
set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/test)
|
||||||
|
|
||||||
set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${ABSL_CXX_STANDARD})
|
set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${ABSL_CXX_STANDARD})
|
||||||
|
|
|
@ -7,6 +7,13 @@ configure_file(
|
||||||
${CMAKE_BINARY_DIR}/googletest-download/CMakeLists.txt
|
${CMAKE_BINARY_DIR}/googletest-download/CMakeLists.txt
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(ABSL_SAVE_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
||||||
|
set(ABSL_SAVE_CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
|
||||||
|
if (BUILD_SHARED_LIBS)
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGTEST_CREATE_SHARED_LIBRARY=1")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Configure and build the downloaded googletest source
|
# Configure and build the downloaded googletest source
|
||||||
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
|
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
|
||||||
RESULT_VARIABLE result
|
RESULT_VARIABLE result
|
||||||
|
@ -22,6 +29,9 @@ if(result)
|
||||||
message(FATAL_ERROR "Build step for googletest failed: ${result}")
|
message(FATAL_ERROR "Build step for googletest failed: ${result}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_CXX_FLAGS ${ABSL_SAVE_CMAKE_CXX_FLAGS})
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${ABSL_SAVE_CMAKE_RUNTIME_OUTPUT_DIRECTORY})
|
||||||
|
|
||||||
# Prevent overriding the parent project's compiler/linker settings on Windows
|
# Prevent overriding the parent project's compiler/linker settings on Windows
|
||||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,12 @@ cmake_policy(SET CMP0048 NEW)
|
||||||
|
|
||||||
project(absl CXX)
|
project(absl CXX)
|
||||||
|
|
||||||
|
# Output directory is correct by default for most build setups. However, when
|
||||||
|
# building Abseil as a DLL, it is important to have the DLL in the same
|
||||||
|
# directory as the executable using it. Thus, we put all executables in a single
|
||||||
|
# /bin directory.
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||||
|
|
||||||
# when absl is included as subproject (i.e. using add_subdirectory(abseil-cpp))
|
# when absl is included as subproject (i.e. using add_subdirectory(abseil-cpp))
|
||||||
# in the source tree of a project that uses it, install rules are disabled.
|
# in the source tree of a project that uses it, install rules are disabled.
|
||||||
if(NOT "^${CMAKE_SOURCE_DIR}$" STREQUAL "^${PROJECT_SOURCE_DIR}$")
|
if(NOT "^${CMAKE_SOURCE_DIR}$" STREQUAL "^${PROJECT_SOURCE_DIR}$")
|
||||||
|
@ -47,6 +53,7 @@ list(APPEND CMAKE_MODULE_PATH
|
||||||
|
|
||||||
include(AbseilInstallDirs)
|
include(AbseilInstallDirs)
|
||||||
include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
|
include(AbseilDll)
|
||||||
include(AbseilHelpers)
|
include(AbseilHelpers)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
add_subdirectory(base)
|
add_subdirectory(base)
|
||||||
add_subdirectory(algorithm)
|
add_subdirectory(algorithm)
|
||||||
add_subdirectory(container)
|
add_subdirectory(container)
|
||||||
|
@ -31,3 +29,7 @@ add_subdirectory(synchronization)
|
||||||
add_subdirectory(time)
|
add_subdirectory(time)
|
||||||
add_subdirectory(types)
|
add_subdirectory(types)
|
||||||
add_subdirectory(utility)
|
add_subdirectory(utility)
|
||||||
|
|
||||||
|
if (${ABSL_BUILD_DLL})
|
||||||
|
absl_make_dll()
|
||||||
|
endif()
|
||||||
|
|
|
@ -563,7 +563,19 @@
|
||||||
|
|
||||||
// ABSL_ATTRIBUTE_PACKED
|
// ABSL_ATTRIBUTE_PACKED
|
||||||
//
|
//
|
||||||
// Prevents the compiler from padding a structure to natural alignment
|
// Instructs the compiler not to use natural alignment for a tagged data
|
||||||
|
// structure, but instead to reduce its alignment to 1. 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 microprosessor supports non-aligned accesses.
|
||||||
#if ABSL_HAVE_ATTRIBUTE(packed) || (defined(__GNUC__) && !defined(__clang__))
|
#if ABSL_HAVE_ATTRIBUTE(packed) || (defined(__GNUC__) && !defined(__clang__))
|
||||||
#define ABSL_ATTRIBUTE_PACKED __attribute__((__packed__))
|
#define ABSL_ATTRIBUTE_PACKED __attribute__((__packed__))
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -643,4 +643,23 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
|
||||||
|
|
||||||
#undef ABSL_INTERNAL_HAS_KEYWORD
|
#undef ABSL_INTERNAL_HAS_KEYWORD
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
|
||||||
#endif // ABSL_BASE_CONFIG_H_
|
#endif // ABSL_BASE_CONFIG_H_
|
||||||
|
|
|
@ -225,7 +225,8 @@ bool RawLoggingFullySupported() {
|
||||||
#endif // !ABSL_LOW_LEVEL_WRITE_SUPPORTED
|
#endif // !ABSL_LOW_LEVEL_WRITE_SUPPORTED
|
||||||
}
|
}
|
||||||
|
|
||||||
ABSL_CONST_INIT absl::base_internal::AtomicHook<InternalLogFunction>
|
ABSL_CONST_INIT ABSL_DLL
|
||||||
|
absl::base_internal::AtomicHook<InternalLogFunction>
|
||||||
internal_log_function(DefaultInternalLog);
|
internal_log_function(DefaultInternalLog);
|
||||||
|
|
||||||
void RegisterInternalLogFunction(InternalLogFunction func) {
|
void RegisterInternalLogFunction(InternalLogFunction func) {
|
||||||
|
|
|
@ -22,9 +22,11 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "absl/base/attributes.h"
|
#include "absl/base/attributes.h"
|
||||||
|
#include "absl/base/config.h"
|
||||||
#include "absl/base/internal/atomic_hook.h"
|
#include "absl/base/internal/atomic_hook.h"
|
||||||
#include "absl/base/log_severity.h"
|
#include "absl/base/log_severity.h"
|
||||||
#include "absl/base/macros.h"
|
#include "absl/base/macros.h"
|
||||||
|
#include "absl/base/optimization.h"
|
||||||
#include "absl/base/port.h"
|
#include "absl/base/port.h"
|
||||||
|
|
||||||
// This is similar to LOG(severity) << format..., but
|
// This is similar to LOG(severity) << format..., but
|
||||||
|
@ -168,7 +170,8 @@ using InternalLogFunction = void (*)(absl::LogSeverity severity,
|
||||||
const char* file, int line,
|
const char* file, int line,
|
||||||
const std::string& message);
|
const std::string& message);
|
||||||
|
|
||||||
extern base_internal::AtomicHook<InternalLogFunction> internal_log_function;
|
ABSL_DLL extern base_internal::AtomicHook<InternalLogFunction>
|
||||||
|
internal_log_function;
|
||||||
|
|
||||||
void RegisterInternalLogFunction(InternalLogFunction func);
|
void RegisterInternalLogFunction(InternalLogFunction func);
|
||||||
|
|
||||||
|
|
|
@ -58,10 +58,6 @@ namespace absl {
|
||||||
ABSL_NAMESPACE_BEGIN
|
ABSL_NAMESPACE_BEGIN
|
||||||
namespace base_internal {
|
namespace base_internal {
|
||||||
|
|
||||||
static once_flag init_system_info_once;
|
|
||||||
static int num_cpus = 0;
|
|
||||||
static double nominal_cpu_frequency = 1.0; // 0.0 might be dangerous.
|
|
||||||
|
|
||||||
static int GetNumCPUs() {
|
static int GetNumCPUs() {
|
||||||
#if defined(__myriad2__)
|
#if defined(__myriad2__)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -265,21 +261,27 @@ static double GetNominalCPUFrequency() {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// InitializeSystemInfo() may be called before main() and before
|
ABSL_CONST_INIT static once_flag init_num_cpus_once;
|
||||||
// malloc is properly initialized, therefore this must not allocate
|
ABSL_CONST_INIT static int num_cpus = 0;
|
||||||
// memory.
|
|
||||||
static void InitializeSystemInfo() {
|
|
||||||
num_cpus = GetNumCPUs();
|
|
||||||
nominal_cpu_frequency = GetNominalCPUFrequency();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// NumCPUs() may be called before main() and before malloc is properly
|
||||||
|
// initialized, therefore this must not allocate memory.
|
||||||
int NumCPUs() {
|
int NumCPUs() {
|
||||||
base_internal::LowLevelCallOnce(&init_system_info_once, InitializeSystemInfo);
|
base_internal::LowLevelCallOnce(
|
||||||
|
&init_num_cpus_once, []() { num_cpus = GetNumCPUs(); });
|
||||||
return num_cpus;
|
return num_cpus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A default frequency of 0.0 might be dangerous if it is used in division.
|
||||||
|
ABSL_CONST_INIT static once_flag init_nominal_cpu_frequency_once;
|
||||||
|
ABSL_CONST_INIT static double nominal_cpu_frequency = 1.0;
|
||||||
|
|
||||||
|
// NominalCPUFrequency() may be called before main() and before malloc is
|
||||||
|
// properly initialized, therefore this must not allocate memory.
|
||||||
double NominalCPUFrequency() {
|
double NominalCPUFrequency() {
|
||||||
base_internal::LowLevelCallOnce(&init_system_info_once, InitializeSystemInfo);
|
base_internal::LowLevelCallOnce(
|
||||||
|
&init_nominal_cpu_frequency_once,
|
||||||
|
[]() { nominal_cpu_frequency = GetNominalCPUFrequency(); });
|
||||||
return nominal_cpu_frequency;
|
return nominal_cpu_frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,18 @@ void SetCurrentThreadIdentity(
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \
|
||||||
|
ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11
|
||||||
|
|
||||||
|
// Please see the comment on `CurrentThreadIdentityIfPresent` in
|
||||||
|
// thread_identity.h. Because DLLs cannot expose thread_local variables in
|
||||||
|
// headers, we opt for the correct-but-slower option of placing the definition
|
||||||
|
// of this function only in a translation unit inside DLL.
|
||||||
|
#if defined(ABSL_BUILD_DLL) || defined(ABSL_CONSUME_DLL)
|
||||||
|
ThreadIdentity* CurrentThreadIdentityIfPresent() { return thread_identity_ptr; }
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
void ClearCurrentThreadIdentity() {
|
void ClearCurrentThreadIdentity() {
|
||||||
#if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \
|
#if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \
|
||||||
ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11
|
ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "absl/base/config.h"
|
||||||
#include "absl/base/internal/per_thread_tls.h"
|
#include "absl/base/internal/per_thread_tls.h"
|
||||||
|
|
||||||
namespace absl {
|
namespace absl {
|
||||||
|
@ -234,9 +235,17 @@ ABSL_CONST_INIT extern thread_local ThreadIdentity* thread_identity_ptr;
|
||||||
#error Thread-local storage not detected on this platform
|
#error Thread-local storage not detected on this platform
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// thread_local variables cannot be in headers exposed by DLLs. However, it is
|
||||||
|
// important for performance reasons in general that
|
||||||
|
// `CurrentThreadIdentityIfPresent` be inlined. This is not possible across a
|
||||||
|
// DLL boundary so, with DLLs, we opt to have the function not be inlined. Note
|
||||||
|
// that `CurrentThreadIdentityIfPresent` is declared above so we can exclude
|
||||||
|
// this entire inline definition when compiling as a DLL.
|
||||||
|
#if !defined(ABSL_BUILD_DLL) && !defined(ABSL_CONSUME_DLL)
|
||||||
inline ThreadIdentity* CurrentThreadIdentityIfPresent() {
|
inline ThreadIdentity* CurrentThreadIdentityIfPresent() {
|
||||||
return thread_identity_ptr;
|
return thread_identity_ptr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#elif ABSL_THREAD_IDENTITY_MODE != \
|
#elif ABSL_THREAD_IDENTITY_MODE != \
|
||||||
ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC
|
ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC
|
||||||
|
|
|
@ -66,7 +66,13 @@
|
||||||
// NOTE: the defaults within this file all assume that Abseil can select the
|
// NOTE: the defaults within this file all assume that Abseil can select the
|
||||||
// proper Abseil implementation at compile-time, which will not be sufficient
|
// proper Abseil implementation at compile-time, which will not be sufficient
|
||||||
// to guarantee ABI stability to package managers.
|
// to guarantee ABI stability to package managers.
|
||||||
//
|
|
||||||
|
// Include a standard library header to allow configuration based on the
|
||||||
|
// standard library in use.
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#include <ciso646>
|
||||||
|
#endif
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Type Compatibility Options
|
// Type Compatibility Options
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -158,7 +164,6 @@
|
||||||
|
|
||||||
#define ABSL_OPTION_USE_STD_STRING_VIEW 2
|
#define ABSL_OPTION_USE_STD_STRING_VIEW 2
|
||||||
|
|
||||||
|
|
||||||
// ABSL_OPTION_USE_STD_VARIANT
|
// ABSL_OPTION_USE_STD_VARIANT
|
||||||
//
|
//
|
||||||
// This option controls whether absl::variant is implemented as an alias to
|
// This option controls whether absl::variant is implemented as an alias to
|
||||||
|
|
|
@ -226,6 +226,30 @@ class btree_map
|
||||||
// Inserts the elements within the initializer list `ilist`.
|
// Inserts the elements within the initializer list `ilist`.
|
||||||
using Base::insert;
|
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()
|
// btree_map::emplace()
|
||||||
//
|
//
|
||||||
// Inserts an element of the specified value by constructing it in-place
|
// Inserts an element of the specified value by constructing it in-place
|
||||||
|
|
|
@ -2345,6 +2345,65 @@ TEST(Btree, EraseIf) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Btree, InsertOrAssign) {
|
||||||
|
absl::btree_map<int, int> m = {{1, 1}, {3, 3}};
|
||||||
|
using value_type = typename decltype(m)::value_type;
|
||||||
|
|
||||||
|
auto ret = m.insert_or_assign(4, 4);
|
||||||
|
EXPECT_EQ(*ret.first, value_type(4, 4));
|
||||||
|
EXPECT_TRUE(ret.second);
|
||||||
|
ret = m.insert_or_assign(3, 100);
|
||||||
|
EXPECT_EQ(*ret.first, value_type(3, 100));
|
||||||
|
EXPECT_FALSE(ret.second);
|
||||||
|
|
||||||
|
auto hint_ret = m.insert_or_assign(ret.first, 3, 200);
|
||||||
|
EXPECT_EQ(*hint_ret, value_type(3, 200));
|
||||||
|
hint_ret = m.insert_or_assign(m.find(1), 0, 1);
|
||||||
|
EXPECT_EQ(*hint_ret, value_type(0, 1));
|
||||||
|
// Test with bad hint.
|
||||||
|
hint_ret = m.insert_or_assign(m.end(), -1, 1);
|
||||||
|
EXPECT_EQ(*hint_ret, value_type(-1, 1));
|
||||||
|
|
||||||
|
EXPECT_THAT(m, ElementsAre(Pair(-1, 1), Pair(0, 1), Pair(1, 1), Pair(3, 200),
|
||||||
|
Pair(4, 4)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Btree, InsertOrAssignMovableOnly) {
|
||||||
|
absl::btree_map<int, MovableOnlyInstance> m;
|
||||||
|
using value_type = typename decltype(m)::value_type;
|
||||||
|
|
||||||
|
auto ret = m.insert_or_assign(4, MovableOnlyInstance(4));
|
||||||
|
EXPECT_EQ(*ret.first, value_type(4, MovableOnlyInstance(4)));
|
||||||
|
EXPECT_TRUE(ret.second);
|
||||||
|
ret = m.insert_or_assign(4, MovableOnlyInstance(100));
|
||||||
|
EXPECT_EQ(*ret.first, value_type(4, MovableOnlyInstance(100)));
|
||||||
|
EXPECT_FALSE(ret.second);
|
||||||
|
|
||||||
|
auto hint_ret = m.insert_or_assign(ret.first, 3, MovableOnlyInstance(200));
|
||||||
|
EXPECT_EQ(*hint_ret, value_type(3, MovableOnlyInstance(200)));
|
||||||
|
|
||||||
|
EXPECT_EQ(m.size(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Btree, BitfieldArgument) {
|
||||||
|
union {
|
||||||
|
int n : 1;
|
||||||
|
};
|
||||||
|
n = 0;
|
||||||
|
absl::btree_map<int, int> m;
|
||||||
|
m.erase(n);
|
||||||
|
m.count(n);
|
||||||
|
m.find(n);
|
||||||
|
m.contains(n);
|
||||||
|
m.equal_range(n);
|
||||||
|
m.insert_or_assign(n, n);
|
||||||
|
m.insert_or_assign(m.end(), n, n);
|
||||||
|
m.try_emplace(n);
|
||||||
|
m.try_emplace(m.end(), n);
|
||||||
|
m.at(n);
|
||||||
|
m[n];
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace container_internal
|
} // namespace container_internal
|
||||||
ABSL_NAMESPACE_END
|
ABSL_NAMESPACE_END
|
||||||
|
|
|
@ -372,7 +372,7 @@ class btree_map_container : public btree_set_container<Tree> {
|
||||||
using super_type = btree_set_container<Tree>;
|
using super_type = btree_set_container<Tree>;
|
||||||
using params_type = typename Tree::params_type;
|
using params_type = typename Tree::params_type;
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
template <class K>
|
template <class K>
|
||||||
using key_arg = typename super_type::template key_arg<K>;
|
using key_arg = typename super_type::template key_arg<K>;
|
||||||
|
|
||||||
|
@ -390,6 +390,69 @@ class btree_map_container : public btree_set_container<Tree> {
|
||||||
btree_map_container() {}
|
btree_map_container() {}
|
||||||
|
|
||||||
// Insertion routines.
|
// Insertion routines.
|
||||||
|
// Note: the nullptr template arguments and extra `const M&` overloads allow
|
||||||
|
// for supporting bitfield arguments.
|
||||||
|
// 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 M>
|
||||||
|
std::pair<iterator, bool> insert_or_assign(const key_type &k, const M &obj) {
|
||||||
|
const std::pair<iterator, bool> ret = this->tree_.insert_unique(k, k, obj);
|
||||||
|
if (!ret.second) ret.first->second = obj;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
template <class M, key_type * = nullptr>
|
||||||
|
std::pair<iterator, bool> insert_or_assign(key_type &&k, const M &obj) {
|
||||||
|
const std::pair<iterator, bool> ret =
|
||||||
|
this->tree_.insert_unique(k, std::move(k), obj);
|
||||||
|
if (!ret.second) ret.first->second = obj;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
template <class M, M * = nullptr>
|
||||||
|
std::pair<iterator, bool> insert_or_assign(const key_type &k, M &&obj) {
|
||||||
|
const std::pair<iterator, bool> ret =
|
||||||
|
this->tree_.insert_unique(k, k, std::forward<M>(obj));
|
||||||
|
if (!ret.second) ret.first->second = std::forward<M>(obj);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
template <class M, key_type * = nullptr, M * = nullptr>
|
||||||
|
std::pair<iterator, bool> insert_or_assign(key_type &&k, M &&obj) {
|
||||||
|
const std::pair<iterator, bool> ret =
|
||||||
|
this->tree_.insert_unique(k, std::move(k), std::forward<M>(obj));
|
||||||
|
if (!ret.second) ret.first->second = std::forward<M>(obj);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
template <class M>
|
||||||
|
iterator insert_or_assign(const_iterator position, const key_type &k,
|
||||||
|
const M &obj) {
|
||||||
|
const std::pair<iterator, bool> ret =
|
||||||
|
this->tree_.insert_hint_unique(iterator(position), k, k, obj);
|
||||||
|
if (!ret.second) ret.first->second = obj;
|
||||||
|
return ret.first;
|
||||||
|
}
|
||||||
|
template <class M, key_type * = nullptr>
|
||||||
|
iterator insert_or_assign(const_iterator position, key_type &&k,
|
||||||
|
const M &obj) {
|
||||||
|
const std::pair<iterator, bool> ret = this->tree_.insert_hint_unique(
|
||||||
|
iterator(position), k, std::move(k), obj);
|
||||||
|
if (!ret.second) ret.first->second = obj;
|
||||||
|
return ret.first;
|
||||||
|
}
|
||||||
|
template <class M, M * = nullptr>
|
||||||
|
iterator insert_or_assign(const_iterator position, const key_type &k,
|
||||||
|
M &&obj) {
|
||||||
|
const std::pair<iterator, bool> ret = this->tree_.insert_hint_unique(
|
||||||
|
iterator(position), k, k, std::forward<M>(obj));
|
||||||
|
if (!ret.second) ret.first->second = std::forward<M>(obj);
|
||||||
|
return ret.first;
|
||||||
|
}
|
||||||
|
template <class M, key_type * = nullptr, M * = nullptr>
|
||||||
|
iterator insert_or_assign(const_iterator position, key_type &&k, M &&obj) {
|
||||||
|
const std::pair<iterator, bool> ret = this->tree_.insert_hint_unique(
|
||||||
|
iterator(position), k, std::move(k), std::forward<M>(obj));
|
||||||
|
if (!ret.second) ret.first->second = std::forward<M>(obj);
|
||||||
|
return ret.first;
|
||||||
|
}
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
std::pair<iterator, bool> try_emplace(const key_type &k, Args &&... args) {
|
std::pair<iterator, bool> try_emplace(const key_type &k, Args &&... args) {
|
||||||
return this->tree_.insert_unique(
|
return this->tree_.insert_unique(
|
||||||
|
|
|
@ -39,17 +39,16 @@ ABSL_CONST_INIT std::atomic<bool> g_hashtablez_enabled{
|
||||||
ABSL_CONST_INIT std::atomic<int32_t> g_hashtablez_sample_parameter{1 << 10};
|
ABSL_CONST_INIT std::atomic<int32_t> g_hashtablez_sample_parameter{1 << 10};
|
||||||
ABSL_CONST_INIT std::atomic<int32_t> g_hashtablez_max_samples{1 << 20};
|
ABSL_CONST_INIT std::atomic<int32_t> g_hashtablez_max_samples{1 << 20};
|
||||||
|
|
||||||
#if ABSL_PER_THREAD_TLS == 1
|
#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
|
||||||
ABSL_PER_THREAD_TLS_KEYWORD absl::base_internal::ExponentialBiased
|
ABSL_PER_THREAD_TLS_KEYWORD absl::base_internal::ExponentialBiased
|
||||||
g_exponential_biased_generator;
|
g_exponential_biased_generator;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#if ABSL_PER_THREAD_TLS == 1
|
#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
|
||||||
ABSL_PER_THREAD_TLS_KEYWORD int64_t global_next_sample = 0;
|
ABSL_PER_THREAD_TLS_KEYWORD int64_t global_next_sample = 0;
|
||||||
#endif // ABSL_PER_THREAD_TLS == 1
|
#endif // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
|
||||||
|
|
||||||
|
|
||||||
HashtablezSampler& HashtablezSampler::Global() {
|
HashtablezSampler& HashtablezSampler::Global() {
|
||||||
static auto* sampler = new HashtablezSampler();
|
static auto* sampler = new HashtablezSampler();
|
||||||
|
@ -192,7 +191,7 @@ HashtablezInfo* SampleSlow(int64_t* next_sample) {
|
||||||
return HashtablezSampler::Global().Register();
|
return HashtablezSampler::Global().Register();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ABSL_PER_THREAD_TLS == 0
|
#if !defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
|
||||||
*next_sample = std::numeric_limits<int64_t>::max();
|
*next_sample = std::numeric_limits<int64_t>::max();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -180,14 +180,23 @@ class HashtablezInfoHandle {
|
||||||
HashtablezInfo* info_;
|
HashtablezInfo* info_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if ABSL_PER_THREAD_TLS == 1
|
#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
|
||||||
|
#error ABSL_INTERNAL_HASHTABLEZ_SAMPLE cannot be directly set
|
||||||
|
#endif // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
|
||||||
|
|
||||||
|
#if (ABSL_PER_THREAD_TLS == 1) && !defined(ABSL_BUILD_DLL) && \
|
||||||
|
!defined(ABSL_CONSUME_DLL)
|
||||||
|
#define ABSL_INTERNAL_HASHTABLEZ_SAMPLE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
|
||||||
extern ABSL_PER_THREAD_TLS_KEYWORD int64_t global_next_sample;
|
extern ABSL_PER_THREAD_TLS_KEYWORD int64_t global_next_sample;
|
||||||
#endif // ABSL_PER_THREAD_TLS
|
#endif // ABSL_PER_THREAD_TLS
|
||||||
|
|
||||||
// Returns an RAII sampling handle that manages registration and unregistation
|
// Returns an RAII sampling handle that manages registration and unregistation
|
||||||
// with the global sampler.
|
// with the global sampler.
|
||||||
inline HashtablezInfoHandle Sample() {
|
inline HashtablezInfoHandle Sample() {
|
||||||
#if ABSL_PER_THREAD_TLS == 1
|
#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
|
||||||
if (ABSL_PREDICT_TRUE(--global_next_sample > 0)) {
|
if (ABSL_PREDICT_TRUE(--global_next_sample > 0)) {
|
||||||
return HashtablezInfoHandle(nullptr);
|
return HashtablezInfoHandle(nullptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,7 +169,7 @@ TEST(HashtablezInfoTest, RecordRehash) {
|
||||||
EXPECT_EQ(info.num_erases.load(), 0);
|
EXPECT_EQ(info.num_erases.load(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ABSL_PER_THREAD_TLS == 1
|
#if defined(ABSL_HASHTABLEZ_SAMPLE)
|
||||||
TEST(HashtablezSamplerTest, SmallSampleParameter) {
|
TEST(HashtablezSamplerTest, SmallSampleParameter) {
|
||||||
SetHashtablezEnabled(true);
|
SetHashtablezEnabled(true);
|
||||||
SetHashtablezSampleParameter(100);
|
SetHashtablezSampleParameter(100);
|
||||||
|
|
|
@ -418,53 +418,6 @@ TEST(Table, Empty) {
|
||||||
EXPECT_TRUE(t.empty());
|
EXPECT_TRUE(t.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
template <class T>
|
|
||||||
ABSL_ATTRIBUTE_ALWAYS_INLINE inline void DoNotOptimize(const T& v) {
|
|
||||||
asm volatile("" : : "r,m"(v) : "memory");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
TEST(Table, Prefetch) {
|
|
||||||
IntTable t;
|
|
||||||
t.emplace(1);
|
|
||||||
// Works for both present and absent keys.
|
|
||||||
t.prefetch(1);
|
|
||||||
t.prefetch(2);
|
|
||||||
|
|
||||||
// Do not run in debug mode, when prefetch is not implemented, or when
|
|
||||||
// sanitizers are enabled, or on WebAssembly.
|
|
||||||
#if defined(NDEBUG) && defined(__GNUC__) && defined(__x86_64__) && \
|
|
||||||
!defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) && \
|
|
||||||
!defined(THREAD_SANITIZER) && !defined(UNDEFINED_BEHAVIOR_SANITIZER) && \
|
|
||||||
!defined(__EMSCRIPTEN__)
|
|
||||||
const auto now = [] { return absl::base_internal::CycleClock::Now(); };
|
|
||||||
|
|
||||||
// Make size enough to not fit in L2 cache (16.7 Mb)
|
|
||||||
static constexpr int size = 1 << 22;
|
|
||||||
for (int i = 0; i < size; ++i) t.insert(i);
|
|
||||||
|
|
||||||
int64_t no_prefetch = 0, prefetch = 0;
|
|
||||||
for (int iter = 0; iter < 10; ++iter) {
|
|
||||||
int64_t time = now();
|
|
||||||
for (int i = 0; i < size; ++i) {
|
|
||||||
DoNotOptimize(t.find(i));
|
|
||||||
}
|
|
||||||
no_prefetch += now() - time;
|
|
||||||
|
|
||||||
time = now();
|
|
||||||
for (int i = 0; i < size; ++i) {
|
|
||||||
t.prefetch(i + 20);
|
|
||||||
DoNotOptimize(t.find(i));
|
|
||||||
}
|
|
||||||
prefetch += now() - time;
|
|
||||||
}
|
|
||||||
|
|
||||||
// no_prefetch is at least 30% slower.
|
|
||||||
EXPECT_GE(1.0 * no_prefetch / prefetch, 1.3);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Table, LookupEmpty) {
|
TEST(Table, LookupEmpty) {
|
||||||
IntTable t;
|
IntTable t;
|
||||||
auto it = t.find(0);
|
auto it = t.find(0);
|
||||||
|
@ -1842,7 +1795,7 @@ TEST(TableDeathTest, EraseOfEndAsserts) {
|
||||||
EXPECT_DEATH_IF_SUPPORTED(t.erase(t.end()), kDeathMsg);
|
EXPECT_DEATH_IF_SUPPORTED(t.erase(t.end()), kDeathMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ABSL_PER_THREAD_TLS == 1
|
#if defined(ABSL_HASHTABLEZ_SAMPLE)
|
||||||
TEST(RawHashSamplerTest, Sample) {
|
TEST(RawHashSamplerTest, Sample) {
|
||||||
// Enable the feature even if the prod default is off.
|
// Enable the feature even if the prod default is off.
|
||||||
SetHashtablezEnabled(true);
|
SetHashtablezEnabled(true);
|
||||||
|
@ -1863,7 +1816,7 @@ TEST(RawHashSamplerTest, Sample) {
|
||||||
EXPECT_NEAR((end_size - start_size) / static_cast<double>(tables.size()),
|
EXPECT_NEAR((end_size - start_size) / static_cast<double>(tables.size()),
|
||||||
0.01, 0.005);
|
0.01, 0.005);
|
||||||
}
|
}
|
||||||
#endif
|
#endif // ABSL_HASHTABLEZ_SAMPLER
|
||||||
|
|
||||||
TEST(RawHashSamplerTest, DoNotSampleCustomAllocators) {
|
TEST(RawHashSamplerTest, DoNotSampleCustomAllocators) {
|
||||||
// Enable the feature even if the prod default is off.
|
// Enable the feature even if the prod default is off.
|
||||||
|
|
|
@ -5,6 +5,13 @@ set(ABSL_LSAN_LINKOPTS "")
|
||||||
set(ABSL_HAVE_LSAN OFF)
|
set(ABSL_HAVE_LSAN OFF)
|
||||||
set(ABSL_DEFAULT_LINKOPTS "")
|
set(ABSL_DEFAULT_LINKOPTS "")
|
||||||
|
|
||||||
|
if (BUILD_SHARED_LIBS AND MSVC)
|
||||||
|
set(ABSL_BUILD_DLL TRUE)
|
||||||
|
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||||
|
else()
|
||||||
|
set(ABSL_BUILD_DLL FALSE)
|
||||||
|
endif()
|
||||||
|
|
||||||
if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64" OR "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AMD64")
|
if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64" OR "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AMD64")
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_MSVC_X64_FLAGS}")
|
set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_MSVC_X64_FLAGS}")
|
||||||
|
|
|
@ -473,6 +473,7 @@ void ABSL_ATTRIBUTE_NOINLINE TestWithReturnAddress() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
|
#if !defined(ABSL_CONSUME_DLL)
|
||||||
|
|
||||||
TEST(Symbolize, Basics) {
|
TEST(Symbolize, Basics) {
|
||||||
EXPECT_STREQ("nonstatic_func", TrySymbolize((void *)(&nonstatic_func)));
|
EXPECT_STREQ("nonstatic_func", TrySymbolize((void *)(&nonstatic_func)));
|
||||||
|
@ -511,6 +512,7 @@ TEST(Symbolize, SymbolizeWithDemangling) {
|
||||||
EXPECT_TRUE(strstr(result, "Foo::func") != nullptr) << result;
|
EXPECT_TRUE(strstr(result, "Foo::func") != nullptr) << result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // !defined(ABSL_CONSUME_DLL)
|
||||||
#else // Symbolizer unimplemented
|
#else // Symbolizer unimplemented
|
||||||
|
|
||||||
TEST(Symbolize, Unimplemented) {
|
TEST(Symbolize, Unimplemented) {
|
||||||
|
|
|
@ -324,6 +324,23 @@ cc_test(
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
cc_binary(
|
||||||
|
name = "flag_benchmark",
|
||||||
|
testonly = 1,
|
||||||
|
srcs = [
|
||||||
|
"flag_benchmark.cc",
|
||||||
|
],
|
||||||
|
copts = ABSL_TEST_COPTS,
|
||||||
|
tags = ["benchmark"],
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
deps = [
|
||||||
|
":flag",
|
||||||
|
"//absl/time",
|
||||||
|
"//absl/types:optional",
|
||||||
|
"@com_github_google_benchmark//:benchmark_main",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
cc_test(
|
cc_test(
|
||||||
name = "marshalling_test",
|
name = "marshalling_test",
|
||||||
size = "small",
|
size = "small",
|
||||||
|
|
|
@ -22,7 +22,14 @@
|
||||||
namespace absl {
|
namespace absl {
|
||||||
ABSL_NAMESPACE_BEGIN
|
ABSL_NAMESPACE_BEGIN
|
||||||
|
|
||||||
// This global nutex protects on-demand construction of flag objects in MSVC
|
#ifndef NDEBUG
|
||||||
|
#define ABSL_FLAGS_GET(T) \
|
||||||
|
T GetFlag(const absl::Flag<T>& flag) { return flag.Get(); }
|
||||||
|
ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(ABSL_FLAGS_GET)
|
||||||
|
#undef ABSL_FLAGS_GET
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// This global mutex protects on-demand construction of flag objects in MSVC
|
||||||
// builds.
|
// builds.
|
||||||
#if defined(_MSC_VER) && !defined(__clang__)
|
#if defined(_MSC_VER) && !defined(__clang__)
|
||||||
|
|
||||||
|
|
|
@ -186,25 +186,29 @@ class Flag {
|
||||||
//
|
//
|
||||||
// // FLAGS_firstname is a Flag of type `std::string`
|
// // FLAGS_firstname is a Flag of type `std::string`
|
||||||
// std::string first_name = absl::GetFlag(FLAGS_firstname);
|
// std::string first_name = absl::GetFlag(FLAGS_firstname);
|
||||||
|
#ifndef NDEBUG
|
||||||
|
// We want to validate the type mismatch between type definition and
|
||||||
|
// declaration. The lock-free implementation does not allow us to do it,
|
||||||
|
// so in debug builds we always use the slower implementation, which always
|
||||||
|
// validates the type.
|
||||||
|
template <typename T>
|
||||||
|
ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag) {
|
||||||
|
return flag.Get();
|
||||||
|
}
|
||||||
|
// We currently need an external linkage for built-in types because shared
|
||||||
|
// libraries have different addresses of flags_internal::FlagOps<T> which
|
||||||
|
// might cause log spam when checking the same flag type.
|
||||||
|
#define ABSL_FLAGS_INTERNAL_BUILT_IN_EXPORT(T) \
|
||||||
|
ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag);
|
||||||
|
ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(ABSL_FLAGS_INTERNAL_BUILT_IN_EXPORT)
|
||||||
|
#undef ABSL_FLAGS_INTERNAL_BUILT_IN_EXPORT
|
||||||
|
#else
|
||||||
template <typename T,
|
template <typename T,
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
!flags_internal::IsAtomicFlagTypeTrait<T>::value, int>::type = 0>
|
!flags_internal::IsAtomicFlagTypeTrait<T>::value, int>::type = 0>
|
||||||
ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag) {
|
ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag) {
|
||||||
return flag.Get();
|
return flag.Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We want to validate the type mismatch between type definition and
|
|
||||||
// declaration. The lock-free implementation does not allow us to do it,
|
|
||||||
// so in debug builds we always use the slower implementation, which always
|
|
||||||
// validates the type.
|
|
||||||
#ifndef NDEBUG
|
|
||||||
template <typename T,
|
|
||||||
typename std::enable_if<
|
|
||||||
flags_internal::IsAtomicFlagTypeTrait<T>::value, int>::type = 0>
|
|
||||||
ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag) {
|
|
||||||
return flag.Get();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// Overload for `GetFlag()` for types that support lock-free reads.
|
// Overload for `GetFlag()` for types that support lock-free reads.
|
||||||
template <typename T,
|
template <typename T,
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
|
|
111
absl/flags/flag_benchmark.cc
Normal file
111
absl/flags/flag_benchmark.cc
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
//
|
||||||
|
// Copyright 2020 The Abseil Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "absl/flags/flag.h"
|
||||||
|
#include "absl/time/time.h"
|
||||||
|
#include "absl/types/optional.h"
|
||||||
|
#include "benchmark/benchmark.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
using String = std::string;
|
||||||
|
using VectorOfStrings = std::vector<std::string>;
|
||||||
|
using AbslDuration = absl::Duration;
|
||||||
|
|
||||||
|
// We do not want to take over marshalling for the types absl::optional<int>,
|
||||||
|
// absl::optional<std::string> which we do not own. Instead we introduce unique
|
||||||
|
// "aliases" to these types, which we do.
|
||||||
|
using AbslOptionalInt = absl::optional<int>;
|
||||||
|
struct OptionalInt : AbslOptionalInt {
|
||||||
|
using AbslOptionalInt::AbslOptionalInt;
|
||||||
|
};
|
||||||
|
// Next two functions represent Abseil Flags marshalling for OptionalInt.
|
||||||
|
bool AbslParseFlag(absl::string_view src, OptionalInt* flag,
|
||||||
|
std::string* error) {
|
||||||
|
int val;
|
||||||
|
if (src.empty())
|
||||||
|
flag->reset();
|
||||||
|
else if (!absl::ParseFlag(src, &val, error))
|
||||||
|
return false;
|
||||||
|
*flag = val;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
std::string AbslUnparseFlag(const OptionalInt& flag) {
|
||||||
|
return !flag ? "" : absl::UnparseFlag(*flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
using AbslOptionalString = absl::optional<std::string>;
|
||||||
|
struct OptionalString : AbslOptionalString {
|
||||||
|
using AbslOptionalString::AbslOptionalString;
|
||||||
|
};
|
||||||
|
// Next two functions represent Abseil Flags marshalling for OptionalString.
|
||||||
|
bool AbslParseFlag(absl::string_view src, OptionalString* flag,
|
||||||
|
std::string* error) {
|
||||||
|
std::string val;
|
||||||
|
if (src.empty())
|
||||||
|
flag->reset();
|
||||||
|
else if (!absl::ParseFlag(src, &val, error))
|
||||||
|
return false;
|
||||||
|
*flag = val;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
std::string AbslUnparseFlag(const OptionalString& flag) {
|
||||||
|
return !flag ? "" : absl::UnparseFlag(*flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct UDT {
|
||||||
|
UDT() = default;
|
||||||
|
UDT(const UDT&) {}
|
||||||
|
UDT& operator=(const UDT&) { return *this; }
|
||||||
|
};
|
||||||
|
// Next two functions represent Abseil Flags marshalling for UDT.
|
||||||
|
bool AbslParseFlag(absl::string_view, UDT*, std::string*) { return true; }
|
||||||
|
std::string AbslUnparseFlag(const UDT&) { return ""; }
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#define BENCHMARKED_TYPES(A) \
|
||||||
|
A(bool) \
|
||||||
|
A(int16_t) \
|
||||||
|
A(uint16_t) \
|
||||||
|
A(int32_t) \
|
||||||
|
A(uint32_t) \
|
||||||
|
A(int64_t) \
|
||||||
|
A(uint64_t) \
|
||||||
|
A(double) \
|
||||||
|
A(float) \
|
||||||
|
A(String) \
|
||||||
|
A(VectorOfStrings) \
|
||||||
|
A(OptionalInt) \
|
||||||
|
A(OptionalString) \
|
||||||
|
A(AbslDuration) \
|
||||||
|
A(UDT)
|
||||||
|
|
||||||
|
#define FLAG_DEF(T) ABSL_FLAG(T, T##_flag, {}, "");
|
||||||
|
|
||||||
|
BENCHMARKED_TYPES(FLAG_DEF)
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
#define BM_GetFlag(T) \
|
||||||
|
void BM_GetFlag_##T(benchmark::State& state) { \
|
||||||
|
for (auto _ : state) { \
|
||||||
|
benchmark::DoNotOptimize(absl::GetFlag(FLAGS_##T##_flag)); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
BENCHMARK(BM_GetFlag_##T);
|
||||||
|
|
||||||
|
BENCHMARKED_TYPES(BM_GetFlag)
|
||||||
|
|
||||||
|
} // namespace
|
|
@ -708,7 +708,8 @@ struct is_hashable
|
||||||
: std::integral_constant<bool, HashSelect::template Apply<T>::value> {};
|
: std::integral_constant<bool, HashSelect::template Apply<T>::value> {};
|
||||||
|
|
||||||
// CityHashState
|
// CityHashState
|
||||||
class CityHashState : public HashStateBase<CityHashState> {
|
class ABSL_DLL CityHashState
|
||||||
|
: public HashStateBase<CityHashState> {
|
||||||
// absl::uint128 is not an alias or a thin wrapper around the intrinsic.
|
// absl::uint128 is not an alias or a thin wrapper around the intrinsic.
|
||||||
// We use the intrinsic when available to improve performance.
|
// We use the intrinsic when available to improve performance.
|
||||||
#ifdef ABSL_HAVE_INTRINSIC_INT128
|
#ifdef ABSL_HAVE_INTRINSIC_INT128
|
||||||
|
|
|
@ -25,8 +25,8 @@
|
||||||
namespace absl {
|
namespace absl {
|
||||||
ABSL_NAMESPACE_BEGIN
|
ABSL_NAMESPACE_BEGIN
|
||||||
|
|
||||||
const uint128 kuint128max = MakeUint128(std::numeric_limits<uint64_t>::max(),
|
ABSL_DLL const uint128 kuint128max = MakeUint128(
|
||||||
std::numeric_limits<uint64_t>::max());
|
std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::max());
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
|
|
@ -234,7 +234,7 @@ class
|
||||||
// Prefer to use the constexpr `Uint128Max()`.
|
// Prefer to use the constexpr `Uint128Max()`.
|
||||||
//
|
//
|
||||||
// TODO(absl-team) deprecate kuint128max once migration tool is released.
|
// TODO(absl-team) deprecate kuint128max once migration tool is released.
|
||||||
extern const uint128 kuint128max;
|
ABSL_DLL extern const uint128 kuint128max;
|
||||||
|
|
||||||
// allow uint128 to be logged
|
// allow uint128 to be logged
|
||||||
std::ostream& operator<<(std::ostream& os, uint128 v);
|
std::ostream& operator<<(std::ostream& os, uint128 v);
|
||||||
|
|
|
@ -67,6 +67,7 @@ cc_library(
|
||||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||||
deps = [
|
deps = [
|
||||||
"//absl/base:base_internal",
|
"//absl/base:base_internal",
|
||||||
|
"//absl/base:config",
|
||||||
"//absl/base:core_headers",
|
"//absl/base:core_headers",
|
||||||
"//absl/meta:type_traits",
|
"//absl/meta:type_traits",
|
||||||
"//absl/random/internal:distributions",
|
"//absl/random/internal:distributions",
|
||||||
|
@ -183,6 +184,7 @@ cc_test(
|
||||||
timeout = "eternal", # Android can take a very long time
|
timeout = "eternal", # Android can take a very long time
|
||||||
srcs = ["beta_distribution_test.cc"],
|
srcs = ["beta_distribution_test.cc"],
|
||||||
copts = ABSL_TEST_COPTS,
|
copts = ABSL_TEST_COPTS,
|
||||||
|
flaky = 1,
|
||||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||||
deps = [
|
deps = [
|
||||||
":distributions",
|
":distributions",
|
||||||
|
|
|
@ -183,6 +183,7 @@ absl_cc_library(
|
||||||
${ABSL_DEFAULT_LINKOPTS}
|
${ABSL_DEFAULT_LINKOPTS}
|
||||||
DEPS
|
DEPS
|
||||||
absl::base_internal
|
absl::base_internal
|
||||||
|
absl::config
|
||||||
absl::core_headers
|
absl::core_headers
|
||||||
absl::random_internal_generate_real
|
absl::random_internal_generate_real
|
||||||
absl::random_internal_distributions
|
absl::random_internal_distributions
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include "absl/base/config.h"
|
||||||
#include "absl/random/internal/fast_uniform_bits.h"
|
#include "absl/random/internal/fast_uniform_bits.h"
|
||||||
#include "absl/random/internal/generate_real.h"
|
#include "absl/random/internal/generate_real.h"
|
||||||
#include "absl/random/internal/iostream_state_saver.h"
|
#include "absl/random/internal/iostream_state_saver.h"
|
||||||
|
@ -43,7 +44,7 @@ namespace random_internal {
|
||||||
// The specific algorithm has some of the improvements suggested by the
|
// The specific algorithm has some of the improvements suggested by the
|
||||||
// 2005 paper, "An Improved Ziggurat Method to Generate Normal Random Samples",
|
// 2005 paper, "An Improved Ziggurat Method to Generate Normal Random Samples",
|
||||||
// Jurgen A Doornik. (https://www.doornik.com/research/ziggurat.pdf)
|
// Jurgen A Doornik. (https://www.doornik.com/research/ziggurat.pdf)
|
||||||
class gaussian_distribution_base {
|
class ABSL_DLL gaussian_distribution_base {
|
||||||
public:
|
public:
|
||||||
template <typename URBG>
|
template <typename URBG>
|
||||||
inline double zignor(URBG& g); // NOLINT(runtime/references)
|
inline double zignor(URBG& g); // NOLINT(runtime/references)
|
||||||
|
|
|
@ -37,7 +37,6 @@ cc_library(
|
||||||
"internal/charconv_bigint.h",
|
"internal/charconv_bigint.h",
|
||||||
"internal/charconv_parse.cc",
|
"internal/charconv_parse.cc",
|
||||||
"internal/charconv_parse.h",
|
"internal/charconv_parse.h",
|
||||||
"internal/escaping.cc",
|
|
||||||
"internal/memutil.cc",
|
"internal/memutil.cc",
|
||||||
"internal/memutil.h",
|
"internal/memutil.h",
|
||||||
"internal/stl_type_traits.h",
|
"internal/stl_type_traits.h",
|
||||||
|
@ -55,7 +54,6 @@ cc_library(
|
||||||
"ascii.h",
|
"ascii.h",
|
||||||
"charconv.h",
|
"charconv.h",
|
||||||
"escaping.h",
|
"escaping.h",
|
||||||
"internal/escaping.h",
|
|
||||||
"match.h",
|
"match.h",
|
||||||
"numbers.h",
|
"numbers.h",
|
||||||
"str_cat.h",
|
"str_cat.h",
|
||||||
|
@ -85,11 +83,13 @@ cc_library(
|
||||||
cc_library(
|
cc_library(
|
||||||
name = "internal",
|
name = "internal",
|
||||||
srcs = [
|
srcs = [
|
||||||
|
"internal/escaping.cc",
|
||||||
"internal/ostringstream.cc",
|
"internal/ostringstream.cc",
|
||||||
"internal/utf8.cc",
|
"internal/utf8.cc",
|
||||||
],
|
],
|
||||||
hdrs = [
|
hdrs = [
|
||||||
"internal/char_map.h",
|
"internal/char_map.h",
|
||||||
|
"internal/escaping.h",
|
||||||
"internal/ostringstream.h",
|
"internal/ostringstream.h",
|
||||||
"internal/resize_uninitialized.h",
|
"internal/resize_uninitialized.h",
|
||||||
"internal/utf8.h",
|
"internal/utf8.h",
|
||||||
|
@ -99,6 +99,7 @@ cc_library(
|
||||||
"//absl/base:config",
|
"//absl/base:config",
|
||||||
"//absl/base:core_headers",
|
"//absl/base:core_headers",
|
||||||
"//absl/base:endian",
|
"//absl/base:endian",
|
||||||
|
"//absl/base:raw_logging_internal",
|
||||||
"//absl/meta:type_traits",
|
"//absl/meta:type_traits",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -38,8 +38,6 @@ absl_cc_library(
|
||||||
"internal/charconv_bigint.h"
|
"internal/charconv_bigint.h"
|
||||||
"internal/charconv_parse.cc"
|
"internal/charconv_parse.cc"
|
||||||
"internal/charconv_parse.h"
|
"internal/charconv_parse.h"
|
||||||
"internal/escaping.cc"
|
|
||||||
"internal/escaping.h"
|
|
||||||
"internal/memutil.cc"
|
"internal/memutil.cc"
|
||||||
"internal/memutil.h"
|
"internal/memutil.h"
|
||||||
"internal/stl_type_traits.h"
|
"internal/stl_type_traits.h"
|
||||||
|
@ -74,6 +72,8 @@ absl_cc_library(
|
||||||
strings_internal
|
strings_internal
|
||||||
HDRS
|
HDRS
|
||||||
"internal/char_map.h"
|
"internal/char_map.h"
|
||||||
|
"internal/escaping.cc"
|
||||||
|
"internal/escaping.h"
|
||||||
"internal/ostringstream.h"
|
"internal/ostringstream.h"
|
||||||
"internal/resize_uninitialized.h"
|
"internal/resize_uninitialized.h"
|
||||||
"internal/utf8.h"
|
"internal/utf8.h"
|
||||||
|
@ -86,6 +86,7 @@ absl_cc_library(
|
||||||
absl::config
|
absl::config
|
||||||
absl::core_headers
|
absl::core_headers
|
||||||
absl::endian
|
absl::endian
|
||||||
|
absl::raw_logging_internal
|
||||||
absl::type_traits
|
absl::type_traits
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace ascii_internal {
|
||||||
// of these bits is tightly coupled to this implementation, the individual bits
|
// of these bits is tightly coupled to this implementation, the individual bits
|
||||||
// are not named. Note that bitfields for all characters above ASCII 127 are
|
// are not named. Note that bitfields for all characters above ASCII 127 are
|
||||||
// zero-initialized.
|
// zero-initialized.
|
||||||
const unsigned char kPropertyBits[256] = {
|
ABSL_DLL const unsigned char kPropertyBits[256] = {
|
||||||
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x00
|
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x00
|
||||||
0x40, 0x68, 0x48, 0x48, 0x48, 0x48, 0x40, 0x40,
|
0x40, 0x68, 0x48, 0x48, 0x48, 0x48, 0x40, 0x40,
|
||||||
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x10
|
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x10
|
||||||
|
@ -79,7 +79,7 @@ const unsigned char kPropertyBits[256] = {
|
||||||
// Array of characters for the ascii_tolower() function. For values 'A'
|
// Array of characters for the ascii_tolower() function. For values 'A'
|
||||||
// through 'Z', return the lower-case character; otherwise, return the
|
// through 'Z', return the lower-case character; otherwise, return the
|
||||||
// identity of the passed character.
|
// identity of the passed character.
|
||||||
const char kToLower[256] = {
|
ABSL_DLL const char kToLower[256] = {
|
||||||
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
|
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
|
||||||
'\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
|
'\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
|
||||||
'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
|
'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
|
||||||
|
@ -117,7 +117,7 @@ const char kToLower[256] = {
|
||||||
// Array of characters for the ascii_toupper() function. For values 'a'
|
// Array of characters for the ascii_toupper() function. For values 'a'
|
||||||
// through 'z', return the upper-case character; otherwise, return the
|
// through 'z', return the upper-case character; otherwise, return the
|
||||||
// identity of the passed character.
|
// identity of the passed character.
|
||||||
const char kToUpper[256] = {
|
ABSL_DLL const char kToUpper[256] = {
|
||||||
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
|
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
|
||||||
'\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
|
'\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
|
||||||
'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
|
'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "absl/base/attributes.h"
|
#include "absl/base/attributes.h"
|
||||||
|
#include "absl/base/config.h"
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
|
|
||||||
namespace absl {
|
namespace absl {
|
||||||
|
@ -63,13 +64,13 @@ ABSL_NAMESPACE_BEGIN
|
||||||
namespace ascii_internal {
|
namespace ascii_internal {
|
||||||
|
|
||||||
// Declaration for an array of bitfields holding character information.
|
// Declaration for an array of bitfields holding character information.
|
||||||
extern const unsigned char kPropertyBits[256];
|
ABSL_DLL extern const unsigned char kPropertyBits[256];
|
||||||
|
|
||||||
// Declaration for the array of characters to upper-case characters.
|
// Declaration for the array of characters to upper-case characters.
|
||||||
extern const char kToUpper[256];
|
ABSL_DLL extern const char kToUpper[256];
|
||||||
|
|
||||||
// Declaration for the array of characters to lower-case characters.
|
// Declaration for the array of characters to lower-case characters.
|
||||||
extern const char kToLower[256];
|
ABSL_DLL extern const char kToLower[256];
|
||||||
|
|
||||||
} // namespace ascii_internal
|
} // namespace ascii_internal
|
||||||
|
|
||||||
|
|
|
@ -158,12 +158,12 @@ const uint32_t* LargePowerOfFiveData(int i) {
|
||||||
int LargePowerOfFiveSize(int i) { return 2 * i; }
|
int LargePowerOfFiveSize(int i) { return 2 * i; }
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
const uint32_t kFiveToNth[14] = {
|
ABSL_DLL const uint32_t kFiveToNth[14] = {
|
||||||
1, 5, 25, 125, 625, 3125, 15625,
|
1, 5, 25, 125, 625, 3125, 15625,
|
||||||
78125, 390625, 1953125, 9765625, 48828125, 244140625, 1220703125,
|
78125, 390625, 1953125, 9765625, 48828125, 244140625, 1220703125,
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint32_t kTenToNth[10] = {
|
ABSL_DLL const uint32_t kTenToNth[10] = {
|
||||||
1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000,
|
1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "absl/base/config.h"
|
||||||
#include "absl/strings/ascii.h"
|
#include "absl/strings/ascii.h"
|
||||||
#include "absl/strings/internal/charconv_parse.h"
|
#include "absl/strings/internal/charconv_parse.h"
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
|
@ -33,8 +34,9 @@ constexpr int kMaxSmallPowerOfFive = 13;
|
||||||
// The largest power that 10 that can be raised to, and still fit in a uint32_t.
|
// The largest power that 10 that can be raised to, and still fit in a uint32_t.
|
||||||
constexpr int kMaxSmallPowerOfTen = 9;
|
constexpr int kMaxSmallPowerOfTen = 9;
|
||||||
|
|
||||||
extern const uint32_t kFiveToNth[kMaxSmallPowerOfFive + 1];
|
ABSL_DLL extern const uint32_t
|
||||||
extern const uint32_t kTenToNth[kMaxSmallPowerOfTen + 1];
|
kFiveToNth[kMaxSmallPowerOfFive + 1];
|
||||||
|
ABSL_DLL extern const uint32_t kTenToNth[kMaxSmallPowerOfTen + 1];
|
||||||
|
|
||||||
// Large, fixed-width unsigned integer.
|
// Large, fixed-width unsigned integer.
|
||||||
//
|
//
|
||||||
|
|
|
@ -122,8 +122,8 @@ class FormatSpecTemplate
|
||||||
#endif // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
|
#endif // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
|
||||||
|
|
||||||
template <Conv... C, typename = typename std::enable_if<
|
template <Conv... C, typename = typename std::enable_if<
|
||||||
sizeof...(C) == sizeof...(Args) &&
|
AllOf(sizeof...(C) == sizeof...(Args),
|
||||||
AllOf(Contains(ArgumentToConv<Args>(),
|
Contains(ArgumentToConv<Args>(),
|
||||||
C)...)>::type>
|
C)...)>::type>
|
||||||
FormatSpecTemplate(const ExtendedParsedFormat<C...>& pc) // NOLINT
|
FormatSpecTemplate(const ExtendedParsedFormat<C...>& pc) // NOLINT
|
||||||
: Base(&pc) {}
|
: Base(&pc) {}
|
||||||
|
|
|
@ -17,10 +17,12 @@
|
||||||
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_
|
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
|
#include "absl/base/config.h"
|
||||||
#include "absl/base/port.h"
|
#include "absl/base/port.h"
|
||||||
#include "absl/strings/internal/str_format/output.h"
|
#include "absl/strings/internal/str_format/output.h"
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
|
@ -134,7 +136,7 @@ struct Flags {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LengthMod {
|
struct ABSL_DLL LengthMod {
|
||||||
public:
|
public:
|
||||||
enum Id : uint8_t {
|
enum Id : uint8_t {
|
||||||
h, hh, l, ll, L, j, z, t, q, none
|
h, hh, l, ll, L, j, z, t, q, none
|
||||||
|
@ -196,7 +198,7 @@ struct LengthMod {
|
||||||
X_VAL(n) X_SEP X_VAL(p)
|
X_VAL(n) X_SEP X_VAL(p)
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
struct ConversionChar {
|
struct ABSL_DLL ConversionChar {
|
||||||
public:
|
public:
|
||||||
enum Id : uint8_t {
|
enum Id : uint8_t {
|
||||||
c, C, s, S, // text
|
c, C, s, S, // text
|
||||||
|
|
|
@ -900,9 +900,10 @@ inline bool safe_uint_internal(absl::string_view text, IntType* value_p,
|
||||||
namespace numbers_internal {
|
namespace numbers_internal {
|
||||||
|
|
||||||
// Digit conversion.
|
// Digit conversion.
|
||||||
ABSL_CONST_INIT const char kHexChar[] = "0123456789abcdef";
|
ABSL_CONST_INIT ABSL_DLL const char kHexChar[] =
|
||||||
|
"0123456789abcdef";
|
||||||
|
|
||||||
ABSL_CONST_INIT const char kHexTable[513] =
|
ABSL_CONST_INIT ABSL_DLL const char kHexTable[513] =
|
||||||
"000102030405060708090a0b0c0d0e0f"
|
"000102030405060708090a0b0c0d0e0f"
|
||||||
"101112131415161718191a1b1c1d1e1f"
|
"101112131415161718191a1b1c1d1e1f"
|
||||||
"202122232425262728292a2b2c2d2e2f"
|
"202122232425262728292a2b2c2d2e2f"
|
||||||
|
@ -920,7 +921,7 @@ ABSL_CONST_INIT const char kHexTable[513] =
|
||||||
"e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
|
"e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
|
||||||
"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
|
"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
|
||||||
|
|
||||||
ABSL_CONST_INIT const char two_ASCII_digits[100][2] = {
|
ABSL_CONST_INIT ABSL_DLL const char two_ASCII_digits[100][2] = {
|
||||||
{'0', '0'}, {'0', '1'}, {'0', '2'}, {'0', '3'}, {'0', '4'}, {'0', '5'},
|
{'0', '0'}, {'0', '1'}, {'0', '2'}, {'0', '3'}, {'0', '4'}, {'0', '5'},
|
||||||
{'0', '6'}, {'0', '7'}, {'0', '8'}, {'0', '9'}, {'1', '0'}, {'1', '1'},
|
{'0', '6'}, {'0', '7'}, {'0', '8'}, {'0', '9'}, {'1', '0'}, {'1', '1'},
|
||||||
{'1', '2'}, {'1', '3'}, {'1', '4'}, {'1', '5'}, {'1', '6'}, {'1', '7'},
|
{'1', '2'}, {'1', '3'}, {'1', '4'}, {'1', '5'}, {'1', '6'}, {'1', '7'},
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include "absl/base/config.h"
|
||||||
#include "absl/base/internal/bits.h"
|
#include "absl/base/internal/bits.h"
|
||||||
#ifdef __SSE4_2__
|
#ifdef __SSE4_2__
|
||||||
// TODO(jorg): Remove this when we figure out the right way
|
// TODO(jorg): Remove this when we figure out the right way
|
||||||
|
@ -106,9 +107,11 @@ ABSL_NAMESPACE_BEGIN
|
||||||
namespace numbers_internal {
|
namespace numbers_internal {
|
||||||
|
|
||||||
// Digit conversion.
|
// Digit conversion.
|
||||||
extern const char kHexChar[17]; // 0123456789abcdef
|
ABSL_DLL extern const char kHexChar[17]; // 0123456789abcdef
|
||||||
extern const char kHexTable[513]; // 000102030405060708090a0b0c0d0e0f1011...
|
ABSL_DLL extern const char
|
||||||
extern const char two_ASCII_digits[100][2]; // 00, 01, 02, 03...
|
kHexTable[513]; // 000102030405060708090a0b0c0d0e0f1011...
|
||||||
|
ABSL_DLL extern const char
|
||||||
|
two_ASCII_digits[100][2]; // 00, 01, 02, 03...
|
||||||
|
|
||||||
// Writes a two-character representation of 'i' to 'buf'. 'i' must be in the
|
// 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:
|
// range 0 <= i < 100, and buf must have space for two characters. Example:
|
||||||
|
|
|
@ -28,7 +28,19 @@
|
||||||
#define ABSL_STRINGS_STRING_VIEW_H_
|
#define ABSL_STRINGS_STRING_VIEW_H_
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstring>
|
||||||
|
#include <iosfwd>
|
||||||
|
#include <iterator>
|
||||||
|
#include <limits>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "absl/base/config.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
|
#ifdef ABSL_USES_STD_STRING_VIEW
|
||||||
|
|
||||||
|
@ -49,19 +61,6 @@ ABSL_NAMESPACE_END
|
||||||
#define ABSL_INTERNAL_STRING_VIEW_MEMCMP memcmp
|
#define ABSL_INTERNAL_STRING_VIEW_MEMCMP memcmp
|
||||||
#endif // ABSL_HAVE_BUILTIN(__builtin_memcmp)
|
#endif // ABSL_HAVE_BUILTIN(__builtin_memcmp)
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstring>
|
|
||||||
#include <iosfwd>
|
|
||||||
#include <iterator>
|
|
||||||
#include <limits>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "absl/base/internal/throw_delegate.h"
|
|
||||||
#include "absl/base/macros.h"
|
|
||||||
#include "absl/base/optimization.h"
|
|
||||||
#include "absl/base/port.h"
|
|
||||||
|
|
||||||
namespace absl {
|
namespace absl {
|
||||||
ABSL_NAMESPACE_BEGIN
|
ABSL_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
|
|
@ -24,11 +24,14 @@ namespace cctz = absl::time_internal::cctz;
|
||||||
namespace absl {
|
namespace absl {
|
||||||
ABSL_NAMESPACE_BEGIN
|
ABSL_NAMESPACE_BEGIN
|
||||||
|
|
||||||
extern const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez";
|
ABSL_DLL extern const char RFC3339_full[] =
|
||||||
extern const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez";
|
"%Y-%m-%dT%H:%M:%E*S%Ez";
|
||||||
|
ABSL_DLL extern const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez";
|
||||||
|
|
||||||
extern const char RFC1123_full[] = "%a, %d %b %E4Y %H:%M:%S %z";
|
ABSL_DLL extern const char RFC1123_full[] =
|
||||||
extern const char RFC1123_no_wday[] = "%d %b %E4Y %H:%M:%S %z";
|
"%a, %d %b %E4Y %H:%M:%S %z";
|
||||||
|
ABSL_DLL extern const char RFC1123_no_wday[] =
|
||||||
|
"%d %b %E4Y %H:%M:%S %z";
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
|
|
@ -89,29 +89,29 @@ std::string FixedOffsetToName(const seconds& offset) {
|
||||||
// offsets and to (somewhat) limit the total number of zones.
|
// offsets and to (somewhat) limit the total number of zones.
|
||||||
return "UTC";
|
return "UTC";
|
||||||
}
|
}
|
||||||
int seconds = static_cast<int>(offset.count());
|
int offset_seconds = static_cast<int>(offset.count());
|
||||||
const char sign = (seconds < 0 ? '-' : '+');
|
const char sign = (offset_seconds < 0 ? '-' : '+');
|
||||||
int minutes = seconds / 60;
|
int offset_minutes = offset_seconds / 60;
|
||||||
seconds %= 60;
|
offset_seconds %= 60;
|
||||||
if (sign == '-') {
|
if (sign == '-') {
|
||||||
if (seconds > 0) {
|
if (offset_seconds > 0) {
|
||||||
seconds -= 60;
|
offset_seconds -= 60;
|
||||||
minutes += 1;
|
offset_minutes += 1;
|
||||||
}
|
}
|
||||||
seconds = -seconds;
|
offset_seconds = -offset_seconds;
|
||||||
minutes = -minutes;
|
offset_minutes = -offset_minutes;
|
||||||
}
|
}
|
||||||
int hours = minutes / 60;
|
int offset_hours = offset_minutes / 60;
|
||||||
minutes %= 60;
|
offset_minutes %= 60;
|
||||||
const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1;
|
const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1;
|
||||||
char buf[prefix_len + sizeof("-24:00:00")];
|
char buf[prefix_len + sizeof("-24:00:00")];
|
||||||
char* ep = std::copy(kFixedZonePrefix, kFixedZonePrefix + prefix_len, buf);
|
char* ep = std::copy(kFixedZonePrefix, kFixedZonePrefix + prefix_len, buf);
|
||||||
*ep++ = sign;
|
*ep++ = sign;
|
||||||
ep = Format02d(ep, hours);
|
ep = Format02d(ep, offset_hours);
|
||||||
*ep++ = ':';
|
*ep++ = ':';
|
||||||
ep = Format02d(ep, minutes);
|
ep = Format02d(ep, offset_minutes);
|
||||||
*ep++ = ':';
|
*ep++ = ':';
|
||||||
ep = Format02d(ep, seconds);
|
ep = Format02d(ep, offset_seconds);
|
||||||
*ep++ = '\0';
|
*ep++ = '\0';
|
||||||
assert(ep == buf + sizeof(buf));
|
assert(ep == buf + sizeof(buf));
|
||||||
return buf;
|
return buf;
|
||||||
|
|
|
@ -1252,9 +1252,9 @@ TEST(Parse, ExtendedSubecondsScan) {
|
||||||
const auto expected = chrono::system_clock::from_time_t(0) +
|
const auto expected = chrono::system_clock::from_time_t(0) +
|
||||||
chrono::nanoseconds(micros * 1000 + ns);
|
chrono::nanoseconds(micros * 1000 + ns);
|
||||||
for (int ps = 0; ps < 1000; ps += 250) {
|
for (int ps = 0; ps < 1000; ps += 250) {
|
||||||
std::ostringstream oss;
|
std::ostringstream ps_oss;
|
||||||
oss << std::setfill('0') << std::setw(3) << ps;
|
oss << std::setfill('0') << std::setw(3) << ps;
|
||||||
const std::string input = nanos + oss.str() + "999";
|
const std::string input = nanos + ps_oss.str() + "999";
|
||||||
EXPECT_TRUE(parse("%E*f", input, tz, &tp));
|
EXPECT_TRUE(parse("%E*f", input, tz, &tp));
|
||||||
EXPECT_EQ(expected + chrono::nanoseconds(ps) / 1000, tp) << input;
|
EXPECT_EQ(expected + chrono::nanoseconds(ps) / 1000, tp) << input;
|
||||||
}
|
}
|
||||||
|
|
|
@ -641,9 +641,9 @@ std::unique_ptr<ZoneInfoSource> FileZoneInfoSource::Open(
|
||||||
if (fp == nullptr) return nullptr;
|
if (fp == nullptr) return nullptr;
|
||||||
std::size_t length = 0;
|
std::size_t length = 0;
|
||||||
if (fseek(fp, 0, SEEK_END) == 0) {
|
if (fseek(fp, 0, SEEK_END) == 0) {
|
||||||
long pos = ftell(fp);
|
long offset = ftell(fp);
|
||||||
if (pos >= 0) {
|
if (offset >= 0) {
|
||||||
length = static_cast<std::size_t>(pos);
|
length = static_cast<std::size_t>(offset);
|
||||||
}
|
}
|
||||||
rewind(fp);
|
rewind(fp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1028,16 +1028,17 @@ TEST(MakeTime, LocalTimeLibC) {
|
||||||
ASSERT_EQ(0, setenv("TZ", *np, 1)); // change what "localtime" means
|
ASSERT_EQ(0, setenv("TZ", *np, 1)); // change what "localtime" means
|
||||||
const auto zi = local_time_zone();
|
const auto zi = local_time_zone();
|
||||||
const auto lc = LoadZone("libc:localtime");
|
const auto lc = LoadZone("libc:localtime");
|
||||||
time_zone::civil_transition trans;
|
time_zone::civil_transition transition;
|
||||||
for (auto tp = zi.lookup(civil_second()).trans;
|
for (auto tp = zi.lookup(civil_second()).trans;
|
||||||
zi.next_transition(tp, &trans); tp = zi.lookup(trans.to).trans) {
|
zi.next_transition(tp, &transition);
|
||||||
const auto fcl = zi.lookup(trans.from);
|
tp = zi.lookup(transition.to).trans) {
|
||||||
const auto tcl = zi.lookup(trans.to);
|
const auto fcl = zi.lookup(transition.from);
|
||||||
|
const auto tcl = zi.lookup(transition.to);
|
||||||
civil_second cs; // compare cs in zi and lc
|
civil_second cs; // compare cs in zi and lc
|
||||||
if (fcl.kind == time_zone::civil_lookup::UNIQUE) {
|
if (fcl.kind == time_zone::civil_lookup::UNIQUE) {
|
||||||
if (tcl.kind == time_zone::civil_lookup::UNIQUE) {
|
if (tcl.kind == time_zone::civil_lookup::UNIQUE) {
|
||||||
// Both unique; must be an is_dst or abbr change.
|
// Both unique; must be an is_dst or abbr change.
|
||||||
ASSERT_EQ(trans.from, trans.to);
|
ASSERT_EQ(transition.from, transition.to);
|
||||||
const auto trans = fcl.trans;
|
const auto trans = fcl.trans;
|
||||||
const auto tal = zi.lookup(trans);
|
const auto tal = zi.lookup(trans);
|
||||||
const auto tprev = trans - absl::time_internal::cctz::seconds(1);
|
const auto tprev = trans - absl::time_internal::cctz::seconds(1);
|
||||||
|
@ -1048,11 +1049,11 @@ TEST(MakeTime, LocalTimeLibC) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ASSERT_EQ(time_zone::civil_lookup::REPEATED, tcl.kind);
|
ASSERT_EQ(time_zone::civil_lookup::REPEATED, tcl.kind);
|
||||||
cs = trans.to;
|
cs = transition.to;
|
||||||
} else {
|
} else {
|
||||||
ASSERT_EQ(time_zone::civil_lookup::UNIQUE, tcl.kind);
|
ASSERT_EQ(time_zone::civil_lookup::UNIQUE, tcl.kind);
|
||||||
ASSERT_EQ(time_zone::civil_lookup::SKIPPED, fcl.kind);
|
ASSERT_EQ(time_zone::civil_lookup::SKIPPED, fcl.kind);
|
||||||
cs = trans.from;
|
cs = transition.from;
|
||||||
}
|
}
|
||||||
if (cs.year() > 2037) break; // limit test time (and to 32-bit time_t)
|
if (cs.year() > 2037) break; // limit test time (and to 32-bit time_t)
|
||||||
const auto cl_zi = zi.lookup(cs);
|
const auto cl_zi = zi.lookup(cs);
|
||||||
|
|
|
@ -527,59 +527,30 @@ std::chrono::seconds ToChronoSeconds(Duration d);
|
||||||
std::chrono::minutes ToChronoMinutes(Duration d);
|
std::chrono::minutes ToChronoMinutes(Duration d);
|
||||||
std::chrono::hours ToChronoHours(Duration d);
|
std::chrono::hours ToChronoHours(Duration d);
|
||||||
|
|
||||||
|
|
||||||
// FormatDuration()
|
// FormatDuration()
|
||||||
//
|
//
|
||||||
// Returns a string represention of the duration in a format consisting of a
|
// Returns a string representing the duration in the form "72h3m0.5s".
|
||||||
// possibly-signed prefix and a sequence of decimal numbers, each with an
|
// Returns "inf" or "-inf" for +/- `InfiniteDuration()`.
|
||||||
// optional fractional part and a unit suffix.
|
|
||||||
//
|
|
||||||
// Valid unit suffixes are "ns", "us" "ms", "s", "m", and "h".
|
|
||||||
//
|
|
||||||
// Simple examples include "300ms", "-1.5h", and "2h45m". Returns "inf" or
|
|
||||||
// "-inf" for +/- `InfiniteDuration()` values and "0" for `ZeroDuration()`
|
|
||||||
// values.
|
|
||||||
//
|
|
||||||
// This string format is used both as an input for parsing (when handling
|
|
||||||
// command-line flags of type `absl::Duration`) and as an output in
|
|
||||||
// `FormatDuration()`
|
|
||||||
std::string FormatDuration(Duration d);
|
std::string FormatDuration(Duration d);
|
||||||
|
|
||||||
// ParseDuration()
|
// Output stream operator.
|
||||||
//
|
|
||||||
// Parses a `dur_string` of the format noted above into an `absl::Duration`
|
|
||||||
// value.
|
|
||||||
//
|
|
||||||
// Parses "0" as a zero-length duration value. Parses "-inf" or "+inf" as
|
|
||||||
// infinite durations values.
|
|
||||||
bool ParseDuration(const std::string& dur_string, Duration* d);
|
|
||||||
|
|
||||||
// AbslParseFlag()
|
|
||||||
//
|
|
||||||
// Parses the command-line flag string representation `text` (using the format
|
|
||||||
// noted above) into an `absl::Duration` destination, setting `error` on
|
|
||||||
// failure.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
//
|
|
||||||
// --timeout=6h30m
|
|
||||||
// --timeout=inf // Equivalent to `InfiniteDuration()`
|
|
||||||
// --timeout=0 // Equivalent to `ZeroDuration()`
|
|
||||||
bool AbslParseFlag(absl::string_view text, Duration* dst, std::string* error);
|
|
||||||
|
|
||||||
// AbslUnparseFlag()
|
|
||||||
//
|
|
||||||
// Unparses an `absl::Duration` into a command-line string representation using
|
|
||||||
// the format noted above.
|
|
||||||
std::string AbslUnparseFlag(Duration d);
|
|
||||||
|
|
||||||
// operator<<()
|
|
||||||
//
|
|
||||||
// Output stream operator, returning a stream in the format noted above.
|
|
||||||
inline std::ostream& operator<<(std::ostream& os, Duration d) {
|
inline std::ostream& operator<<(std::ostream& os, Duration d) {
|
||||||
return os << FormatDuration(d);
|
return os << 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(const std::string& dur_string, Duration* d);
|
||||||
|
|
||||||
|
// Support for flag values of type Duration. 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);
|
||||||
|
std::string AbslUnparseFlag(Duration d);
|
||||||
ABSL_DEPRECATED("Use AbslParseFlag() instead.")
|
ABSL_DEPRECATED("Use AbslParseFlag() instead.")
|
||||||
bool ParseFlag(const std::string& text, Duration* dst, std::string* error);
|
bool ParseFlag(const std::string& text, Duration* dst, std::string* error);
|
||||||
ABSL_DEPRECATED("Use AbslUnparseFlag() instead.")
|
ABSL_DEPRECATED("Use AbslUnparseFlag() instead.")
|
||||||
|
@ -842,29 +813,18 @@ Time FromChrono(const std::chrono::system_clock::time_point& tp);
|
||||||
// // tp == std::chrono::system_clock::from_time_t(123);
|
// // tp == std::chrono::system_clock::from_time_t(123);
|
||||||
std::chrono::system_clock::time_point ToChronoTime(Time);
|
std::chrono::system_clock::time_point ToChronoTime(Time);
|
||||||
|
|
||||||
// AbslParseFlag()
|
// Support for flag values of type Time. Time flags must be specified in a
|
||||||
//
|
// format that matches absl::RFC3339_full. For example:
|
||||||
// Parses the command-line flag string representation `text` into an
|
|
||||||
// `absl::Time` destination, setting `error` on failure. Time flag string
|
|
||||||
// representations must be specified in a format that matches
|
|
||||||
// `absl::RFC3339_full`.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
//
|
//
|
||||||
// --start_time=2016-01-02T03:04:05.678+08:00
|
// --start_time=2016-01-02T03:04:05.678+08:00
|
||||||
//
|
//
|
||||||
// Note: A UTC offset (or 'Z' indicating a zero-offset from UTC) is required.
|
// 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
|
// 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
|
// seconds/milliseconds/etc from the Unix epoch, use an absl::Duration flag
|
||||||
// and add that duration to `absl::UnixEpoch()` to get an `absl::Time`.
|
// and add that duration to absl::UnixEpoch() to get an absl::Time.
|
||||||
bool AbslParseFlag(absl::string_view text, Time* t, std::string* error);
|
bool AbslParseFlag(absl::string_view text, Time* t, std::string* error);
|
||||||
|
|
||||||
// AbslUnparseFlag()
|
|
||||||
//
|
|
||||||
// Unparses an `absl::Time` into a command-line string format as noted above.
|
|
||||||
std::string AbslUnparseFlag(Time t);
|
std::string AbslUnparseFlag(Time t);
|
||||||
|
|
||||||
ABSL_DEPRECATED("Use AbslParseFlag() instead.")
|
ABSL_DEPRECATED("Use AbslParseFlag() instead.")
|
||||||
bool ParseFlag(const std::string& text, Time* t, std::string* error);
|
bool ParseFlag(const std::string& text, Time* t, std::string* error);
|
||||||
ABSL_DEPRECATED("Use AbslUnparseFlag() instead.")
|
ABSL_DEPRECATED("Use AbslUnparseFlag() instead.")
|
||||||
|
@ -1243,15 +1203,18 @@ struct tm ToTM(Time t, TimeZone tz);
|
||||||
// time with UTC offset. Also note the use of "%Y": RFC3339 mandates that
|
// 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
|
// years have exactly four digits, but we allow them to take their natural
|
||||||
// width.
|
// width.
|
||||||
extern const char RFC3339_full[]; // %Y-%m-%dT%H:%M:%E*S%Ez
|
ABSL_DLL extern const char
|
||||||
extern const char RFC3339_sec[]; // %Y-%m-%dT%H:%M:%S%Ez
|
RFC3339_full[]; // %Y-%m-%dT%H:%M:%E*S%Ez
|
||||||
|
ABSL_DLL extern const char RFC3339_sec[]; // %Y-%m-%dT%H:%M:%S%Ez
|
||||||
|
|
||||||
// RFC1123_full
|
// RFC1123_full
|
||||||
// RFC1123_no_wday
|
// RFC1123_no_wday
|
||||||
//
|
//
|
||||||
// FormatTime()/ParseTime() format specifiers for RFC1123 date/time strings.
|
// FormatTime()/ParseTime() format specifiers for RFC1123 date/time strings.
|
||||||
extern const char RFC1123_full[]; // %a, %d %b %E4Y %H:%M:%S %z
|
ABSL_DLL extern const char
|
||||||
extern const char RFC1123_no_wday[]; // %d %b %E4Y %H:%M:%S %z
|
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()
|
// FormatTime()
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue