From c5c4db4f5191fe5e76cbf68dcc71fb28702f7d2b Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 5 Aug 2019 11:32:04 -0700 Subject: Export of internal Abseil changes -- f8fe0f483378c7520d8f8bdfabe4b20de4d96c7e by Andy Soffer : Ensure that Invoke can support C++17 in the sense that noexcept is part of the type. PiperOrigin-RevId: 261730155 -- bf796ab71653a80498f9374bc8c5111d065c64ba by Abseil Team : Fix typo in static_assert message for copy/move constructible by replacing "by" with "be". PiperOrigin-RevId: 261713992 -- 8c7c17c40d03a322f304a2fd73ed34462dbf265a by Andy Soffer : Add absl::is_function drop-in replacement for std::is_function. Some standard libraries incorrectly implement std::is_function in a few corner cases. In particular, libstdc++ functions marked noexcept. The trick being used here is that function types decay to pointers. After excluding cases like is_class, etc, we can distinguish function types by testing for this decay. Many thanks to ericwf@ for essentially writing this CL. PiperOrigin-RevId: 261705008 -- c5adf42d0a132c2525d17a719329eab2ffe0aa94 by Abseil Team : Add microbenchmark for StrSplit that uses delimiter ByAnyChar. PiperOrigin-RevId: 261424010 -- 66a342f9381ec56be2fe3aa5b3193dd3538a9740 by Andy Soffer : CMake support for Abseil Random This change touches almost build-related files for CMake almost exclusively. The one minor exception is random/internal/salted_seed_seq.h. The default warnings configuration for one of our CI builds requests not having named but unused parameters. The change in this file cleans up that warning. PiperOrigin-RevId: 261192369 GitOrigin-RevId: f8fe0f483378c7520d8f8bdfabe4b20de4d96c7e Change-Id: I05f662baacfe78750651535aa658f61c2327bc44 --- absl/random/CMakeLists.txt | 1034 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1034 insertions(+) create mode 100644 absl/random/CMakeLists.txt (limited to 'absl/random/CMakeLists.txt') diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt new file mode 100644 index 00000000..2d5c0658 --- /dev/null +++ b/absl/random/CMakeLists.txt @@ -0,0 +1,1034 @@ +# +# Copyright 2019 The Abseil Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +absl_cc_library( + NAME + random_random + HDRS + "random.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_distributions + absl::random_internal_nonsecure_base + absl::random_internal_pcg_engine + absl::random_internal_pool_urbg + absl::random_internal_randen_engine + absl::random_seed_sequences +) + +absl_cc_library( + NAME + random_distributions + SRCS + "discrete_distribution.cc" + "gaussian_distribution.cc" + HDRS + "bernoulli_distribution.h" + "beta_distribution.h" + "discrete_distribution.h" + "distribution_format_traits.h" + "distributions.h" + "exponential_distribution.h" + "gaussian_distribution.h" + "log_uniform_int_distribution.h" + "poisson_distribution.h" + "uniform_int_distribution.h" + "uniform_real_distribution.h" + "zipf_distribution.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::base_internal + absl::core_headers + absl::random_internal_distribution_impl + absl::random_internal_distributions + absl::random_internal_fast_uniform_bits + absl::random_internal_fastmath + absl::random_internal_iostream_state_saver + absl::random_internal_traits + absl::random_internal_uniform_helper + absl::strings + absl::span + absl::type_traits +) + +absl_cc_library( + NAME + random_seed_gen_exception + SRCS + "seed_gen_exception.cc" + HDRS + "seed_gen_exception.h" + COPTS + ${ABSL_DEFAULT_COPTS} + ${ABSL_EXCEPTIONS_FLAG} + LINKOPTS + ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::config +) + +absl_cc_library( + NAME + random_seed_sequences + SRCS + "seed_sequences.cc" + HDRS + "seed_sequences.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::inlined_vector + absl::random_internal_nonsecure_base + absl::random_internal_pool_urbg + absl::random_internal_salted_seed_seq + absl::random_internal_seed_material + absl::random_seed_gen_exception + absl::span +) + +absl_cc_test( + NAME + random_bernoulli_distribution_test + SRCS + "bernoulli_distribution_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_distributions + absl::random_random + absl::random_internal_sequence_urbg + gmock + gtest_main +) + +absl_cc_test( + NAME + random_beta_distribution_test + SRCS + "beta_distribution_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_distributions + absl::random_random + absl::base + absl::random_internal_distribution_test_util + absl::random_internal_sequence_urbg + absl::strings + absl::str_format + gmock + gtest_main +) + +absl_cc_test( + NAME + random_distributions_test + SRCS + "distributions_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_distributions + absl::random_random + absl::random_internal_distribution_test_util + gmock + gtest_main +) + +absl_cc_test( + NAME + random_generators_test + SRCS + "generators_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + absl::random_distributions + absl::random_random + gmock + gtest_main +) + +absl_cc_test( + NAME + random_log_uniform_int_distribution_test + SRCS + "log_uniform_int_distribution_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + absl::base + absl::core_headers + absl::random_distributions + absl::random_internal_distribution_test_util + absl::random_internal_sequence_urbg + absl::random_random + absl::strings + absl::str_format + gmock + gtest_main +) + +absl_cc_test( + NAME + random_discrete_distribution_test + SRCS + "discrete_distribution_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::base + absl::random_distributions + absl::random_internal_distribution_test_util + absl::random_internal_sequence_urbg + absl::random_random + absl::strings + gmock + gtest_main +) + +absl_cc_test( + NAME + random_poisson_distribution_test + SRCS + "poisson_distribution_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_distributions + absl::random_random + absl::base + absl::core_headers + absl::flat_hash_map + absl::random_internal_distribution_test_util + absl::random_internal_sequence_urbg + absl::strings + absl::str_format + gmock + gtest_main +) + +absl_cc_test( + NAME + random_exponential_distribution_test + SRCS + "exponential_distribution_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::base + absl::core_headers + absl::random_distributions + absl::random_internal_distribution_test_util + absl::random_internal_sequence_urbg + absl::random_random + absl::strings + absl::str_format + gmock + gtest_main +) + +absl_cc_test( + NAME + random_gaussian_distribution_test + SRCS + "gaussian_distribution_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::base + absl::core_headers + absl::random_distributions + absl::random_internal_distribution_test_util + absl::random_internal_sequence_urbg + absl::random_random + absl::strings + absl::str_format + gmock + gtest_main +) + +absl_cc_test( + NAME + random_uniform_int_distribution_test + SRCS + "uniform_int_distribution_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::base + absl::random_distributions + absl::random_internal_distribution_test_util + absl::random_internal_sequence_urbg + absl::random_random + absl::strings + gmock + gtest_main +) + +absl_cc_test( + NAME + random_uniform_real_distribution_test + SRCS + "uniform_real_distribution_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::base + absl::random_distributions + absl::random_internal_distribution_test_util + absl::random_internal_sequence_urbg + absl::random_random + absl::strings + gmock + gtest_main +) + +absl_cc_test( + NAME + random_zipf_distribution_test + SRCS + "zipf_distribution_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::base + absl::random_distributions + absl::random_internal_distribution_test_util + absl::random_internal_sequence_urbg + absl::random_random + absl::strings + gmock + gtest_main +) + +absl_cc_test( + NAME + random_examples_test + SRCS + "examples_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_random + gtest_main +) + +absl_cc_test( + NAME + random_seed_sequences_test + SRCS + "seed_sequences_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_seed_sequences + absl::random_internal_nonsecure_base + absl::random_random + gmock + gtest_main +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_traits + HDRS + "internal/traits.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::config +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_distribution_caller + HDRS + "internal/distribution_caller.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_distributions + HDRS + "internal/distributions.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_internal_distribution_caller + absl::random_internal_fast_uniform_bits + absl::random_internal_fastmath + absl::random_internal_traits + absl::random_internal_uniform_helper + absl::span + absl::strings + absl::type_traits +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_fast_uniform_bits + HDRS + "internal/fast_uniform_bits.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_seed_material + SRCS + "internal/seed_material.cc" + HDRS + "internal/seed_material.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::base + absl::core_headers + absl::optional + absl::random_internal_fast_uniform_bits + absl::span + absl::strings +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_pool_urbg + SRCS + "internal/pool_urbg.cc" + HDRS + "internal/pool_urbg.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::base + absl::config + absl::core_headers + absl::endian + absl::random_internal_randen + absl::random_internal_seed_material + absl::random_internal_traits + absl::random_seed_gen_exception + absl::span +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_explicit_seed_seq + HDRS + "internal/random_internal_explicit_seed_seq.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + TESTONLY +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_sequence_urbg + HDRS + "internal/sequence_urbg.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + TESTONLY +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_salted_seed_seq + HDRS + "internal/salted_seed_seq.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::inlined_vector + absl::optional + absl::span + absl::random_internal_seed_material + absl::type_traits +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_iostream_state_saver + HDRS + "internal/iostream_state_saver.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::int128 + absl::type_traits +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_distribution_impl + HDRS + "internal/distribution_impl.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::bits + absl::config + absl::int128 + absl::random_internal_fastmath + absl::random_internal_traits +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_fastmath + HDRS + "internal/fastmath.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::bits +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_nonsecure_base + HDRS + "internal/nonsecure_base.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::core_headers + absl::optional + absl::random_internal_pool_urbg + absl::random_internal_salted_seed_seq + absl::random_internal_seed_material + absl::span + absl::strings + absl::type_traits +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_pcg_engine + HDRS + "internal/pcg_engine.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::config + absl::int128 + absl::random_internal_fastmath + absl::random_internal_iostream_state_saver + absl::type_traits +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_randen_engine + HDRS + "internal/randen_engine.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_internal_iostream_state_saver + absl::random_internal_randen + absl::type_traits +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_platform + HDRS + "internal/randen_traits.h" + "internal/randen-keys.inc" + "internal/platform.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_randen + SRCS + "internal/randen.cc" + HDRS + "internal/randen.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::base + absl::random_internal_platform + absl::random_internal_randen_hwaes + absl::random_internal_randen_slow +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_randen_slow + SRCS + "internal/randen_slow.cc" + HDRS + "internal/randen_slow.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_internal_platform +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_randen_hwaes + SRCS + "internal/randen_detect.cc" + HDRS + "internal/randen_detect.h" + "internal/randen_hwaes.h" + COPTS + ${ABSL_DEFAULT_COPTS} + ${ABSL_RANDOM_RANDEN_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_internal_platform + absl::random_internal_randen_hwaes_impl +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_randen_hwaes_impl + SRCS + "internal/randen_hwaes.cc" + "internal/randen_hwaes.h" + COPTS + ${ABSL_DEFAULT_COPTS} + ${ABSL_RANDOM_RANDEN_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_internal_platform +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_distribution_test_util + SRCS + "internal/chi_square.cc" + "internal/distribution_test_util.cc" + HDRS + "internal/chi_square.h" + "internal/distribution_test_util.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::base + absl::core_headers + absl::strings + absl::str_format + absl::span +) + +# Internal-only target, do not depend on directly. +absl_cc_test( + NAME + random_internal_traits_test + SRCS + "internal/traits_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_internal_traits + gtest_main +) + +# Internal-only target, do not depend on directly. +absl_cc_test( + NAME + random_internal_distribution_impl_test + SRCS + "internal/distribution_impl_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::bits + absl::flags + absl::int128 + absl::random_internal_distribution_impl + gtest_main +) + +# Internal-only target, do not depend on directly. +absl_cc_test( + NAME + random_internal_distribution_test_util_test + SRCS + "internal/distribution_test_util_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_internal_distribution_test_util + gtest_main +) + +# Internal-only target, do not depend on directly. +absl_cc_test( + NAME + random_internal_fastmath_test + SRCS + "internal/fastmath_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_internal_fastmath + gtest_main +) + +# Internal-only target, do not depend on directly. +absl_cc_test( + NAME + random_internal_explicit_seed_seq_test + SRCS + "internal/explicit_seed_seq_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_internal_explicit_seed_seq + absl::random_seed_sequences + gmock + gtest_main +) + +# Internal-only target, do not depend on directly. +absl_cc_test( + NAME + random_internal_salted_seed_seq_test + SRCS + "internal/salted_seed_seq_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_internal_salted_seed_seq + gmock + gtest_main +) + +# Internal-only target, do not depend on directly. +absl_cc_test( + NAME + random_internal_chi_square_test + SRCS + "internal/chi_square_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::core_headers + absl::random_internal_distribution_test_util + gtest_main +) + +# Internal-only target, do not depend on directly. +absl_cc_test( + NAME + random_internal_fast_uniform_bits_test + SRCS + "internal/fast_uniform_bits_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_internal_fast_uniform_bits + gtest_main +) + +# Internal-only target, do not depend on directly. +absl_cc_test( + NAME + random_internal_nonsecure_base_test + SRCS + "internal/nonsecure_base_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_internal_nonsecure_base + absl::random_random + absl::random_distributions + absl::random_seed_sequences + absl::strings + gtest_main +) + +# Internal-only target, do not depend on directly. +absl_cc_test( + NAME + random_internal_seed_material_test + SRCS + "internal/seed_material_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_internal_seed_material + gmock + gtest_main +) + +# Internal-only target, do not depend on directly. +absl_cc_test( + NAME + random_internal_pool_urbg_test + SRCS + "internal/pool_urbg_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_internal_pool_urbg + absl::span + absl::type_traits + gtest_main +) + +# Internal-only target, do not depend on directly. +absl_cc_test( + NAME + random_internal_pcg_engine_test + SRCS + "internal/pcg_engine_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_internal_explicit_seed_seq + absl::random_internal_pcg_engine + absl::time + gmock + gtest_main +) + +# Internal-only target, do not depend on directly. +absl_cc_test( + NAME + random_internal_randen_engine_test + SRCS + "internal/randen_engine_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::base + absl::random_internal_explicit_seed_seq + absl::random_internal_randen_engine + absl::strings + absl::time + gmock + gtest_main +) + +# Internal-only target, do not depend on directly. +absl_cc_test( + NAME + random_internal_randen_test + SRCS + "internal/randen_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_internal_randen + absl::type_traits + gtest_main +) + +# Internal-only target, do not depend on directly. +absl_cc_test( + NAME + random_internal_randen_slow_test + SRCS + "internal/randen_slow_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_internal_randen_slow + gtest_main +) + +# Internal-only target, do not depend on directly. +absl_cc_test( + NAME + random_internal_randen_hwaes_test + SRCS + "internal/randen_hwaes_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_internal_platform + absl::random_internal_randen_hwaes + absl::random_internal_randen_hwaes_impl + absl::base + absl::str_format + gmock + gtest +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_uniform_helper + HDRS + "internal/uniform_helper.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::core_headers + absl::random_internal_distribution_impl + absl::random_internal_fast_uniform_bits + absl::random_internal_iostream_state_saver + absl::random_internal_traits + absl::type_traits +) + +# Internal-only target, do not depend on directly. +absl_cc_test( + NAME + random_internal_iostream_state_saver_test + SRCS + "internal/iostream_state_saver_test.cc" + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_internal_iostream_state_saver + gtest_main +) -- cgit v1.2.3 From d9aa92d7fb324314f9df487ac23d32a25650b742 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 13 Aug 2019 10:20:16 -0700 Subject: Export of internal Abseil changes -- 2dd3b23ea940804de727e396b300cfae4b1b71a1 by Derek Mauro : Upgrade to LLVM r366207 and Bazel 0.28.1 for Linux-Clang testing. PiperOrigin-RevId: 263162761 -- f03ae9e4e9f42c075745d28b4ced78071e73724a by Derek Mauro : Remove unneeded dependencies on //absl/base from targets that no longer depend on it. PiperOrigin-RevId: 263129193 -- 8ec2aab1eea50e7f71a6a687a07e5ae0e0945f5e by Derek Mauro : Move raw_logging to a separate target (raw_logging_internal) PiperOrigin-RevId: 262972007 GitOrigin-RevId: 2dd3b23ea940804de727e396b300cfae4b1b71a1 Change-Id: I3f4580e87797386b0b5e90c8ced74cbf078f61c1 --- absl/base/BUILD.bazel | 20 ++++++++++++++------ absl/base/CMakeLists.txt | 21 +++++++++++++++------ absl/container/BUILD.bazel | 11 ++++++----- absl/container/CMakeLists.txt | 9 +++++---- absl/debugging/BUILD.bazel | 16 +++++++++------- absl/debugging/CMakeLists.txt | 17 ++++++++++------- absl/flags/BUILD.bazel | 6 +++--- absl/flags/CMakeLists.txt | 8 ++++---- absl/memory/BUILD.bazel | 1 - absl/memory/CMakeLists.txt | 1 - absl/random/BUILD.bazel | 18 +++++++++--------- absl/random/CMakeLists.txt | 29 +++++++++++++++-------------- absl/random/internal/BUILD.bazel | 17 +++++++++-------- absl/strings/BUILD.bazel | 18 ++++++++---------- absl/strings/CMakeLists.txt | 11 +++++------ absl/synchronization/BUILD.bazel | 10 ++++++---- absl/synchronization/CMakeLists.txt | 8 +++++--- absl/time/BUILD.bazel | 4 ++-- absl/time/CMakeLists.txt | 24 ++++++++++++------------ absl/types/BUILD.bazel | 12 ++++++------ absl/types/CMakeLists.txt | 14 +++++++------- ci/linux_clang-latest_libcxx_asan_bazel.sh | 2 +- ci/linux_clang-latest_libcxx_bazel.sh | 2 +- ci/linux_clang-latest_libcxx_tsan_bazel.sh | 2 +- ci/linux_clang-latest_libstdcxx_bazel.sh | 2 +- 25 files changed, 154 insertions(+), 129 deletions(-) (limited to 'absl/random/CMakeLists.txt') diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index a512272a..bfdc7ab5 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -48,11 +48,19 @@ cc_library( cc_library( name = "raw_logging_internal", + srcs = ["internal/raw_logging.cc"], + hdrs = ["internal/raw_logging.h"], copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, visibility = [ "//absl:__subpackages__", ], + deps = [ + ":atomic_hook", + ":config", + ":core_headers", + ":log_severity", + ], ) cc_library( @@ -137,6 +145,7 @@ cc_library( ":config", ":core_headers", ":dynamic_annotations", + ":raw_logging_internal", ":spinlock_wait", ], ) @@ -164,7 +173,6 @@ cc_library( name = "base", srcs = [ "internal/cycleclock.cc", - "internal/raw_logging.cc", "internal/spinlock.cc", "internal/sysinfo.cc", "internal/thread_identity.cc", @@ -176,7 +184,6 @@ cc_library( "internal/cycleclock.h", "internal/low_level_scheduling.h", "internal/per_thread_tls.h", - "internal/raw_logging.h", "internal/spinlock.h", "internal/sysinfo.h", "internal/thread_identity.h", @@ -195,6 +202,7 @@ cc_library( ":core_headers", ":dynamic_annotations", ":log_severity", + ":raw_logging_internal", ":spinlock_wait", "//absl/meta:type_traits", ], @@ -238,8 +246,8 @@ cc_library( "//absl:__subpackages__", ], deps = [ - ":base", ":config", + ":raw_logging_internal", ], ) @@ -382,6 +390,7 @@ cc_library( deps = [ ":base", ":base_internal", + ":raw_logging_internal", "//absl/synchronization", "@com_github_google_benchmark//:benchmark_main", ], @@ -455,7 +464,7 @@ cc_test( copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ - ":base", + ":raw_logging_internal", "//absl/strings", "@com_google_googletest//:gtest_main", ], @@ -543,7 +552,7 @@ cc_library( visibility = [ "//absl:__subpackages__", ], - deps = [":base"], + deps = [":raw_logging_internal"], ) cc_test( @@ -565,7 +574,6 @@ cc_test( copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ - ":base", ":log_severity", "@com_google_googletest//:gtest_main", ], diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index cc7960e3..bd56b5c3 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt @@ -39,6 +39,15 @@ absl_cc_library( absl_cc_library( NAME raw_logging_internal + HDRS + "internal/raw_logging.h" + SRCS + "internal/raw_logging.cc" + DEPS + absl::atomic_hook + absl::config + absl::core_headers + absl::log_severity COPTS ${ABSL_DEFAULT_COPTS} ) @@ -119,6 +128,7 @@ absl_cc_library( absl::config absl::core_headers absl::dynamic_annotations + absl::raw_logging_internal absl::spinlock_wait Threads::Threads ) @@ -146,7 +156,6 @@ absl_cc_library( "internal/cycleclock.h" "internal/low_level_scheduling.h" "internal/per_thread_tls.h" - "internal/raw_logging.h" "internal/spinlock.h" "internal/sysinfo.h" "internal/thread_identity.h" @@ -155,7 +164,6 @@ absl_cc_library( "log_severity.h" SRCS "internal/cycleclock.cc" - "internal/raw_logging.cc" "internal/spinlock.cc" "internal/sysinfo.cc" "internal/thread_identity.cc" @@ -170,6 +178,7 @@ absl_cc_library( absl::core_headers absl::dynamic_annotations absl::log_severity + absl::raw_logging_internal absl::spinlock_wait absl::type_traits Threads::Threads @@ -187,7 +196,8 @@ absl_cc_library( ${ABSL_DEFAULT_COPTS} ${ABSL_EXCEPTIONS_FLAG} DEPS - absl::base + absl::config + absl::raw_logging_internal ) absl_cc_library( @@ -415,7 +425,7 @@ absl_cc_test( COPTS ${ABSL_TEST_COPTS} DEPS - absl::base + absl::raw_logging_internal absl::strings gtest_main ) @@ -493,7 +503,7 @@ absl_cc_library( COPTS ${ABSL_DEFAULT_COPTS} DEPS - absl::base + absl::raw_logging_internal ) absl_cc_test( @@ -525,7 +535,6 @@ absl_cc_test( SRCS "log_severity_test.cc" DEPS - absl::base absl::log_severity gmock gtest_main diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index 1859d9e9..90f4d0b7 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -166,9 +166,9 @@ cc_test( ":counting_allocator", ":inlined_vector", ":test_instance_tracker", - "//absl/base", "//absl/base:core_headers", "//absl/base:exception_testing", + "//absl/base:raw_logging_internal", "//absl/hash:hash_testing", "//absl/memory", "//absl/strings", @@ -185,9 +185,9 @@ cc_test( ":counting_allocator", ":inlined_vector", ":test_instance_tracker", - "//absl/base", "//absl/base:core_headers", "//absl/base:exception_testing", + "//absl/base:raw_logging_internal", "//absl/hash:hash_testing", "//absl/memory", "//absl/strings", @@ -203,8 +203,8 @@ cc_test( tags = ["benchmark"], deps = [ ":inlined_vector", - "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", "//absl/strings", "@com_github_google_benchmark//:benchmark_main", ], @@ -635,6 +635,7 @@ cc_test( ":raw_hash_set", "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", "//absl/strings", "@com_google_googletest//:gtest_main", ], @@ -678,8 +679,8 @@ cc_test( visibility = ["//visibility:private"], deps = [ ":layout", - "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", "//absl/types:span", "@com_google_googletest//:gtest_main", ], @@ -884,7 +885,7 @@ cc_test( ":btree_test_common", ":counting_allocator", ":test_instance_tracker", - "//absl/base", + "//absl/base:raw_logging_internal", "//absl/flags:flag", "//absl/hash:hash_testing", "//absl/memory", diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index 6cabe0c9..fb966ec7 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt @@ -72,13 +72,13 @@ absl_cc_test( SRCS "btree_test.cc" DEPS - absl::base absl::btree absl::btree_test_common absl::compare absl::counting_allocator absl::flags absl::hash_testing + absl::raw_logging_internal absl::strings absl::test_instance_tracker absl::type_traits @@ -235,11 +235,11 @@ absl_cc_test( absl::counting_allocator absl::inlined_vector absl::test_instance_tracker - absl::base absl::core_headers absl::exception_testing absl::hash_testing absl::memory + absl::raw_logging_internal absl::strings gmock_main ) @@ -254,11 +254,11 @@ absl_cc_test( DEPS absl::inlined_vector absl::test_instance_tracker - absl::base absl::core_headers absl::exception_testing absl::hash_testing absl::memory + absl::raw_logging_internal absl::strings gmock_main ) @@ -715,6 +715,7 @@ absl_cc_test( absl::raw_hash_set absl::base absl::core_headers + absl::raw_logging_internal absl::strings gmock_main ) @@ -758,8 +759,8 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::layout - absl::base absl::core_headers + absl::raw_logging_internal absl::span gmock_main ) diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel index 913cfafb..760c481f 100644 --- a/absl/debugging/BUILD.bazel +++ b/absl/debugging/BUILD.bazel @@ -37,7 +37,6 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":debugging_internal", - "//absl/base", "//absl/base:core_headers", ], ) @@ -63,6 +62,7 @@ cc_library( "//absl/base:core_headers", "//absl/base:dynamic_annotations", "//absl/base:malloc_internal", + "//absl/base:raw_logging_internal", ], ) @@ -76,6 +76,7 @@ cc_test( ":symbolize", "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", "//absl/memory", "@com_google_googletest//:gtest", ], @@ -95,8 +96,8 @@ cc_library( deps = [ ":stacktrace", ":symbolize", - "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", ], ) @@ -112,6 +113,7 @@ cc_library( "//absl/base", "//absl/base:config", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", ], ) @@ -127,7 +129,7 @@ cc_test( ":failure_signal_handler", ":stacktrace", ":symbolize", - "//absl/base", + "//absl/base:raw_logging_internal", "//absl/strings", "@com_google_googletest//:gtest", ], @@ -156,9 +158,9 @@ cc_library( copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ - "//absl/base", "//absl/base:core_headers", "//absl/base:dynamic_annotations", + "//absl/base:raw_logging_internal", ], ) @@ -181,8 +183,8 @@ cc_test( deps = [ ":demangle_internal", ":stack_consumption", - "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", "//absl/memory", "@com_google_googletest//:gtest_main", ], @@ -292,8 +294,8 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, visibility = ["//visibility:private"], deps = [ - "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", ], ) @@ -304,8 +306,8 @@ cc_test( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":stack_consumption", - "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", "@com_google_googletest//:gtest_main", ], ) diff --git a/absl/debugging/CMakeLists.txt b/absl/debugging/CMakeLists.txt index 001e2727..c409e33e 100644 --- a/absl/debugging/CMakeLists.txt +++ b/absl/debugging/CMakeLists.txt @@ -25,7 +25,6 @@ absl_cc_library( ${ABSL_DEFAULT_COPTS} DEPS absl::debugging_internal - absl::base absl::core_headers PUBLIC ) @@ -52,6 +51,7 @@ absl_cc_library( absl::core_headers absl::dynamic_annotations absl::malloc_internal + absl::raw_logging_internal PUBLIC ) @@ -68,6 +68,7 @@ absl_cc_test( absl::base absl::core_headers absl::memory + absl::raw_logging_internal gmock ) @@ -83,8 +84,8 @@ absl_cc_library( DEPS absl::stacktrace absl::symbolize - absl::base absl::core_headers + absl::raw_logging_internal ) absl_cc_library( @@ -102,6 +103,7 @@ absl_cc_library( absl::base absl::config absl::core_headers + absl::raw_logging_internal PUBLIC ) @@ -116,8 +118,8 @@ absl_cc_test( absl::failure_signal_handler absl::stacktrace absl::symbolize - absl::base absl::strings + absl::raw_logging_internal Threads::Threads gmock ) @@ -144,9 +146,9 @@ absl_cc_library( COPTS ${ABSL_DEFAULT_COPTS} DEPS - absl::base absl::core_headers absl::dynamic_annotations + absl::raw_logging_internal ) absl_cc_library( @@ -174,9 +176,9 @@ absl_cc_test( DEPS absl::demangle_internal absl::stack_consumption - absl::base absl::core_headers absl::memory + absl::raw_logging_internal gmock_main ) @@ -273,6 +275,7 @@ absl_cc_test( absl::leak_check_api_enabled_for_testing absl::leak_check_disable absl::base + absl::raw_logging_internal gmock_main ) @@ -286,8 +289,8 @@ absl_cc_library( COPTS ${ABSL_DEFAULT_COPTS} DEPS - absl::base absl::core_headers + absl::raw_logging_internal TESTONLY ) @@ -300,8 +303,8 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::stack_consumption - absl::base absl::core_headers + absl::raw_logging_internal gmock_main ) diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel index 2fe61eaa..4720791a 100644 --- a/absl/flags/BUILD.bazel +++ b/absl/flags/BUILD.bazel @@ -97,8 +97,8 @@ cc_library( deps = [ ":config", ":marshalling", - "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", "//absl/strings", "//absl/synchronization", "//absl/types:optional", @@ -123,9 +123,9 @@ cc_library( deps = [ ":config", ":handle", - "//absl/base", "//absl/base:core_headers", "//absl/base:dynamic_annotations", + "//absl/base:raw_logging_internal", "//absl/strings", "//absl/synchronization", ], @@ -306,7 +306,7 @@ cc_test( deps = [ ":flag", ":parse", - "//absl/base", + "//absl/base:raw_logging_internal", "//absl/base:scoped_set_env", "//absl/strings", "//absl/types:span", diff --git a/absl/flags/CMakeLists.txt b/absl/flags/CMakeLists.txt index fa1d4e17..9860979c 100644 --- a/absl/flags/CMakeLists.txt +++ b/absl/flags/CMakeLists.txt @@ -84,11 +84,11 @@ absl_cc_library( DEPS absl::flags_config absl::flags_marshalling - absl::base absl::core_headers + absl::optional + absl::raw_logging_internal absl::strings absl::synchronization - absl::optional ) # Internal-only target, do not depend on directly. @@ -108,9 +108,9 @@ absl_cc_library( DEPS absl::flags_config absl::flags_handle - absl::base absl::core_headers absl::dynamic_annotations + absl::raw_logging_internal absl::strings absl::synchronization ) @@ -265,8 +265,8 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::flags - absl::base absl::flags_parse + absl::raw_logging_internal absl::scoped_set_env absl::span absl::strings diff --git a/absl/memory/BUILD.bazel b/absl/memory/BUILD.bazel index f815ef94..4dba6366 100644 --- a/absl/memory/BUILD.bazel +++ b/absl/memory/BUILD.bazel @@ -45,7 +45,6 @@ cc_test( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":memory", - "//absl/base", "//absl/base:core_headers", "@com_google_googletest//:gtest_main", ], diff --git a/absl/memory/CMakeLists.txt b/absl/memory/CMakeLists.txt index 0a812203..1b3697ec 100644 --- a/absl/memory/CMakeLists.txt +++ b/absl/memory/CMakeLists.txt @@ -36,7 +36,6 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::memory - absl::base absl::core_headers gmock_main ) diff --git a/absl/random/BUILD.bazel b/absl/random/BUILD.bazel index f7587bf9..d09f0cb3 100644 --- a/absl/random/BUILD.bazel +++ b/absl/random/BUILD.bazel @@ -119,7 +119,7 @@ cc_test( deps = [ ":distributions", ":random", - "//absl/base", + "//absl/base:raw_logging_internal", "//absl/random/internal:distribution_test_util", "//absl/random/internal:sequence_urbg", "//absl/strings", @@ -168,8 +168,8 @@ cc_test( deps = [ ":distributions", ":random", - "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", "//absl/random/internal:distribution_test_util", "//absl/random/internal:sequence_urbg", "//absl/strings", @@ -189,7 +189,7 @@ cc_test( deps = [ ":distributions", ":random", - "//absl/base", + "//absl/base:raw_logging_internal", "//absl/random/internal:distribution_test_util", "//absl/random/internal:sequence_urbg", "//absl/strings", @@ -214,8 +214,8 @@ cc_test( deps = [ ":distributions", ":random", - "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", "//absl/container:flat_hash_map", "//absl/random/internal:distribution_test_util", "//absl/random/internal:sequence_urbg", @@ -234,8 +234,8 @@ cc_test( deps = [ ":distributions", ":random", - "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", "//absl/random/internal:distribution_test_util", "//absl/random/internal:sequence_urbg", "//absl/strings", @@ -256,8 +256,8 @@ cc_test( deps = [ ":distributions", ":random", - "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", "//absl/random/internal:distribution_test_util", "//absl/random/internal:sequence_urbg", "//absl/strings", @@ -278,7 +278,7 @@ cc_test( deps = [ ":distributions", ":random", - "//absl/base", + "//absl/base:raw_logging_internal", "//absl/random/internal:distribution_test_util", "//absl/random/internal:sequence_urbg", "//absl/strings", @@ -302,7 +302,7 @@ cc_test( deps = [ ":distributions", ":random", - "//absl/base", + "//absl/base:raw_logging_internal", "//absl/random/internal:distribution_test_util", "//absl/random/internal:sequence_urbg", "//absl/strings", @@ -321,7 +321,7 @@ cc_test( deps = [ ":distributions", ":random", - "//absl/base", + "//absl/base:raw_logging_internal", "//absl/random/internal:distribution_test_util", "//absl/random/internal:sequence_urbg", "//absl/strings", diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt index 2d5c0658..7603690d 100644 --- a/absl/random/CMakeLists.txt +++ b/absl/random/CMakeLists.txt @@ -137,9 +137,9 @@ absl_cc_test( DEPS absl::random_distributions absl::random_random - absl::base absl::random_internal_distribution_test_util absl::random_internal_sequence_urbg + absl::raw_logging_internal absl::strings absl::str_format gmock @@ -174,6 +174,7 @@ absl_cc_test( ${ABSL_DEFAULT_LINKOPTS} absl::random_distributions absl::random_random + absl::raw_logging_internal gmock gtest_main ) @@ -187,12 +188,12 @@ absl_cc_test( ${ABSL_TEST_COPTS} LINKOPTS ${ABSL_DEFAULT_LINKOPTS} - absl::base absl::core_headers absl::random_distributions absl::random_internal_distribution_test_util absl::random_internal_sequence_urbg absl::random_random + absl::raw_logging_internal absl::strings absl::str_format gmock @@ -209,11 +210,11 @@ absl_cc_test( LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS - absl::base absl::random_distributions absl::random_internal_distribution_test_util absl::random_internal_sequence_urbg absl::random_random + absl::raw_logging_internal absl::strings gmock gtest_main @@ -231,11 +232,11 @@ absl_cc_test( DEPS absl::random_distributions absl::random_random - absl::base absl::core_headers absl::flat_hash_map absl::random_internal_distribution_test_util absl::random_internal_sequence_urbg + absl::raw_logging_internal absl::strings absl::str_format gmock @@ -252,12 +253,12 @@ absl_cc_test( LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS - absl::base absl::core_headers absl::random_distributions absl::random_internal_distribution_test_util absl::random_internal_sequence_urbg absl::random_random + absl::raw_logging_internal absl::strings absl::str_format gmock @@ -274,12 +275,12 @@ absl_cc_test( LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS - absl::base absl::core_headers absl::random_distributions absl::random_internal_distribution_test_util absl::random_internal_sequence_urbg absl::random_random + absl::raw_logging_internal absl::strings absl::str_format gmock @@ -296,11 +297,11 @@ absl_cc_test( LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS - absl::base absl::random_distributions absl::random_internal_distribution_test_util absl::random_internal_sequence_urbg absl::random_random + absl::raw_logging_internal absl::strings gmock gtest_main @@ -316,7 +317,6 @@ absl_cc_test( LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS - absl::base absl::random_distributions absl::random_internal_distribution_test_util absl::random_internal_sequence_urbg @@ -336,11 +336,11 @@ absl_cc_test( LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS - absl::base absl::random_distributions absl::random_internal_distribution_test_util absl::random_internal_sequence_urbg absl::random_random + absl::raw_logging_internal absl::strings gmock gtest_main @@ -449,10 +449,10 @@ absl_cc_library( LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS - absl::base absl::core_headers absl::optional absl::random_internal_fast_uniform_bits + absl::raw_logging_internal absl::span absl::strings ) @@ -478,6 +478,7 @@ absl_cc_library( absl::random_internal_seed_material absl::random_internal_traits absl::random_seed_gen_exception + absl::raw_logging_internal absl::span ) @@ -624,6 +625,7 @@ absl_cc_library( DEPS absl::random_internal_iostream_state_saver absl::random_internal_randen + absl::raw_logging_internal absl::type_traits ) @@ -654,7 +656,6 @@ absl_cc_library( LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS - absl::base absl::random_internal_platform absl::random_internal_randen_hwaes absl::random_internal_randen_slow @@ -726,8 +727,8 @@ absl_cc_library( LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS - absl::base absl::core_headers + absl::raw_logging_internal absl::strings absl::str_format absl::span @@ -941,9 +942,9 @@ absl_cc_test( LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS - absl::base absl::random_internal_explicit_seed_seq absl::random_internal_randen_engine + absl::raw_logging_internal absl::strings absl::time gmock @@ -995,7 +996,7 @@ absl_cc_test( absl::random_internal_platform absl::random_internal_randen_hwaes absl::random_internal_randen_hwaes_impl - absl::base + absl::raw_logging_internal absl::str_format gmock gtest diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel index fd5471a6..7416e936 100644 --- a/absl/random/internal/BUILD.bazel +++ b/absl/random/internal/BUILD.bazel @@ -78,8 +78,8 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":fast_uniform_bits", - "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", "//absl/strings", "//absl/types:optional", "//absl/types:span", @@ -107,6 +107,7 @@ cc_library( "//absl/base:config", "//absl/base:core_headers", "//absl/base:endian", + "//absl/base:raw_logging_internal", "//absl/random:seed_gen_exception", "//absl/types:span", ], @@ -255,7 +256,7 @@ cc_library( ":platform", ":randen_hwaes", ":randen_slow", - "//absl/base", + "//absl/base:raw_logging_internal", ], ) @@ -334,8 +335,8 @@ cc_library( copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ - "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", "//absl/strings", "//absl/strings:str_format", "//absl/types:span", @@ -531,7 +532,7 @@ cc_test( deps = [ ":explicit_seed_seq", ":randen_engine", - "//absl/base", + "//absl/base:raw_logging_internal", "//absl/strings", "//absl/time", "@com_google_googletest//:gtest_main", @@ -574,7 +575,7 @@ cc_test( ":platform", ":randen_hwaes", ":randen_hwaes_impl", # build_cleaner: keep - "//absl/base", + "//absl/base:raw_logging_internal", "//absl/strings:str_format", "@com_google_googletest//:gtest", ], @@ -588,7 +589,7 @@ cc_library( deps = [ ":platform", ":randen_engine", - "//absl/base", + "//absl/base:raw_logging_internal", ], ) @@ -620,7 +621,7 @@ cc_test( ], deps = [ ":nanobenchmark", - "//absl/base", + "//absl/base:raw_logging_internal", "//absl/strings", ], ) @@ -641,7 +642,7 @@ cc_test( ":randen_hwaes", ":randen_hwaes_impl", ":randen_slow", - "//absl/base", + "//absl/base:raw_logging_internal", "//absl/strings", ], ) diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel index 20511a35..9679dc30 100644 --- a/absl/strings/BUILD.bazel +++ b/absl/strings/BUILD.bazel @@ -73,6 +73,7 @@ cc_library( "//absl/base:config", "//absl/base:core_headers", "//absl/base:endian", + "//absl/base:raw_logging_internal", "//absl/base:throw_delegate", "//absl/memory", "//absl/meta:type_traits", @@ -140,7 +141,7 @@ cc_test( visibility = ["//visibility:private"], deps = [ ":strings", - "//absl/base", + "//absl/base:raw_logging_internal", "@com_github_google_benchmark//:benchmark_main", ], ) @@ -225,8 +226,8 @@ cc_test( visibility = ["//visibility:private"], deps = [ ":strings", - "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", "@com_github_google_benchmark//:benchmark_main", ], ) @@ -268,7 +269,7 @@ cc_test( visibility = ["//visibility:private"], deps = [ ":strings", - "//absl/base", + "//absl/base:raw_logging_internal", "@com_github_google_benchmark//:benchmark_main", ], ) @@ -306,7 +307,7 @@ cc_test( visibility = ["//visibility:private"], deps = [ ":strings", - "//absl/base", + "//absl/base:raw_logging_internal", "@com_github_google_benchmark//:benchmark_main", ], ) @@ -414,8 +415,8 @@ cc_test( deps = [ ":pow10_helper", ":strings", - "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", "@com_google_googletest//:gtest_main", ], ) @@ -428,7 +429,7 @@ cc_test( visibility = ["//visibility:private"], deps = [ ":strings", - "//absl/base", + "//absl/base:raw_logging_internal", "@com_github_google_benchmark//:benchmark_main", ], ) @@ -474,7 +475,6 @@ cc_test( ":pow10_helper", ":str_format", ":strings", - "//absl/base", "@com_google_googletest//:gtest_main", ], ) @@ -488,7 +488,7 @@ cc_test( copts = ABSL_TEST_COPTS, deps = [ ":strings", - "//absl/base", + "//absl/base:raw_logging_internal", "@com_google_googletest//:gtest_main", ], ) @@ -503,7 +503,6 @@ cc_test( copts = ABSL_TEST_COPTS, deps = [ ":strings", - "//absl/base", "@com_google_googletest//:gtest_main", ], ) @@ -518,7 +517,6 @@ cc_test( ], deps = [ ":strings", - "//absl/base", "@com_github_google_benchmark//:benchmark_main", ], ) diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt index e63eec19..82a906b7 100644 --- a/absl/strings/CMakeLists.txt +++ b/absl/strings/CMakeLists.txt @@ -59,10 +59,11 @@ absl_cc_library( absl::config absl::core_headers absl::endian - absl::throw_delegate + absl::int128 absl::memory + absl::raw_logging_internal + absl::throw_delegate absl::type_traits - absl::int128 PUBLIC ) @@ -276,9 +277,9 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::strings - absl::base absl::core_headers absl::pow10_helper + absl::raw_logging_internal gmock_main ) @@ -317,7 +318,6 @@ absl_cc_test( DEPS absl::strings absl::str_format - absl::base absl::pow10_helper gmock_main ) @@ -332,7 +332,7 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::strings - absl::base + absl::raw_logging_internal gmock_main ) @@ -347,7 +347,6 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::strings - absl::base gmock_main ) diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel index fca8cb69..d40d861f 100644 --- a/absl/synchronization/BUILD.bazel +++ b/absl/synchronization/BUILD.bazel @@ -44,6 +44,7 @@ cc_library( "//absl/base:base_internal", "//absl/base:core_headers", "//absl/base:malloc_internal", + "//absl/base:raw_logging_internal", ], ) @@ -84,6 +85,7 @@ cc_library( "//absl/base:core_headers", "//absl/base:dynamic_annotations", "//absl/base:malloc_internal", + "//absl/base:raw_logging_internal", "//absl/debugging:stacktrace", "//absl/debugging:symbolize", "//absl/time", @@ -124,8 +126,8 @@ cc_test( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":graphcycles_internal", - "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", "@com_google_googletest//:gtest_main", ], ) @@ -140,7 +142,7 @@ cc_test( ], deps = [ ":graphcycles_internal", - "//absl/base", + "//absl/base:raw_logging_internal", "@com_github_google_benchmark//:benchmark_main", ], ) @@ -171,6 +173,7 @@ cc_test( ":thread_pool", "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", "//absl/memory", "//absl/time", "@com_google_googletest//:gtest_main", @@ -243,7 +246,6 @@ cc_test( deps = [ ":per_thread_sem_test_common", ":synchronization", - "//absl/base", "//absl/strings", "//absl/time", "@com_google_googletest//:gtest_main", @@ -260,7 +262,7 @@ cc_test( tags = ["no_test_ios_x86_64"], deps = [ ":synchronization", - "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", ], ) diff --git a/absl/synchronization/CMakeLists.txt b/absl/synchronization/CMakeLists.txt index 4b708823..ce669c52 100644 --- a/absl/synchronization/CMakeLists.txt +++ b/absl/synchronization/CMakeLists.txt @@ -28,6 +28,7 @@ absl_cc_library( absl::base_internal absl::core_headers absl::malloc_internal + absl::raw_logging_internal ) absl_cc_library( @@ -62,6 +63,7 @@ absl_cc_library( absl::core_headers absl::dynamic_annotations absl::malloc_internal + absl::raw_logging_internal absl::stacktrace absl::symbolize absl::time @@ -104,8 +106,8 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::graphcycles_internal - absl::base absl::core_headers + absl::raw_logging_internal gmock_main ) @@ -135,6 +137,7 @@ absl_cc_test( absl::base absl::core_headers absl::memory + absl::raw_logging_internal absl::time gmock_main ) @@ -178,7 +181,6 @@ absl_cc_test( DEPS absl::per_thread_sem_test_common absl::synchronization - absl::base absl::strings absl::time gmock_main @@ -193,6 +195,6 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::synchronization - absl::base absl::core_headers + absl::raw_logging_internal ) diff --git a/absl/time/BUILD.bazel b/absl/time/BUILD.bazel index 55e83a8c..1c387e46 100644 --- a/absl/time/BUILD.bazel +++ b/absl/time/BUILD.bazel @@ -46,6 +46,7 @@ cc_library( deps = [ "//absl/base", "//absl/base:core_headers", + "//absl/base:raw_logging_internal", "//absl/numeric:int128", "//absl/strings", "//absl/time/internal/cctz:civil_time", @@ -68,7 +69,7 @@ cc_library( ], deps = [ ":time", - "//absl/base", + "//absl/base:raw_logging_internal", "//absl/time/internal/cctz:time_zone", "@com_google_googletest//:gtest", ], @@ -89,7 +90,6 @@ cc_test( deps = [ ":test_util", ":time", - "//absl/base", "//absl/base:config", "//absl/base:core_headers", "//absl/time/internal/cctz:time_zone", diff --git a/absl/time/CMakeLists.txt b/absl/time/CMakeLists.txt index 59098321..853563e8 100644 --- a/absl/time/CMakeLists.txt +++ b/absl/time/CMakeLists.txt @@ -22,21 +22,22 @@ absl_cc_library( "clock.h" "time.h" SRCS - "civil_time.cc" - "clock.cc" - "duration.cc" - "format.cc" - "internal/get_current_time_chrono.inc" - "internal/get_current_time_posix.inc" - "time.cc" + "civil_time.cc" + "clock.cc" + "duration.cc" + "format.cc" + "internal/get_current_time_chrono.inc" + "internal/get_current_time_posix.inc" + "time.cc" COPTS ${ABSL_DEFAULT_COPTS} DEPS absl::base + absl::civil_time absl::core_headers absl::int128 + absl::raw_logging_internal absl::strings - absl::civil_time absl::time_zone PUBLIC ) @@ -88,7 +89,7 @@ absl_cc_library( absl_cc_library( NAME - test_util + time_internal_test_util HDRS "internal/test_util.h" SRCS @@ -98,7 +99,7 @@ absl_cc_library( ${ABSL_DEFAULT_COPTS} DEPS absl::time - absl::base + absl::raw_logging_internal absl::time_zone gmock TESTONLY @@ -117,9 +118,8 @@ absl_cc_test( COPTS ${ABSL_TEST_COPTS} DEPS - absl::test_util + absl::time_internal_test_util absl::time - absl::base absl::config absl::core_headers absl::time_zone diff --git a/absl/types/BUILD.bazel b/absl/types/BUILD.bazel index 66ecb044..6e287ce0 100644 --- a/absl/types/BUILD.bazel +++ b/absl/types/BUILD.bazel @@ -62,8 +62,8 @@ cc_library( linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, visibility = ["//visibility:private"], deps = [ - "//absl/base", "//absl/base:config", + "//absl/base:raw_logging_internal", ], ) @@ -77,9 +77,9 @@ cc_test( linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, deps = [ ":any", - "//absl/base", "//absl/base:config", "//absl/base:exception_testing", + "//absl/base:raw_logging_internal", "//absl/container:test_instance_tracker", "@com_google_googletest//:gtest_main", ], @@ -95,9 +95,9 @@ cc_test( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":any", - "//absl/base", "//absl/base:config", "//absl/base:exception_testing", + "//absl/base:raw_logging_internal", "//absl/container:test_instance_tracker", "@com_google_googletest//:gtest_main", ], @@ -195,8 +195,8 @@ cc_library( copts = ABSL_DEFAULT_COPTS + ABSL_EXCEPTIONS_FLAG, linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, deps = [ - "//absl/base", "//absl/base:config", + "//absl/base:raw_logging_internal", ], ) @@ -207,8 +207,8 @@ cc_library( copts = ABSL_EXCEPTIONS_FLAG + ABSL_DEFAULT_COPTS, linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, deps = [ - "//absl/base", "//absl/base:config", + "//absl/base:raw_logging_internal", ], ) @@ -222,8 +222,8 @@ cc_test( linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, deps = [ ":optional", - "//absl/base", "//absl/base:config", + "//absl/base:raw_logging_internal", "//absl/meta:type_traits", "//absl/strings", "@com_google_googletest//:gtest_main", diff --git a/absl/types/CMakeLists.txt b/absl/types/CMakeLists.txt index 4ce685da..ddae7f2a 100644 --- a/absl/types/CMakeLists.txt +++ b/absl/types/CMakeLists.txt @@ -54,8 +54,8 @@ absl_cc_library( LINKOPTS ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS - absl::base absl::config + absl::raw_logging_internal ) absl_cc_test( @@ -70,9 +70,9 @@ absl_cc_test( ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS absl::any - absl::base absl::config absl::exception_testing + absl::raw_logging_internal absl::test_instance_tracker gmock_main ) @@ -86,9 +86,9 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::any - absl::base absl::config absl::exception_testing + absl::raw_logging_internal absl::test_instance_tracker gmock_main ) @@ -202,8 +202,8 @@ absl_cc_library( LINKOPTS ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS - absl::base absl::config + absl::raw_logging_internal PUBLIC ) @@ -220,8 +220,8 @@ absl_cc_library( LINKOPTS ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS - absl::base absl::config + absl::raw_logging_internal PUBLIC ) @@ -237,10 +237,10 @@ absl_cc_test( ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS absl::optional - absl::base absl::config - absl::type_traits + absl::raw_logging_internal absl::strings + absl::type_traits gmock_main ) diff --git a/ci/linux_clang-latest_libcxx_asan_bazel.sh b/ci/linux_clang-latest_libcxx_asan_bazel.sh index 07af64d0..e18cf882 100755 --- a/ci/linux_clang-latest_libcxx_asan_bazel.sh +++ b/ci/linux_clang-latest_libcxx_asan_bazel.sh @@ -32,7 +32,7 @@ if [ -z ${COMPILATION_MODE:-} ]; then COMPILATION_MODE="fastbuild opt" fi -readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190701" +readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190813" # USE_BAZEL_CACHE=1 only works on Kokoro. # Without access to the credentials this won't work. diff --git a/ci/linux_clang-latest_libcxx_bazel.sh b/ci/linux_clang-latest_libcxx_bazel.sh index 1197369a..42bde353 100755 --- a/ci/linux_clang-latest_libcxx_bazel.sh +++ b/ci/linux_clang-latest_libcxx_bazel.sh @@ -32,7 +32,7 @@ if [ -z ${COMPILATION_MODE:-} ]; then COMPILATION_MODE="fastbuild opt" fi -readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190701" +readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190813" # USE_BAZEL_CACHE=1 only works on Kokoro. # Without access to the credentials this won't work. diff --git a/ci/linux_clang-latest_libcxx_tsan_bazel.sh b/ci/linux_clang-latest_libcxx_tsan_bazel.sh index 04171df8..452c515c 100755 --- a/ci/linux_clang-latest_libcxx_tsan_bazel.sh +++ b/ci/linux_clang-latest_libcxx_tsan_bazel.sh @@ -32,7 +32,7 @@ if [ -z ${COMPILATION_MODE:-} ]; then COMPILATION_MODE="fastbuild opt" fi -readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190701" +readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190813" # USE_BAZEL_CACHE=1 only works on Kokoro. # Without access to the credentials this won't work. diff --git a/ci/linux_clang-latest_libstdcxx_bazel.sh b/ci/linux_clang-latest_libstdcxx_bazel.sh index c2217a07..4b063ad8 100755 --- a/ci/linux_clang-latest_libstdcxx_bazel.sh +++ b/ci/linux_clang-latest_libstdcxx_bazel.sh @@ -32,7 +32,7 @@ if [ -z ${COMPILATION_MODE:-} ]; then COMPILATION_MODE="fastbuild opt" fi -readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190701" +readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190813" # USE_BAZEL_CACHE=1 only works on Kokoro. # Without access to the credentials this won't work. -- cgit v1.2.3 From 1948f6f967e34db9793cfa8b4bcbaf370d039fd8 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Fri, 30 Aug 2019 15:03:24 -0400 Subject: Export of internal Abseil changes -- bc74316103bbda92541896f588f71c9d45bea768 by Gennadiy Civil : Manually fixing the BUILD.bazel files -- d41bf9ea916a0dc8c69e6ba77f58f9d55649880e by Shaindel Schwartz : Minor cleanup to miscellaneous BUILD files. PiperOrigin-RevId: 266420157 -- 08a8dc2cbd48d27e1115809f9ca8d178551cd66e by Gennadiy Civil : Internal Change BEGIN_PUBLIC Internal Change END_PUBLIC -- 8617d58fde1ece40e4aa79eaa5e250b42d19835f by Shaindel Schwartz : Internal Change BEGIN_PUBLIC Internal Change END_PUBLIC -- 3a0fc7d48bdc70c4f7dffc219578693dea84eb2d by Derek Mauro : Implement absl::string_view::at() PiperOrigin-RevId: 266024644 -- ba53a9da8ede8fe7b8971eaab6b3a1fa34763ff6 by Andy Soffer : Remove forcing of optimization levels in MSVC. PiperOrigin-RevId: 265927588 -- df86f2046b54bba7da2e345040806d43470de5c0 by Shaindel Schwartz : Internal change PiperOrigin-RevId: 265811077 -- e2e3a6e8194363e7c6377672560c806d638a7c74 by Derek Mauro : Remove ABI unsafe mixed exceptions mode compilation. Testing will now be done on CI with the exceptions flag set globally. PiperOrigin-RevId: 265796079 GitOrigin-RevId: bc74316103bbda92541896f588f71c9d45bea768 Change-Id: Ibccd00f4829520454aa55c4f55c7cb2dc9c6b65a --- absl/base/BUILD.bazel | 19 +++--- absl/base/CMakeLists.txt | 8 +-- absl/base/exception_safety_testing_test.cc | 4 ++ absl/base/internal/exception_safety_testing.cc | 4 ++ absl/base/internal/exception_safety_testing.h | 7 ++- absl/base/throw_delegate_test.cc | 13 ++++ absl/container/BUILD.bazel | 45 ++------------ absl/container/CMakeLists.txt | 48 +-------------- .../container/fixed_array_exception_safety_test.cc | 9 ++- .../inlined_vector_exception_safety_test.cc | 9 ++- absl/copts/AbseilConfigureCopts.cmake | 8 --- absl/copts/GENERATED_AbseilCopts.cmake | 22 ------- absl/copts/GENERATED_copts.bzl | 22 ------- absl/copts/configure_copts.bzl | 13 ---- absl/copts/copts.py | 17 +----- absl/flags/BUILD.bazel | 2 +- absl/hash/BUILD.bazel | 2 +- absl/memory/BUILD.bazel | 9 ++- absl/memory/CMakeLists.txt | 4 +- absl/memory/memory_exception_safety_test.cc | 6 ++ absl/random/BUILD.bazel | 6 +- absl/random/CMakeLists.txt | 2 - absl/random/internal/BUILD.bazel | 4 +- absl/strings/BUILD.bazel | 5 +- absl/strings/CMakeLists.txt | 3 - absl/strings/string_view.h | 14 ++++- absl/strings/string_view_test.cc | 20 +++++- absl/types/BUILD.bazel | 71 +++++----------------- absl/types/CMakeLists.txt | 30 --------- absl/types/variant_test.cc | 6 +- absl/utility/BUILD.bazel | 4 +- 31 files changed, 132 insertions(+), 304 deletions(-) (limited to 'absl/random/CMakeLists.txt') diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index cd5dd74f..a2e510f8 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -19,8 +19,6 @@ load( "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", "ABSL_DEFAULT_LINKOPTS", - "ABSL_EXCEPTIONS_FLAG", - "ABSL_EXCEPTIONS_FLAG_LINKOPTS", "ABSL_TEST_COPTS", ) @@ -241,8 +239,8 @@ cc_library( name = "throw_delegate", srcs = ["internal/throw_delegate.cc"], hdrs = ["internal/throw_delegate.h"], - copts = ABSL_DEFAULT_COPTS + ABSL_EXCEPTIONS_FLAG, - linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, + copts = ABSL_DEFAULT_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, visibility = [ "//absl:__subpackages__", ], @@ -255,9 +253,10 @@ cc_library( cc_test( name = "throw_delegate_test", srcs = ["throw_delegate_test.cc"], - copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, - linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ + ":config", ":throw_delegate", "@com_google_googletest//:gtest_main", ], @@ -290,8 +289,8 @@ cc_library( testonly = 1, srcs = ["internal/exception_safety_testing.cc"], hdrs = ["internal/exception_safety_testing.h"], - copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, - linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":config", ":pretty_function", @@ -306,8 +305,8 @@ cc_library( cc_test( name = "exception_safety_testing_test", srcs = ["exception_safety_testing_test.cc"], - copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, - linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":exception_safety_testing", "//absl/memory", diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index bd56b5c3..15a92f5f 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt @@ -194,7 +194,6 @@ absl_cc_library( "internal/throw_delegate.cc" COPTS ${ABSL_DEFAULT_COPTS} - ${ABSL_EXCEPTIONS_FLAG} DEPS absl::config absl::raw_logging_internal @@ -231,9 +230,6 @@ absl_cc_library( "internal/exception_safety_testing.cc" COPTS ${ABSL_TEST_COPTS} - ${ABSL_EXCEPTIONS_FLAG} - LINKOPTS - ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS absl::config absl::pretty_function @@ -252,9 +248,6 @@ absl_cc_test( "exception_safety_testing_test.cc" COPTS ${ABSL_TEST_COPTS} - ${ABSL_EXCEPTIONS_FLAG} - LINKOPTS - ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS absl::exception_safety_testing absl::memory @@ -296,6 +289,7 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::base + absl::config absl::throw_delegate gtest_main ) diff --git a/absl/base/exception_safety_testing_test.cc b/absl/base/exception_safety_testing_test.cc index 2ed38606..575b535d 100644 --- a/absl/base/exception_safety_testing_test.cc +++ b/absl/base/exception_safety_testing_test.cc @@ -14,6 +14,8 @@ #include "absl/base/internal/exception_safety_testing.h" +#ifdef ABSL_HAVE_EXCEPTIONS + #include #include #include @@ -952,3 +954,5 @@ TEST(ThrowingAllocatorTraitsTest, Assignablility) { } // namespace } // namespace testing + +#endif // ABSL_HAVE_EXCEPTIONS diff --git a/absl/base/internal/exception_safety_testing.cc b/absl/base/internal/exception_safety_testing.cc index 6ef4325c..6ccac418 100644 --- a/absl/base/internal/exception_safety_testing.cc +++ b/absl/base/internal/exception_safety_testing.cc @@ -14,6 +14,8 @@ #include "absl/base/internal/exception_safety_testing.h" +#ifdef ABSL_HAVE_EXCEPTIONS + #include "gtest/gtest.h" #include "absl/meta/type_traits.h" @@ -73,3 +75,5 @@ std::string GetSpecString(AllocSpec spec) { } // namespace exceptions_internal } // namespace testing + +#endif // ABSL_HAVE_EXCEPTIONS diff --git a/absl/base/internal/exception_safety_testing.h b/absl/base/internal/exception_safety_testing.h index be38ba54..6ba89d05 100644 --- a/absl/base/internal/exception_safety_testing.h +++ b/absl/base/internal/exception_safety_testing.h @@ -17,6 +17,10 @@ #ifndef ABSL_BASE_INTERNAL_EXCEPTION_SAFETY_TESTING_H_ #define ABSL_BASE_INTERNAL_EXCEPTION_SAFETY_TESTING_H_ +#include "absl/base/config.h" + +#ifdef ABSL_HAVE_EXCEPTIONS + #include #include #include @@ -27,7 +31,6 @@ #include #include "gtest/gtest.h" -#include "absl/base/config.h" #include "absl/base/internal/pretty_function.h" #include "absl/memory/memory.h" #include "absl/meta/type_traits.h" @@ -1093,4 +1096,6 @@ class ExceptionSafetyTestBuilder { } // namespace testing +#endif // ABSL_HAVE_EXCEPTIONS + #endif // ABSL_BASE_INTERNAL_EXCEPTION_SAFETY_TESTING_H_ diff --git a/absl/base/throw_delegate_test.cc b/absl/base/throw_delegate_test.cc index a74dd3cd..5ba4ce55 100644 --- a/absl/base/throw_delegate_test.cc +++ b/absl/base/throw_delegate_test.cc @@ -18,6 +18,7 @@ #include #include +#include "absl/base/config.h" #include "gtest/gtest.h" namespace { @@ -38,31 +39,43 @@ constexpr const char* what_arg = "The quick brown fox jumps over the lazy dog"; template void ExpectThrowChar(void (*f)(const char*)) { +#ifdef ABSL_HAVE_EXCEPTIONS try { f(what_arg); FAIL() << "Didn't throw"; } catch (const E& e) { EXPECT_STREQ(e.what(), what_arg); } +#else + EXPECT_DEATH_IF_SUPPORTED(f(what_arg), what_arg); +#endif } template void ExpectThrowString(void (*f)(const std::string&)) { +#ifdef ABSL_HAVE_EXCEPTIONS try { f(what_arg); FAIL() << "Didn't throw"; } catch (const E& e) { EXPECT_STREQ(e.what(), what_arg); } +#else + EXPECT_DEATH_IF_SUPPORTED(f(what_arg), what_arg); +#endif } template void ExpectThrowNoWhat(void (*f)()) { +#ifdef ABSL_HAVE_EXCEPTIONS try { f(); FAIL() << "Didn't throw"; } catch (const E& e) { } +#else + EXPECT_DEATH_IF_SUPPORTED(f(), ""); +#endif } TEST(ThrowHelper, Test) { diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index 19c538bc..0894bb20 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -19,8 +19,6 @@ load( "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", "ABSL_DEFAULT_LINKOPTS", - "ABSL_EXCEPTIONS_FLAG", - "ABSL_EXCEPTIONS_FLAG_LINKOPTS", "ABSL_TEST_COPTS", ) @@ -72,20 +70,6 @@ cc_library( cc_test( name = "fixed_array_test", srcs = ["fixed_array_test.cc"], - copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, - linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, - deps = [ - ":fixed_array", - "//absl/base:exception_testing", - "//absl/hash:hash_testing", - "//absl/memory", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "fixed_array_test_noexceptions", - srcs = ["fixed_array_test.cc"], copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ @@ -100,10 +84,11 @@ cc_test( cc_test( name = "fixed_array_exception_safety_test", srcs = ["fixed_array_exception_safety_test.cc"], - copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, - linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":fixed_array", + "//absl/base:config", "//absl/base:exception_safety_testing", "@com_google_googletest//:gtest_main", ], @@ -161,25 +146,6 @@ cc_library( cc_test( name = "inlined_vector_test", srcs = ["inlined_vector_test.cc"], - copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, - linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, - deps = [ - ":counting_allocator", - ":inlined_vector", - ":test_instance_tracker", - "//absl/base:core_headers", - "//absl/base:exception_testing", - "//absl/base:raw_logging_internal", - "//absl/hash:hash_testing", - "//absl/memory", - "//absl/strings", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "inlined_vector_test_noexceptions", - srcs = ["inlined_vector_test.cc"], copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ @@ -214,9 +180,10 @@ cc_test( cc_test( name = "inlined_vector_exception_safety_test", srcs = ["inlined_vector_exception_safety_test.cc"], - copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, + copts = ABSL_TEST_COPTS, deps = [ ":inlined_vector", + "//absl/base:config", "//absl/base:exception_safety_testing", "@com_google_googletest//:gtest_main", ], @@ -878,7 +845,7 @@ cc_test( srcs = [ "btree_test.cc", ], - copts = ABSL_TEST_COPTS + ["-fexceptions"], + copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, shard_count = 10, visibility = ["//visibility:private"], diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index 111cc783..933c7a8c 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt @@ -141,24 +141,6 @@ absl_cc_test( fixed_array_test SRCS "fixed_array_test.cc" - COPTS - ${ABSL_TEST_COPTS} - ${ABSL_EXCEPTIONS_FLAG} - LINKOPTS - ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} - DEPS - absl::fixed_array - absl::exception_testing - absl::hash_testing - absl::memory - gmock_main -) - -absl_cc_test( - NAME - fixed_array_test_noexceptions - SRCS - "fixed_array_test.cc" COPTS ${ABSL_TEST_COPTS} DEPS @@ -176,11 +158,9 @@ absl_cc_test( "fixed_array_exception_safety_test.cc" COPTS ${ABSL_TEST_COPTS} - ${ABSL_EXCEPTIONS_FLAG} - LINKOPTS - ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS absl::fixed_array + absl::config absl::exception_safety_testing gmock_main ) @@ -233,9 +213,6 @@ absl_cc_test( "inlined_vector_test.cc" COPTS ${ABSL_TEST_COPTS} - ${ABSL_EXCEPTIONS_FLAG} - LINKOPTS - ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS absl::counting_allocator absl::inlined_vector @@ -249,25 +226,6 @@ absl_cc_test( gmock_main ) -absl_cc_test( - NAME - inlined_vector_test_noexceptions - SRCS - "inlined_vector_test.cc" - COPTS - ${ABSL_TEST_COPTS} - DEPS - absl::inlined_vector - absl::test_instance_tracker - absl::core_headers - absl::exception_testing - absl::hash_testing - absl::memory - absl::raw_logging_internal - absl::strings - gmock_main -) - absl_cc_test( NAME inlined_vector_exception_safety_test @@ -275,11 +233,9 @@ absl_cc_test( "inlined_vector_exception_safety_test.cc" COPTS ${ABSL_TEST_COPTS} - ${ABSL_EXCEPTIONS_FLAG} - LINKOPTS - ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS absl::inlined_vector + absl::config absl::exception_safety_testing gmock_main ) diff --git a/absl/container/fixed_array_exception_safety_test.cc b/absl/container/fixed_array_exception_safety_test.cc index 9984a5e2..9aabfd5c 100644 --- a/absl/container/fixed_array_exception_safety_test.cc +++ b/absl/container/fixed_array_exception_safety_test.cc @@ -12,11 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "absl/container/fixed_array.h" + +#include "absl/base/config.h" + +#ifdef ABSL_HAVE_EXCEPTIONS + #include #include "gtest/gtest.h" #include "absl/base/internal/exception_safety_testing.h" -#include "absl/container/fixed_array.h" namespace absl { @@ -114,3 +119,5 @@ TEST(FixedArrayExceptionSafety, Fill) { } // namespace } // namespace absl + +#endif // ABSL_HAVE_EXCEPTIONS diff --git a/absl/container/inlined_vector_exception_safety_test.cc b/absl/container/inlined_vector_exception_safety_test.cc index b4fff325..25994f16 100644 --- a/absl/container/inlined_vector_exception_safety_test.cc +++ b/absl/container/inlined_vector_exception_safety_test.cc @@ -12,6 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "absl/container/inlined_vector.h" + +#include "absl/base/config.h" + +#ifdef ABSL_HAVE_EXCEPTIONS + #include #include #include @@ -20,7 +26,6 @@ #include "gtest/gtest.h" #include "absl/base/internal/exception_safety_testing.h" -#include "absl/container/inlined_vector.h" namespace { @@ -487,3 +492,5 @@ TYPED_TEST(TwoSizeTest, Swap) { } } // namespace + +#endif // ABSL_HAVE_EXCEPTIONS diff --git a/absl/copts/AbseilConfigureCopts.cmake b/absl/copts/AbseilConfigureCopts.cmake index 4ece4c6f..b430873c 100644 --- a/absl/copts/AbseilConfigureCopts.cmake +++ b/absl/copts/AbseilConfigureCopts.cmake @@ -8,7 +8,6 @@ set(ABSL_DEFAULT_LINKOPTS "") if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set(ABSL_DEFAULT_COPTS "${ABSL_GCC_FLAGS}") set(ABSL_TEST_COPTS "${ABSL_GCC_FLAGS};${ABSL_GCC_TEST_FLAGS}") - set(ABSL_EXCEPTIONS_FLAG "${ABSL_GCC_EXCEPTIONS_FLAGS}") set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_X64_FLAGS}") elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # MATCHES so we get both Clang and AppleClang @@ -16,13 +15,11 @@ elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # clang-cl is half MSVC, half LLVM set(ABSL_DEFAULT_COPTS "${ABSL_CLANG_CL_FLAGS}") set(ABSL_TEST_COPTS "${ABSL_CLANG_CL_FLAGS};${ABSL_CLANG_CL_TEST_FLAGS}") - set(ABSL_EXCEPTIONS_FLAG "${ABSL_CLANG_CL_EXCEPTIONS_FLAGS}") set(ABSL_DEFAULT_LINKOPTS "${ABSL_MSVC_LINKOPTS}") set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_MSVC_X64_FLAGS}") else() set(ABSL_DEFAULT_COPTS "${ABSL_LLVM_FLAGS}") set(ABSL_TEST_COPTS "${ABSL_LLVM_FLAGS};${ABSL_LLVM_TEST_FLAGS}") - set(ABSL_EXCEPTIONS_FLAG "${ABSL_LLVM_EXCEPTIONS_FLAGS}") set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_X64_FLAGS}") if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") # AppleClang doesn't have lsan @@ -36,20 +33,15 @@ elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") set(ABSL_DEFAULT_COPTS "${ABSL_MSVC_FLAGS}") set(ABSL_TEST_COPTS "${ABSL_MSVC_FLAGS};${ABSL_MSVC_TEST_FLAGS}") - set(ABSL_EXCEPTIONS_FLAG "${ABSL_MSVC_EXCEPTIONS_FLAGS}") set(ABSL_DEFAULT_LINKOPTS "${ABSL_MSVC_LINKOPTS}") set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_MSVC_X64_FLAGS}") else() message(WARNING "Unknown compiler: ${CMAKE_CXX_COMPILER}. Building with no default flags") set(ABSL_DEFAULT_COPTS "") set(ABSL_TEST_COPTS "") - set(ABSL_EXCEPTIONS_FLAG "") set(ABSL_RANDOM_RANDEN_COPTS "") endif() -# This flag is used internally for Bazel builds and is kept here for consistency -set(ABSL_EXCEPTIONS_FLAG_LINKOPTS "") - if("${CMAKE_CXX_STANDARD}" EQUAL 98) message(FATAL_ERROR "Abseil requires at least C++11") elseif(NOT "${CMAKE_CXX_STANDARD}") diff --git a/absl/copts/GENERATED_AbseilCopts.cmake b/absl/copts/GENERATED_AbseilCopts.cmake index 57394c53..39b79c53 100644 --- a/absl/copts/GENERATED_AbseilCopts.cmake +++ b/absl/copts/GENERATED_AbseilCopts.cmake @@ -3,12 +3,6 @@ # (1) Edit absl/copts/copts.py. # (2) Run `python /copts/generate_copts.py`. -list(APPEND ABSL_CLANG_CL_EXCEPTIONS_FLAGS - "/U_HAS_EXCEPTIONS" - "/D_HAS_EXCEPTIONS=1" - "/EHsc" -) - list(APPEND ABSL_CLANG_CL_FLAGS "/W3" "-Wno-c++98-compat-pedantic" @@ -80,10 +74,6 @@ list(APPEND ABSL_CLANG_CL_TEST_FLAGS "-Wno-gnu-zero-variadic-macro-arguments" ) -list(APPEND ABSL_GCC_EXCEPTIONS_FLAGS - "-fexceptions" -) - list(APPEND ABSL_GCC_FLAGS "-Wall" "-Wextra" @@ -111,10 +101,6 @@ list(APPEND ABSL_GCC_TEST_FLAGS "-Wno-unused-private-field" ) -list(APPEND ABSL_LLVM_EXCEPTIONS_FLAGS - "-fexceptions" -) - list(APPEND ABSL_LLVM_FLAGS "-Wall" "-Wextra" @@ -183,12 +169,6 @@ list(APPEND ABSL_LLVM_TEST_FLAGS "-Wno-gnu-zero-variadic-macro-arguments" ) -list(APPEND ABSL_MSVC_EXCEPTIONS_FLAGS - "/U_HAS_EXCEPTIONS" - "/D_HAS_EXCEPTIONS=1" - "/EHsc" -) - list(APPEND ABSL_MSVC_FLAGS "/W3" "/DNOMINMAX" @@ -227,8 +207,6 @@ list(APPEND ABSL_RANDOM_HWAES_ARM64_FLAGS ) list(APPEND ABSL_RANDOM_HWAES_MSVC_X64_FLAGS - "/O2" - "/Ob2" ) list(APPEND ABSL_RANDOM_HWAES_X64_FLAGS diff --git a/absl/copts/GENERATED_copts.bzl b/absl/copts/GENERATED_copts.bzl index 18dbb681..7d645cc3 100644 --- a/absl/copts/GENERATED_copts.bzl +++ b/absl/copts/GENERATED_copts.bzl @@ -4,12 +4,6 @@ (2) Run `python /copts/generate_copts.py`. """ -ABSL_CLANG_CL_EXCEPTIONS_FLAGS = [ - "/U_HAS_EXCEPTIONS", - "/D_HAS_EXCEPTIONS=1", - "/EHsc", -] - ABSL_CLANG_CL_FLAGS = [ "/W3", "-Wno-c++98-compat-pedantic", @@ -81,10 +75,6 @@ ABSL_CLANG_CL_TEST_FLAGS = [ "-Wno-gnu-zero-variadic-macro-arguments", ] -ABSL_GCC_EXCEPTIONS_FLAGS = [ - "-fexceptions", -] - ABSL_GCC_FLAGS = [ "-Wall", "-Wextra", @@ -112,10 +102,6 @@ ABSL_GCC_TEST_FLAGS = [ "-Wno-unused-private-field", ] -ABSL_LLVM_EXCEPTIONS_FLAGS = [ - "-fexceptions", -] - ABSL_LLVM_FLAGS = [ "-Wall", "-Wextra", @@ -184,12 +170,6 @@ ABSL_LLVM_TEST_FLAGS = [ "-Wno-gnu-zero-variadic-macro-arguments", ] -ABSL_MSVC_EXCEPTIONS_FLAGS = [ - "/U_HAS_EXCEPTIONS", - "/D_HAS_EXCEPTIONS=1", - "/EHsc", -] - ABSL_MSVC_FLAGS = [ "/W3", "/DNOMINMAX", @@ -228,8 +208,6 @@ ABSL_RANDOM_HWAES_ARM64_FLAGS = [ ] ABSL_RANDOM_HWAES_MSVC_X64_FLAGS = [ - "/O2", - "/Ob2", ] ABSL_RANDOM_HWAES_X64_FLAGS = [ diff --git a/absl/copts/configure_copts.bzl b/absl/copts/configure_copts.bzl index 8c4efe77..2829e4ec 100644 --- a/absl/copts/configure_copts.bzl +++ b/absl/copts/configure_copts.bzl @@ -6,13 +6,10 @@ change Abseil copts, edit absl/copts/copts.py load( "//absl:copts/GENERATED_copts.bzl", - "ABSL_GCC_EXCEPTIONS_FLAGS", "ABSL_GCC_FLAGS", "ABSL_GCC_TEST_FLAGS", - "ABSL_LLVM_EXCEPTIONS_FLAGS", "ABSL_LLVM_FLAGS", "ABSL_LLVM_TEST_FLAGS", - "ABSL_MSVC_EXCEPTIONS_FLAGS", "ABSL_MSVC_FLAGS", "ABSL_MSVC_LINKOPTS", "ABSL_MSVC_TEST_FLAGS", @@ -36,16 +33,6 @@ ABSL_TEST_COPTS = ABSL_DEFAULT_COPTS + select({ "//conditions:default": ABSL_GCC_TEST_FLAGS, }) -ABSL_EXCEPTIONS_FLAG = select({ - "//absl:windows": ABSL_MSVC_EXCEPTIONS_FLAGS, - "//absl:llvm_compiler": ABSL_LLVM_EXCEPTIONS_FLAGS, - "//conditions:default": ABSL_GCC_EXCEPTIONS_FLAGS, -}) - -ABSL_EXCEPTIONS_FLAG_LINKOPTS = select({ - "//conditions:default": [], -}) - ABSL_DEFAULT_LINKOPTS = select({ "//absl:windows": ABSL_MSVC_LINKOPTS, "//conditions:default": [], diff --git a/absl/copts/copts.py b/absl/copts/copts.py index 0db6e069..a5425415 100644 --- a/absl/copts/copts.py +++ b/absl/copts/copts.py @@ -109,12 +109,6 @@ LLVM_TEST_DISABLE_WARNINGS_FLAGS = [ "-Wno-gnu-zero-variadic-macro-arguments", ] -MSVC_STYLE_EXCEPTIONS_FLAGS = [ - "/U_HAS_EXCEPTIONS", - "/D_HAS_EXCEPTIONS=1", - "/EHsc" -] - MSVC_DEFINES = [ "/DNOMINMAX", # Don't define min and max macros (windows.h) # Don't bloat namespace with incompatible winsock versions. @@ -157,18 +151,14 @@ COPT_VARS = { "-Wno-unused-parameter", "-Wno-unused-private-field", ], - "ABSL_GCC_EXCEPTIONS_FLAGS": ["-fexceptions"], "ABSL_LLVM_FLAGS": LLVM_BIG_WARNING_FLAGS + LLVM_DISABLE_WARNINGS_FLAGS, "ABSL_LLVM_TEST_FLAGS": LLVM_TEST_DISABLE_WARNINGS_FLAGS, - "ABSL_LLVM_EXCEPTIONS_FLAGS": ["-fexceptions"], "ABSL_CLANG_CL_FLAGS": (MSVC_BIG_WARNING_FLAGS + LLVM_DISABLE_WARNINGS_FLAGS + MSVC_DEFINES), "ABSL_CLANG_CL_TEST_FLAGS": LLVM_TEST_DISABLE_WARNINGS_FLAGS, - "ABSL_CLANG_CL_EXCEPTIONS_FLAGS": - MSVC_STYLE_EXCEPTIONS_FLAGS, "ABSL_MSVC_FLAGS": MSVC_BIG_WARNING_FLAGS + MSVC_DEFINES + [ # Increase the number of sections available in object files @@ -193,8 +183,6 @@ COPT_VARS = { "/wd4996", # use of deprecated symbol "/DNOMINMAX", # disable the min() and max() macros from ], - "ABSL_MSVC_EXCEPTIONS_FLAGS": - MSVC_STYLE_EXCEPTIONS_FLAGS, "ABSL_MSVC_LINKOPTS": [ # Object file doesn't export any previously undefined symbols "-ignore:4221", @@ -209,8 +197,5 @@ COPT_VARS = { "-maes", "-msse4.1", ], - "ABSL_RANDOM_HWAES_MSVC_X64_FLAGS": [ - "/O2", # Maximize speed - "/Ob2", # Aggressive inlining - ], + "ABSL_RANDOM_HWAES_MSVC_X64_FLAGS": [], } diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel index e7742de6..4ed6585b 100644 --- a/absl/flags/BUILD.bazel +++ b/absl/flags/BUILD.bazel @@ -1,5 +1,5 @@ # -# Copyright 2019 The Abseil Authors. +# Copyright 2019 The Abseil Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/absl/hash/BUILD.bazel b/absl/hash/BUILD.bazel index d6d8dabc..c51248a5 100644 --- a/absl/hash/BUILD.bazel +++ b/absl/hash/BUILD.bazel @@ -1,5 +1,5 @@ # -# Copyright 2018 The Abseil Authors. +# Copyright 2019 The Abseil Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/absl/memory/BUILD.bazel b/absl/memory/BUILD.bazel index 00f60657..2ba9d7cb 100644 --- a/absl/memory/BUILD.bazel +++ b/absl/memory/BUILD.bazel @@ -1,5 +1,5 @@ # -# Copyright 2017 The Abseil Authors. +# Copyright 2019 The Abseil Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,8 +19,6 @@ load( "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", "ABSL_DEFAULT_LINKOPTS", - "ABSL_EXCEPTIONS_FLAG", - "ABSL_EXCEPTIONS_FLAG_LINKOPTS", "ABSL_TEST_COPTS", ) @@ -56,10 +54,11 @@ cc_test( srcs = [ "memory_exception_safety_test.cc", ], - copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, - linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":memory", + "//absl/base:config", "//absl/base:exception_safety_testing", "@com_google_googletest//:gtest_main", ], diff --git a/absl/memory/CMakeLists.txt b/absl/memory/CMakeLists.txt index 1b3697ec..78fb7e1b 100644 --- a/absl/memory/CMakeLists.txt +++ b/absl/memory/CMakeLists.txt @@ -47,11 +47,9 @@ absl_cc_test( "memory_exception_safety_test.cc" COPTS ${ABSL_TEST_COPTS} - ${ABSL_EXCEPTIONS_FLAG} - LINKOPTS - ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS absl::memory + absl::config absl::exception_safety_testing gmock_main ) diff --git a/absl/memory/memory_exception_safety_test.cc b/absl/memory/memory_exception_safety_test.cc index a1c39707..729507e9 100644 --- a/absl/memory/memory_exception_safety_test.cc +++ b/absl/memory/memory_exception_safety_test.cc @@ -14,6 +14,10 @@ #include "absl/memory/memory.h" +#include "absl/base/config.h" + +#ifdef ABSL_HAVE_EXCEPTIONS + #include "gtest/gtest.h" #include "absl/base/internal/exception_safety_testing.h" @@ -50,3 +54,5 @@ TEST(MakeUnique, CheckForLeaks) { } // namespace } // namespace absl + +#endif // ABSL_HAVE_EXCEPTIONS diff --git a/absl/random/BUILD.bazel b/absl/random/BUILD.bazel index be641474..c904618d 100644 --- a/absl/random/BUILD.bazel +++ b/absl/random/BUILD.bazel @@ -21,8 +21,6 @@ load( "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", "ABSL_DEFAULT_LINKOPTS", - "ABSL_EXCEPTIONS_FLAG", - "ABSL_EXCEPTIONS_FLAG_LINKOPTS", "ABSL_TEST_COPTS", ) @@ -87,8 +85,8 @@ cc_library( name = "seed_gen_exception", srcs = ["seed_gen_exception.cc"], hdrs = ["seed_gen_exception.h"], - copts = ABSL_DEFAULT_COPTS + ABSL_EXCEPTIONS_FLAG, - linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, + copts = ABSL_DEFAULT_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, deps = ["//absl/base:config"], ) diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt index 7603690d..cde89bfd 100644 --- a/absl/random/CMakeLists.txt +++ b/absl/random/CMakeLists.txt @@ -79,9 +79,7 @@ absl_cc_library( "seed_gen_exception.h" COPTS ${ABSL_DEFAULT_COPTS} - ${ABSL_EXCEPTIONS_FLAG} LINKOPTS - ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} ${ABSL_DEFAULT_LINKOPTS} DEPS absl::config diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel index 21fa43ca..8eb6c61a 100644 --- a/absl/random/internal/BUILD.bazel +++ b/absl/random/internal/BUILD.bazel @@ -55,9 +55,7 @@ cc_library( cc_library( name = "distributions", - hdrs = [ - "distributions.h", - ], + hdrs = ["distributions.h"], copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel index cb808416..eae75d85 100644 --- a/absl/strings/BUILD.bazel +++ b/absl/strings/BUILD.bazel @@ -17,8 +17,6 @@ load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") load( "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", - "ABSL_EXCEPTIONS_FLAG", - "ABSL_EXCEPTIONS_FLAG_LINKOPTS", "ABSL_TEST_COPTS", ) @@ -237,8 +235,7 @@ cc_test( name = "string_view_test", size = "small", srcs = ["string_view_test.cc"], - copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, - linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS, + copts = ABSL_TEST_COPTS, visibility = ["//visibility:private"], deps = [ ":strings", diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt index 82a906b7..ccff4441 100644 --- a/absl/strings/CMakeLists.txt +++ b/absl/strings/CMakeLists.txt @@ -161,9 +161,6 @@ absl_cc_test( "string_view_test.cc" COPTS ${ABSL_TEST_COPTS} - ${ABSL_EXCEPTIONS_FLAG} - LINKOPTS - ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS absl::strings absl::config diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h index a1b5a17b..68b90aa3 100644 --- a/absl/strings/string_view.h +++ b/absl/strings/string_view.h @@ -269,10 +269,22 @@ class string_view { // string_view::operator[] // - // Returns the ith element of an `string_view` using the array operator. + // Returns the ith element of the `string_view` using the array operator. // Note that this operator does not perform any bounds checking. constexpr const_reference operator[](size_type i) const { return ptr_[i]; } + // string_view::at() + // + // Returns the ith element of the `string_view`. Bounds checking is performed, + // and an exception of type `std::out_of_range` will be thrown on invalid + // access. + constexpr const_reference at(size_type i) const { + return ABSL_PREDICT_TRUE(i < size()) + ? ptr_[i] + : (base_internal::ThrowStdOutOfRange("absl::string_view::at"), + ptr_[i]); + } + // string_view::front() // // Returns the first element of a `string_view`. diff --git a/absl/strings/string_view_test.cc b/absl/strings/string_view_test.cc index 4f531226..eb8b170b 100644 --- a/absl/strings/string_view_test.cc +++ b/absl/strings/string_view_test.cc @@ -29,7 +29,8 @@ #include "absl/base/config.h" #include "absl/base/dynamic_annotations.h" -#ifdef __ANDROID__ +#if defined(ABSL_HAVE_STD_STRING_VIEW) || defined(__ANDROID__) +// We don't control the death messaging when using std::string_view. // Android assert messages only go to system log, so death tests cannot inspect // the message for matching. #define ABSL_EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ @@ -372,7 +373,7 @@ TEST(StringViewTest, STL1) { #ifdef ABSL_HAVE_EXCEPTIONS EXPECT_THROW(a.copy(buf, 1, 27), std::out_of_range); #else - EXPECT_DEATH(a.copy(buf, 1, 27), "absl::string_view::copy"); + ABSL_EXPECT_DEATH_IF_SUPPORTED(a.copy(buf, 1, 27), "absl::string_view::copy"); #endif } @@ -686,7 +687,8 @@ TEST(StringViewTest, STL2Substr) { #ifdef ABSL_HAVE_EXCEPTIONS EXPECT_THROW((void)a.substr(99, 2), std::out_of_range); #else - EXPECT_DEATH((void)a.substr(99, 2), "absl::string_view::substr"); + ABSL_EXPECT_DEATH_IF_SUPPORTED((void)a.substr(99, 2), + "absl::string_view::substr"); #endif } @@ -894,6 +896,18 @@ TEST(StringViewTest, Comparisons2) { EXPECT_LT(digits.compare(0, npos, "0123456789", 3, 5), 0); // 6 } +TEST(StringViewTest, At) { + absl::string_view abc = "abc"; + EXPECT_EQ(abc.at(0), 'a'); + EXPECT_EQ(abc.at(1), 'b'); + EXPECT_EQ(abc.at(2), 'c'); +#ifdef ABSL_HAVE_EXCEPTIONS + EXPECT_THROW(abc.at(3), std::out_of_range); +#else + ABSL_EXPECT_DEATH_IF_SUPPORTED(abc.at(3), "absl::string_view::at"); +#endif +} + struct MyCharAlloc : std::allocator {}; TEST(StringViewTest, ExplicitConversionOperator) { diff --git a/absl/types/BUILD.bazel b/absl/types/BUILD.bazel index 037d499a..236c24bc 100644 --- a/absl/types/BUILD.bazel +++ b/absl/types/BUILD.bazel @@ -19,8 +19,6 @@ load( "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", "ABSL_DEFAULT_LINKOPTS", - "ABSL_EXCEPTIONS_FLAG", - "ABSL_EXCEPTIONS_FLAG_LINKOPTS", "ABSL_TEST_COPTS", ) @@ -59,8 +57,8 @@ cc_library( "bad_any_cast.cc", "bad_any_cast.h", ], - copts = ABSL_EXCEPTIONS_FLAG + ABSL_DEFAULT_COPTS, - linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, + copts = ABSL_DEFAULT_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, visibility = ["//visibility:private"], deps = [ "//absl/base:config", @@ -74,24 +72,6 @@ cc_test( srcs = [ "any_test.cc", ], - copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, - linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, - deps = [ - ":any", - "//absl/base:config", - "//absl/base:exception_testing", - "//absl/base:raw_logging_internal", - "//absl/container:test_instance_tracker", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "any_test_noexceptions", - size = "small", - srcs = [ - "any_test.cc", - ], copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ @@ -107,8 +87,8 @@ cc_test( cc_test( name = "any_exception_safety_test", srcs = ["any_exception_safety_test.cc"], - copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, - linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":any", "//absl/base:config", @@ -139,25 +119,6 @@ cc_test( name = "span_test", size = "small", srcs = ["span_test.cc"], - copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, - linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, - deps = [ - ":span", - "//absl/base:config", - "//absl/base:core_headers", - "//absl/base:exception_testing", - "//absl/container:fixed_array", - "//absl/container:inlined_vector", - "//absl/hash:hash_testing", - "//absl/strings", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "span_test_noexceptions", - size = "small", - srcs = ["span_test.cc"], copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ @@ -194,8 +155,8 @@ cc_library( name = "bad_optional_access", srcs = ["bad_optional_access.cc"], hdrs = ["bad_optional_access.h"], - copts = ABSL_DEFAULT_COPTS + ABSL_EXCEPTIONS_FLAG, - linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, + copts = ABSL_DEFAULT_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ "//absl/base:config", "//absl/base:raw_logging_internal", @@ -206,8 +167,8 @@ cc_library( name = "bad_variant_access", srcs = ["bad_variant_access.cc"], hdrs = ["bad_variant_access.h"], - copts = ABSL_EXCEPTIONS_FLAG + ABSL_DEFAULT_COPTS, - linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, + copts = ABSL_DEFAULT_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ "//absl/base:config", "//absl/base:raw_logging_internal", @@ -220,8 +181,8 @@ cc_test( srcs = [ "optional_test.cc", ], - copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, - linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":optional", "//absl/base:config", @@ -237,8 +198,8 @@ cc_test( srcs = [ "optional_exception_safety_test.cc", ], - copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, - linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":optional", "//absl/base:config", @@ -267,8 +228,8 @@ cc_test( name = "variant_test", size = "small", srcs = ["variant_test.cc"], - copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, - linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":variant", "//absl/base:config", @@ -301,8 +262,8 @@ cc_test( srcs = [ "variant_exception_safety_test.cc", ], - copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, - linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS, + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":variant", "//absl/base:config", diff --git a/absl/types/CMakeLists.txt b/absl/types/CMakeLists.txt index 1f7fde09..952efc34 100644 --- a/absl/types/CMakeLists.txt +++ b/absl/types/CMakeLists.txt @@ -50,9 +50,6 @@ absl_cc_library( "bad_any_cast.cc" COPTS ${ABSL_DEFAULT_COPTS} - ${ABSL_EXCEPTIONS_FLAG} - LINKOPTS - ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS absl::config absl::raw_logging_internal @@ -65,9 +62,6 @@ absl_cc_test( "any_test.cc" COPTS ${ABSL_TEST_COPTS} - ${ABSL_EXCEPTIONS_FLAG} - LINKOPTS - ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS absl::any absl::config @@ -100,9 +94,6 @@ absl_cc_test( "any_exception_safety_test.cc" COPTS ${ABSL_TEST_COPTS} - ${ABSL_EXCEPTIONS_FLAG} - LINKOPTS - ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS absl::any absl::config @@ -134,9 +125,6 @@ absl_cc_test( "span_test.cc" COPTS ${ABSL_TEST_COPTS} - ${ABSL_EXCEPTIONS_FLAG} - LINKOPTS - ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS absl::span absl::base @@ -199,9 +187,6 @@ absl_cc_library( "bad_optional_access.cc" COPTS ${ABSL_DEFAULT_COPTS} - ${ABSL_EXCEPTIONS_FLAG} - LINKOPTS - ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS absl::config absl::raw_logging_internal @@ -217,9 +202,6 @@ absl_cc_library( "bad_variant_access.cc" COPTS ${ABSL_DEFAULT_COPTS} - ${ABSL_EXCEPTIONS_FLAG} - LINKOPTS - ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS absl::config absl::raw_logging_internal @@ -233,9 +215,6 @@ absl_cc_test( "optional_test.cc" COPTS ${ABSL_TEST_COPTS} - ${ABSL_EXCEPTIONS_FLAG} - LINKOPTS - ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS absl::optional absl::config @@ -252,9 +231,6 @@ absl_cc_test( "optional_exception_safety_test.cc" COPTS ${ABSL_TEST_COPTS} - ${ABSL_EXCEPTIONS_FLAG} - LINKOPTS - ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS absl::optional absl::config @@ -288,9 +264,6 @@ absl_cc_test( "variant_test.cc" COPTS ${ABSL_TEST_COPTS} - ${ABSL_EXCEPTIONS_FLAG} - LINKOPTS - ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS absl::variant absl::config @@ -337,9 +310,6 @@ absl_cc_test( "variant_exception_safety_test.cc" COPTS ${ABSL_TEST_COPTS} - ${ABSL_EXCEPTIONS_FLAG} - LINKOPTS - ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS absl::variant absl::config diff --git a/absl/types/variant_test.cc b/absl/types/variant_test.cc index 56a6e01c..b5912745 100644 --- a/absl/types/variant_test.cc +++ b/absl/types/variant_test.cc @@ -1042,8 +1042,6 @@ TEST(VariantTest, MemberSwap) { using V = variant; int i = 33; std::string s = "abc"; - V valueless(in_place_index<0>); - ToValuelessByException(valueless); { // lhs and rhs holds different alternative V lhs(i), rhs(s); @@ -1051,6 +1049,9 @@ TEST(VariantTest, MemberSwap) { EXPECT_THAT(lhs, VariantWith(s)); EXPECT_THAT(rhs, VariantWith(i)); } +#ifdef ABSL_HAVE_EXCEPTIONS + V valueless(in_place_index<0>); + ToValuelessByException(valueless); { // lhs is valueless V lhs(valueless), rhs(i); @@ -1072,6 +1073,7 @@ TEST(VariantTest, MemberSwap) { EXPECT_TRUE(lhs.valueless_by_exception()); EXPECT_TRUE(rhs.valueless_by_exception()); } +#endif // ABSL_HAVE_EXCEPTIONS } ////////////////////// diff --git a/absl/utility/BUILD.bazel b/absl/utility/BUILD.bazel index 61de30be..6881f939 100644 --- a/absl/utility/BUILD.bazel +++ b/absl/utility/BUILD.bazel @@ -28,7 +28,9 @@ licenses(["notice"]) # Apache 2.0 cc_library( name = "utility", - hdrs = ["utility.h"], + hdrs = [ + "utility.h", + ], copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ -- cgit v1.2.3 From 97c1664b4bbab5f78fac2b151ab02656268fb34b Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 9 Sep 2019 08:20:10 -0700 Subject: Export of internal Abseil changes -- 167cd2647144583746311129b0cc98a89a9897e1 by Andy Soffer : Internal Changes PiperOrigin-RevId: 268000987 -- ab44fea7dfdaf763c69609a08ddfac22480ce520 by Derek Mauro : Fix flags Cmake tests on Windows PiperOrigin-RevId: 267859442 -- d7ec9f7611370b01bc9a5aed7e18460df2a15429 by Abseil Team : Fix undefined behavior in symbolize_elf.inc PiperOrigin-RevId: 267684904 -- e7c5f8e472a91ed99bdf4876942f2bda5751aa6c by Abseil Team : Turn off ABSL_HAS_ALARM on Fuchsia. PiperOrigin-RevId: 267666090 -- b7d25d5c71a49e697a8bf6440ed30f2e3f036420 by Chris Kennelly : Mark once initialization function as no inline. We expect this code to run infrequently. PiperOrigin-RevId: 267649713 -- dc2a5e5f1e39a03fff837d34a319033fde55d9ba by Derek Mauro : Fix the MSVC CMake random build PiperOrigin-RevId: 267624074 -- ba2751b67fa17d1b6c53e5ba79f81a5371e4a03a by Abseil Team : Move "internal/flag.*" files to the "internal" build target. PiperOrigin-RevId: 267588996 -- 05b985a33eec4f8acff1809ad9218a1e22220f34 by Abseil Team : Move "internal/flag.*" files to the "internal" build target. PiperOrigin-RevId: 267580412 GitOrigin-RevId: 167cd2647144583746311129b0cc98a89a9897e1 Change-Id: Ibd334f46a5671c7c1d3fcf5354029e2fbb7ba91f --- absl/base/call_once.h | 1 + absl/base/config.h | 2 + absl/debugging/symbolize_elf.inc | 13 +++- absl/flags/BUILD.bazel | 2 + absl/flags/CMakeLists.txt | 2 + absl/flags/flag_test.cc | 92 ++++++++++++++++++----------- absl/flags/internal/commandlineflag_test.cc | 34 +++++++++-- absl/flags/internal/usage_test.cc | 4 +- absl/random/CMakeLists.txt | 2 + absl/random/beta_distribution.h | 2 +- absl/random/distribution_format_traits.h | 39 ++++++++++++ absl/random/internal/BUILD.bazel | 9 +-- absl/random/internal/distributions.h | 12 ++-- absl/random/internal/uniform_helper.h | 2 +- 14 files changed, 154 insertions(+), 62 deletions(-) (limited to 'absl/random/CMakeLists.txt') diff --git a/absl/base/call_once.h b/absl/base/call_once.h index e7fc2300..4aa6360c 100644 --- a/absl/base/call_once.h +++ b/absl/base/call_once.h @@ -142,6 +142,7 @@ enum { }; template +ABSL_ATTRIBUTE_NOINLINE void CallOnceImpl(std::atomic* control, base_internal::SchedulingMode scheduling_mode, Callable&& fn, Args&&... args) { diff --git a/absl/base/config.h b/absl/base/config.h index 90d98214..1cb69b0f 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -336,6 +336,8 @@ // feature tests for Microsoft's library #elif defined(__EMSCRIPTEN__) // emscripten doesn't support signals +#elif defined(__Fuchsia__) +// Signals don't exist on fuchsia. #elif defined(__native_client__) #else // other standard libraries diff --git a/absl/debugging/symbolize_elf.inc b/absl/debugging/symbolize_elf.inc index e7305213..14f0c972 100644 --- a/absl/debugging/symbolize_elf.inc +++ b/absl/debugging/symbolize_elf.inc @@ -624,6 +624,13 @@ static bool InSection(const void *address, const ElfW(Shdr) * section) { return start <= address && address < (start + size); } +static const char *ComputeOffset(const char *base, ptrdiff_t offset) { + // Note: cast to uintptr_t to avoid undefined behavior when base evaluates to + // zero and offset is non-zero. + return reinterpret_cast( + reinterpret_cast(base) + offset); +} + // Read a symbol table and look for the symbol containing the // pc. Iterate over symbols in a symbol table and look for the symbol // containing "pc". If the symbol is found, and its name fits in @@ -676,7 +683,8 @@ static ABSL_ATTRIBUTE_NOINLINE FindSymbolResult FindSymbol( // We keep the original address for opd redirection below. const char *const original_start_address = reinterpret_cast(symbol.st_value); - const char *start_address = original_start_address + relocation; + const char *start_address = + ComputeOffset(original_start_address, relocation); if (deref_function_descriptor_pointer && InSection(original_start_address, opd)) { @@ -688,8 +696,7 @@ static ABSL_ATTRIBUTE_NOINLINE FindSymbolResult FindSymbol( // If pc is inside the .opd section, it points to a function descriptor. const size_t size = pc_in_opd ? kFunctionDescriptorSize : symbol.st_size; - const void *const end_address = - reinterpret_cast(start_address) + size; + const void *const end_address = ComputeOffset(start_address, size); if (symbol.st_value != 0 && // Skip null value symbols. symbol.st_shndx != 0 && // Skip undefined symbols. #ifdef STT_TLS diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel index 4ed6585b..9e923ffb 100644 --- a/absl/flags/BUILD.bazel +++ b/absl/flags/BUILD.bazel @@ -231,6 +231,7 @@ cc_test( copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ + ":config", ":flag", ":handle", ":registry", @@ -264,6 +265,7 @@ cc_test( copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ + ":config", ":flag", "//absl/strings", "@com_google_googletest//:gtest_main", diff --git a/absl/flags/CMakeLists.txt b/absl/flags/CMakeLists.txt index d9084a9c..3eac8f0a 100644 --- a/absl/flags/CMakeLists.txt +++ b/absl/flags/CMakeLists.txt @@ -213,6 +213,7 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::flags + absl::flags_config absl::flags_handle absl::flags_registry absl::memory @@ -242,6 +243,7 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::flags + absl::flags_config absl::strings gtest_main ) diff --git a/absl/flags/flag_test.cc b/absl/flags/flag_test.cc index 1bcd7e96..a652042c 100644 --- a/absl/flags/flag_test.cc +++ b/absl/flags/flag_test.cc @@ -15,7 +15,11 @@ #include "absl/flags/flag.h" +#include +#include + #include "gtest/gtest.h" +#include "absl/flags/usage_config.h" #include "absl/strings/match.h" #include "absl/strings/numbers.h" #include "absl/strings/str_cat.h" @@ -63,7 +67,27 @@ struct UDT { bool AbslParseFlag(absl::string_view, UDT*, std::string*) { return true; } std::string AbslUnparseFlag(const UDT&) { return ""; } -TEST(FlagTest, TestConstruction) { +class FlagTest : public testing::Test { + protected: + static void SetUpTestSuite() { + // Install a function to normalize filenames before this test is run. + absl::FlagsUsageConfig default_config; + default_config.normalize_filename = &FlagTest::NormalizeFileName; + absl::SetFlagsUsageConfig(default_config); + } + + private: + static std::string NormalizeFileName(absl::string_view fname) { +#ifdef _WIN32 + std::string normalized(fname); + std::replace(normalized.begin(), normalized.end(), '\\', '/'); + fname = normalized; +#endif + return std::string(fname); + } +}; + +TEST_F(FlagTest, TestConstruction) { TestConstructionFor(); TestConstructionFor(); TestConstructionFor(); @@ -98,7 +122,7 @@ namespace { #if !ABSL_FLAGS_STRIP_NAMES -TEST(FlagTest, TestFlagDeclaration) { +TEST_F(FlagTest, TestFlagDeclaration) { // test that we can access flag objects. EXPECT_EQ(FLAGS_test_flag_01.Name(), "test_flag_01"); EXPECT_EQ(FLAGS_test_flag_02.Name(), "test_flag_02"); @@ -133,69 +157,69 @@ ABSL_FLAG(std::string, test_flag_11, "", "test flag 11"); namespace { #if !ABSL_FLAGS_STRIP_NAMES -TEST(FlagTest, TestFlagDefinition) { +TEST_F(FlagTest, TestFlagDefinition) { absl::string_view expected_file_name = "absl/flags/flag_test.cc"; EXPECT_EQ(FLAGS_test_flag_01.Name(), "test_flag_01"); EXPECT_EQ(FLAGS_test_flag_01.Help(), "test flag 01"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_01.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_01.Filename(), expected_file_name)) + << FLAGS_test_flag_01.Filename(); EXPECT_EQ(FLAGS_test_flag_02.Name(), "test_flag_02"); EXPECT_EQ(FLAGS_test_flag_02.Help(), "test flag 02"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_02.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_02.Filename(), expected_file_name)) + << FLAGS_test_flag_02.Filename(); EXPECT_EQ(FLAGS_test_flag_03.Name(), "test_flag_03"); EXPECT_EQ(FLAGS_test_flag_03.Help(), "test flag 03"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_03.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_03.Filename(), expected_file_name)) + << FLAGS_test_flag_03.Filename(); EXPECT_EQ(FLAGS_test_flag_04.Name(), "test_flag_04"); EXPECT_EQ(FLAGS_test_flag_04.Help(), "test flag 04"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_04.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_04.Filename(), expected_file_name)) + << FLAGS_test_flag_04.Filename(); EXPECT_EQ(FLAGS_test_flag_05.Name(), "test_flag_05"); EXPECT_EQ(FLAGS_test_flag_05.Help(), "test flag 05"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_05.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_05.Filename(), expected_file_name)) + << FLAGS_test_flag_05.Filename(); EXPECT_EQ(FLAGS_test_flag_06.Name(), "test_flag_06"); EXPECT_EQ(FLAGS_test_flag_06.Help(), "test flag 06"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_06.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_06.Filename(), expected_file_name)) + << FLAGS_test_flag_06.Filename(); EXPECT_EQ(FLAGS_test_flag_07.Name(), "test_flag_07"); EXPECT_EQ(FLAGS_test_flag_07.Help(), "test flag 07"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_07.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_07.Filename(), expected_file_name)) + << FLAGS_test_flag_07.Filename(); EXPECT_EQ(FLAGS_test_flag_08.Name(), "test_flag_08"); EXPECT_EQ(FLAGS_test_flag_08.Help(), "test flag 08"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_08.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_08.Filename(), expected_file_name)) + << FLAGS_test_flag_08.Filename(); EXPECT_EQ(FLAGS_test_flag_09.Name(), "test_flag_09"); EXPECT_EQ(FLAGS_test_flag_09.Help(), "test flag 09"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_09.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_09.Filename(), expected_file_name)) + << FLAGS_test_flag_09.Filename(); EXPECT_EQ(FLAGS_test_flag_10.Name(), "test_flag_10"); EXPECT_EQ(FLAGS_test_flag_10.Help(), "test flag 10"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_10.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_10.Filename(), expected_file_name)) + << FLAGS_test_flag_10.Filename(); EXPECT_EQ(FLAGS_test_flag_11.Name(), "test_flag_11"); EXPECT_EQ(FLAGS_test_flag_11.Help(), "test flag 11"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_11.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_11.Filename(), expected_file_name)) + << FLAGS_test_flag_11.Filename(); } #endif // !ABSL_FLAGS_STRIP_NAMES // -------------------------------------------------------------------- -TEST(FlagTest, TestDefault) { +TEST_F(FlagTest, TestDefault) { EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_01), true); EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_02), 1234); EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_03), -34); @@ -211,7 +235,7 @@ TEST(FlagTest, TestDefault) { // -------------------------------------------------------------------- -TEST(FlagTest, TestGetSet) { +TEST_F(FlagTest, TestGetSet) { absl::SetFlag(&FLAGS_test_flag_01, false); EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_01), false); @@ -258,7 +282,7 @@ ABSL_FLAG(std::string, test_flag_13, absl::StrCat("AAA", "BBB"), namespace { -TEST(FlagTest, TestNonConstexprDefault) { +TEST_F(FlagTest, TestNonConstexprDefault) { EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_12), 1); EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_13), "AAABBB"); } @@ -272,7 +296,7 @@ ABSL_FLAG(bool, test_flag_14, true, absl::StrCat("test ", "flag ", "14")); namespace { #if !ABSL_FLAGS_STRIP_HELP -TEST(FlagTest, TestNonConstexprHelp) { +TEST_F(FlagTest, TestNonConstexprHelp) { EXPECT_EQ(FLAGS_test_flag_14.Help(), "test flag 14"); } #endif //! ABSL_FLAGS_STRIP_HELP @@ -296,7 +320,7 @@ namespace { void TestFlagCB() { cb_test_value = absl::GetFlag(FLAGS_test_flag_with_cb); } // Tests side-effects of callback invocation. -TEST(FlagTest, CallbackInvocation) { +TEST_F(FlagTest, CallbackInvocation) { EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_with_cb), 100); EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_with_lambda_cb), 200); EXPECT_EQ(cb_test_value, 300); @@ -343,7 +367,7 @@ ABSL_FLAG(CustomUDT, test_flag_15, CustomUDT(), "test flag 15"); namespace { -TEST(FlagTest, TestCustomUDT) { +TEST_F(FlagTest, TestCustomUDT) { EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_15), CustomUDT(1, 1)); absl::SetFlag(&FLAGS_test_flag_15, CustomUDT(2, 3)); EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_15), CustomUDT(2, 3)); @@ -409,7 +433,7 @@ ABSL_FLAG(ConversionTestVal, test_flag_16, namespace { -TEST(FlagTest, CanSetViaImplicitConversion) { +TEST_F(FlagTest, CanSetViaImplicitConversion) { EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_16).a, 10); absl::SetFlag(&FLAGS_test_flag_16, ConversionTestVal::ViaImplicitConv::kEleven); @@ -447,7 +471,7 @@ ABSL_FLAG(NonDfltConstructible, ndc_flag2, 0, namespace { -TEST(FlagTest, TestNonDefaultConstructibleType) { +TEST_F(FlagTest, TestNonDefaultConstructibleType) { EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag1).value, '1' + 100); EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag2).value, 0); @@ -468,7 +492,7 @@ ABSL_RETIRED_FLAG(std::string, old_str_flag, "", absl::StrCat("old ", "descr")); namespace { -TEST(FlagTest, TestRetiredFlagRegistration) { +TEST_F(FlagTest, TestRetiredFlagRegistration) { bool is_bool = false; EXPECT_TRUE(flags::IsRetiredFlag("old_bool_flag", &is_bool)); EXPECT_TRUE(is_bool); diff --git a/absl/flags/internal/commandlineflag_test.cc b/absl/flags/internal/commandlineflag_test.cc index f0d57adb..5a0c271e 100644 --- a/absl/flags/internal/commandlineflag_test.cc +++ b/absl/flags/internal/commandlineflag_test.cc @@ -15,9 +15,13 @@ #include "absl/flags/internal/commandlineflag.h" +#include +#include + #include "gtest/gtest.h" #include "absl/flags/flag.h" #include "absl/flags/internal/registry.h" +#include "absl/flags/usage_config.h" #include "absl/memory/memory.h" #include "absl/strings/match.h" #include "absl/strings/str_cat.h" @@ -33,10 +37,26 @@ namespace flags = absl::flags_internal; class CommandLineFlagTest : public testing::Test { protected: + static void SetUpTestSuite() { + // Install a function to normalize filenames before this test is run. + absl::FlagsUsageConfig default_config; + default_config.normalize_filename = &CommandLineFlagTest::NormalizeFileName; + absl::SetFlagsUsageConfig(default_config); + } + void SetUp() override { flag_saver_ = absl::make_unique(); } void TearDown() override { flag_saver_.reset(); } private: + static std::string NormalizeFileName(absl::string_view fname) { +#ifdef _WIN32 + std::string normalized(fname); + std::replace(normalized.begin(), normalized.end(), '\\', '/'); + fname = normalized; +#endif + return std::string(fname); + } + std::unique_ptr flag_saver_; }; @@ -49,9 +69,10 @@ TEST_F(CommandLineFlagTest, TestAttributesAccessMethods) { EXPECT_EQ(flag_01->Typename(), ""); EXPECT_TRUE(!flag_01->IsRetired()); EXPECT_TRUE(flag_01->IsOfType()); - EXPECT_TRUE(absl::EndsWith( - flag_01->Filename(), - "absl/flags/internal/commandlineflag_test.cc")); + EXPECT_TRUE( + absl::EndsWith(flag_01->Filename(), + "absl/flags/internal/commandlineflag_test.cc")) + << flag_01->Filename(); auto* flag_02 = flags::FindCommandLineFlag("string_flag"); @@ -61,9 +82,10 @@ TEST_F(CommandLineFlagTest, TestAttributesAccessMethods) { EXPECT_EQ(flag_02->Typename(), ""); EXPECT_TRUE(!flag_02->IsRetired()); EXPECT_TRUE(flag_02->IsOfType()); - EXPECT_TRUE(absl::EndsWith( - flag_02->Filename(), - "absl/flags/internal/commandlineflag_test.cc")); + EXPECT_TRUE( + absl::EndsWith(flag_02->Filename(), + "absl/flags/internal/commandlineflag_test.cc")) + << flag_02->Filename(); auto* flag_03 = flags::FindRetiredFlag("bool_retired_flag"); diff --git a/absl/flags/internal/usage_test.cc b/absl/flags/internal/usage_test.cc index 8538b2b6..d15e4484 100644 --- a/absl/flags/internal/usage_test.cc +++ b/absl/flags/internal/usage_test.cc @@ -67,9 +67,9 @@ static std::string NormalizeFileName(absl::string_view fname) { fname = normalized; #endif - auto absl_pos = fname.find("/absl/"); + auto absl_pos = fname.rfind("absl/"); if (absl_pos != absl::string_view::npos) { - fname = fname.substr(absl_pos + 1); + fname = fname.substr(absl_pos); } return std::string(fname); } diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt index cde89bfd..151cefa4 100644 --- a/absl/random/CMakeLists.txt +++ b/absl/random/CMakeLists.txt @@ -1025,6 +1025,8 @@ absl_cc_test( random_internal_iostream_state_saver_test SRCS "internal/iostream_state_saver_test.cc" + COPTS + ${ABSL_TEST_COPTS} LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS diff --git a/absl/random/beta_distribution.h b/absl/random/beta_distribution.h index d7afd61c..e29894f2 100644 --- a/absl/random/beta_distribution.h +++ b/absl/random/beta_distribution.h @@ -129,7 +129,7 @@ class beta_distribution { private: friend class beta_distribution; -#ifdef COMPILER_MSVC +#ifdef _MSC_VER // MSVC does not have constexpr implementations for std::log and std::exp // so they are computed at runtime. #define ABSL_RANDOM_INTERNAL_LOG_EXP_CONSTEXPR diff --git a/absl/random/distribution_format_traits.h b/absl/random/distribution_format_traits.h index 3f28c906..3298c2cd 100644 --- a/absl/random/distribution_format_traits.h +++ b/absl/random/distribution_format_traits.h @@ -36,6 +36,12 @@ #include "absl/types/span.h" namespace absl { + +struct IntervalClosedClosedTag; +struct IntervalClosedOpenTag; +struct IntervalOpenClosedTag; +struct IntervalOpenOpenTag; + namespace random_internal { // ScalarTypeName defines a preferred hierarchy of preferred type names for @@ -243,6 +249,39 @@ struct DistributionFormatTraits> { } }; +template +struct UniformDistributionWrapper; + +template +struct DistributionFormatTraits> { + using distribution_t = UniformDistributionWrapper; + using result_t = NumType; + + static constexpr const char* Name() { return "Uniform"; } + + static std::string FunctionName() { + return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); + } + static std::string FormatArgs(const distribution_t& d) { + absl::string_view tag; + if (std::is_same::value) { + tag = "IntervalClosedClosed"; + } else if (std::is_same::value) { + tag = "IntervalClosedOpen"; + } else if (std::is_same::value) { + tag = "IntervalOpenClosed"; + } else if (std::is_same::value) { + tag = "IntervalOpenOpen"; + } else { + tag = "[[unknown tag type]]"; + } + return absl::StrCat(tag, ", ", (d.min)(), ", ", (d.max)()); + } + static std::string FormatResults(absl::Span results) { + return absl::StrJoin(results, ", "); + } +}; + } // namespace random_internal } // namespace absl diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel index 8eb6c61a..cd50982d 100644 --- a/absl/random/internal/BUILD.bazel +++ b/absl/random/internal/BUILD.bazel @@ -60,13 +60,11 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":distribution_caller", - ":fast_uniform_bits", - ":fastmath", ":traits", ":uniform_helper", + "//absl/base", "//absl/meta:type_traits", "//absl/strings", - "//absl/types:span", ], ) @@ -618,11 +616,6 @@ cc_library( copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ - ":distribution_impl", - ":fast_uniform_bits", - ":iostream_state_saver", - ":traits", - "//absl/base:core_headers", "//absl/meta:type_traits", ], ) diff --git a/absl/random/internal/distributions.h b/absl/random/internal/distributions.h index 34db3b32..96f8bae3 100644 --- a/absl/random/internal/distributions.h +++ b/absl/random/internal/distributions.h @@ -39,22 +39,20 @@ NumType UniformImpl(TagType tag, "absl::Uniform() must use an integer or real parameter type."); using distribution_t = - typename std::conditional::value, - absl::uniform_int_distribution, - absl::uniform_real_distribution>::type; + UniformDistributionWrapper, NumType>; using format_t = random_internal::DistributionFormatTraits; + auto a = uniform_lower_bound(tag, lo, hi); + auto b = uniform_upper_bound(tag, lo, hi); - auto a = random_internal::uniform_lower_bound(tag, lo, hi); - auto b = random_internal::uniform_upper_bound(tag, lo, hi); // TODO(lar): it doesn't make a lot of sense to ask for a random number in an // empty range. Right now we just return a boundary--even though that // boundary is not an acceptable value! Is there something better we can do // here? + if (a > b) return a; using gen_t = absl::decay_t; - if (a > b) return a; return DistributionCaller::template Call( - &urbg, a, b); + &urbg, tag, lo, hi); } // In the absence of an explicitly provided return-type, the template diff --git a/absl/random/internal/uniform_helper.h b/absl/random/internal/uniform_helper.h index 9e89e526..2929407e 100644 --- a/absl/random/internal/uniform_helper.h +++ b/absl/random/internal/uniform_helper.h @@ -156,7 +156,7 @@ using UniformDistribution = template struct UniformDistributionWrapper : public UniformDistribution { - explicit UniformDistributionWrapper(NumType lo, NumType hi) + explicit UniformDistributionWrapper(TagType, NumType lo, NumType hi) : UniformDistribution( uniform_lower_bound(TagType{}, lo, hi), uniform_upper_bound(TagType{}, lo, hi)) {} -- cgit v1.2.3 From a15364ce4d88534ae2295127e5d8e32aefb6b446 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 16 Oct 2019 15:51:11 -0700 Subject: Export of internal Abseil changes -- d35c72d705155dcd89a92835103540f14c643d10 by Gennadiy Rozental : helpxml changed to report types of flags with built-in value type. PiperOrigin-RevId: 275131440 -- f3478792943d7dd40a6ef6083a8e5d374f43a65e by Abseil Team : Add space padding tests for hex conversions. PiperOrigin-RevId: 275120155 -- 7c2e4725403e173660f33f94af686a75d3722936 by Andy Soffer : Fix https://github.com/abseil/abseil-cpp/issues/379 by renaming `roundup` to `round_up` PiperOrigin-RevId: 275106110 -- 84cb30d6ee509961ac4359cfdda1360973b9527d by Laramie Leavitt : Move random_internal::wide_multiply into a file by the same name. PiperOrigin-RevId: 275059359 -- 06d691a8c187b5d899e7863784b23bdcfd580cb2 by Abseil Team : Add missing "return" keyword. PiperOrigin-RevId: 275036408 GitOrigin-RevId: d35c72d705155dcd89a92835103540f14c643d10 Change-Id: Id837b4de6c9cfe18f0a088363754bfe389df985b --- absl/base/internal/low_level_alloc.cc | 16 ++-- absl/flags/flag.h | 2 +- absl/flags/internal/usage.cc | 26 +++++- absl/random/BUILD.bazel | 1 + absl/random/CMakeLists.txt | 34 ++++++++ absl/random/internal/BUILD.bazel | 27 ++++++ absl/random/internal/distribution_impl.h | 66 --------------- absl/random/internal/distribution_impl_test.cc | 42 ---------- absl/random/internal/wide_multiply.h | 109 +++++++++++++++++++++++++ absl/random/internal/wide_multiply_test.cc | 66 +++++++++++++++ absl/random/uniform_int_distribution.h | 1 + absl/strings/numbers_test.cc | 3 + 12 files changed, 275 insertions(+), 118 deletions(-) create mode 100644 absl/random/internal/wide_multiply.h create mode 100644 absl/random/internal/wide_multiply_test.cc (limited to 'absl/random/CMakeLists.txt') diff --git a/absl/base/internal/low_level_alloc.cc b/absl/base/internal/low_level_alloc.cc index 64d7aa80..f7314ab1 100644 --- a/absl/base/internal/low_level_alloc.cc +++ b/absl/base/internal/low_level_alloc.cc @@ -211,7 +211,7 @@ struct LowLevelAlloc::Arena { // Result of sysconf(_SC_PAGESIZE) const size_t pagesize; // Lowest power of two >= max(16, sizeof(AllocList)) - const size_t roundup; + const size_t round_up; // Smallest allocation block size const size_t min_size; // PRNG state @@ -336,11 +336,11 @@ size_t GetPageSize() { size_t RoundedUpBlockSize() { // Round up block sizes to a power of two close to the header size. - size_t roundup = 16; - while (roundup < sizeof(AllocList::Header)) { - roundup += roundup; + size_t round_up = 16; + while (round_up < sizeof(AllocList::Header)) { + round_up += round_up; } - return roundup; + return round_up; } } // namespace @@ -350,8 +350,8 @@ LowLevelAlloc::Arena::Arena(uint32_t flags_value) allocation_count(0), flags(flags_value), pagesize(GetPageSize()), - roundup(RoundedUpBlockSize()), - min_size(2 * roundup), + round_up(RoundedUpBlockSize()), + min_size(2 * round_up), random(0) { freelist.header.size = 0; freelist.header.magic = @@ -528,7 +528,7 @@ static void *DoAllocWithArena(size_t request, LowLevelAlloc::Arena *arena) { ArenaLock section(arena); // round up with header size_t req_rnd = RoundUp(CheckedAdd(request, sizeof (s->header)), - arena->roundup); + arena->round_up); for (;;) { // loop until we find a suitable region // find the minimum levels that a block of this size must have int i = LLA_SkiplistLevels(req_rnd, arena->min_size, nullptr) - 1; diff --git a/absl/flags/flag.h b/absl/flags/flag.h index 4927757b..85900ef8 100644 --- a/absl/flags/flag.h +++ b/absl/flags/flag.h @@ -121,7 +121,7 @@ class Flag { bool IsModified() const { return GetImpl()->IsModified(); } void SetModified(bool is_modified) { GetImpl()->SetModified(is_modified); } bool IsSpecifiedOnCommandLine() const { - GetImpl()->IsSpecifiedOnCommandLine(); + return GetImpl()->IsSpecifiedOnCommandLine(); } absl::string_view Typename() const { return GetImpl()->Typename(); } std::string Filename() const { return GetImpl()->Filename(); } diff --git a/absl/flags/internal/usage.cc b/absl/flags/internal/usage.cc index 03048514..181c35c6 100644 --- a/absl/flags/internal/usage.cc +++ b/absl/flags/internal/usage.cc @@ -47,6 +47,27 @@ namespace absl { namespace flags_internal { namespace { +absl::string_view TypenameForHelp(const flags_internal::CommandLineFlag& flag) { + // Only report names of v1 built-in types +#define HANDLE_V1_BUILTIN_TYPE(t) \ + if (flag.IsOfType()) { \ + return #t; \ + } + + HANDLE_V1_BUILTIN_TYPE(bool); + HANDLE_V1_BUILTIN_TYPE(int32_t); + HANDLE_V1_BUILTIN_TYPE(int64_t); + HANDLE_V1_BUILTIN_TYPE(uint64_t); + HANDLE_V1_BUILTIN_TYPE(double); +#undef HANDLE_V1_BUILTIN_TYPE + + if (flag.IsOfType()) { + return "string"; + } + + return ""; +} + // This class is used to emit an XML element with `tag` and `text`. // It adds opening and closing tags and escapes special characters in the text. // For example: @@ -186,7 +207,7 @@ void FlagHelpHumanReadable(const flags_internal::CommandLineFlag& flag, // Flag data type (for V1 flags only). if (!flag.IsAbseilFlag() && !flag.IsRetired()) { - printer.Write(absl::StrCat("type: ", flag.Typename(), ";")); + printer.Write(absl::StrCat("type: ", TypenameForHelp(flag), ";")); } // The listed default value will be the actual default from the flag @@ -223,6 +244,9 @@ void FlagsHelpImpl(std::ostream& out, flags_internal::FlagKindFilter filter_cb, } else { // XML schema is not a part of our public API for now. out << "\n" + << "\n" + << "\n" // The document. << "\n" // The program name and usage. diff --git a/absl/random/BUILD.bazel b/absl/random/BUILD.bazel index 92111827..828f1348 100644 --- a/absl/random/BUILD.bazel +++ b/absl/random/BUILD.bazel @@ -76,6 +76,7 @@ cc_library( "//absl/random/internal:iostream_state_saver", "//absl/random/internal:traits", "//absl/random/internal:uniform_helper", + "//absl/random/internal:wide_multiply", "//absl/strings", "//absl/types:span", ], diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt index 151cefa4..19dd2cab 100644 --- a/absl/random/CMakeLists.txt +++ b/absl/random/CMakeLists.txt @@ -65,6 +65,7 @@ absl_cc_library( absl::random_internal_iostream_state_saver absl::random_internal_traits absl::random_internal_uniform_helper + absl::random_internal_wide_multiply absl::strings absl::span absl::type_traits @@ -557,6 +558,22 @@ absl_cc_library( absl::random_internal_traits ) +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_wide_multiply + HDRS + "internal/wide_multiply.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::bits + absl::config + absl::int128 +) + # Internal-only target, do not depend on directly. absl_cc_library( NAME @@ -1033,3 +1050,20 @@ absl_cc_test( absl::random_internal_iostream_state_saver gtest_main ) + +# Internal-only target, do not depend on directly. +absl_cc_test( + NAME + random_internal_wide_multiply_test + SRCS + internal/wide_multiply_test.cc + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_internal_wide_multiply + absl::bits + absl::int128 + gtest_main +) diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel index cd50982d..ec58cecd 100644 --- a/absl/random/internal/BUILD.bazel +++ b/absl/random/internal/BUILD.bazel @@ -200,6 +200,19 @@ cc_library( deps = ["//absl/base:bits"], ) +cc_library( + name = "wide_multiply", + hdrs = ["wide_multiply.h"], + copts = ABSL_DEFAULT_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + ":traits", + "//absl/base:bits", + "//absl/base:config", + "//absl/numeric:int128", + ], +) + cc_library( name = "nonsecure_base", hdrs = ["nonsecure_base.h"], @@ -598,6 +611,20 @@ cc_test( ], ) +cc_test( + name = "wide_multiply_test", + size = "small", + srcs = ["wide_multiply_test.cc"], + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + ":wide_multiply", + "//absl/base:bits", + "//absl/numeric:int128", + "@com_google_googletest//:gtest_main", + ], +) + cc_library( name = "nanobenchmark", srcs = ["nanobenchmark.cc"], diff --git a/absl/random/internal/distribution_impl.h b/absl/random/internal/distribution_impl.h index 9b6ffb0f..49b3e1a6 100644 --- a/absl/random/internal/distribution_impl.h +++ b/absl/random/internal/distribution_impl.h @@ -188,72 +188,6 @@ struct RandU64ToReal { } }; -inline uint128 MultiplyU64ToU128(uint64_t a, uint64_t b) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return uint128(static_cast<__uint128_t>(a) * b); -#elif defined(ABSL_INTERNAL_USE_UMUL128) - // uint64_t * uint64_t => uint128 multiply using imul intrinsic on MSVC. - uint64_t high = 0; - const uint64_t low = _umul128(a, b, &high); - return absl::MakeUint128(high, low); -#else - // uint128(a) * uint128(b) in emulated mode computes a full 128-bit x 128-bit - // multiply. However there are many cases where that is not necessary, and it - // is only necessary to support a 64-bit x 64-bit = 128-bit multiply. This is - // for those cases. - const uint64_t a00 = static_cast(a); - const uint64_t a32 = a >> 32; - const uint64_t b00 = static_cast(b); - const uint64_t b32 = b >> 32; - - const uint64_t c00 = a00 * b00; - const uint64_t c32a = a00 * b32; - const uint64_t c32b = a32 * b00; - const uint64_t c64 = a32 * b32; - - const uint32_t carry = - static_cast(((c00 >> 32) + static_cast(c32a) + - static_cast(c32b)) >> - 32); - - return absl::MakeUint128(c64 + (c32a >> 32) + (c32b >> 32) + carry, - c00 + (c32a << 32) + (c32b << 32)); -#endif -} - -// wide_multiply multiplies two N-bit values to a 2N-bit result. -template -struct wide_multiply { - static constexpr size_t kN = std::numeric_limits::digits; - using input_type = UIntType; - using result_type = typename random_internal::unsigned_bits::type; - - static result_type multiply(input_type a, input_type b) { - return static_cast(a) * b; - } - - static input_type hi(result_type r) { return r >> kN; } - static input_type lo(result_type r) { return r; } - - static_assert(std::is_unsigned::value, - "Class-template wide_multiply<> argument must be unsigned."); -}; - -#ifndef ABSL_HAVE_INTRINSIC_INT128 -template <> -struct wide_multiply { - using input_type = uint64_t; - using result_type = uint128; - - static result_type multiply(uint64_t a, uint64_t b) { - return MultiplyU64ToU128(a, b); - } - - static uint64_t hi(result_type r) { return Uint128High64(r); } - static uint64_t lo(result_type r) { return Uint128Low64(r); } -}; -#endif - } // namespace random_internal } // namespace absl diff --git a/absl/random/internal/distribution_impl_test.cc b/absl/random/internal/distribution_impl_test.cc index 09e7a318..fcc16904 100644 --- a/absl/random/internal/distribution_impl_test.cc +++ b/absl/random/internal/distribution_impl_test.cc @@ -461,46 +461,4 @@ TEST(DistributionImplTest, ExhaustiveFloat) { } } -TEST(DistributionImplTest, MultiplyU64ToU128Test) { - using absl::random_internal::MultiplyU64ToU128; - constexpr uint64_t k1 = 1; - constexpr uint64_t kMax = ~static_cast(0); - - EXPECT_EQ(absl::uint128(0), MultiplyU64ToU128(0, 0)); - - // Max uint64 - EXPECT_EQ(MultiplyU64ToU128(kMax, kMax), - absl::MakeUint128(0xfffffffffffffffe, 0x0000000000000001)); - EXPECT_EQ(absl::MakeUint128(0, kMax), MultiplyU64ToU128(kMax, 1)); - EXPECT_EQ(absl::MakeUint128(0, kMax), MultiplyU64ToU128(1, kMax)); - for (int i = 0; i < 64; ++i) { - EXPECT_EQ(absl::MakeUint128(0, kMax) << i, - MultiplyU64ToU128(kMax, k1 << i)); - EXPECT_EQ(absl::MakeUint128(0, kMax) << i, - MultiplyU64ToU128(k1 << i, kMax)); - } - - // 1-bit x 1-bit. - for (int i = 0; i < 64; ++i) { - for (int j = 0; j < 64; ++j) { - EXPECT_EQ(absl::MakeUint128(0, 1) << (i + j), - MultiplyU64ToU128(k1 << i, k1 << j)); - EXPECT_EQ(absl::MakeUint128(0, 1) << (i + j), - MultiplyU64ToU128(k1 << i, k1 << j)); - } - } - - // Verified multiplies - EXPECT_EQ(MultiplyU64ToU128(0xffffeeeeddddcccc, 0xbbbbaaaa99998888), - absl::MakeUint128(0xbbbb9e2692c5dddc, 0xc28f7531048d2c60)); - EXPECT_EQ(MultiplyU64ToU128(0x0123456789abcdef, 0xfedcba9876543210), - absl::MakeUint128(0x0121fa00ad77d742, 0x2236d88fe5618cf0)); - EXPECT_EQ(MultiplyU64ToU128(0x0123456789abcdef, 0xfdb97531eca86420), - absl::MakeUint128(0x0120ae99d26725fc, 0xce197f0ecac319e0)); - EXPECT_EQ(MultiplyU64ToU128(0x97a87f4f261ba3f2, 0xfedcba9876543210), - absl::MakeUint128(0x96fbf1a8ae78d0ba, 0x5a6dd4b71f278320)); - EXPECT_EQ(MultiplyU64ToU128(0xfedcba9876543210, 0xfdb97531eca86420), - absl::MakeUint128(0xfc98c6981a413e22, 0x342d0bbf48948200)); -} - } // namespace diff --git a/absl/random/internal/wide_multiply.h b/absl/random/internal/wide_multiply.h new file mode 100644 index 00000000..ebbfa1f2 --- /dev/null +++ b/absl/random/internal/wide_multiply.h @@ -0,0 +1,109 @@ +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_RANDOM_INTERNAL_WIDE_MULTIPLY_H_ +#define ABSL_RANDOM_INTERNAL_WIDE_MULTIPLY_H_ + +#include +#include +#include + +#if (defined(_WIN32) || defined(_WIN64)) && defined(_M_IA64) +#include // NOLINT(build/include_order) +#pragma intrinsic(_umul128) +#define ABSL_INTERNAL_USE_UMUL128 1 +#endif + +#include "absl/base/config.h" +#include "absl/base/internal/bits.h" +#include "absl/numeric/int128.h" +#include "absl/random/internal/traits.h" + +namespace absl { +namespace random_internal { + +// Helper object to multiply two 64-bit values to a 128-bit value. +// MultiplyU64ToU128 multiplies two 64-bit values to a 128-bit value. +// If an intrinsic is available, it is used, otherwise use native 32-bit +// multiplies to construct the result. +inline uint128 MultiplyU64ToU128(uint64_t a, uint64_t b) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return uint128(static_cast<__uint128_t>(a) * b); +#elif defined(ABSL_INTERNAL_USE_UMUL128) + // uint64_t * uint64_t => uint128 multiply using imul intrinsic on MSVC. + uint64_t high = 0; + const uint64_t low = _umul128(a, b, &high); + return absl::MakeUint128(high, low); +#else + // uint128(a) * uint128(b) in emulated mode computes a full 128-bit x 128-bit + // multiply. However there are many cases where that is not necessary, and it + // is only necessary to support a 64-bit x 64-bit = 128-bit multiply. This is + // for those cases. + const uint64_t a00 = static_cast(a); + const uint64_t a32 = a >> 32; + const uint64_t b00 = static_cast(b); + const uint64_t b32 = b >> 32; + + const uint64_t c00 = a00 * b00; + const uint64_t c32a = a00 * b32; + const uint64_t c32b = a32 * b00; + const uint64_t c64 = a32 * b32; + + const uint32_t carry = + static_cast(((c00 >> 32) + static_cast(c32a) + + static_cast(c32b)) >> + 32); + + return absl::MakeUint128(c64 + (c32a >> 32) + (c32b >> 32) + carry, + c00 + (c32a << 32) + (c32b << 32)); +#endif +} + +// wide_multiply multiplies two N-bit values to a 2N-bit result. +template +struct wide_multiply { + static constexpr size_t kN = std::numeric_limits::digits; + using input_type = UIntType; + using result_type = typename random_internal::unsigned_bits::type; + + static result_type multiply(input_type a, input_type b) { + return static_cast(a) * b; + } + + static input_type hi(result_type r) { return r >> kN; } + static input_type lo(result_type r) { return r; } + + static_assert(std::is_unsigned::value, + "Class-template wide_multiply<> argument must be unsigned."); +}; + +#ifndef ABSL_HAVE_INTRINSIC_INT128 +template <> +struct wide_multiply { + using input_type = uint64_t; + using result_type = uint128; + + static result_type multiply(uint64_t a, uint64_t b) { + return MultiplyU64ToU128(a, b); + } + + static uint64_t hi(result_type r) { return Uint128High64(r); } + static uint64_t lo(result_type r) { return Uint128Low64(r); } +}; +#endif + +} // namespace random_internal +} // namespace absl + +#endif // ABSL_RANDOM_INTERNAL_WIDE_MULTIPLY_H_ diff --git a/absl/random/internal/wide_multiply_test.cc b/absl/random/internal/wide_multiply_test.cc new file mode 100644 index 00000000..922603f2 --- /dev/null +++ b/absl/random/internal/wide_multiply_test.cc @@ -0,0 +1,66 @@ +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/random/internal/wide_multiply.h" + +#include "gtest/gtest.h" +#include "absl/base/internal/bits.h" +#include "absl/numeric/int128.h" + +using absl::random_internal::MultiplyU64ToU128; + +namespace { + +TEST(WideMultiplyTest, MultiplyU64ToU128Test) { + constexpr uint64_t k1 = 1; + constexpr uint64_t kMax = ~static_cast(0); + + EXPECT_EQ(absl::uint128(0), MultiplyU64ToU128(0, 0)); + + // Max uint64 + EXPECT_EQ(MultiplyU64ToU128(kMax, kMax), + absl::MakeUint128(0xfffffffffffffffe, 0x0000000000000001)); + EXPECT_EQ(absl::MakeUint128(0, kMax), MultiplyU64ToU128(kMax, 1)); + EXPECT_EQ(absl::MakeUint128(0, kMax), MultiplyU64ToU128(1, kMax)); + for (int i = 0; i < 64; ++i) { + EXPECT_EQ(absl::MakeUint128(0, kMax) << i, + MultiplyU64ToU128(kMax, k1 << i)); + EXPECT_EQ(absl::MakeUint128(0, kMax) << i, + MultiplyU64ToU128(k1 << i, kMax)); + } + + // 1-bit x 1-bit. + for (int i = 0; i < 64; ++i) { + for (int j = 0; j < 64; ++j) { + EXPECT_EQ(absl::MakeUint128(0, 1) << (i + j), + MultiplyU64ToU128(k1 << i, k1 << j)); + EXPECT_EQ(absl::MakeUint128(0, 1) << (i + j), + MultiplyU64ToU128(k1 << i, k1 << j)); + } + } + + // Verified multiplies + EXPECT_EQ(MultiplyU64ToU128(0xffffeeeeddddcccc, 0xbbbbaaaa99998888), + absl::MakeUint128(0xbbbb9e2692c5dddc, 0xc28f7531048d2c60)); + EXPECT_EQ(MultiplyU64ToU128(0x0123456789abcdef, 0xfedcba9876543210), + absl::MakeUint128(0x0121fa00ad77d742, 0x2236d88fe5618cf0)); + EXPECT_EQ(MultiplyU64ToU128(0x0123456789abcdef, 0xfdb97531eca86420), + absl::MakeUint128(0x0120ae99d26725fc, 0xce197f0ecac319e0)); + EXPECT_EQ(MultiplyU64ToU128(0x97a87f4f261ba3f2, 0xfedcba9876543210), + absl::MakeUint128(0x96fbf1a8ae78d0ba, 0x5a6dd4b71f278320)); + EXPECT_EQ(MultiplyU64ToU128(0xfedcba9876543210, 0xfdb97531eca86420), + absl::MakeUint128(0xfc98c6981a413e22, 0x342d0bbf48948200)); +} + +} // namespace diff --git a/absl/random/uniform_int_distribution.h b/absl/random/uniform_int_distribution.h index 4970486a..02aa3765 100644 --- a/absl/random/uniform_int_distribution.h +++ b/absl/random/uniform_int_distribution.h @@ -38,6 +38,7 @@ #include "absl/random/internal/fast_uniform_bits.h" #include "absl/random/internal/iostream_state_saver.h" #include "absl/random/internal/traits.h" +#include "absl/random/internal/wide_multiply.h" namespace absl { diff --git a/absl/strings/numbers_test.cc b/absl/strings/numbers_test.cc index 4edf8891..d964e562 100644 --- a/absl/strings/numbers_test.cc +++ b/absl/strings/numbers_test.cc @@ -204,6 +204,9 @@ void CheckHex64(uint64_t v) { std::string actual = absl::StrCat(absl::Hex(v, absl::kZeroPad16)); snprintf(expected, sizeof(expected), "%016" PRIx64, static_cast(v)); EXPECT_EQ(expected, actual) << " Input " << v; + actual = absl::StrCat(absl::Hex(v, absl::kSpacePad16)); + snprintf(expected, sizeof(expected), "%16" PRIx64, static_cast(v)); + EXPECT_EQ(expected, actual) << " Input " << v; } TEST(Numbers, TestFastPrints) { -- cgit v1.2.3 From 078b89b3c046d230ef3ad39494e5852184eb528b Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 23 Oct 2019 19:35:39 -0700 Subject: Export of internal Abseil changes -- e54b9c7bbb0c58475676c268e2e19c69f4bce48a by Jorg Brown : Tweak ABSL_PREDICT_TRUE slightly, for better code on some platforms and/or optimization levels. "false || (x)" is more verbose than "!!(x)", but ultimately more efficient. For example, given this code: void InitIfNecessary() { if (ABSL_PREDICT_TRUE(NeedsInit())) { SlowInitIfNecessary(); } } Clang with default optimization level will produce: Before this CL After this CL InitIfNecessary: InitIfNecessary: push rbp push rbp mov rbp, rsp mov rbp, rsp call NeedsInit call NeedsInit xor al, -1 xor al, -1 test al, 1 test al, 1 jne .LBB2_1 jne .LBB3_1 jmp .LBB2_2 jmp .LBB3_2 .LBB2_1: .LBB3_1: call SlowInitIfNecessary call SlowInitIfNecessary .LBB2_2: .LBB3_2: pop rbp pop rbp ret ret PiperOrigin-RevId: 276401386 -- 0a3c4dfd8342bf2b1b11a87f1c662c883f73cab7 by Abseil Team : Fix comment nit: sem_open => sem_init. The code calls sem_init, not sem_open, to initialize an unnamed semaphore. (sem_open creates or opens a named semaphore.) PiperOrigin-RevId: 276344072 -- b36a664e9459057509a90e83d3482e1d3a4c44c7 by Abseil Team : Fix typo in flat_hash_map.h: exchaged -> exchanged PiperOrigin-RevId: 276295792 -- 7bbd8d18276eb110c8335743e35fceb662ddf3d6 by Samuel Benzaquen : Add assertions to verify use of iterators. PiperOrigin-RevId: 276283300 -- 677398a8ffcb1f59182cffe57a4fe7ff147a0404 by Laramie Leavitt : Migrate distribution_impl.h/cc to generate_real.h/cc. Combine the methods RandU64To into a single method: GenerateRealFromBits(). Remove rejection sampling from absl::uniform_real_distribution. PiperOrigin-RevId: 276158675 -- c60c9d11d24b0c546329d998e78e15a84b3153f5 by Abseil Team : Internal change PiperOrigin-RevId: 276126962 -- 4c840cab6a8d86efa29b397cafaf7520eece68cc by Andy Soffer : Update CMakeLists.txt to address https://github.com/abseil/abseil-cpp/issues/365. This does not cover every platform, but it does at least address the first-order issue of assuming gcc implies x86. PiperOrigin-RevId: 276116253 -- 98da366e6b5d51afe5d7ac6722126aca23d85ee6 by Abseil Team : Internal change PiperOrigin-RevId: 276097452 GitOrigin-RevId: e54b9c7bbb0c58475676c268e2e19c69f4bce48a Change-Id: I02d84454bb71ab21ad3d39650acf6cc6e36f58d7 --- absl/base/BUILD.bazel | 25 ++ absl/base/CMakeLists.txt | 26 ++ absl/base/config.h | 2 +- absl/base/internal/exponential_biased.cc | 84 +++++ absl/base/internal/exponential_biased.h | 77 ++++ absl/base/internal/exponential_biased_test.cc | 168 +++++++++ absl/base/optimization.h | 2 +- absl/container/BUILD.bazel | 1 + absl/container/CMakeLists.txt | 1 + absl/container/flat_hash_map.h | 2 +- absl/container/internal/hashtablez_sampler.cc | 83 +---- absl/container/internal/raw_hash_set.h | 20 +- absl/container/internal/raw_hash_set_test.cc | 2 +- absl/copts/AbseilConfigureCopts.cmake | 25 +- absl/random/BUILD.bazel | 2 +- absl/random/CMakeLists.txt | 17 +- absl/random/beta_distribution.h | 31 +- absl/random/beta_distribution_test.cc | 2 +- absl/random/exponential_distribution.h | 14 +- absl/random/gaussian_distribution.h | 22 +- absl/random/internal/BUILD.bazel | 16 +- absl/random/internal/distribution_impl.h | 194 ---------- absl/random/internal/distribution_impl_test.cc | 464 ----------------------- absl/random/internal/generate_real.h | 144 +++++++ absl/random/internal/generate_real_test.cc | 497 +++++++++++++++++++++++++ absl/random/log_uniform_int_distribution.h | 2 +- absl/random/poisson_distribution.h | 20 +- absl/random/uniform_int_distribution.h | 1 - absl/random/uniform_real_distribution.h | 15 +- 29 files changed, 1164 insertions(+), 795 deletions(-) create mode 100644 absl/base/internal/exponential_biased.cc create mode 100644 absl/base/internal/exponential_biased.h create mode 100644 absl/base/internal/exponential_biased_test.cc delete mode 100644 absl/random/internal/distribution_impl.h delete mode 100644 absl/random/internal/distribution_impl_test.cc create mode 100644 absl/random/internal/generate_real.h create mode 100644 absl/random/internal/generate_real_test.cc (limited to 'absl/random/CMakeLists.txt') diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index d74bac63..ffeca630 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -557,6 +557,31 @@ cc_test( ], ) +cc_library( + name = "exponential_biased", + srcs = ["internal/exponential_biased.cc"], + hdrs = ["internal/exponential_biased.h"], + linkopts = ABSL_DEFAULT_LINKOPTS, + visibility = [ + "//absl:__subpackages__", + ], + deps = [":core_headers"], +) + +cc_test( + name = "exponential_biased_test", + size = "small", + srcs = ["internal/exponential_biased_test.cc"], + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + visibility = ["//visibility:private"], + deps = [ + ":exponential_biased", + "//absl/strings", + "@com_google_googletest//:gtest_main", + ], +) + cc_library( name = "scoped_set_env", testonly = 1, diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index 79ee5b93..2698213c 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt @@ -503,6 +503,32 @@ absl_cc_test( gtest_main ) +absl_cc_library( + NAME + exponential_biased + SRCS + "internal/exponential_biased.cc" + HDRS + "internal/exponential_biased.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::core_headers +) + +absl_cc_test( + NAME + exponential_biased_test + SRCS + "internal/exponential_biased_test.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::exponential_biased + absl::strings + gmock_main +) + absl_cc_library( NAME scoped_set_env diff --git a/absl/base/config.h b/absl/base/config.h index 039b73d8..24851fa3 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -307,7 +307,7 @@ // ABSL_HAVE_SEMAPHORE_H // -// Checks whether the platform supports the header and sem_open(3) +// Checks whether the platform supports the header and sem_init(3) // family of functions as standardized in POSIX.1-2001. // // Note: While Apple provides for both iOS and macOS, it is diff --git a/absl/base/internal/exponential_biased.cc b/absl/base/internal/exponential_biased.cc new file mode 100644 index 00000000..d7ffd184 --- /dev/null +++ b/absl/base/internal/exponential_biased.cc @@ -0,0 +1,84 @@ +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/base/internal/exponential_biased.h" + +#include + +#include +#include +#include + +#include "absl/base/attributes.h" +#include "absl/base/optimization.h" + +namespace absl { +namespace base_internal { + +// The algorithm generates a random number between 0 and 1 and applies the +// inverse cumulative distribution function for an exponential. Specifically: +// Let m be the inverse of the sample period, then the probability +// distribution function is m*exp(-mx) so the CDF is +// p = 1 - exp(-mx), so +// q = 1 - p = exp(-mx) +// log_e(q) = -mx +// -log_e(q)/m = x +// log_2(q) * (-log_e(2) * 1/m) = x +// In the code, q is actually in the range 1 to 2**26, hence the -26 below +int64_t ExponentialBiased::Get(int64_t mean) { + if (ABSL_PREDICT_FALSE(!initialized_)) { + Initialize(); + } + + uint64_t rng = NextRandom(rng_); + rng_ = rng; + + // Take the top 26 bits as the random number + // (This plus the 1<<58 sampling bound give a max possible step of + // 5194297183973780480 bytes.) + // The uint32_t cast is to prevent a (hard-to-reproduce) NAN + // under piii debug for some binaries. + double q = static_cast(rng >> (kPrngNumBits - 26)) + 1.0; + // Put the computed p-value through the CDF of a geometric. + double interval = (std::log2(q) - 26) * (-std::log(2.0) * mean); + // Very large values of interval overflow int64_t. To avoid that, we will cheat + // and clamp any huge values to (int64_t max)/2. This is a potential source of + // bias, but the mean would need to be such a large value that it's not likely + // to come up. For example, with a mean of 1e18, the probability of hitting + // this condition is about 1/1000. For a mean of 1e17, standard calculators + // claim that this event won't happen. + if (interval > static_cast(std::numeric_limits::max() / 2)) { + return std::numeric_limits::max() / 2; + } + + return static_cast(interval); +} + +void ExponentialBiased::Initialize() { + // We don't get well distributed numbers from `this` so we call NextRandom() a + // bunch to mush the bits around. We use a global_rand to handle the case + // where the same thread (by memory address) gets created and destroyed + // repeatedly. + ABSL_CONST_INIT static std::atomic global_rand(0); + uint64_t r = reinterpret_cast(this) + + global_rand.fetch_add(1, std::memory_order_relaxed); + for (int i = 0; i < 20; ++i) { + r = NextRandom(r); + } + rng_ = r; + initialized_ = true; +} + +} // namespace base_internal +} // namespace absl diff --git a/absl/base/internal/exponential_biased.h b/absl/base/internal/exponential_biased.h new file mode 100644 index 00000000..cac2d8ad --- /dev/null +++ b/absl/base/internal/exponential_biased.h @@ -0,0 +1,77 @@ +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_BASE_INTERNAL_EXPONENTIAL_BIASED_H_ +#define ABSL_BASE_INTERNAL_EXPONENTIAL_BIASED_H_ + +#include + +namespace absl { +namespace base_internal { + +// ExponentialBiased provides a small and fast random number generator for a +// rounded exponential distribution. This generator doesn't requires very little +// state doesn't impose synchronization overhead, which makes it useful in some +// specialized scenarios. +// +// For the generated variable X, X ~ floor(Exponential(1/mean)). The floor +// operation introduces a small amount of bias, but the distribution is useful +// to generate a wait time. That is, if an operation is supposed to happen on +// average to 1/mean events, then the generated variable X will describe how +// many events to skip before performing the operation and computing a new X. +// +// The mathematically precise distribution to use for integer wait times is a +// Geometric distribution, but a Geometric distribution takes slightly more time +// to compute and when the mean is large (say, 100+), the Geometric distribution +// is hard to distinguish from the result of ExponentialBiased. +// +// This class is thread-compatible. +class ExponentialBiased { + public: + // The number of bits set by NextRandom. + static constexpr int kPrngNumBits = 48; + + // Generates the floor of an exponentially distributed random variable by + // rounding the value down to the nearest integer. The result will be in the + // range [0, int64_t max / 2]. + int64_t Get(int64_t mean); + + // Computes a random number in the range [0, 1<<(kPrngNumBits+1) - 1] + // + // This is public to enable testing. + static uint64_t NextRandom(uint64_t rnd); + + private: + void Initialize(); + + uint64_t rng_{0}; + bool initialized_{false}; +}; + +// Returns the next prng value. +// pRNG is: aX+b mod c with a = 0x5DEECE66D, b = 0xB, c = 1<<48 +// This is the lrand64 generator. +inline uint64_t ExponentialBiased::NextRandom(uint64_t rnd) { + const uint64_t prng_mult = uint64_t{0x5DEECE66D}; + const uint64_t prng_add = 0xB; + const uint64_t prng_mod_power = 48; + const uint64_t prng_mod_mask = + ~((~static_cast(0)) << prng_mod_power); + return (prng_mult * rnd + prng_add) & prng_mod_mask; +} + +} // namespace base_internal +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_EXPONENTIAL_BIASED_H_ diff --git a/absl/base/internal/exponential_biased_test.cc b/absl/base/internal/exponential_biased_test.cc new file mode 100644 index 00000000..09b511d1 --- /dev/null +++ b/absl/base/internal/exponential_biased_test.cc @@ -0,0 +1,168 @@ +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/base/internal/exponential_biased.h" + +#include + +#include +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/strings/str_cat.h" + +using ::testing::Ge; + +namespace absl { +namespace base_internal { + +MATCHER_P2(IsBetween, a, b, + absl::StrCat(std::string(negation ? "isn't" : "is"), " between ", a, + " and ", b)) { + return a <= arg && arg <= b; +} + +// Tests of the quality of the random numbers generated +// This uses the Anderson Darling test for uniformity. +// See "Evaluating the Anderson-Darling Distribution" by Marsaglia +// for details. + +// Short cut version of ADinf(z), z>0 (from Marsaglia) +// This returns the p-value for Anderson Darling statistic in +// the limit as n-> infinity. For finite n, apply the error fix below. +double AndersonDarlingInf(double z) { + if (z < 2) { + return exp(-1.2337141 / z) / sqrt(z) * + (2.00012 + + (0.247105 - + (0.0649821 - (0.0347962 - (0.011672 - 0.00168691 * z) * z) * z) * + z) * + z); + } + return exp( + -exp(1.0776 - + (2.30695 - + (0.43424 - (0.082433 - (0.008056 - 0.0003146 * z) * z) * z) * z) * + z)); +} + +// Corrects the approximation error in AndersonDarlingInf for small values of n +// Add this to AndersonDarlingInf to get a better approximation +// (from Marsaglia) +double AndersonDarlingErrFix(int n, double x) { + if (x > 0.8) { + return (-130.2137 + + (745.2337 - + (1705.091 - (1950.646 - (1116.360 - 255.7844 * x) * x) * x) * x) * + x) / + n; + } + double cutoff = 0.01265 + 0.1757 / n; + if (x < cutoff) { + double t = x / cutoff; + t = sqrt(t) * (1 - t) * (49 * t - 102); + return t * (0.0037 / (n * n) + 0.00078 / n + 0.00006) / n; + } else { + double t = (x - cutoff) / (0.8 - cutoff); + t = -0.00022633 + + (6.54034 - (14.6538 - (14.458 - (8.259 - 1.91864 * t) * t) * t) * t) * + t; + return t * (0.04213 + 0.01365 / n) / n; + } +} + +// Returns the AndersonDarling p-value given n and the value of the statistic +double AndersonDarlingPValue(int n, double z) { + double ad = AndersonDarlingInf(z); + double errfix = AndersonDarlingErrFix(n, ad); + return ad + errfix; +} + +double AndersonDarlingStatistic(const std::vector& random_sample) { + int n = random_sample.size(); + double ad_sum = 0; + for (int i = 0; i < n; i++) { + ad_sum += (2 * i + 1) * + std::log(random_sample[i] * (1 - random_sample[n - 1 - i])); + } + double ad_statistic = -n - 1 / static_cast(n) * ad_sum; + return ad_statistic; +} + +// Tests if the array of doubles is uniformly distributed. +// Returns the p-value of the Anderson Darling Statistic +// for the given set of sorted random doubles +// See "Evaluating the Anderson-Darling Distribution" by +// Marsaglia and Marsaglia for details. +double AndersonDarlingTest(const std::vector& random_sample) { + double ad_statistic = AndersonDarlingStatistic(random_sample); + double p = AndersonDarlingPValue(random_sample.size(), ad_statistic); + return p; +} + +// Testing that NextRandom generates uniform random numbers. Applies the +// Anderson-Darling test for uniformity +TEST(ExponentialBiasedTest, TestNextRandom) { + for (auto n : std::vector({ + 10, // Check short-range correlation + 100, 1000, + 10000 // Make sure there's no systemic error + })) { + uint64_t x = 1; + // This assumes that the prng returns 48 bit numbers + uint64_t max_prng_value = static_cast(1) << 48; + // Initialize. + for (int i = 1; i <= 20; i++) { + x = ExponentialBiased::NextRandom(x); + } + std::vector int_random_sample(n); + // Collect samples + for (int i = 0; i < n; i++) { + int_random_sample[i] = x; + x = ExponentialBiased::NextRandom(x); + } + // First sort them... + std::sort(int_random_sample.begin(), int_random_sample.end()); + std::vector random_sample(n); + // Convert them to uniform randoms (in the range [0,1]) + for (int i = 0; i < n; i++) { + random_sample[i] = + static_cast(int_random_sample[i]) / max_prng_value; + } + // Now compute the Anderson-Darling statistic + double ad_pvalue = AndersonDarlingTest(random_sample); + EXPECT_GT(std::min(ad_pvalue, 1 - ad_pvalue), 0.0001) + << "prng is not uniform: n = " << n << " p = " << ad_pvalue; + } +} + +// The generator needs to be available as a thread_local and as a static +// variable. +TEST(ExponentialBiasedTest, InitializationModes) { + ABSL_CONST_INIT static ExponentialBiased eb_static; + EXPECT_THAT(eb_static.Get(2), Ge(0)); + +#if ABSL_HAVE_THREAD_LOCAL + thread_local ExponentialBiased eb_thread; + EXPECT_THAT(eb_thread.Get(2), Ge(0)); +#endif + + ExponentialBiased eb_stack; + EXPECT_THAT(eb_stack.Get(2), Ge(0)); +} + +} // namespace base_internal +} // namespace absl diff --git a/absl/base/optimization.h b/absl/base/optimization.h index 0dcbef32..646523b3 100644 --- a/absl/base/optimization.h +++ b/absl/base/optimization.h @@ -172,7 +172,7 @@ #if ABSL_HAVE_BUILTIN(__builtin_expect) || \ (defined(__GNUC__) && !defined(__clang__)) #define ABSL_PREDICT_FALSE(x) (__builtin_expect(x, 0)) -#define ABSL_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) +#define ABSL_PREDICT_TRUE(x) (__builtin_expect(false || (x), true)) #else #define ABSL_PREDICT_FALSE(x) (x) #define ABSL_PREDICT_TRUE(x) (x) diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index 0894bb20..e60979b2 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -493,6 +493,7 @@ cc_library( ":have_sse", "//absl/base", "//absl/base:core_headers", + "//absl/base:exponential_biased", "//absl/debugging:stacktrace", "//absl/memory", "//absl/synchronization", diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index 933c7a8c..aa33659b 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt @@ -538,6 +538,7 @@ absl_cc_library( ${ABSL_DEFAULT_COPTS} DEPS absl::base + absl::exponential_biased absl::have_sse absl::synchronization ) diff --git a/absl/container/flat_hash_map.h b/absl/container/flat_hash_map.h index 5c16ac88..283f2439 100644 --- a/absl/container/flat_hash_map.h +++ b/absl/container/flat_hash_map.h @@ -401,7 +401,7 @@ class flat_hash_map : public absl::container_internal::raw_hash_map< // for the past-the-end iterator, which is invalidated. // // `swap()` requires that the flat hash map's hashing and key equivalence - // functions be Swappable, and are exchaged using unqualified calls to + // functions be Swappable, and are exchanged using unqualified calls to // non-member `swap()`. If the map's allocator has // `std::allocator_traits::propagate_on_container_swap::value` // set to `true`, the allocators are also exchanged using an unqualified call diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc index 054e8981..0a7ef61c 100644 --- a/absl/container/internal/hashtablez_sampler.cc +++ b/absl/container/internal/hashtablez_sampler.cc @@ -21,6 +21,7 @@ #include #include "absl/base/attributes.h" +#include "absl/base/internal/exponential_biased.h" #include "absl/container/internal/have_sse.h" #include "absl/debugging/stacktrace.h" #include "absl/memory/memory.h" @@ -37,77 +38,13 @@ ABSL_CONST_INIT std::atomic g_hashtablez_enabled{ ABSL_CONST_INIT std::atomic g_hashtablez_sample_parameter{1 << 10}; ABSL_CONST_INIT std::atomic g_hashtablez_max_samples{1 << 20}; -// Returns the next pseudo-random value. -// pRNG is: aX+b mod c with a = 0x5DEECE66D, b = 0xB, c = 1<<48 -// This is the lrand64 generator. -uint64_t NextRandom(uint64_t rnd) { - const uint64_t prng_mult = uint64_t{0x5DEECE66D}; - const uint64_t prng_add = 0xB; - const uint64_t prng_mod_power = 48; - const uint64_t prng_mod_mask = ~(~uint64_t{0} << prng_mod_power); - return (prng_mult * rnd + prng_add) & prng_mod_mask; -} - -// Generates a geometric variable with the specified mean. -// This is done by generating a random number between 0 and 1 and applying -// the inverse cumulative distribution function for an exponential. -// Specifically: Let m be the inverse of the sample period, then -// the probability distribution function is m*exp(-mx) so the CDF is -// p = 1 - exp(-mx), so -// q = 1 - p = exp(-mx) -// log_e(q) = -mx -// -log_e(q)/m = x -// log_2(q) * (-log_e(2) * 1/m) = x -// In the code, q is actually in the range 1 to 2**26, hence the -26 below -// -int64_t GetGeometricVariable(int64_t mean) { #if ABSL_HAVE_THREAD_LOCAL - thread_local -#else // ABSL_HAVE_THREAD_LOCAL - // SampleSlow and hence GetGeometricVariable is guarded by a single mutex when - // there are not thread locals. Thus, a single global rng is acceptable for - // that case. - static -#endif // ABSL_HAVE_THREAD_LOCAL - uint64_t rng = []() { - // We don't get well distributed numbers from this so we call - // NextRandom() a bunch to mush the bits around. We use a global_rand - // to handle the case where the same thread (by memory address) gets - // created and destroyed repeatedly. - ABSL_CONST_INIT static std::atomic global_rand(0); - uint64_t r = reinterpret_cast(&rng) + - global_rand.fetch_add(1, std::memory_order_relaxed); - for (int i = 0; i < 20; ++i) { - r = NextRandom(r); - } - return r; - }(); - - rng = NextRandom(rng); - - // Take the top 26 bits as the random number - // (This plus the 1<<58 sampling bound give a max possible step of - // 5194297183973780480 bytes.) - const uint64_t prng_mod_power = 48; // Number of bits in prng - // The uint32_t cast is to prevent a (hard-to-reproduce) NAN - // under piii debug for some binaries. - double q = static_cast(rng >> (prng_mod_power - 26)) + 1.0; - // Put the computed p-value through the CDF of a geometric. - double interval = (log2(q) - 26) * (-std::log(2.0) * mean); - - // Very large values of interval overflow int64_t. If we happen to - // hit such improbable condition, we simply cheat and clamp interval - // to largest supported value. - if (interval > static_cast(std::numeric_limits::max() / 2)) { - return std::numeric_limits::max() / 2; - } - - // Small values of interval are equivalent to just sampling next time. - if (interval < 1) { - return 1; - } - return static_cast(interval); -} +thread_local absl::base_internal::ExponentialBiased + g_exponential_biased_generator; +#else +ABSL_CONST_INIT static absl::base_internal::ExponentialBiased + g_exponential_biased_generator; +#endif } // namespace @@ -253,8 +190,12 @@ HashtablezInfo* SampleSlow(int64_t* next_sample) { } bool first = *next_sample < 0; - *next_sample = GetGeometricVariable( + *next_sample = g_exponential_biased_generator.Get( g_hashtablez_sample_parameter.load(std::memory_order_relaxed)); + // Small values of interval are equivalent to just sampling next time. + if (*next_sample < 1) { + *next_sample = 1; + } // g_hashtablez_enabled can be dynamically flipped, we need to set a threshold // low enough that we will start sampling in a reasonable time, so we just use diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 42b3c468..9992ba4b 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -614,13 +614,17 @@ class raw_hash_set { iterator() {} // PRECONDITION: not an end() iterator. - reference operator*() const { return PolicyTraits::element(slot_); } + reference operator*() const { + /* To be enabled: assert_is_full(); */ + return PolicyTraits::element(slot_); + } // PRECONDITION: not an end() iterator. pointer operator->() const { return &operator*(); } // PRECONDITION: not an end() iterator. iterator& operator++() { + /* To be enabled: assert_is_full(); */ ++ctrl_; ++slot_; skip_empty_or_deleted(); @@ -634,6 +638,8 @@ class raw_hash_set { } friend bool operator==(const iterator& a, const iterator& b) { + /* To be enabled: a.assert_is_valid(); */ + /* To be enabled: b.assert_is_valid(); */ return a.ctrl_ == b.ctrl_; } friend bool operator!=(const iterator& a, const iterator& b) { @@ -644,6 +650,11 @@ class raw_hash_set { iterator(ctrl_t* ctrl) : ctrl_(ctrl) {} // for end() iterator(ctrl_t* ctrl, slot_type* slot) : ctrl_(ctrl), slot_(slot) {} + void assert_is_full() const { assert(IsFull(*ctrl_)); } + void assert_is_valid() const { + assert(!ctrl_ || IsFull(*ctrl_) || *ctrl_ == kSentinel); + } + void skip_empty_or_deleted() { while (IsEmptyOrDeleted(*ctrl_)) { // ctrl is not necessarily aligned to Group::kWidth. It is also likely @@ -1155,7 +1166,7 @@ class raw_hash_set { // This overload is necessary because otherwise erase(const K&) would be // a better match if non-const iterator is passed as an argument. void erase(iterator it) { - assert(it != end()); + it.assert_is_full(); PolicyTraits::destroy(&alloc_ref(), it.slot_); erase_meta_only(it); } @@ -1172,12 +1183,14 @@ class raw_hash_set { template void merge(raw_hash_set& src) { // NOLINT assert(this != &src); - for (auto it = src.begin(), e = src.end(); it != e; ++it) { + for (auto it = src.begin(), e = src.end(); it != e;) { + auto next = std::next(it); if (PolicyTraits::apply(InsertSlot{*this, std::move(*it.slot_)}, PolicyTraits::element(it.slot_)) .second) { src.erase_meta_only(it); } + it = next; } } @@ -1187,6 +1200,7 @@ class raw_hash_set { } node_type extract(const_iterator position) { + position.inner_.assert_is_full(); auto node = CommonAccess::Transfer(alloc_ref(), position.inner_.slot_); erase_meta_only(position); diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc index ed4ca8c8..33cfa72c 100644 --- a/absl/container/internal/raw_hash_set_test.cc +++ b/absl/container/internal/raw_hash_set_test.cc @@ -1837,7 +1837,7 @@ TEST(TableDeathTest, EraseOfEndAsserts) { IntTable t; // Extra simple "regexp" as regexp support is highly varied across platforms. - constexpr char kDeathMsg[] = "it != end"; + constexpr char kDeathMsg[] = "IsFull"; EXPECT_DEATH_IF_SUPPORTED(t.erase(t.end()), kDeathMsg); } diff --git a/absl/copts/AbseilConfigureCopts.cmake b/absl/copts/AbseilConfigureCopts.cmake index b430873c..b4426469 100644 --- a/absl/copts/AbseilConfigureCopts.cmake +++ b/absl/copts/AbseilConfigureCopts.cmake @@ -5,10 +5,29 @@ set(ABSL_LSAN_LINKOPTS "") set(ABSL_HAVE_LSAN OFF) set(ABSL_DEFAULT_LINKOPTS "") +if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") + if (MSVC) + set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_MSVC_X64_FLAGS}") + else() + set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_X64_FLAGS}") + endif() +elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "arm") + if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8") + set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_ARM64_FLAGS}") + elseif("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4") + set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_ARM32_FLAGS}") + else() + message(WARNING "Value of CMAKE_SIZEOF_VOID_P (${CMAKE_SIZEOF_VOID_P}) is not supported.") + endif() +else() + message(WARNING "Value of CMAKE_SYSTEM_PROCESSOR (${CMAKE_SYSTEM_PROCESSOR}) is unknown and cannot be used to set ABSL_RANDOM_RANDEN_COPTS") + set(ABSL_RANDOM_RANDEN_COPTS "") +endif() + + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set(ABSL_DEFAULT_COPTS "${ABSL_GCC_FLAGS}") set(ABSL_TEST_COPTS "${ABSL_GCC_FLAGS};${ABSL_GCC_TEST_FLAGS}") - set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_X64_FLAGS}") elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # MATCHES so we get both Clang and AppleClang if(MSVC) @@ -16,11 +35,9 @@ elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") set(ABSL_DEFAULT_COPTS "${ABSL_CLANG_CL_FLAGS}") set(ABSL_TEST_COPTS "${ABSL_CLANG_CL_FLAGS};${ABSL_CLANG_CL_TEST_FLAGS}") set(ABSL_DEFAULT_LINKOPTS "${ABSL_MSVC_LINKOPTS}") - set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_MSVC_X64_FLAGS}") else() set(ABSL_DEFAULT_COPTS "${ABSL_LLVM_FLAGS}") set(ABSL_TEST_COPTS "${ABSL_LLVM_FLAGS};${ABSL_LLVM_TEST_FLAGS}") - set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_X64_FLAGS}") if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") # AppleClang doesn't have lsan # https://developer.apple.com/documentation/code_diagnostics @@ -34,12 +51,10 @@ elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") set(ABSL_DEFAULT_COPTS "${ABSL_MSVC_FLAGS}") set(ABSL_TEST_COPTS "${ABSL_MSVC_FLAGS};${ABSL_MSVC_TEST_FLAGS}") set(ABSL_DEFAULT_LINKOPTS "${ABSL_MSVC_LINKOPTS}") - set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_MSVC_X64_FLAGS}") else() message(WARNING "Unknown compiler: ${CMAKE_CXX_COMPILER}. Building with no default flags") set(ABSL_DEFAULT_COPTS "") set(ABSL_TEST_COPTS "") - set(ABSL_RANDOM_RANDEN_COPTS "") endif() if("${CMAKE_CXX_STANDARD}" EQUAL 98) diff --git a/absl/random/BUILD.bazel b/absl/random/BUILD.bazel index 828f1348..c3520df8 100644 --- a/absl/random/BUILD.bazel +++ b/absl/random/BUILD.bazel @@ -69,10 +69,10 @@ cc_library( "//absl/base:base_internal", "//absl/base:core_headers", "//absl/meta:type_traits", - "//absl/random/internal:distribution_impl", "//absl/random/internal:distributions", "//absl/random/internal:fast_uniform_bits", "//absl/random/internal:fastmath", + "//absl/random/internal:generate_real", "//absl/random/internal:iostream_state_saver", "//absl/random/internal:traits", "//absl/random/internal:uniform_helper", diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt index 19dd2cab..289854ff 100644 --- a/absl/random/CMakeLists.txt +++ b/absl/random/CMakeLists.txt @@ -58,7 +58,7 @@ absl_cc_library( DEPS absl::base_internal absl::core_headers - absl::random_internal_distribution_impl + absl::random_internal_generate_real absl::random_internal_distributions absl::random_internal_fast_uniform_bits absl::random_internal_fastmath @@ -543,19 +543,18 @@ absl_cc_library( # Internal-only target, do not depend on directly. absl_cc_library( NAME - random_internal_distribution_impl + random_internal_generate_real HDRS - "internal/distribution_impl.h" + "internal/generate_real.h" COPTS ${ABSL_DEFAULT_COPTS} LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS absl::bits - absl::config - absl::int128 absl::random_internal_fastmath absl::random_internal_traits + absl::type_traits ) # Internal-only target, do not depend on directly. @@ -767,9 +766,9 @@ absl_cc_test( # Internal-only target, do not depend on directly. absl_cc_test( NAME - random_internal_distribution_impl_test + random_internal_generate_real_test SRCS - "internal/distribution_impl_test.cc" + "internal/generate_real_test.cc" COPTS ${ABSL_TEST_COPTS} LINKOPTS @@ -777,8 +776,7 @@ absl_cc_test( DEPS absl::bits absl::flags - absl::int128 - absl::random_internal_distribution_impl + absl::random_internal_generate_real gtest_main ) @@ -1029,7 +1027,6 @@ absl_cc_library( ${ABSL_DEFAULT_LINKOPTS} DEPS absl::core_headers - absl::random_internal_distribution_impl absl::random_internal_fast_uniform_bits absl::random_internal_iostream_state_saver absl::random_internal_traits diff --git a/absl/random/beta_distribution.h b/absl/random/beta_distribution.h index e29894f2..b09b02f0 100644 --- a/absl/random/beta_distribution.h +++ b/absl/random/beta_distribution.h @@ -22,9 +22,10 @@ #include #include -#include "absl/random/internal/distribution_impl.h" +#include "absl/meta/type_traits.h" #include "absl/random/internal/fast_uniform_bits.h" #include "absl/random/internal/fastmath.h" +#include "absl/random/internal/generate_real.h" #include "absl/random/internal/iostream_state_saver.h" namespace absl { @@ -275,15 +276,21 @@ typename beta_distribution::result_type beta_distribution::AlgorithmJoehnk( URBG& g, // NOLINT(runtime/references) const param_type& p) { + using random_internal::GeneratePositiveTag; + using random_internal::GenerateRealFromBits; + using real_type = + absl::conditional_t::value, float, double>; + // Based on Joehnk, M. D. Erzeugung von betaverteilten und gammaverteilten // Zufallszahlen. Metrika 8.1 (1964): 5-15. // This method is described in Knuth, Vol 2 (Third Edition), pp 134. - using RandU64ToReal = typename random_internal::RandU64ToReal; - using random_internal::PositiveValueT; + result_type u, v, x, y, z; for (;;) { - u = RandU64ToReal::template Value(fast_u64_(g)); - v = RandU64ToReal::template Value(fast_u64_(g)); + u = GenerateRealFromBits( + fast_u64_(g)); + v = GenerateRealFromBits( + fast_u64_(g)); // Direct method. std::pow is slow for float, so rely on the optimizer to // remove the std::pow() path for that case. @@ -327,12 +334,14 @@ typename beta_distribution::result_type beta_distribution::AlgorithmCheng( URBG& g, // NOLINT(runtime/references) const param_type& p) { + using random_internal::GeneratePositiveTag; + using random_internal::GenerateRealFromBits; + using real_type = + absl::conditional_t::value, float, double>; + // Based on Cheng, Russell CH. Generating beta variates with nonintegral // shape parameters. Communications of the ACM 21.4 (1978): 317-322. // (https://dl.acm.org/citation.cfm?id=359482). - using RandU64ToReal = typename random_internal::RandU64ToReal; - using random_internal::PositiveValueT; - static constexpr result_type kLogFour = result_type(1.3862943611198906188344642429163531361); // log(4) static constexpr result_type kS = @@ -341,8 +350,10 @@ beta_distribution::AlgorithmCheng( const bool use_algorithm_ba = (p.method_ == param_type::CHENG_BA); result_type u1, u2, v, w, z, r, s, t, bw_inv, lhs; for (;;) { - u1 = RandU64ToReal::template Value(fast_u64_(g)); - u2 = RandU64ToReal::template Value(fast_u64_(g)); + u1 = GenerateRealFromBits( + fast_u64_(g)); + u2 = GenerateRealFromBits( + fast_u64_(g)); v = p.y_ * std::log(u1 / (1 - u1)); w = p.a_ * std::exp(v); bw_inv = result_type(1) / (p.b_ + w); diff --git a/absl/random/beta_distribution_test.cc b/absl/random/beta_distribution_test.cc index 966ad08b..d0111b3e 100644 --- a/absl/random/beta_distribution_test.cc +++ b/absl/random/beta_distribution_test.cc @@ -92,7 +92,7 @@ TYPED_TEST(BetaDistributionInterfaceTest, SerializeTest) { for (TypeParam alpha : kValues) { for (TypeParam beta : kValues) { ABSL_INTERNAL_LOG( - INFO, absl::StrFormat("Smoke test for Beta(%f, %f)", alpha, beta)); + INFO, absl::StrFormat("Smoke test for Beta(%a, %a)", alpha, beta)); param_type param(alpha, beta); absl::beta_distribution before(alpha, beta); diff --git a/absl/random/exponential_distribution.h b/absl/random/exponential_distribution.h index c8af1975..24abf57e 100644 --- a/absl/random/exponential_distribution.h +++ b/absl/random/exponential_distribution.h @@ -21,8 +21,9 @@ #include #include -#include "absl/random/internal/distribution_impl.h" +#include "absl/meta/type_traits.h" #include "absl/random/internal/fast_uniform_bits.h" +#include "absl/random/internal/generate_real.h" #include "absl/random/internal/iostream_state_saver.h" namespace absl { @@ -118,9 +119,14 @@ typename exponential_distribution::result_type exponential_distribution::operator()( URBG& g, // NOLINT(runtime/references) const param_type& p) { - using random_internal::NegativeValueT; - const result_type u = random_internal::RandU64ToReal< - result_type>::template Value(fast_u64_(g)); + using random_internal::GenerateNegativeTag; + using random_internal::GenerateRealFromBits; + using real_type = + absl::conditional_t::value, float, double>; + + const result_type u = GenerateRealFromBits(fast_u64_(g)); // U(-1, 0) + // log1p(-x) is mathematically equivalent to log(1 - x) but has more // accuracy for x near zero. return p.neg_inv_lambda_ * std::log1p(u); diff --git a/absl/random/gaussian_distribution.h b/absl/random/gaussian_distribution.h index 1d1347bc..c299e944 100644 --- a/absl/random/gaussian_distribution.h +++ b/absl/random/gaussian_distribution.h @@ -28,8 +28,8 @@ #include #include -#include "absl/random/internal/distribution_impl.h" #include "absl/random/internal/fast_uniform_bits.h" +#include "absl/random/internal/generate_real.h" #include "absl/random/internal/iostream_state_saver.h" namespace absl { @@ -207,12 +207,18 @@ namespace random_internal { template inline double gaussian_distribution_base::zignor_fallback(URBG& g, bool neg) { + using random_internal::GeneratePositiveTag; + using random_internal::GenerateRealFromBits; + // This fallback path happens approximately 0.05% of the time. double x, y; do { // kRInv = 1/r, U(0, 1) - x = kRInv * std::log(RandU64ToDouble(fast_u64_(g))); - y = -std::log(RandU64ToDouble(fast_u64_(g))); + x = kRInv * + std::log(GenerateRealFromBits( + fast_u64_(g))); + y = -std::log( + GenerateRealFromBits(fast_u64_(g))); } while ((y + y) < (x * x)); return neg ? (x - kR) : (kR - x); } @@ -220,6 +226,10 @@ inline double gaussian_distribution_base::zignor_fallback(URBG& g, bool neg) { template inline double gaussian_distribution_base::zignor( URBG& g) { // NOLINT(runtime/references) + using random_internal::GeneratePositiveTag; + using random_internal::GenerateRealFromBits; + using random_internal::GenerateSignedTag; + while (true) { // We use a single uint64_t to generate both a double and a strip. // These bits are unused when the generated double is > 1/2^5. @@ -227,7 +237,8 @@ inline double gaussian_distribution_base::zignor( // values (those smaller than 1/2^5, which all end up on the left tail). uint64_t bits = fast_u64_(g); int i = static_cast(bits & kMask); // pick a random strip - double j = RandU64ToDouble(bits); // U(-1, 1) + double j = GenerateRealFromBits( + bits); // U(-1, 1) const double x = j * zg_.x[i]; // Retangular box. Handles >97% of all cases. @@ -244,7 +255,8 @@ inline double gaussian_distribution_base::zignor( } // i > 0: Wedge samples using precomputed values. - double v = RandU64ToDouble(fast_u64_(g)); // U(0, 1) + double v = GenerateRealFromBits( + fast_u64_(g)); // U(0, 1) if ((zg_.f[i + 1] + v * (zg_.f[i] - zg_.f[i + 1])) < std::exp(-0.5 * x * x)) { return x; diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel index ec58cecd..91388d19 100644 --- a/absl/random/internal/BUILD.bazel +++ b/absl/random/internal/BUILD.bazel @@ -175,9 +175,9 @@ cc_library( ) cc_library( - name = "distribution_impl", + name = "generate_real", hdrs = [ - "distribution_impl.h", + "generate_real.h", ], copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, @@ -185,8 +185,7 @@ cc_library( ":fastmath", ":traits", "//absl/base:bits", - "//absl/base:config", - "//absl/numeric:int128", + "//absl/meta:type_traits", ], ) @@ -398,16 +397,17 @@ cc_test( ) cc_test( - name = "distribution_impl_test", + name = "generate_real_test", size = "small", - srcs = ["distribution_impl_test.cc"], + srcs = [ + "generate_real_test.cc", + ], copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ - ":distribution_impl", + ":generate_real", "//absl/base:bits", "//absl/flags:flag", - "//absl/numeric:int128", "@com_google_googletest//:gtest_main", ], ) diff --git a/absl/random/internal/distribution_impl.h b/absl/random/internal/distribution_impl.h deleted file mode 100644 index 49b3e1a6..00000000 --- a/absl/random/internal/distribution_impl.h +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_DISTRIBUTION_IMPL_H_ -#define ABSL_RANDOM_INTERNAL_DISTRIBUTION_IMPL_H_ - -// This file contains some implementation details which are used by one or more -// of the absl random number distributions. - -#include -#include -#include -#include -#include -#include - -#if (defined(_WIN32) || defined(_WIN64)) && defined(_M_IA64) -#include // NOLINT(build/include_order) -#pragma intrinsic(_umul128) -#define ABSL_INTERNAL_USE_UMUL128 1 -#endif - -#include "absl/base/config.h" -#include "absl/base/internal/bits.h" -#include "absl/numeric/int128.h" -#include "absl/random/internal/fastmath.h" -#include "absl/random/internal/traits.h" - -namespace absl { -namespace random_internal { - -// Creates a double from `bits`, with the template fields controlling the -// output. -// -// RandU64To is both more efficient and generates more unique values in the -// result interval than known implementations of std::generate_canonical(). -// -// The `Signed` parameter controls whether positive, negative, or both are -// returned (thus affecting the output interval). -// When Signed == SignedValueT, range is U(-1, 1) -// When Signed == NegativeValueT, range is U(-1, 0) -// When Signed == PositiveValueT, range is U(0, 1) -// -// When the `IncludeZero` parameter is true, the function may return 0 for some -// inputs, otherwise it never returns 0. -// -// The `ExponentBias` parameter determines the scale of the output range by -// adjusting the exponent. -// -// When a value in U(0,1) is required, use: -// RandU64ToDouble(); -// -// When a value in U(-1,1) is required, use: -// RandU64ToDouble() => U(-1, 1) -// This generates more distinct values than the mathematically equivalent -// expression `U(0, 1) * 2.0 - 1.0`, and is preferable. -// -// Scaling the result by powers of 2 (and avoiding a multiply) is also possible: -// RandU64ToDouble(); => U(0, 2) -// RandU64ToDouble(); => U(0, 0.5) -// - -// Tristate types controlling the output. -struct PositiveValueT {}; -struct NegativeValueT {}; -struct SignedValueT {}; - -// RandU64ToDouble is the double-result variant of RandU64To, described above. -template -inline double RandU64ToDouble(uint64_t bits) { - static_assert(std::is_same::value || - std::is_same::value || - std::is_same::value, - ""); - - // Maybe use the left-most bit for a sign bit. - uint64_t sign = std::is_same::value - ? 0x8000000000000000ull - : 0; // Sign bits. - - if (std::is_same::value) { - sign = bits & 0x8000000000000000ull; - bits = bits & 0x7FFFFFFFFFFFFFFFull; - } - if (IncludeZero) { - if (bits == 0u) return 0; - } - - // Number of leading zeros is mapped to the exponent: 2^-clz - int clz = base_internal::CountLeadingZeros64(bits); - // Shift number left to erase leading zeros. - bits <<= IncludeZero ? clz : (clz & 63); - - // Shift number right to remove bits that overflow double mantissa. The - // direction of the shift depends on `clz`. - bits >>= (64 - DBL_MANT_DIG); - - // Compute IEEE 754 double exponent. - // In the Signed case, bits is a 63-bit number with a 0 msb. Adjust the - // exponent to account for that. - const uint64_t exp = - (std::is_same::value ? 1023U : 1022U) + - static_cast(ExponentBias - clz); - constexpr int kExp = DBL_MANT_DIG - 1; - // Construct IEEE 754 double from exponent and mantissa. - const uint64_t val = sign | (exp << kExp) | (bits & ((1ULL << kExp) - 1U)); - - double res; - static_assert(sizeof(res) == sizeof(val), "double is not 64 bit"); - // Memcpy value from "val" to "res" to avoid aliasing problems. Assumes that - // endian-ness is same for double and uint64_t. - std::memcpy(&res, &val, sizeof(res)); - - return res; -} - -// RandU64ToFloat is the float-result variant of RandU64To, described above. -template -inline float RandU64ToFloat(uint64_t bits) { - static_assert(std::is_same::value || - std::is_same::value || - std::is_same::value, - ""); - - // Maybe use the left-most bit for a sign bit. - uint64_t sign = std::is_same::value - ? 0x80000000ul - : 0; // Sign bits. - - if (std::is_same::value) { - uint64_t a = bits & 0x8000000000000000ull; - sign = static_cast(a >> 32); - bits = bits & 0x7FFFFFFFFFFFFFFFull; - } - if (IncludeZero) { - if (bits == 0u) return 0; - } - - // Number of leading zeros is mapped to the exponent: 2^-clz - int clz = base_internal::CountLeadingZeros64(bits); - // Shift number left to erase leading zeros. - bits <<= IncludeZero ? clz : (clz & 63); - // Shift number right to remove bits that overflow double mantissa. The - // direction of the shift depends on `clz`. - bits >>= (64 - FLT_MANT_DIG); - - // Construct IEEE 754 float exponent. - // In the Signed case, bits is a 63-bit number with a 0 msb. Adjust the - // exponent to account for that. - const uint32_t exp = - (std::is_same::value ? 127U : 126U) + - static_cast(ExponentBias - clz); - constexpr int kExp = FLT_MANT_DIG - 1; - const uint32_t val = sign | (exp << kExp) | (bits & ((1U << kExp) - 1U)); - - float res; - static_assert(sizeof(res) == sizeof(val), "float is not 32 bit"); - // Assumes that endian-ness is same for float and uint32_t. - std::memcpy(&res, &val, sizeof(res)); - - return res; -} - -template -struct RandU64ToReal { - template - static inline Result Value(uint64_t bits) { - return RandU64ToDouble(bits); - } -}; - -template <> -struct RandU64ToReal { - template - static inline float Value(uint64_t bits) { - return RandU64ToFloat(bits); - } -}; - -} // namespace random_internal -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_DISTRIBUTION_IMPL_H_ diff --git a/absl/random/internal/distribution_impl_test.cc b/absl/random/internal/distribution_impl_test.cc deleted file mode 100644 index fcc16904..00000000 --- a/absl/random/internal/distribution_impl_test.cc +++ /dev/null @@ -1,464 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/distribution_impl.h" - -#include "gtest/gtest.h" -#include "absl/base/internal/bits.h" -#include "absl/flags/flag.h" -#include "absl/numeric/int128.h" - -ABSL_FLAG(int64_t, absl_random_test_trials, 50000, - "Number of trials for the probability tests."); - -using absl::random_internal::NegativeValueT; -using absl::random_internal::PositiveValueT; -using absl::random_internal::RandU64ToDouble; -using absl::random_internal::RandU64ToFloat; -using absl::random_internal::SignedValueT; - -namespace { - -TEST(DistributionImplTest, U64ToFloat_Positive_NoZero_Test) { - auto ToFloat = [](uint64_t a) { - return RandU64ToFloat(a); - }; - EXPECT_EQ(ToFloat(0x0000000000000000), 2.710505431e-20f); - EXPECT_EQ(ToFloat(0x0000000000000001), 5.421010862e-20f); - EXPECT_EQ(ToFloat(0x8000000000000000), 0.5); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 0.9999999404f); -} - -TEST(DistributionImplTest, U64ToFloat_Positive_Zero_Test) { - auto ToFloat = [](uint64_t a) { - return RandU64ToFloat(a); - }; - EXPECT_EQ(ToFloat(0x0000000000000000), 0.0); - EXPECT_EQ(ToFloat(0x0000000000000001), 5.421010862e-20f); - EXPECT_EQ(ToFloat(0x8000000000000000), 0.5); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 0.9999999404f); -} - -TEST(DistributionImplTest, U64ToFloat_Negative_NoZero_Test) { - auto ToFloat = [](uint64_t a) { - return RandU64ToFloat(a); - }; - EXPECT_EQ(ToFloat(0x0000000000000000), -2.710505431e-20f); - EXPECT_EQ(ToFloat(0x0000000000000001), -5.421010862e-20f); - EXPECT_EQ(ToFloat(0x8000000000000000), -0.5); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f); -} - -TEST(DistributionImplTest, U64ToFloat_Signed_NoZero_Test) { - auto ToFloat = [](uint64_t a) { - return RandU64ToFloat(a); - }; - EXPECT_EQ(ToFloat(0x0000000000000000), 5.421010862e-20f); - EXPECT_EQ(ToFloat(0x0000000000000001), 1.084202172e-19f); - EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), 0.9999999404f); - EXPECT_EQ(ToFloat(0x8000000000000000), -5.421010862e-20f); - EXPECT_EQ(ToFloat(0x8000000000000001), -1.084202172e-19f); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f); -} - -TEST(DistributionImplTest, U64ToFloat_Signed_Zero_Test) { - auto ToFloat = [](uint64_t a) { - return RandU64ToFloat(a); - }; - EXPECT_EQ(ToFloat(0x0000000000000000), 0); - EXPECT_EQ(ToFloat(0x0000000000000001), 1.084202172e-19f); - EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), 0.9999999404f); - EXPECT_EQ(ToFloat(0x8000000000000000), 0); - EXPECT_EQ(ToFloat(0x8000000000000001), -1.084202172e-19f); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f); -} - -TEST(DistributionImplTest, U64ToFloat_Signed_Bias_Test) { - auto ToFloat = [](uint64_t a) { - return RandU64ToFloat(a); - }; - EXPECT_EQ(ToFloat(0x0000000000000000), 0); - EXPECT_EQ(ToFloat(0x0000000000000001), 2 * 1.084202172e-19f); - EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), 2 * 0.9999999404f); - EXPECT_EQ(ToFloat(0x8000000000000000), 0); - EXPECT_EQ(ToFloat(0x8000000000000001), 2 * -1.084202172e-19f); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 2 * -0.9999999404f); -} - -TEST(DistributionImplTest, U64ToFloatTest) { - auto ToFloat = [](uint64_t a) -> float { - return RandU64ToFloat(a); - }; - - EXPECT_EQ(ToFloat(0x0000000000000000), 0.0f); - - EXPECT_EQ(ToFloat(0x8000000000000000), 0.5f); - EXPECT_EQ(ToFloat(0x8000000000000001), 0.5f); - EXPECT_EQ(ToFloat(0x800000FFFFFFFFFF), 0.5f); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 0.9999999404f); - - EXPECT_GT(ToFloat(0x0000000000000001), 0.0f); - - EXPECT_NE(ToFloat(0x7FFFFF0000000000), ToFloat(0x7FFFFEFFFFFFFFFF)); - - EXPECT_LT(ToFloat(0xFFFFFFFFFFFFFFFF), 1.0f); - int32_t two_to_24 = 1 << 24; - EXPECT_EQ(static_cast(ToFloat(0xFFFFFFFFFFFFFFFF) * two_to_24), - two_to_24 - 1); - EXPECT_NE(static_cast(ToFloat(0xFFFFFFFFFFFFFFFF) * two_to_24 * 2), - two_to_24 * 2 - 1); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), ToFloat(0xFFFFFF0000000000)); - EXPECT_NE(ToFloat(0xFFFFFFFFFFFFFFFF), ToFloat(0xFFFFFEFFFFFFFFFF)); - EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), ToFloat(0x7FFFFF8000000000)); - EXPECT_NE(ToFloat(0x7FFFFFFFFFFFFFFF), ToFloat(0x7FFFFF7FFFFFFFFF)); - EXPECT_EQ(ToFloat(0x3FFFFFFFFFFFFFFF), ToFloat(0x3FFFFFC000000000)); - EXPECT_NE(ToFloat(0x3FFFFFFFFFFFFFFF), ToFloat(0x3FFFFFBFFFFFFFFF)); - - // For values where every bit counts, the values scale as multiples of the - // input. - for (int i = 0; i < 100; ++i) { - EXPECT_EQ(i * ToFloat(0x0000000000000001), ToFloat(i)); - } - - // For each i: value generated from (1 << i). - float exp_values[64]; - exp_values[63] = 0.5f; - for (int i = 62; i >= 0; --i) exp_values[i] = 0.5f * exp_values[i + 1]; - constexpr uint64_t one = 1; - for (int i = 0; i < 64; ++i) { - EXPECT_EQ(ToFloat(one << i), exp_values[i]); - for (int j = 1; j < FLT_MANT_DIG && i - j >= 0; ++j) { - EXPECT_NE(exp_values[i] + exp_values[i - j], exp_values[i]); - EXPECT_EQ(ToFloat((one << i) + (one << (i - j))), - exp_values[i] + exp_values[i - j]); - } - for (int j = FLT_MANT_DIG; i - j >= 0; ++j) { - EXPECT_EQ(exp_values[i] + exp_values[i - j], exp_values[i]); - EXPECT_EQ(ToFloat((one << i) + (one << (i - j))), exp_values[i]); - } - } -} - -TEST(DistributionImplTest, U64ToDouble_Positive_NoZero_Test) { - auto ToDouble = [](uint64_t a) { - return RandU64ToDouble(a); - }; - - EXPECT_EQ(ToDouble(0x0000000000000000), 2.710505431213761085e-20); - EXPECT_EQ(ToDouble(0x0000000000000001), 5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x0000000000000002), 1.084202172485504434e-19); - EXPECT_EQ(ToDouble(0x8000000000000000), 0.5); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), 0.999999999999999888978); -} - -TEST(DistributionImplTest, U64ToDouble_Positive_Zero_Test) { - auto ToDouble = [](uint64_t a) { - return RandU64ToDouble(a); - }; - - EXPECT_EQ(ToDouble(0x0000000000000000), 0.0); - EXPECT_EQ(ToDouble(0x0000000000000001), 5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x8000000000000000), 0.5); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), 0.999999999999999888978); -} - -TEST(DistributionImplTest, U64ToDouble_Negative_NoZero_Test) { - auto ToDouble = [](uint64_t a) { - return RandU64ToDouble(a); - }; - - EXPECT_EQ(ToDouble(0x0000000000000000), -2.710505431213761085e-20); - EXPECT_EQ(ToDouble(0x0000000000000001), -5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x0000000000000002), -1.084202172485504434e-19); - EXPECT_EQ(ToDouble(0x8000000000000000), -0.5); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978); -} - -TEST(DistributionImplTest, U64ToDouble_Signed_NoZero_Test) { - auto ToDouble = [](uint64_t a) { - return RandU64ToDouble(a); - }; - - EXPECT_EQ(ToDouble(0x0000000000000000), 5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19); - EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), 0.999999999999999888978); - EXPECT_EQ(ToDouble(0x8000000000000000), -5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978); -} - -TEST(DistributionImplTest, U64ToDouble_Signed_Zero_Test) { - auto ToDouble = [](uint64_t a) { - return RandU64ToDouble(a); - }; - EXPECT_EQ(ToDouble(0x0000000000000000), 0); - EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19); - EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), 0.999999999999999888978); - EXPECT_EQ(ToDouble(0x8000000000000000), 0); - EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978); -} - -TEST(DistributionImplTest, U64ToDouble_Signed_Bias_Test) { - auto ToDouble = [](uint64_t a) { - return RandU64ToDouble(a); - }; - EXPECT_EQ(ToDouble(0x0000000000000000), 0); - EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19 / 2); - EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), 0.999999999999999888978 / 2); - EXPECT_EQ(ToDouble(0x8000000000000000), 0); - EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19 / 2); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978 / 2); -} - -TEST(DistributionImplTest, U64ToDoubleTest) { - auto ToDouble = [](uint64_t a) { - return RandU64ToDouble(a); - }; - - EXPECT_EQ(ToDouble(0x0000000000000000), 0.0); - EXPECT_EQ(ToDouble(0x0000000000000000), 0.0); - - EXPECT_EQ(ToDouble(0x0000000000000001), 5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x7fffffffffffffef), 0.499999999999999944489); - EXPECT_EQ(ToDouble(0x8000000000000000), 0.5); - - // For values > 0.5, RandU64ToDouble discards up to 11 bits. (64-53). - EXPECT_EQ(ToDouble(0x8000000000000001), 0.5); - EXPECT_EQ(ToDouble(0x80000000000007FF), 0.5); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), 0.999999999999999888978); - EXPECT_NE(ToDouble(0x7FFFFFFFFFFFF800), ToDouble(0x7FFFFFFFFFFFF7FF)); - - EXPECT_LT(ToDouble(0xFFFFFFFFFFFFFFFF), 1.0); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), ToDouble(0xFFFFFFFFFFFFF800)); - EXPECT_NE(ToDouble(0xFFFFFFFFFFFFFFFF), ToDouble(0xFFFFFFFFFFFFF7FF)); - EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFFC00)); - EXPECT_NE(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFFBFF)); - EXPECT_EQ(ToDouble(0x3FFFFFFFFFFFFFFF), ToDouble(0x3FFFFFFFFFFFFE00)); - EXPECT_NE(ToDouble(0x3FFFFFFFFFFFFFFF), ToDouble(0x3FFFFFFFFFFFFDFF)); - - EXPECT_EQ(ToDouble(0x1000000000000001), 0.0625); - EXPECT_EQ(ToDouble(0x2000000000000001), 0.125); - EXPECT_EQ(ToDouble(0x3000000000000001), 0.1875); - EXPECT_EQ(ToDouble(0x4000000000000001), 0.25); - EXPECT_EQ(ToDouble(0x5000000000000001), 0.3125); - EXPECT_EQ(ToDouble(0x6000000000000001), 0.375); - EXPECT_EQ(ToDouble(0x7000000000000001), 0.4375); - EXPECT_EQ(ToDouble(0x8000000000000001), 0.5); - EXPECT_EQ(ToDouble(0x9000000000000001), 0.5625); - EXPECT_EQ(ToDouble(0xa000000000000001), 0.625); - EXPECT_EQ(ToDouble(0xb000000000000001), 0.6875); - EXPECT_EQ(ToDouble(0xc000000000000001), 0.75); - EXPECT_EQ(ToDouble(0xd000000000000001), 0.8125); - EXPECT_EQ(ToDouble(0xe000000000000001), 0.875); - EXPECT_EQ(ToDouble(0xf000000000000001), 0.9375); - - // Large powers of 2. - int64_t two_to_53 = int64_t{1} << 53; - EXPECT_EQ(static_cast(ToDouble(0xFFFFFFFFFFFFFFFF) * two_to_53), - two_to_53 - 1); - EXPECT_NE(static_cast(ToDouble(0xFFFFFFFFFFFFFFFF) * two_to_53 * 2), - two_to_53 * 2 - 1); - - // For values where every bit counts, the values scale as multiples of the - // input. - for (int i = 0; i < 100; ++i) { - EXPECT_EQ(i * ToDouble(0x0000000000000001), ToDouble(i)); - } - - // For each i: value generated from (1 << i). - double exp_values[64]; - exp_values[63] = 0.5; - for (int i = 62; i >= 0; --i) exp_values[i] = 0.5 * exp_values[i + 1]; - constexpr uint64_t one = 1; - for (int i = 0; i < 64; ++i) { - EXPECT_EQ(ToDouble(one << i), exp_values[i]); - for (int j = 1; j < DBL_MANT_DIG && i - j >= 0; ++j) { - EXPECT_NE(exp_values[i] + exp_values[i - j], exp_values[i]); - EXPECT_EQ(ToDouble((one << i) + (one << (i - j))), - exp_values[i] + exp_values[i - j]); - } - for (int j = DBL_MANT_DIG; i - j >= 0; ++j) { - EXPECT_EQ(exp_values[i] + exp_values[i - j], exp_values[i]); - EXPECT_EQ(ToDouble((one << i) + (one << (i - j))), exp_values[i]); - } - } -} - -TEST(DistributionImplTest, U64ToDoubleSignedTest) { - auto ToDouble = [](uint64_t a) { - return RandU64ToDouble(a); - }; - - EXPECT_EQ(ToDouble(0x0000000000000000), 5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19); - - EXPECT_EQ(ToDouble(0x8000000000000000), -5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19); - - const double e_plus = ToDouble(0x0000000000000001); - const double e_minus = ToDouble(0x8000000000000001); - EXPECT_EQ(e_plus, 1.084202172485504434e-19); - EXPECT_EQ(e_minus, -1.084202172485504434e-19); - - EXPECT_EQ(ToDouble(0x3fffffffffffffef), 0.499999999999999944489); - EXPECT_EQ(ToDouble(0xbfffffffffffffef), -0.499999999999999944489); - - // For values > 0.5, RandU64ToDouble discards up to 10 bits. (63-53). - EXPECT_EQ(ToDouble(0x4000000000000000), 0.5); - EXPECT_EQ(ToDouble(0x4000000000000001), 0.5); - EXPECT_EQ(ToDouble(0x40000000000003FF), 0.5); - - EXPECT_EQ(ToDouble(0xC000000000000000), -0.5); - EXPECT_EQ(ToDouble(0xC000000000000001), -0.5); - EXPECT_EQ(ToDouble(0xC0000000000003FF), -0.5); - - EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFe), 0.999999999999999888978); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFe), -0.999999999999999888978); - - EXPECT_NE(ToDouble(0x7FFFFFFFFFFFF800), ToDouble(0x7FFFFFFFFFFFF7FF)); - - EXPECT_LT(ToDouble(0x7FFFFFFFFFFFFFFF), 1.0); - EXPECT_GT(ToDouble(0x7FFFFFFFFFFFFFFF), 0.9999999999); - - EXPECT_GT(ToDouble(0xFFFFFFFFFFFFFFFe), -1.0); - EXPECT_LT(ToDouble(0xFFFFFFFFFFFFFFFe), -0.999999999); - - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFe), ToDouble(0xFFFFFFFFFFFFFC00)); - EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFFC00)); - EXPECT_NE(ToDouble(0xFFFFFFFFFFFFFFFe), ToDouble(0xFFFFFFFFFFFFF3FF)); - EXPECT_NE(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFF3FF)); - - EXPECT_EQ(ToDouble(0x1000000000000001), 0.125); - EXPECT_EQ(ToDouble(0x2000000000000001), 0.25); - EXPECT_EQ(ToDouble(0x3000000000000001), 0.375); - EXPECT_EQ(ToDouble(0x4000000000000001), 0.5); - EXPECT_EQ(ToDouble(0x5000000000000001), 0.625); - EXPECT_EQ(ToDouble(0x6000000000000001), 0.75); - EXPECT_EQ(ToDouble(0x7000000000000001), 0.875); - EXPECT_EQ(ToDouble(0x7800000000000001), 0.9375); - EXPECT_EQ(ToDouble(0x7c00000000000001), 0.96875); - EXPECT_EQ(ToDouble(0x7e00000000000001), 0.984375); - EXPECT_EQ(ToDouble(0x7f00000000000001), 0.9921875); - - // 0x8000000000000000 ~= 0 - EXPECT_EQ(ToDouble(0x9000000000000001), -0.125); - EXPECT_EQ(ToDouble(0xa000000000000001), -0.25); - EXPECT_EQ(ToDouble(0xb000000000000001), -0.375); - EXPECT_EQ(ToDouble(0xc000000000000001), -0.5); - EXPECT_EQ(ToDouble(0xd000000000000001), -0.625); - EXPECT_EQ(ToDouble(0xe000000000000001), -0.75); - EXPECT_EQ(ToDouble(0xf000000000000001), -0.875); - - // Large powers of 2. - int64_t two_to_53 = int64_t{1} << 53; - EXPECT_EQ(static_cast(ToDouble(0x7FFFFFFFFFFFFFFF) * two_to_53), - two_to_53 - 1); - EXPECT_EQ(static_cast(ToDouble(0xFFFFFFFFFFFFFFFF) * two_to_53), - -(two_to_53 - 1)); - - EXPECT_NE(static_cast(ToDouble(0x7FFFFFFFFFFFFFFF) * two_to_53 * 2), - two_to_53 * 2 - 1); - - // For values where every bit counts, the values scale as multiples of the - // input. - for (int i = 1; i < 100; ++i) { - EXPECT_EQ(i * e_plus, ToDouble(i)) << i; - EXPECT_EQ(i * e_minus, ToDouble(0x8000000000000000 | i)) << i; - } -} - -TEST(DistributionImplTest, ExhaustiveFloat) { - using absl::base_internal::CountLeadingZeros64; - auto ToFloat = [](uint64_t a) { - return RandU64ToFloat(a); - }; - - // Rely on RandU64ToFloat generating values from greatest to least when - // supplied with uint64_t values from greatest (0xfff...) to least (0x0). Thus, - // this algorithm stores the previous value, and if the new value is at - // greater than or equal to the previous value, then there is a collision in - // the generation algorithm. - // - // Use the computation below to convert the random value into a result: - // double res = a() * (1.0f - sample) + b() * sample; - float last_f = 1.0, last_g = 2.0; - uint64_t f_collisions = 0, g_collisions = 0; - uint64_t f_unique = 0, g_unique = 0; - uint64_t total = 0; - auto count = [&](const float r) { - total++; - // `f` is mapped to the range [0, 1) (default) - const float f = 0.0f * (1.0f - r) + 1.0f * r; - if (f >= last_f) { - f_collisions++; - } else { - f_unique++; - last_f = f; - } - // `g` is mapped to the range [1, 2) - const float g = 1.0f * (1.0f - r) + 2.0f * r; - if (g >= last_g) { - g_collisions++; - } else { - g_unique++; - last_g = g; - } - }; - - size_t limit = absl::GetFlag(FLAGS_absl_random_test_trials); - - // Generate all uint64_t which have unique floating point values. - // Counting down from 0xFFFFFFFFFFFFFFFFu ... 0x0u - uint64_t x = ~uint64_t(0); - for (; x != 0 && limit > 0;) { - constexpr int kDig = (64 - FLT_MANT_DIG); - // Set a decrement value & the next point at which to change - // the decrement value. By default these are 1, 0. - uint64_t dec = 1; - uint64_t chk = 0; - - // Adjust decrement and check value based on how many leading 0 - // bits are set in the current value. - const int clz = CountLeadingZeros64(x); - if (clz < kDig) { - dec <<= (kDig - clz); - chk = (~uint64_t(0)) >> (clz + 1); - } - for (; x > chk && limit > 0; x -= dec) { - count(ToFloat(x)); - --limit; - } - } - - static_assert(FLT_MANT_DIG == 24, - "The float type is expected to have a 24 bit mantissa."); - - if (limit != 0) { - // There are between 2^28 and 2^29 unique values in the range [0, 1). For - // the low values of x, there are 2^24 -1 unique values. Once x > 2^24, - // there are 40 * 2^24 unique values. Thus: - // (2 + 4 + 8 ... + 2^23) + 40 * 2^23 - EXPECT_LT(1 << 28, f_unique); - EXPECT_EQ((1 << 24) + 40 * (1 << 23) - 1, f_unique); - EXPECT_EQ(total, f_unique); - EXPECT_EQ(0, f_collisions); - - // Expect at least 2^23 unique values for the range [1, 2) - EXPECT_LE(1 << 23, g_unique); - EXPECT_EQ(total - g_unique, g_collisions); - } -} - -} // namespace diff --git a/absl/random/internal/generate_real.h b/absl/random/internal/generate_real.h new file mode 100644 index 00000000..246d863e --- /dev/null +++ b/absl/random/internal/generate_real.h @@ -0,0 +1,144 @@ +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_ +#define ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_ + +// This file contains some implementation details which are used by one or more +// of the absl random number distributions. + +#include +#include +#include +#include + +#include "absl/base/internal/bits.h" +#include "absl/meta/type_traits.h" +#include "absl/random/internal/fastmath.h" +#include "absl/random/internal/traits.h" + +namespace absl { +namespace random_internal { + +// Tristate tag types controlling the output of GenerateRealFromBits. +struct GeneratePositiveTag {}; +struct GenerateNegativeTag {}; +struct GenerateSignedTag {}; + +// GenerateRealFromBits generates a single real value from a single 64-bit +// `bits` with template fields controlling the output. +// +// The `SignedTag` parameter controls whether positive, negative, +// or either signed/unsigned may be returned. +// When SignedTag == GeneratePositiveTag, range is U(0, 1) +// When SignedTag == GenerateNegativeTag, range is U(-1, 0) +// When SignedTag == GenerateSignedTag, range is U(-1, 1) +// +// When the `IncludeZero` parameter is true, the function may return 0 for some +// inputs, otherwise it never returns 0. +// +// When a value in U(0,1) is required, use: +// Uniform64ToReal; +// +// When a value in U(-1,1) is required, use: +// Uniform64ToReal; +// +// This generates more distinct values than the mathematical equivalent +// `U(0, 1) * 2.0 - 1.0`. +// +// Scaling the result by powers of 2 (and avoiding a multiply) is also possible: +// GenerateRealFromBits(..., -1); => U(0, 0.5) +// GenerateRealFromBits(..., 1); => U(0, 2) +// +template +inline RealType GenerateRealFromBits(uint64_t bits, int exp_bias = 0) { + using real_type = RealType; + using uint_type = absl::conditional_t::value, + uint32_t, uint64_t>; + + static_assert( + (std::is_same::value || + std::is_same::value), + "GenerateRealFromBits must be parameterized by either float or double."); + + static_assert(sizeof(uint_type) == sizeof(real_type), + "Mismatched unsinged and real types."); + + static_assert((std::numeric_limits::is_iec559 && + std::numeric_limits::radix == 2), + "RealType representation is not IEEE 754 binary."); + + static_assert((std::is_same::value || + std::is_same::value || + std::is_same::value), + ""); + + static constexpr int kExp = std::numeric_limits::digits - 1; + static constexpr uint_type kMask = (static_cast(1) << kExp) - 1u; + static constexpr int kUintBits = sizeof(uint_type) * 8; + + int exp = exp_bias + int{std::numeric_limits::max_exponent - 2}; + + // Determine the sign bit. + // Depending on the SignedTag, this may use the left-most bit + // or it may be a constant value. + uint_type sign = std::is_same::value + ? (static_cast(1) << (kUintBits - 1)) + : 0; + if (std::is_same::value) { + if (std::is_same::value) { + sign = bits & uint64_t{0x8000000000000000}; + } + if (std::is_same::value) { + const uint64_t tmp = bits & uint64_t{0x8000000000000000}; + sign = static_cast(tmp >> 32); + } + // adjust the bits and the exponent to account for removing + // the leading bit. + bits = bits & uint64_t{0x7FFFFFFFFFFFFFFF}; + exp++; + } + if (IncludeZero) { + if (bits == 0u) return 0; + } + + // Number of leading zeros is mapped to the exponent: 2^-clz + // bits is 0..01xxxxxx. After shifting, we're left with 1xxx...0..0 + int clz = base_internal::CountLeadingZeros64(bits); + bits <<= (IncludeZero ? clz : (clz & 63)); // remove 0-bits. + exp -= clz; // set the exponent. + bits >>= (63 - kExp); + + // Construct the 32-bit or 64-bit IEEE 754 floating-point value from + // the individual fields: sign, exp, mantissa(bits). + uint_type val = + (std::is_same::value ? 0u : sign) | + (static_cast(exp) << kExp) | + (static_cast(bits) & kMask); + + // bit_cast to the output-type + real_type result; + memcpy(static_cast(&result), static_cast(&val), + sizeof(result)); + return result; +} + +} // namespace random_internal +} // namespace absl + +#endif // ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_ diff --git a/absl/random/internal/generate_real_test.cc b/absl/random/internal/generate_real_test.cc new file mode 100644 index 00000000..aa02f0c2 --- /dev/null +++ b/absl/random/internal/generate_real_test.cc @@ -0,0 +1,497 @@ +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/random/internal/generate_real.h" + +#include +#include +#include +#include + +#include "gtest/gtest.h" +#include "absl/base/internal/bits.h" +#include "absl/flags/flag.h" + +ABSL_FLAG(int64_t, absl_random_test_trials, 50000, + "Number of trials for the probability tests."); + +using absl::random_internal::GenerateNegativeTag; +using absl::random_internal::GeneratePositiveTag; +using absl::random_internal::GenerateRealFromBits; +using absl::random_internal::GenerateSignedTag; + +namespace { + +TEST(GenerateRealTest, U64ToFloat_Positive_NoZero_Test) { + auto ToFloat = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + EXPECT_EQ(ToFloat(0x0000000000000000), 2.710505431e-20f); + EXPECT_EQ(ToFloat(0x0000000000000001), 5.421010862e-20f); + EXPECT_EQ(ToFloat(0x8000000000000000), 0.5); + EXPECT_EQ(ToFloat(0x8000000000000001), 0.5); + EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 0.9999999404f); +} + +TEST(GenerateRealTest, U64ToFloat_Positive_Zero_Test) { + auto ToFloat = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + EXPECT_EQ(ToFloat(0x0000000000000000), 0.0); + EXPECT_EQ(ToFloat(0x0000000000000001), 5.421010862e-20f); + EXPECT_EQ(ToFloat(0x8000000000000000), 0.5); + EXPECT_EQ(ToFloat(0x8000000000000001), 0.5); + EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 0.9999999404f); +} + +TEST(GenerateRealTest, U64ToFloat_Negative_NoZero_Test) { + auto ToFloat = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + EXPECT_EQ(ToFloat(0x0000000000000000), -2.710505431e-20f); + EXPECT_EQ(ToFloat(0x0000000000000001), -5.421010862e-20f); + EXPECT_EQ(ToFloat(0x8000000000000000), -0.5); + EXPECT_EQ(ToFloat(0x8000000000000001), -0.5); + EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f); +} + +TEST(GenerateRealTest, U64ToFloat_Negative_Zero_Test) { + auto ToFloat = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + EXPECT_EQ(ToFloat(0x0000000000000000), 0.0); + EXPECT_EQ(ToFloat(0x0000000000000001), -5.421010862e-20f); + EXPECT_EQ(ToFloat(0x8000000000000000), -0.5); + EXPECT_EQ(ToFloat(0x8000000000000001), -0.5); + EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f); +} + +TEST(GenerateRealTest, U64ToFloat_Signed_NoZero_Test) { + auto ToFloat = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + EXPECT_EQ(ToFloat(0x0000000000000000), 5.421010862e-20f); + EXPECT_EQ(ToFloat(0x0000000000000001), 1.084202172e-19f); + EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), 0.9999999404f); + EXPECT_EQ(ToFloat(0x8000000000000000), -5.421010862e-20f); + EXPECT_EQ(ToFloat(0x8000000000000001), -1.084202172e-19f); + EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f); +} + +TEST(GenerateRealTest, U64ToFloat_Signed_Zero_Test) { + auto ToFloat = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + EXPECT_EQ(ToFloat(0x0000000000000000), 0); + EXPECT_EQ(ToFloat(0x0000000000000001), 1.084202172e-19f); + EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), 0.9999999404f); + EXPECT_EQ(ToFloat(0x8000000000000000), 0); + EXPECT_EQ(ToFloat(0x8000000000000001), -1.084202172e-19f); + EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f); +} + +TEST(GenerateRealTest, U64ToFloat_Signed_Bias_Test) { + auto ToFloat = [](uint64_t a) { + return GenerateRealFromBits(a, 1); + }; + EXPECT_EQ(ToFloat(0x0000000000000000), 0); + EXPECT_EQ(ToFloat(0x0000000000000001), 2 * 1.084202172e-19f); + EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), 2 * 0.9999999404f); + EXPECT_EQ(ToFloat(0x8000000000000000), 0); + EXPECT_EQ(ToFloat(0x8000000000000001), 2 * -1.084202172e-19f); + EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 2 * -0.9999999404f); +} + +TEST(GenerateRealTest, U64ToFloatTest) { + auto ToFloat = [](uint64_t a) -> float { + return GenerateRealFromBits(a); + }; + + EXPECT_EQ(ToFloat(0x0000000000000000), 0.0f); + + EXPECT_EQ(ToFloat(0x8000000000000000), 0.5f); + EXPECT_EQ(ToFloat(0x8000000000000001), 0.5f); + EXPECT_EQ(ToFloat(0x800000FFFFFFFFFF), 0.5f); + EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 0.9999999404f); + + EXPECT_GT(ToFloat(0x0000000000000001), 0.0f); + + EXPECT_NE(ToFloat(0x7FFFFF0000000000), ToFloat(0x7FFFFEFFFFFFFFFF)); + + EXPECT_LT(ToFloat(0xFFFFFFFFFFFFFFFF), 1.0f); + int32_t two_to_24 = 1 << 24; + EXPECT_EQ(static_cast(ToFloat(0xFFFFFFFFFFFFFFFF) * two_to_24), + two_to_24 - 1); + EXPECT_NE(static_cast(ToFloat(0xFFFFFFFFFFFFFFFF) * two_to_24 * 2), + two_to_24 * 2 - 1); + EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), ToFloat(0xFFFFFF0000000000)); + EXPECT_NE(ToFloat(0xFFFFFFFFFFFFFFFF), ToFloat(0xFFFFFEFFFFFFFFFF)); + EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), ToFloat(0x7FFFFF8000000000)); + EXPECT_NE(ToFloat(0x7FFFFFFFFFFFFFFF), ToFloat(0x7FFFFF7FFFFFFFFF)); + EXPECT_EQ(ToFloat(0x3FFFFFFFFFFFFFFF), ToFloat(0x3FFFFFC000000000)); + EXPECT_NE(ToFloat(0x3FFFFFFFFFFFFFFF), ToFloat(0x3FFFFFBFFFFFFFFF)); + + // For values where every bit counts, the values scale as multiples of the + // input. + for (int i = 0; i < 100; ++i) { + EXPECT_EQ(i * ToFloat(0x0000000000000001), ToFloat(i)); + } + + // For each i: value generated from (1 << i). + float exp_values[64]; + exp_values[63] = 0.5f; + for (int i = 62; i >= 0; --i) exp_values[i] = 0.5f * exp_values[i + 1]; + constexpr uint64_t one = 1; + for (int i = 0; i < 64; ++i) { + EXPECT_EQ(ToFloat(one << i), exp_values[i]); + for (int j = 1; j < FLT_MANT_DIG && i - j >= 0; ++j) { + EXPECT_NE(exp_values[i] + exp_values[i - j], exp_values[i]); + EXPECT_EQ(ToFloat((one << i) + (one << (i - j))), + exp_values[i] + exp_values[i - j]); + } + for (int j = FLT_MANT_DIG; i - j >= 0; ++j) { + EXPECT_EQ(exp_values[i] + exp_values[i - j], exp_values[i]); + EXPECT_EQ(ToFloat((one << i) + (one << (i - j))), exp_values[i]); + } + } +} + +TEST(GenerateRealTest, U64ToDouble_Positive_NoZero_Test) { + auto ToDouble = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + + EXPECT_EQ(ToDouble(0x0000000000000000), 2.710505431213761085e-20); + EXPECT_EQ(ToDouble(0x0000000000000001), 5.42101086242752217004e-20); + EXPECT_EQ(ToDouble(0x0000000000000002), 1.084202172485504434e-19); + EXPECT_EQ(ToDouble(0x8000000000000000), 0.5); + EXPECT_EQ(ToDouble(0x8000000000000001), 0.5); + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), 0.999999999999999888978); +} + +TEST(GenerateRealTest, U64ToDouble_Positive_Zero_Test) { + auto ToDouble = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + + EXPECT_EQ(ToDouble(0x0000000000000000), 0.0); + EXPECT_EQ(ToDouble(0x0000000000000001), 5.42101086242752217004e-20); + EXPECT_EQ(ToDouble(0x8000000000000000), 0.5); + EXPECT_EQ(ToDouble(0x8000000000000001), 0.5); + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), 0.999999999999999888978); +} + +TEST(GenerateRealTest, U64ToDouble_Negative_NoZero_Test) { + auto ToDouble = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + + EXPECT_EQ(ToDouble(0x0000000000000000), -2.710505431213761085e-20); + EXPECT_EQ(ToDouble(0x0000000000000001), -5.42101086242752217004e-20); + EXPECT_EQ(ToDouble(0x0000000000000002), -1.084202172485504434e-19); + EXPECT_EQ(ToDouble(0x8000000000000000), -0.5); + EXPECT_EQ(ToDouble(0x8000000000000001), -0.5); + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978); +} + +TEST(GenerateRealTest, U64ToDouble_Negative_Zero_Test) { + auto ToDouble = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + + EXPECT_EQ(ToDouble(0x0000000000000000), 0.0); + EXPECT_EQ(ToDouble(0x0000000000000001), -5.42101086242752217004e-20); + EXPECT_EQ(ToDouble(0x0000000000000002), -1.084202172485504434e-19); + EXPECT_EQ(ToDouble(0x8000000000000000), -0.5); + EXPECT_EQ(ToDouble(0x8000000000000001), -0.5); + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978); +} + +TEST(GenerateRealTest, U64ToDouble_Signed_NoZero_Test) { + auto ToDouble = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + + EXPECT_EQ(ToDouble(0x0000000000000000), 5.42101086242752217004e-20); + EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19); + EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), 0.999999999999999888978); + EXPECT_EQ(ToDouble(0x8000000000000000), -5.42101086242752217004e-20); + EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19); + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978); +} + +TEST(GenerateRealTest, U64ToDouble_Signed_Zero_Test) { + auto ToDouble = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + EXPECT_EQ(ToDouble(0x0000000000000000), 0); + EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19); + EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), 0.999999999999999888978); + EXPECT_EQ(ToDouble(0x8000000000000000), 0); + EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19); + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978); +} + +TEST(GenerateRealTest, U64ToDouble_GenerateSignedTag_Bias_Test) { + auto ToDouble = [](uint64_t a) { + return GenerateRealFromBits(a, -1); + }; + EXPECT_EQ(ToDouble(0x0000000000000000), 0); + EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19 / 2); + EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), 0.999999999999999888978 / 2); + EXPECT_EQ(ToDouble(0x8000000000000000), 0); + EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19 / 2); + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978 / 2); +} + +TEST(GenerateRealTest, U64ToDoubleTest) { + auto ToDouble = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + + EXPECT_EQ(ToDouble(0x0000000000000000), 0.0); + EXPECT_EQ(ToDouble(0x0000000000000000), 0.0); + + EXPECT_EQ(ToDouble(0x0000000000000001), 5.42101086242752217004e-20); + EXPECT_EQ(ToDouble(0x7fffffffffffffef), 0.499999999999999944489); + EXPECT_EQ(ToDouble(0x8000000000000000), 0.5); + + // For values > 0.5, RandU64ToDouble discards up to 11 bits. (64-53). + EXPECT_EQ(ToDouble(0x8000000000000001), 0.5); + EXPECT_EQ(ToDouble(0x80000000000007FF), 0.5); + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), 0.999999999999999888978); + EXPECT_NE(ToDouble(0x7FFFFFFFFFFFF800), ToDouble(0x7FFFFFFFFFFFF7FF)); + + EXPECT_LT(ToDouble(0xFFFFFFFFFFFFFFFF), 1.0); + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), ToDouble(0xFFFFFFFFFFFFF800)); + EXPECT_NE(ToDouble(0xFFFFFFFFFFFFFFFF), ToDouble(0xFFFFFFFFFFFFF7FF)); + EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFFC00)); + EXPECT_NE(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFFBFF)); + EXPECT_EQ(ToDouble(0x3FFFFFFFFFFFFFFF), ToDouble(0x3FFFFFFFFFFFFE00)); + EXPECT_NE(ToDouble(0x3FFFFFFFFFFFFFFF), ToDouble(0x3FFFFFFFFFFFFDFF)); + + EXPECT_EQ(ToDouble(0x1000000000000001), 0.0625); + EXPECT_EQ(ToDouble(0x2000000000000001), 0.125); + EXPECT_EQ(ToDouble(0x3000000000000001), 0.1875); + EXPECT_EQ(ToDouble(0x4000000000000001), 0.25); + EXPECT_EQ(ToDouble(0x5000000000000001), 0.3125); + EXPECT_EQ(ToDouble(0x6000000000000001), 0.375); + EXPECT_EQ(ToDouble(0x7000000000000001), 0.4375); + EXPECT_EQ(ToDouble(0x8000000000000001), 0.5); + EXPECT_EQ(ToDouble(0x9000000000000001), 0.5625); + EXPECT_EQ(ToDouble(0xa000000000000001), 0.625); + EXPECT_EQ(ToDouble(0xb000000000000001), 0.6875); + EXPECT_EQ(ToDouble(0xc000000000000001), 0.75); + EXPECT_EQ(ToDouble(0xd000000000000001), 0.8125); + EXPECT_EQ(ToDouble(0xe000000000000001), 0.875); + EXPECT_EQ(ToDouble(0xf000000000000001), 0.9375); + + // Large powers of 2. + int64_t two_to_53 = int64_t{1} << 53; + EXPECT_EQ(static_cast(ToDouble(0xFFFFFFFFFFFFFFFF) * two_to_53), + two_to_53 - 1); + EXPECT_NE(static_cast(ToDouble(0xFFFFFFFFFFFFFFFF) * two_to_53 * 2), + two_to_53 * 2 - 1); + + // For values where every bit counts, the values scale as multiples of the + // input. + for (int i = 0; i < 100; ++i) { + EXPECT_EQ(i * ToDouble(0x0000000000000001), ToDouble(i)); + } + + // For each i: value generated from (1 << i). + double exp_values[64]; + exp_values[63] = 0.5; + for (int i = 62; i >= 0; --i) exp_values[i] = 0.5 * exp_values[i + 1]; + constexpr uint64_t one = 1; + for (int i = 0; i < 64; ++i) { + EXPECT_EQ(ToDouble(one << i), exp_values[i]); + for (int j = 1; j < DBL_MANT_DIG && i - j >= 0; ++j) { + EXPECT_NE(exp_values[i] + exp_values[i - j], exp_values[i]); + EXPECT_EQ(ToDouble((one << i) + (one << (i - j))), + exp_values[i] + exp_values[i - j]); + } + for (int j = DBL_MANT_DIG; i - j >= 0; ++j) { + EXPECT_EQ(exp_values[i] + exp_values[i - j], exp_values[i]); + EXPECT_EQ(ToDouble((one << i) + (one << (i - j))), exp_values[i]); + } + } +} + +TEST(GenerateRealTest, U64ToDoubleSignedTest) { + auto ToDouble = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + + EXPECT_EQ(ToDouble(0x0000000000000000), 5.42101086242752217004e-20); + EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19); + + EXPECT_EQ(ToDouble(0x8000000000000000), -5.42101086242752217004e-20); + EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19); + + const double e_plus = ToDouble(0x0000000000000001); + const double e_minus = ToDouble(0x8000000000000001); + EXPECT_EQ(e_plus, 1.084202172485504434e-19); + EXPECT_EQ(e_minus, -1.084202172485504434e-19); + + EXPECT_EQ(ToDouble(0x3fffffffffffffef), 0.499999999999999944489); + EXPECT_EQ(ToDouble(0xbfffffffffffffef), -0.499999999999999944489); + + // For values > 0.5, RandU64ToDouble discards up to 10 bits. (63-53). + EXPECT_EQ(ToDouble(0x4000000000000000), 0.5); + EXPECT_EQ(ToDouble(0x4000000000000001), 0.5); + EXPECT_EQ(ToDouble(0x40000000000003FF), 0.5); + + EXPECT_EQ(ToDouble(0xC000000000000000), -0.5); + EXPECT_EQ(ToDouble(0xC000000000000001), -0.5); + EXPECT_EQ(ToDouble(0xC0000000000003FF), -0.5); + + EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFe), 0.999999999999999888978); + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFe), -0.999999999999999888978); + + EXPECT_NE(ToDouble(0x7FFFFFFFFFFFF800), ToDouble(0x7FFFFFFFFFFFF7FF)); + + EXPECT_LT(ToDouble(0x7FFFFFFFFFFFFFFF), 1.0); + EXPECT_GT(ToDouble(0x7FFFFFFFFFFFFFFF), 0.9999999999); + + EXPECT_GT(ToDouble(0xFFFFFFFFFFFFFFFe), -1.0); + EXPECT_LT(ToDouble(0xFFFFFFFFFFFFFFFe), -0.999999999); + + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFe), ToDouble(0xFFFFFFFFFFFFFC00)); + EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFFC00)); + EXPECT_NE(ToDouble(0xFFFFFFFFFFFFFFFe), ToDouble(0xFFFFFFFFFFFFF3FF)); + EXPECT_NE(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFF3FF)); + + EXPECT_EQ(ToDouble(0x1000000000000001), 0.125); + EXPECT_EQ(ToDouble(0x2000000000000001), 0.25); + EXPECT_EQ(ToDouble(0x3000000000000001), 0.375); + EXPECT_EQ(ToDouble(0x4000000000000001), 0.5); + EXPECT_EQ(ToDouble(0x5000000000000001), 0.625); + EXPECT_EQ(ToDouble(0x6000000000000001), 0.75); + EXPECT_EQ(ToDouble(0x7000000000000001), 0.875); + EXPECT_EQ(ToDouble(0x7800000000000001), 0.9375); + EXPECT_EQ(ToDouble(0x7c00000000000001), 0.96875); + EXPECT_EQ(ToDouble(0x7e00000000000001), 0.984375); + EXPECT_EQ(ToDouble(0x7f00000000000001), 0.9921875); + + // 0x8000000000000000 ~= 0 + EXPECT_EQ(ToDouble(0x9000000000000001), -0.125); + EXPECT_EQ(ToDouble(0xa000000000000001), -0.25); + EXPECT_EQ(ToDouble(0xb000000000000001), -0.375); + EXPECT_EQ(ToDouble(0xc000000000000001), -0.5); + EXPECT_EQ(ToDouble(0xd000000000000001), -0.625); + EXPECT_EQ(ToDouble(0xe000000000000001), -0.75); + EXPECT_EQ(ToDouble(0xf000000000000001), -0.875); + + // Large powers of 2. + int64_t two_to_53 = int64_t{1} << 53; + EXPECT_EQ(static_cast(ToDouble(0x7FFFFFFFFFFFFFFF) * two_to_53), + two_to_53 - 1); + EXPECT_EQ(static_cast(ToDouble(0xFFFFFFFFFFFFFFFF) * two_to_53), + -(two_to_53 - 1)); + + EXPECT_NE(static_cast(ToDouble(0x7FFFFFFFFFFFFFFF) * two_to_53 * 2), + two_to_53 * 2 - 1); + + // For values where every bit counts, the values scale as multiples of the + // input. + for (int i = 1; i < 100; ++i) { + EXPECT_EQ(i * e_plus, ToDouble(i)) << i; + EXPECT_EQ(i * e_minus, ToDouble(0x8000000000000000 | i)) << i; + } +} + +TEST(GenerateRealTest, ExhaustiveFloat) { + using absl::base_internal::CountLeadingZeros64; + auto ToFloat = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + + // Rely on RandU64ToFloat generating values from greatest to least when + // supplied with uint64_t values from greatest (0xfff...) to least (0x0). Thus, + // this algorithm stores the previous value, and if the new value is at + // greater than or equal to the previous value, then there is a collision in + // the generation algorithm. + // + // Use the computation below to convert the random value into a result: + // double res = a() * (1.0f - sample) + b() * sample; + float last_f = 1.0, last_g = 2.0; + uint64_t f_collisions = 0, g_collisions = 0; + uint64_t f_unique = 0, g_unique = 0; + uint64_t total = 0; + auto count = [&](const float r) { + total++; + // `f` is mapped to the range [0, 1) (default) + const float f = 0.0f * (1.0f - r) + 1.0f * r; + if (f >= last_f) { + f_collisions++; + } else { + f_unique++; + last_f = f; + } + // `g` is mapped to the range [1, 2) + const float g = 1.0f * (1.0f - r) + 2.0f * r; + if (g >= last_g) { + g_collisions++; + } else { + g_unique++; + last_g = g; + } + }; + + size_t limit = absl::GetFlag(FLAGS_absl_random_test_trials); + + // Generate all uint64_t which have unique floating point values. + // Counting down from 0xFFFFFFFFFFFFFFFFu ... 0x0u + uint64_t x = ~uint64_t(0); + for (; x != 0 && limit > 0;) { + constexpr int kDig = (64 - FLT_MANT_DIG); + // Set a decrement value & the next point at which to change + // the decrement value. By default these are 1, 0. + uint64_t dec = 1; + uint64_t chk = 0; + + // Adjust decrement and check value based on how many leading 0 + // bits are set in the current value. + const int clz = CountLeadingZeros64(x); + if (clz < kDig) { + dec <<= (kDig - clz); + chk = (~uint64_t(0)) >> (clz + 1); + } + for (; x > chk && limit > 0; x -= dec) { + count(ToFloat(x)); + --limit; + } + } + + static_assert(FLT_MANT_DIG == 24, + "The float type is expected to have a 24 bit mantissa."); + + if (limit != 0) { + // There are between 2^28 and 2^29 unique values in the range [0, 1). For + // the low values of x, there are 2^24 -1 unique values. Once x > 2^24, + // there are 40 * 2^24 unique values. Thus: + // (2 + 4 + 8 ... + 2^23) + 40 * 2^23 + EXPECT_LT(1 << 28, f_unique); + EXPECT_EQ((1 << 24) + 40 * (1 << 23) - 1, f_unique); + EXPECT_EQ(total, f_unique); + EXPECT_EQ(0, f_collisions); + + // Expect at least 2^23 unique values for the range [1, 2) + EXPECT_LE(1 << 23, g_unique); + EXPECT_EQ(total - g_unique, g_collisions); + } +} + +} // namespace diff --git a/absl/random/log_uniform_int_distribution.h b/absl/random/log_uniform_int_distribution.h index ac43416e..956a6907 100644 --- a/absl/random/log_uniform_int_distribution.h +++ b/absl/random/log_uniform_int_distribution.h @@ -23,8 +23,8 @@ #include #include -#include "absl/random/internal/distribution_impl.h" #include "absl/random/internal/fastmath.h" +#include "absl/random/internal/generate_real.h" #include "absl/random/internal/iostream_state_saver.h" #include "absl/random/internal/traits.h" #include "absl/random/uniform_int_distribution.h" diff --git a/absl/random/poisson_distribution.h b/absl/random/poisson_distribution.h index 7750b1c9..23a953ff 100644 --- a/absl/random/poisson_distribution.h +++ b/absl/random/poisson_distribution.h @@ -22,9 +22,9 @@ #include #include -#include "absl/random/internal/distribution_impl.h" #include "absl/random/internal/fast_uniform_bits.h" #include "absl/random/internal/fastmath.h" +#include "absl/random/internal/generate_real.h" #include "absl/random/internal/iostream_state_saver.h" namespace absl { @@ -164,9 +164,9 @@ typename poisson_distribution::result_type poisson_distribution::operator()( URBG& g, // NOLINT(runtime/references) const param_type& p) { - using random_internal::PositiveValueT; - using random_internal::RandU64ToDouble; - using random_internal::SignedValueT; + using random_internal::GeneratePositiveTag; + using random_internal::GenerateRealFromBits; + using random_internal::GenerateSignedTag; if (p.split_ != 0) { // Use Knuth's algorithm with range splitting to avoid floating-point @@ -186,7 +186,8 @@ poisson_distribution::operator()( for (int split = p.split_; split > 0; --split) { double r = 1.0; do { - r *= RandU64ToDouble(fast_u64_(g)); + r *= GenerateRealFromBits( + fast_u64_(g)); // U(-1, 0) ++n; } while (r > p.emu_); --n; @@ -205,10 +206,11 @@ poisson_distribution::operator()( // and k = max(f). const double a = p.mean_ + 0.5; for (;;) { - const double u = - RandU64ToDouble(fast_u64_(g)); // (0, 1) - const double v = - RandU64ToDouble(fast_u64_(g)); // (-1, 1) + const double u = GenerateRealFromBits( + fast_u64_(g)); // U(0, 1) + const double v = GenerateRealFromBits( + fast_u64_(g)); // U(-1, 1) + const double x = std::floor(p.s_ * v / u + a); if (x < 0) continue; // f(negative) = 0 const double rhs = x * p.lmu_; diff --git a/absl/random/uniform_int_distribution.h b/absl/random/uniform_int_distribution.h index 02aa3765..dc8ba8c1 100644 --- a/absl/random/uniform_int_distribution.h +++ b/absl/random/uniform_int_distribution.h @@ -34,7 +34,6 @@ #include #include "absl/base/optimization.h" -#include "absl/random/internal/distribution_impl.h" #include "absl/random/internal/fast_uniform_bits.h" #include "absl/random/internal/iostream_state_saver.h" #include "absl/random/internal/traits.h" diff --git a/absl/random/uniform_real_distribution.h b/absl/random/uniform_real_distribution.h index 336abb39..bf2ed2c5 100644 --- a/absl/random/uniform_real_distribution.h +++ b/absl/random/uniform_real_distribution.h @@ -39,8 +39,9 @@ #include #include -#include "absl/random/internal/distribution_impl.h" +#include "absl/meta/type_traits.h" #include "absl/random/internal/fast_uniform_bits.h" +#include "absl/random/internal/generate_real.h" #include "absl/random/internal/iostream_state_saver.h" namespace absl { @@ -76,6 +77,7 @@ class uniform_real_distribution { // is not possible, so value generation cannot use the full range of the // real type. assert(range_ <= (std::numeric_limits::max)()); + assert(std::isfinite(range_)); } result_type a() const { return lo_; } @@ -151,10 +153,15 @@ template typename uniform_real_distribution::result_type uniform_real_distribution::operator()( URBG& gen, const param_type& p) { // NOLINT(runtime/references) - using random_internal::PositiveValueT; + using random_internal::GeneratePositiveTag; + using random_internal::GenerateRealFromBits; + using real_type = + absl::conditional_t::value, float, double>; + while (true) { - const result_type sample = random_internal::RandU64ToReal< - result_type>::template Value(fast_u64_(gen)); + const result_type sample = + GenerateRealFromBits( + fast_u64_(gen)); const result_type res = p.a() + (sample * p.range_); if (res < p.b() || p.range_ <= 0 || !std::isfinite(p.range_)) { return res; -- cgit v1.2.3 From fa8c75182fbfdeddb2485fc0d53baeda3f40b7a3 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 13 Nov 2019 08:54:32 -0800 Subject: Export of internal Abseil changes -- 049ac45508e335c6f010f2d28d71016b9fa65b4e by Derek Mauro : Fix librt detection PiperOrigin-RevId: 280207723 -- 6382c3a9fb2643af9dc031f92ca846c4a78e249c by Andy Getzendanner : Fix Conan builds Import of https://github.com/abseil/abseil-cpp/pull/400 PiperOrigin-RevId: 280025424 -- aebcd52b1686ac82663a8d0193b60d0122a43372 by Samuel Benzaquen : Enable the assertion in the iterator's operator== and operator!= PiperOrigin-RevId: 279998951 -- 5b61d909e2159ac6fd45e0e456818db1e725ecd1 by Derek Mauro : Add best effort support for compiling much of Abseil with MinGW. This involves disabling ABSL_ATTRIBUTE_WEAK and adding link flags. A change to CCTZ is still necessary. Tests were not run yet, but most of them now build. PiperOrigin-RevId: 279966541 -- 4336f8b10cff906e2defdd7d1d449cde4907da5d by Abseil Team : Add comments and relax memory orders in base_internal::CallOnceImpl. Add a comment to document the memory order guarantee if base_internal::SpinLockWait() is called and returns kOnceDone. Add a comment for the load/store sequence in base_internal::CallOnceImpl based on Mike Burrows' explanation. The atomic load of 'control' in the #ifndef NDEBUG block does not need std::memory_order_acquire. It can use std::memory_order_relaxed. The atomic compare_exchange_strong of 'control' does not need std::memory_order_acquire in the success case. It can use std::memory_order_relaxed. PiperOrigin-RevId: 279814155 -- 407de3a5e9af957cded54a136ca0468bde620d4d by Abseil Team : Added a script to generate abseil.podspec from all BUILD.bazel files automatically. PiperOrigin-RevId: 279811441 -- 26139497d4a363d6c7bc989c554da593e8819a07 by Derek Mauro : Add missing copyright and Apache License to //absl/functional/BUILD.bazel PiperOrigin-RevId: 279795227 -- 98ed625b02af6e5834edf52a920d8ca2dab4cd90 by Matt Kulukundis : Switch the implementation of hashtablez to *only* work on platforms that have a PER_THREAD_TLS. The old case is very slow (global mutex) and nobody collects data from that configuration anyway. PiperOrigin-RevId: 279775149 -- 07225900ef672c005c38f467ad3f92f38d0922b3 by Derek Mauro : Remove the minumum glibc version check PiperOrigin-RevId: 279750412 -- ec09956a951b4f52228ecc81968b8db7ae19ed15 by Derek Mauro : CMake only: link with -lrt to support older glibc versions PiperOrigin-RevId: 279741661 -- 97b113fb2e8246f6152c36330ba13793b37154b6 by Xiaoyi Zhang : Internal change. PiperOrigin-RevId: 279390188 -- ca8f72f2721546cc9b01bd01b2ea144962e6e0c5 by Andy Getzendanner : Expose PutTwoDigits for internal use within Abseil. PiperOrigin-RevId: 279374239 -- 14c6384cc03bbdfdefd2e4b635f104af5dd7e026 by Derek Mauro : Remove log_severity sources from the base target. They are already compiled as part of a separate library. PiperOrigin-RevId: 279372619 -- 3c5d926c718f8bf394e3bee87b6ba8d94601e0d3 by Abseil Team : s/indepdent/independent/g in SimpleAtof's documentation. PiperOrigin-RevId: 279350836 -- de2c44be8a8edf9efa1fe2007cba3564f3e5b0b8 by Abseil Team : Internal change PiperOrigin-RevId: 279346990 -- 2ba078341423fcf6d0ba5ca1831f86570a26e615 by Samuel Benzaquen : Add hash support for std::wstring, std::u16string and std::u32string. PiperOrigin-RevId: 279320672 -- 3272d3ffcfa55283a04f90e5868701912da95ef7 by Andy Soffer : Removing a bunch of __restricts that amount to no performance differences. One of these is the cause of https://github.com/abseil/abseil-cpp/issues/396. In particular, in one of the Vector128Store functions, restricts on two pointers that were indeed aliased seems to be the root cause of the issues. Closes #396 PiperOrigin-RevId: 279318999 -- 342f338ab31cc24344d5de8f28cf455bbb629a17 by Jorg Brown : Support uint128 in SimpleAtoi PiperOrigin-RevId: 279234038 -- 81cb0a04cf2dc4515d303679fc60968712191571 by Derek Mauro : Change the check for futex availability to support older Linux systems PiperOrigin-RevId: 279147079 -- cb4ca4aa4c8d2d710a5d483c56c4ce4f979e14b1 by Abseil Team : Add IWYU pragma: export for int128 .inc files. PiperOrigin-RevId: 279107098 -- b8df86ef610c366729f07326c726f3e34817b4dd by Abseil Team : An optimization for Waiter::Post() in the SEM waiter mode. Like the FUTEX waiter mode, Waiter::Post() only needs to call Poke() if it incremented the atomic variable from 0. PiperOrigin-RevId: 279086133 GitOrigin-RevId: 049ac45508e335c6f010f2d28d71016b9fa65b4e Change-Id: I4c1a4073fff62cb6a1fcb1c104aa7d62dad588c2 --- absl/abseil.podspec.gen.py | 247 +++++++++++++++++++++ absl/base/BUILD.bazel | 4 +- absl/base/CMakeLists.txt | 8 +- absl/base/attributes.h | 6 +- absl/base/call_once.h | 13 +- absl/base/policy_checks.h | 10 - absl/container/internal/hashtablez_sampler.cc | 21 +- absl/container/internal/hashtablez_sampler.h | 10 +- absl/container/internal/hashtablez_sampler_test.cc | 2 + absl/container/internal/raw_hash_set.h | 4 +- absl/container/internal/raw_hash_set_test.cc | 2 + absl/debugging/BUILD.bazel | 5 +- absl/debugging/CMakeLists.txt | 1 + absl/functional/BUILD.bazel | 16 ++ absl/hash/hash_test.cc | 27 +++ absl/hash/internal/hash.h | 13 ++ absl/numeric/int128.h | 4 +- absl/random/CMakeLists.txt | 1 + absl/random/internal/BUILD.bazel | 5 +- absl/random/internal/randen_hwaes.cc | 48 ++-- absl/strings/internal/numbers_test_common.h | 5 +- absl/strings/numbers.cc | 66 +++--- absl/strings/numbers.h | 21 +- absl/strings/numbers_test.cc | 63 +++++- absl/synchronization/internal/waiter.cc | 7 +- absl/synchronization/internal/waiter.h | 11 +- 26 files changed, 503 insertions(+), 117 deletions(-) create mode 100755 absl/abseil.podspec.gen.py (limited to 'absl/random/CMakeLists.txt') diff --git a/absl/abseil.podspec.gen.py b/absl/abseil.podspec.gen.py new file mode 100755 index 00000000..2bf153c0 --- /dev/null +++ b/absl/abseil.podspec.gen.py @@ -0,0 +1,247 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +"""This script generates abseil.podspec from all BUILD.bazel files. + +This is expected to run on abseil git repository with Bazel 1.0 on Linux. +It recursively analyzes BUILD.bazel files using query command of Bazel to +dump its build rules in XML format. From these rules, it constructs podspec +structure. +""" + +import argparse +import collections +import os +import re +import subprocess +import xml.etree.ElementTree + +# Template of root podspec. +SPEC_TEMPLATE = """ +# This file has been automatically generated from a script. +# Please make modifications to `abseil.podspec.gen.py` instead. +Pod::Spec.new do |s| + s.name = 'abseil' + s.version = '${version}' + s.summary = 'Abseil Common Libraries (C++) from Google' + s.homepage = 'https://abseil.io' + s.license = 'Apache License, Version 2.0' + s.authors = { 'Abseil Team' => 'abseil-io@googlegroups.com' } + s.source = { + :git => 'https://github.com/abseil/abseil-cpp.git', + :tag => '${tag}', + } + s.module_name = 'absl' + s.header_mappings_dir = 'absl' + s.header_dir = 'absl' + s.libraries = 'c++' + s.compiler_flags = '-Wno-everything' + s.pod_target_xcconfig = { + 'USER_HEADER_SEARCH_PATHS' => '$(inherited) "$(PODS_TARGET_SRCROOT)"', + 'USE_HEADERMAP' => 'NO', + 'ALWAYS_SEARCH_USER_PATHS' => 'NO', + } + s.ios.deployment_target = '7.0' + s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '9.0' + s.watchos.deployment_target = '2.0' +""" + +# Limited platforms that abseil supports. +# This is mainly because of sigaltstack unavailable on watchOS. +LIMITED_SUPPORT_PLATFORMS = [ + "ios.deployment_target = '7.0'", + "osx.deployment_target = '10.9'", +] + +# Custom specification per rule. +CUSTOM_SPEC_MAP = { + "//absl/debugging:failure_signal_handler": LIMITED_SUPPORT_PLATFORMS, +} + +# Rule object representing the rule of Bazel BUILD. +Rule = collections.namedtuple( + "Rule", "type name package srcs hdrs textual_hdrs deps visibility testonly") + + +def get_elem_value(elem, name): + """Returns the value of XML element with the given name.""" + for child in elem: + if child.attrib.get("name") != name: + continue + if child.tag == "string": + return child.attrib.get("value") + if child.tag == "boolean": + return child.attrib.get("value") == "true" + if child.tag == "list": + return [nested_child.attrib.get("value") for nested_child in child] + raise "Cannot recognize tag: " + child.tag + return None + + +def normalize_paths(paths): + """Returns the list of normalized path.""" + # e.g. ["//absl/strings:dir/header.h"] -> ["absl/strings/dir/header.h"] + return [path.lstrip("/").replace(":", "/") for path in paths] + + +def parse_rule(elem, package): + """Returns a rule from bazel XML rule.""" + return Rule( + type=elem.attrib["class"], + name=get_elem_value(elem, "name"), + package=package, + srcs=normalize_paths(get_elem_value(elem, "srcs") or []), + hdrs=normalize_paths(get_elem_value(elem, "hdrs") or []), + textual_hdrs=normalize_paths(get_elem_value(elem, "textual_hdrs") or []), + deps=get_elem_value(elem, "deps") or [], + visibility=get_elem_value(elem, "visibility") or [], + testonly=get_elem_value(elem, "testonly") or False) + + +def read_build(package): + """Runs bazel query on given package file and returns all cc rules.""" + result = subprocess.check_output( + ["bazel", "query", package + ":all", "--output", "xml"]) + root = xml.etree.ElementTree.fromstring(result) + return [ + parse_rule(elem, package) + for elem in root + if elem.tag == "rule" and elem.attrib["class"].startswith("cc_") + ] + + +def collect_rules(root_path): + """Collects and returns all rules from root path recursively.""" + rules = [] + for cur, _, _ in os.walk(root_path): + build_path = os.path.join(cur, "BUILD.bazel") + if os.path.exists(build_path): + rules.extend(read_build("//" + cur)) + return rules + + +def relevant_rule(rule): + """Returns true if a given rule is relevant when generating a podspec.""" + return ( + # cc_library only (ignore cc_test, cc_binary) + rule.type == "cc_library" and + # ignore empty rule + (rule.hdrs + rule.textual_hdrs + rule.srcs) and + # ignore test-only rule + not rule.testonly) + + +def get_spec_var(depth): + """Returns the name of variable for spec with given depth.""" + return "s" if depth == 0 else "s{}".format(depth) + + +def get_spec_name(label): + """Converts the label of bazel rule to the name of podspec.""" + assert label.startswith("//absl/"), "{} doesn't start with //absl/".format( + label) + # e.g. //absl/apple/banana -> abseil/apple/banana + return "abseil/" + label[7:] + + +def write_podspec(f, rules, args): + """Writes a podspec from given rules and args.""" + rule_dir = build_rule_directory(rules)["abseil"] + # Write root part with given arguments + spec = re.sub(r"\$\{(\w+)\}", lambda x: args[x.group(1)], + SPEC_TEMPLATE).lstrip() + f.write(spec) + # Write all target rules + write_podspec_map(f, rule_dir, 0) + f.write("end\n") + + +def build_rule_directory(rules): + """Builds a tree-style rule directory from given rules.""" + rule_dir = {} + for rule in rules: + cur = rule_dir + for frag in get_spec_name(rule.package).split("/"): + cur = cur.setdefault(frag, {}) + cur[rule.name] = rule + return rule_dir + + +def write_podspec_map(f, cur_map, depth): + """Writes podspec from rule map recursively.""" + for key, value in sorted(cur_map.items()): + indent = " " * (depth + 1) + f.write("{indent}{var0}.subspec '{key}' do |{var1}|\n".format( + indent=indent, + key=key, + var0=get_spec_var(depth), + var1=get_spec_var(depth + 1))) + if isinstance(value, dict): + write_podspec_map(f, value, depth + 1) + else: + write_podspec_rule(f, value, depth + 1) + f.write("{indent}end\n".format(indent=indent)) + + +def write_podspec_rule(f, rule, depth): + """Writes podspec from given rule.""" + indent = " " * (depth + 1) + spec_var = get_spec_var(depth) + # Puts all files in hdrs, textual_hdrs, and srcs into source_files. + # Since CocoaPods treats header_files a bit differently from bazel, + # this won't generate a header_files field so that all source_files + # are considered as header files. + srcs = sorted(set(rule.hdrs + rule.textual_hdrs + rule.srcs)) + write_indented_list( + f, "{indent}{var}.source_files = ".format(indent=indent, var=spec_var), + srcs) + # Writes dependencies of this rule. + for dep in sorted(rule.deps): + name = get_spec_name(dep.replace(":", "/")) + f.write("{indent}{var}.dependency '{dep}'\n".format( + indent=indent, var=spec_var, dep=name)) + # Writes custom specification. + custom_spec = CUSTOM_SPEC_MAP.get(rule.package + ":" + rule.name) + if custom_spec: + for spec in custom_spec: + f.write("{indent}{var}.{spec}\n".format( + indent=indent, var=spec_var, spec=spec)) + + +def write_indented_list(f, leading, values): + """Writes leading values in an indented style.""" + f.write(leading) + f.write((",\n" + " " * len(leading)).join("'{}'".format(v) for v in values)) + f.write("\n") + + +def generate(args): + """Generates a podspec file from all BUILD files under absl directory.""" + rules = filter(relevant_rule, collect_rules("absl")) + with open(args.output, "wt") as f: + write_podspec(f, rules, vars(args)) + + +def main(): + parser = argparse.ArgumentParser( + description="Generates abseil.podspec from BUILD.bazel") + parser.add_argument( + "-v", "--version", help="The version of podspec", required=True) + parser.add_argument( + "-t", + "--tag", + default=None, + help="The name of git tag (default: version)") + parser.add_argument( + "-o", + "--output", + default="abseil.podspec", + help="The name of output file (default: abseil.podspec)") + args = parser.parse_args() + if args.tag is None: + args.tag = args.version + generate(args) + + +if __name__ == "__main__": + main() diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index 6fc712d9..7e234bc6 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -192,7 +192,9 @@ cc_library( ], copts = ABSL_DEFAULT_COPTS, linkopts = select({ - "//absl:windows": [], + "//absl:windows": [ + "-DEFAULTLIB:shlwapi.lib", + ], "//conditions:default": ["-pthread"], }) + ABSL_DEFAULT_LINKOPTS, deps = [ diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index 9550cdb2..7ab6955e 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt @@ -14,6 +14,8 @@ # limitations under the License. # +find_library(LIBRT rt) + absl_cc_library( NAME atomic_hook @@ -163,16 +165,18 @@ absl_cc_library( "internal/thread_identity.h" "internal/tsan_mutex_interface.h" "internal/unscaledcycleclock.h" - "log_severity.h" SRCS "internal/cycleclock.cc" "internal/spinlock.cc" "internal/sysinfo.cc" "internal/thread_identity.cc" "internal/unscaledcycleclock.cc" - "log_severity.cc" COPTS ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + $<$:${LIBRT}> + $<$:"shlwapi"> DEPS absl::atomic_hook absl::base_internal diff --git a/absl/base/attributes.h b/absl/base/attributes.h index 7b7656a8..acd1c526 100644 --- a/absl/base/attributes.h +++ b/absl/base/attributes.h @@ -158,9 +158,11 @@ // Weak attributes currently do not work properly in LLVM's Windows backend, // so disable them there. See https://bugs.llvm.org/show_bug.cgi?id=37598 // for further information. -#if (ABSL_HAVE_ATTRIBUTE(weak) || \ +// The MinGW compiler doesn't complain about the weak attribute until the link +// step, presumably because Windows doesn't use ELF binaries. +#if (ABSL_HAVE_ATTRIBUTE(weak) || \ (defined(__GNUC__) && !defined(__clang__))) && \ - !(defined(__llvm__) && defined(_WIN32)) + !(defined(__llvm__) && defined(_WIN32)) && !defined(__MINGW32__) #undef ABSL_ATTRIBUTE_WEAK #define ABSL_ATTRIBUTE_WEAK __attribute__((weak)) #define ABSL_HAVE_ATTRIBUTE_WEAK 1 diff --git a/absl/base/call_once.h b/absl/base/call_once.h index 4aa6360c..e1614e51 100644 --- a/absl/base/call_once.h +++ b/absl/base/call_once.h @@ -148,7 +148,7 @@ void CallOnceImpl(std::atomic* control, Args&&... args) { #ifndef NDEBUG { - uint32_t old_control = control->load(std::memory_order_acquire); + uint32_t old_control = control->load(std::memory_order_relaxed); if (old_control != kOnceInit && old_control != kOnceRunning && old_control != kOnceWaiter && @@ -166,14 +166,23 @@ void CallOnceImpl(std::atomic* control, // Must do this before potentially modifying control word's state. base_internal::SchedulingHelper maybe_disable_scheduling(scheduling_mode); // Short circuit the simplest case to avoid procedure call overhead. + // The base_internal::SpinLockWait() call returns either kOnceInit or + // kOnceDone. If it returns kOnceDone, it must have loaded the control word + // with std::memory_order_acquire and seen a value of kOnceDone. uint32_t old_control = kOnceInit; if (control->compare_exchange_strong(old_control, kOnceRunning, - std::memory_order_acquire, std::memory_order_relaxed) || base_internal::SpinLockWait(control, ABSL_ARRAYSIZE(trans), trans, scheduling_mode) == kOnceInit) { base_internal::Invoke(std::forward(fn), std::forward(args)...); + // The call to SpinLockWake below is an optimization, because the waiter + // in SpinLockWait is waiting with a short timeout. The atomic load/store + // sequence is slightly faster than an atomic exchange: + // old_control = control->exchange(base_internal::kOnceDone, + // std::memory_order_release); + // We opt for a slightly faster case when there are no waiters, in spite + // of longer tail latency when there are waiters. old_control = control->load(std::memory_order_relaxed); control->store(base_internal::kOnceDone, std::memory_order_release); if (old_control == base_internal::kOnceWaiter) { diff --git a/absl/base/policy_checks.h b/absl/base/policy_checks.h index 699fb1a2..4dfa49e5 100644 --- a/absl/base/policy_checks.h +++ b/absl/base/policy_checks.h @@ -82,16 +82,6 @@ // Standard Library Check // ----------------------------------------------------------------------------- -// We have chosen glibc 2.12 as the minimum as it was tagged for release -// in May, 2010 and includes some functionality used in Google software -// (for instance pthread_setname_np): -// https://sourceware.org/ml/libc-alpha/2010-05/msg00000.html -#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) -#if !__GLIBC_PREREQ(2, 12) -#error "Minimum required version of glibc is 2.12." -#endif -#endif - #if defined(_STLPORT_VERSION) #error "STLPort is not supported." #endif diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc index 0a7ef61c..4aec0a07 100644 --- a/absl/container/internal/hashtablez_sampler.cc +++ b/absl/container/internal/hashtablez_sampler.cc @@ -38,16 +38,18 @@ ABSL_CONST_INIT std::atomic g_hashtablez_enabled{ ABSL_CONST_INIT std::atomic g_hashtablez_sample_parameter{1 << 10}; ABSL_CONST_INIT std::atomic g_hashtablez_max_samples{1 << 20}; -#if ABSL_HAVE_THREAD_LOCAL -thread_local absl::base_internal::ExponentialBiased - g_exponential_biased_generator; -#else -ABSL_CONST_INIT static absl::base_internal::ExponentialBiased +#if ABSL_PER_THREAD_TLS == 1 +ABSL_PER_THREAD_TLS_KEYWORD absl::base_internal::ExponentialBiased g_exponential_biased_generator; #endif } // namespace +#if ABSL_PER_THREAD_TLS == 1 +ABSL_PER_THREAD_TLS_KEYWORD int64_t global_next_sample = 0; +#endif // ABSL_PER_THREAD_TLS == 1 + + HashtablezSampler& HashtablezSampler::Global() { static auto* sampler = new HashtablezSampler(); return *sampler; @@ -189,6 +191,10 @@ HashtablezInfo* SampleSlow(int64_t* next_sample) { return HashtablezSampler::Global().Register(); } +#if ABSL_PER_THREAD_TLS == 0 + *next_sample = std::numeric_limits::max(); + return nullptr; +#else bool first = *next_sample < 0; *next_sample = g_exponential_biased_generator.Get( g_hashtablez_sample_parameter.load(std::memory_order_relaxed)); @@ -210,12 +216,9 @@ HashtablezInfo* SampleSlow(int64_t* next_sample) { } return HashtablezSampler::Global().Register(); +#endif } -#if ABSL_PER_THREAD_TLS == 1 -ABSL_PER_THREAD_TLS_KEYWORD int64_t global_next_sample = 0; -#endif // ABSL_PER_THREAD_TLS == 1 - void UnsampleSlow(HashtablezInfo* info) { HashtablezSampler::Global().Unregister(info); } diff --git a/absl/container/internal/hashtablez_sampler.h b/absl/container/internal/hashtablez_sampler.h index 53996bb9..c694df05 100644 --- a/absl/container/internal/hashtablez_sampler.h +++ b/absl/container/internal/hashtablez_sampler.h @@ -186,16 +186,14 @@ extern ABSL_PER_THREAD_TLS_KEYWORD int64_t global_next_sample; // Returns an RAII sampling handle that manages registration and unregistation // with the global sampler. inline HashtablezInfoHandle Sample() { -#if ABSL_PER_THREAD_TLS == 0 - static auto* mu = new absl::Mutex; - static int64_t global_next_sample = 0; - absl::MutexLock l(mu); -#endif // !ABSL_HAVE_THREAD_LOCAL - +#if ABSL_PER_THREAD_TLS == 1 if (ABSL_PREDICT_TRUE(--global_next_sample > 0)) { return HashtablezInfoHandle(nullptr); } return HashtablezInfoHandle(SampleSlow(&global_next_sample)); +#else + return HashtablezInfoHandle(nullptr); +#endif // !ABSL_PER_THREAD_TLS } // Holds samples and their associated stack traces with a soft limit of diff --git a/absl/container/internal/hashtablez_sampler_test.cc b/absl/container/internal/hashtablez_sampler_test.cc index 7f9e8dd2..af4b5ee1 100644 --- a/absl/container/internal/hashtablez_sampler_test.cc +++ b/absl/container/internal/hashtablez_sampler_test.cc @@ -168,6 +168,7 @@ TEST(HashtablezInfoTest, RecordRehash) { EXPECT_EQ(info.num_erases.load(), 0); } +#if ABSL_PER_THREAD_TLS == 1 TEST(HashtablezSamplerTest, SmallSampleParameter) { SetHashtablezEnabled(true); SetHashtablezSampleParameter(100); @@ -211,6 +212,7 @@ TEST(HashtablezSamplerTest, Sample) { } EXPECT_NEAR(sample_rate, 0.01, 0.005); } +#endif TEST(HashtablezSamplerTest, Handle) { auto& sampler = HashtablezSampler::Global(); diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index bf0c03c4..469226fe 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -638,8 +638,8 @@ class raw_hash_set { } friend bool operator==(const iterator& a, const iterator& b) { - /* To be enabled: a.assert_is_valid(); */ - /* To be enabled: b.assert_is_valid(); */ + a.assert_is_valid(); + b.assert_is_valid(); return a.ctrl_ == b.ctrl_; } friend bool operator!=(const iterator& a, const iterator& b) { diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc index 33cfa72c..ec8f9231 100644 --- a/absl/container/internal/raw_hash_set_test.cc +++ b/absl/container/internal/raw_hash_set_test.cc @@ -1841,6 +1841,7 @@ TEST(TableDeathTest, EraseOfEndAsserts) { EXPECT_DEATH_IF_SUPPORTED(t.erase(t.end()), kDeathMsg); } +#if ABSL_PER_THREAD_TLS == 1 TEST(RawHashSamplerTest, Sample) { // Enable the feature even if the prod default is off. SetHashtablezEnabled(true); @@ -1861,6 +1862,7 @@ TEST(RawHashSamplerTest, Sample) { EXPECT_NEAR((end_size - start_size) / static_cast(tables.size()), 0.01, 0.005); } +#endif TEST(RawHashSamplerTest, DoNotSampleCustomAllocators) { // Enable the feature even if the prod default is off. diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel index beec279f..2601090b 100644 --- a/absl/debugging/BUILD.bazel +++ b/absl/debugging/BUILD.bazel @@ -55,7 +55,10 @@ cc_library( "symbolize.h", ], copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, + linkopts = ABSL_DEFAULT_LINKOPTS + select({ + "//absl:windows": ["-DEFAULTLIB:dbghelp.lib"], + "//conditions:default": [], + }), deps = [ ":debugging_internal", ":demangle_internal", diff --git a/absl/debugging/CMakeLists.txt b/absl/debugging/CMakeLists.txt index b3e35b6d..eff504b4 100644 --- a/absl/debugging/CMakeLists.txt +++ b/absl/debugging/CMakeLists.txt @@ -44,6 +44,7 @@ absl_cc_library( ${ABSL_DEFAULT_COPTS} LINKOPTS ${ABSL_DEFAULT_LINKOPTS} + $<$:"dbghelp"> DEPS absl::debugging_internal absl::demangle_internal diff --git a/absl/functional/BUILD.bazel b/absl/functional/BUILD.bazel index e861b8a5..0a7b588e 100644 --- a/absl/functional/BUILD.bazel +++ b/absl/functional/BUILD.bazel @@ -1,3 +1,19 @@ +# +# Copyright 2019 The Abseil Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") load( "//absl:copts/configure_copts.bzl", diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc index 61f7661f..42c0c3d8 100644 --- a/absl/hash/hash_test.cc +++ b/absl/hash/hash_test.cc @@ -300,6 +300,33 @@ TEST(HashValueTest, Strings) { SpyHash(absl::string_view("ABC"))); } +TEST(HashValueTest, WString) { + EXPECT_TRUE((is_hashable::value)); + + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple( + std::wstring(), std::wstring(L"ABC"), std::wstring(L"ABC"), + std::wstring(L"Some other different string"), + std::wstring(L"Iñtërnâtiônàlizætiøn")))); +} + +TEST(HashValueTest, U16String) { + EXPECT_TRUE((is_hashable::value)); + + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple( + std::u16string(), std::u16string(u"ABC"), std::u16string(u"ABC"), + std::u16string(u"Some other different string"), + std::u16string(u"Iñtërnâtiônàlizætiøn")))); +} + +TEST(HashValueTest, U32String) { + EXPECT_TRUE((is_hashable::value)); + + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple( + std::u32string(), std::u32string(U"ABC"), std::u32string(U"ABC"), + std::u32string(U"Some other different string"), + std::u32string(U"Iñtërnâtiônàlizætiøn")))); +} + TEST(HashValueTest, StdArray) { EXPECT_TRUE((is_hashable>::value)); diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h index e99f8e75..7d44f57d 100644 --- a/absl/hash/internal/hash.h +++ b/absl/hash/internal/hash.h @@ -427,6 +427,19 @@ H AbslHashValue(H hash_state, absl::string_view str) { str.size()); } +// Support std::wstring, std::u16string and std::u32string. +template ::value || + std::is_same::value || + std::is_same::value>> +H AbslHashValue( + H hash_state, + const std::basic_string, Alloc>& str) { + return H::combine( + H::combine_contiguous(std::move(hash_state), str.data(), str.size()), + str.size()); +} + // ----------------------------------------------------------------------------- // AbslHashValue for Sequence Containers // ----------------------------------------------------------------------------- diff --git a/absl/numeric/int128.h b/absl/numeric/int128.h index 10be8eca..4f965686 100644 --- a/absl/numeric/int128.h +++ b/absl/numeric/int128.h @@ -720,9 +720,9 @@ inline uint128& uint128::operator--() { } #if defined(ABSL_HAVE_INTRINSIC_INT128) -#include "absl/numeric/int128_have_intrinsic.inc" +#include "absl/numeric/int128_have_intrinsic.inc" // IWYU pragma: export #else // ABSL_HAVE_INTRINSIC_INT128 -#include "absl/numeric/int128_no_intrinsic.inc" +#include "absl/numeric/int128_no_intrinsic.inc" // IWYU pragma: export #endif // ABSL_HAVE_INTRINSIC_INT128 } // namespace absl diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt index 289854ff..264a6f3c 100644 --- a/absl/random/CMakeLists.txt +++ b/absl/random/CMakeLists.txt @@ -447,6 +447,7 @@ absl_cc_library( ${ABSL_DEFAULT_COPTS} LINKOPTS ${ABSL_DEFAULT_LINKOPTS} + $<$:"bcrypt"> DEPS absl::core_headers absl::optional diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel index 91388d19..cc9bc013 100644 --- a/absl/random/internal/BUILD.bazel +++ b/absl/random/internal/BUILD.bazel @@ -89,7 +89,10 @@ cc_library( "seed_material.h", ], copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, + linkopts = ABSL_DEFAULT_LINKOPTS + select({ + "//absl:windows": ["-DEFAULTLIB:bcrypt.lib"], + "//conditions:default": [], + }), deps = [ ":fast_uniform_bits", "//absl/base:core_headers", diff --git a/absl/random/internal/randen_hwaes.cc b/absl/random/internal/randen_hwaes.cc index 7d5b2b74..6cc36fd3 100644 --- a/absl/random/internal/randen_hwaes.cc +++ b/absl/random/internal/randen_hwaes.cc @@ -159,13 +159,11 @@ inline ABSL_TARGET_CRYPTO Vector128 ReverseBytes(const Vector128& v) { // WARNING: these load/store in native byte order. It is OK to load and then // store an unchanged vector, but interpreting the bits as a number or input // to AES will have undefined results. -inline ABSL_TARGET_CRYPTO Vector128 -Vector128Load(const void* ABSL_RANDOM_INTERNAL_RESTRICT from) { +inline ABSL_TARGET_CRYPTO Vector128 Vector128Load(const void* from) { return vec_vsx_ld(0, reinterpret_cast(from)); } -inline ABSL_TARGET_CRYPTO void Vector128Store( - const Vector128& v, void* ABSL_RANDOM_INTERNAL_RESTRICT to) { +inline ABSL_TARGET_CRYPTO void Vector128Store(const Vector128& v, void* to) { vec_vsx_st(v, 0, reinterpret_cast(to)); } @@ -177,8 +175,7 @@ inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state, } // Enables native loads in the round loop by pre-swapping. -inline ABSL_TARGET_CRYPTO void SwapEndian( - uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state) { +inline ABSL_TARGET_CRYPTO void SwapEndian(uint64_t* state) { using absl::random_internal::RandenTraits; constexpr size_t kLanes = 2; constexpr size_t kFeistelBlocks = RandenTraits::kFeistelBlocks; @@ -230,13 +227,11 @@ using Vector128 = uint8x16_t; namespace { -inline ABSL_TARGET_CRYPTO Vector128 -Vector128Load(const void* ABSL_RANDOM_INTERNAL_RESTRICT from) { +inline ABSL_TARGET_CRYPTO Vector128 Vector128Load(const void* from) { return vld1q_u8(reinterpret_cast(from)); } -inline ABSL_TARGET_CRYPTO void Vector128Store( - const Vector128& v, void* ABSL_RANDOM_INTERNAL_RESTRICT to) { +inline ABSL_TARGET_CRYPTO void Vector128Store(const Vector128& v, void* to) { vst1q_u8(reinterpret_cast(to), v); } @@ -254,8 +249,7 @@ inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state, return vaesmcq_u8(vaeseq_u8(state, uint8x16_t{})) ^ round_key; } -inline ABSL_TARGET_CRYPTO void SwapEndian( - uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT) {} +inline ABSL_TARGET_CRYPTO void SwapEndian(uint64_t*) {} } // namespace @@ -283,15 +277,12 @@ class Vector128 { __m128i data_; }; -inline ABSL_TARGET_CRYPTO Vector128 -Vector128Load(const void* ABSL_RANDOM_INTERNAL_RESTRICT from) { +inline ABSL_TARGET_CRYPTO Vector128 Vector128Load(const void* from) { return Vector128(_mm_load_si128(reinterpret_cast(from))); } -inline ABSL_TARGET_CRYPTO void Vector128Store( - const Vector128& v, void* ABSL_RANDOM_INTERNAL_RESTRICT to) { - _mm_store_si128(reinterpret_cast<__m128i * ABSL_RANDOM_INTERNAL_RESTRICT>(to), - v.data()); +inline ABSL_TARGET_CRYPTO void Vector128Store(const Vector128& v, void* to) { + _mm_store_si128(reinterpret_cast<__m128i*>(to), v.data()); } // One round of AES. "round_key" is a public constant for breaking the @@ -304,8 +295,7 @@ inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state, return Vector128(_mm_aesenc_si128(state.data(), round_key.data())); } -inline ABSL_TARGET_CRYPTO void SwapEndian( - uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT) {} +inline ABSL_TARGET_CRYPTO void SwapEndian(uint64_t*) {} } // namespace @@ -402,8 +392,7 @@ constexpr size_t kLanes = 2; // Block shuffles applies a shuffle to the entire state between AES rounds. // Improved odd-even shuffle from "New criterion for diffusion property". -inline ABSL_TARGET_CRYPTO void BlockShuffle( - uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state) { +inline ABSL_TARGET_CRYPTO void BlockShuffle(uint64_t* state) { static_assert(kFeistelBlocks == 16, "Expecting 16 FeistelBlocks."); constexpr size_t shuffle[kFeistelBlocks] = {7, 2, 13, 4, 11, 8, 3, 6, @@ -452,8 +441,7 @@ inline ABSL_TARGET_CRYPTO void BlockShuffle( // parallel hides the 7-cycle AESNI latency on HSW. Note that the Feistel // XORs are 'free' (included in the second AES instruction). inline ABSL_TARGET_CRYPTO const u64x2* FeistelRound( - uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state, - const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys) { + uint64_t* state, const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys) { static_assert(kFeistelBlocks == 16, "Expecting 16 FeistelBlocks."); // MSVC does a horrible job at unrolling loops. @@ -513,8 +501,7 @@ inline ABSL_TARGET_CRYPTO const u64x2* FeistelRound( // 2^64 queries if the round function is a PRF. This is similar to the b=8 case // of Simpira v2, but more efficient than its generic construction for b=16. inline ABSL_TARGET_CRYPTO void Permute( - const void* ABSL_RANDOM_INTERNAL_RESTRICT keys, - uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state) { + const void* ABSL_RANDOM_INTERNAL_RESTRICT keys, uint64_t* state) { const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys128 = static_cast(keys); @@ -544,10 +531,8 @@ const void* ABSL_TARGET_CRYPTO RandenHwAes::GetKeys() { // NOLINTNEXTLINE void ABSL_TARGET_CRYPTO RandenHwAes::Absorb(const void* seed_void, void* state_void) { - uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state = - reinterpret_cast(state_void); - const uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT seed = - reinterpret_cast(seed_void); + auto* state = static_cast(state_void); + const auto* seed = static_cast(seed_void); constexpr size_t kCapacityBlocks = kCapacityBytes / sizeof(Vector128); constexpr size_t kStateBlocks = kStateBytes / sizeof(Vector128); @@ -623,8 +608,7 @@ void ABSL_TARGET_CRYPTO RandenHwAes::Generate(const void* keys, void* state_void) { static_assert(kCapacityBytes == sizeof(Vector128), "Capacity mismatch"); - uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state = - reinterpret_cast(state_void); + auto* state = static_cast(state_void); const Vector128 prev_inner = Vector128Load(state); diff --git a/absl/strings/internal/numbers_test_common.h b/absl/strings/internal/numbers_test_common.h index 28247205..a263219e 100644 --- a/absl/strings/internal/numbers_test_common.h +++ b/absl/strings/internal/numbers_test_common.h @@ -42,8 +42,9 @@ inline bool Itoa(IntType value, int base, std::string* destination) { while (value != 0) { const IntType next_value = value / base; // Can't use std::abs here because of problems when IntType is unsigned. - int remainder = value > next_value * base ? value - next_value * base - : next_value * base - value; + int remainder = + static_cast(value > next_value * base ? value - next_value * base + : next_value * base - value); char c = remainder < 10 ? '0' + remainder : 'A' + remainder - 10; destination->insert(0, 1, c); value = next_value; diff --git a/absl/strings/numbers.cc b/absl/strings/numbers.cc index d7b94fc1..4890bd54 100644 --- a/absl/strings/numbers.cc +++ b/absl/strings/numbers.cc @@ -93,43 +93,6 @@ bool SimpleAtod(absl::string_view str, double* out) { return true; } -namespace { - -// Writes a two-character representation of 'i' to 'buf'. 'i' must be in the -// range 0 <= i < 100, and buf must have space for two characters. Example: -// char buf[2]; -// PutTwoDigits(42, buf); -// // buf[0] == '4' -// // buf[1] == '2' -inline void PutTwoDigits(size_t i, char* buf) { - static const char two_ASCII_digits[100][2] = { - {'0', '0'}, {'0', '1'}, {'0', '2'}, {'0', '3'}, {'0', '4'}, - {'0', '5'}, {'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', '8'}, {'1', '9'}, - {'2', '0'}, {'2', '1'}, {'2', '2'}, {'2', '3'}, {'2', '4'}, - {'2', '5'}, {'2', '6'}, {'2', '7'}, {'2', '8'}, {'2', '9'}, - {'3', '0'}, {'3', '1'}, {'3', '2'}, {'3', '3'}, {'3', '4'}, - {'3', '5'}, {'3', '6'}, {'3', '7'}, {'3', '8'}, {'3', '9'}, - {'4', '0'}, {'4', '1'}, {'4', '2'}, {'4', '3'}, {'4', '4'}, - {'4', '5'}, {'4', '6'}, {'4', '7'}, {'4', '8'}, {'4', '9'}, - {'5', '0'}, {'5', '1'}, {'5', '2'}, {'5', '3'}, {'5', '4'}, - {'5', '5'}, {'5', '6'}, {'5', '7'}, {'5', '8'}, {'5', '9'}, - {'6', '0'}, {'6', '1'}, {'6', '2'}, {'6', '3'}, {'6', '4'}, - {'6', '5'}, {'6', '6'}, {'6', '7'}, {'6', '8'}, {'6', '9'}, - {'7', '0'}, {'7', '1'}, {'7', '2'}, {'7', '3'}, {'7', '4'}, - {'7', '5'}, {'7', '6'}, {'7', '7'}, {'7', '8'}, {'7', '9'}, - {'8', '0'}, {'8', '1'}, {'8', '2'}, {'8', '3'}, {'8', '4'}, - {'8', '5'}, {'8', '6'}, {'8', '7'}, {'8', '8'}, {'8', '9'}, - {'9', '0'}, {'9', '1'}, {'9', '2'}, {'9', '3'}, {'9', '4'}, - {'9', '5'}, {'9', '6'}, {'9', '7'}, {'9', '8'}, {'9', '9'} - }; - assert(i < 100); - memcpy(buf, two_ASCII_digits[i], 2); -} - -} // namespace - bool SimpleAtob(absl::string_view str, bool* out) { ABSL_RAW_CHECK(out != nullptr, "Output pointer must not be nullptr."); if (EqualsIgnoreCase(str, "true") || EqualsIgnoreCase(str, "t") || @@ -496,13 +459,13 @@ static ExpDigits SplitToSix(const double value) { int two_digits = dddddd / 10000; dddddd -= two_digits * 10000; - PutTwoDigits(two_digits, &exp_dig.digits[0]); + numbers_internal::PutTwoDigits(two_digits, &exp_dig.digits[0]); two_digits = dddddd / 100; dddddd -= two_digits * 100; - PutTwoDigits(two_digits, &exp_dig.digits[2]); + numbers_internal::PutTwoDigits(two_digits, &exp_dig.digits[2]); - PutTwoDigits(dddddd, &exp_dig.digits[4]); + numbers_internal::PutTwoDigits(dddddd, &exp_dig.digits[4]); return exp_dig; } @@ -908,6 +871,25 @@ ABSL_CONST_INIT const char kHexTable[513] = "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; +ABSL_CONST_INIT const char two_ASCII_digits[100][2] = { + {'0', '0'}, {'0', '1'}, {'0', '2'}, {'0', '3'}, {'0', '4'}, {'0', '5'}, + {'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', '8'}, {'1', '9'}, {'2', '0'}, {'2', '1'}, {'2', '2'}, {'2', '3'}, + {'2', '4'}, {'2', '5'}, {'2', '6'}, {'2', '7'}, {'2', '8'}, {'2', '9'}, + {'3', '0'}, {'3', '1'}, {'3', '2'}, {'3', '3'}, {'3', '4'}, {'3', '5'}, + {'3', '6'}, {'3', '7'}, {'3', '8'}, {'3', '9'}, {'4', '0'}, {'4', '1'}, + {'4', '2'}, {'4', '3'}, {'4', '4'}, {'4', '5'}, {'4', '6'}, {'4', '7'}, + {'4', '8'}, {'4', '9'}, {'5', '0'}, {'5', '1'}, {'5', '2'}, {'5', '3'}, + {'5', '4'}, {'5', '5'}, {'5', '6'}, {'5', '7'}, {'5', '8'}, {'5', '9'}, + {'6', '0'}, {'6', '1'}, {'6', '2'}, {'6', '3'}, {'6', '4'}, {'6', '5'}, + {'6', '6'}, {'6', '7'}, {'6', '8'}, {'6', '9'}, {'7', '0'}, {'7', '1'}, + {'7', '2'}, {'7', '3'}, {'7', '4'}, {'7', '5'}, {'7', '6'}, {'7', '7'}, + {'7', '8'}, {'7', '9'}, {'8', '0'}, {'8', '1'}, {'8', '2'}, {'8', '3'}, + {'8', '4'}, {'8', '5'}, {'8', '6'}, {'8', '7'}, {'8', '8'}, {'8', '9'}, + {'9', '0'}, {'9', '1'}, {'9', '2'}, {'9', '3'}, {'9', '4'}, {'9', '5'}, + {'9', '6'}, {'9', '7'}, {'9', '8'}, {'9', '9'}}; + bool safe_strto32_base(absl::string_view text, int32_t* value, int base) { return safe_int_internal(text, value, base); } @@ -924,5 +906,9 @@ bool safe_strtou64_base(absl::string_view text, uint64_t* value, int base) { return safe_uint_internal(text, value, base); } +bool safe_strtou128_base(absl::string_view text, uint128* value, int base) { + return safe_uint_internal(text, value, base); +} + } // namespace numbers_internal } // namespace absl diff --git a/absl/strings/numbers.h b/absl/strings/numbers.h index 9b8ec89a..5e15ca40 100644 --- a/absl/strings/numbers.h +++ b/absl/strings/numbers.h @@ -67,7 +67,7 @@ ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view str, int_type* out); // Converts the given string (optionally followed or preceded by ASCII // whitespace) into a float, which may be rounded on overflow or underflow. // See https://en.cppreference.com/w/c/string/byte/strtof for details about the -// allowed formats for `str`, except SimpleAtof() is locale-indepdent and will +// allowed formats for `str`, except SimpleAtof() is locale-independent and will // always use the "C" locale. If any errors are encountered, this function // returns `false`, leaving `out` in an unspecified state. ABSL_MUST_USE_RESULT bool SimpleAtof(absl::string_view str, float* out); @@ -102,12 +102,26 @@ namespace numbers_internal { // Digit conversion. extern const char kHexChar[17]; // 0123456789abcdef extern const char kHexTable[513]; // 000102030405060708090a0b0c0d0e0f1011... +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 +// range 0 <= i < 100, and buf must have space for two characters. Example: +// char buf[2]; +// PutTwoDigits(42, buf); +// // buf[0] == '4' +// // buf[1] == '2' +inline void PutTwoDigits(size_t i, char* buf) { + assert(i < 100); + memcpy(buf, two_ASCII_digits[i], 2); +} // safe_strto?() functions for implementing SimpleAtoi() bool safe_strto32_base(absl::string_view text, int32_t* value, int base); bool safe_strto64_base(absl::string_view text, int64_t* value, int base); bool safe_strtou32_base(absl::string_view text, uint32_t* value, int base); bool safe_strtou64_base(absl::string_view text, uint64_t* value, int base); +bool safe_strtou128_base(absl::string_view text, absl::uint128* value, + int base); static const int kFastToBufferSize = 32; static const int kSixDigitsToBufferSize = 16; @@ -232,6 +246,11 @@ ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view str, int_type* out) { return numbers_internal::safe_strtoi_base(str, out, 10); } +ABSL_MUST_USE_RESULT inline bool SimpleAtoi(absl::string_view str, + absl::uint128* out) { + return numbers_internal::safe_strtou128_base(str, out, 10); +} + } // namespace absl #endif // ABSL_STRINGS_NUMBERS_H_ diff --git a/absl/strings/numbers_test.cc b/absl/strings/numbers_test.cc index b92b9a8c..68229b15 100644 --- a/absl/strings/numbers_test.cc +++ b/absl/strings/numbers_test.cc @@ -249,7 +249,9 @@ TEST(Numbers, TestFastPrints) { template void VerifySimpleAtoiGood(in_val_type in_value, int_type exp_value) { - std::string s = absl::StrCat(in_value); + std::string s; + // uint128 can be streamed but not StrCat'd + absl::strings_internal::OStringStream(&s) << in_value; int_type x = static_cast(~exp_value); EXPECT_TRUE(SimpleAtoi(s, &x)) << "in_value=" << in_value << " s=" << s << " x=" << x; @@ -325,6 +327,25 @@ TEST(NumbersTest, Atoi) { VerifySimpleAtoiGood(std::numeric_limits::max(), std::numeric_limits::max()); + // SimpleAtoi(absl::string_view, absl::uint128) + VerifySimpleAtoiGood(0, 0); + VerifySimpleAtoiGood(42, 42); + VerifySimpleAtoiBad(-42); + + VerifySimpleAtoiBad(std::numeric_limits::min()); + VerifySimpleAtoiGood(std::numeric_limits::max(), + std::numeric_limits::max()); + VerifySimpleAtoiGood(std::numeric_limits::max(), + std::numeric_limits::max()); + VerifySimpleAtoiBad(std::numeric_limits::min()); + VerifySimpleAtoiGood(std::numeric_limits::max(), + std::numeric_limits::max()); + VerifySimpleAtoiGood(std::numeric_limits::max(), + std::numeric_limits::max()); + VerifySimpleAtoiGood( + std::numeric_limits::max(), + std::numeric_limits::max()); + // Some other types VerifySimpleAtoiGood(-42, -42); VerifySimpleAtoiGood(-42, -42); @@ -657,6 +678,46 @@ TEST(stringtest, safe_strtou32_random) { TEST(stringtest, safe_strtou64_random) { test_random_integer_parse_base(&safe_strtou64_base); } +TEST(stringtest, safe_strtou128_random) { + // random number generators don't work for uint128, and + // uint128 can be streamed but not StrCat'd, so this code must be custom + // implemented for uint128, but is generally the same as what's above. + // test_random_integer_parse_base( + // &absl::numbers_internal::safe_strtou128_base); + using RandomEngine = std::minstd_rand0; + using IntType = absl::uint128; + constexpr auto parse_func = &absl::numbers_internal::safe_strtou128_base; + + std::random_device rd; + RandomEngine rng(rd()); + std::uniform_int_distribution random_uint64( + std::numeric_limits::min()); + std::uniform_int_distribution random_base(2, 35); + + for (size_t i = 0; i < kNumRandomTests; i++) { + IntType value = random_uint64(rng); + value = (value << 64) + random_uint64(rng); + int base = random_base(rng); + std::string str_value; + EXPECT_TRUE(Itoa(value, base, &str_value)); + IntType parsed_value; + + // Test successful parse + EXPECT_TRUE(parse_func(str_value, &parsed_value, base)); + EXPECT_EQ(parsed_value, value); + + // Test overflow + std::string s; + absl::strings_internal::OStringStream(&s) + << std::numeric_limits::max() << value; + EXPECT_FALSE(parse_func(s, &parsed_value, base)); + + // Test underflow + s.clear(); + absl::strings_internal::OStringStream(&s) << "-" << value; + EXPECT_FALSE(parse_func(s, &parsed_value, base)); + } +} TEST(stringtest, safe_strtou32_base) { for (int i = 0; strtouint32_test_cases()[i].str != nullptr; ++i) { diff --git a/absl/synchronization/internal/waiter.cc b/absl/synchronization/internal/waiter.cc index 8e713770..f1425872 100644 --- a/absl/synchronization/internal/waiter.cc +++ b/absl/synchronization/internal/waiter.cc @@ -342,8 +342,11 @@ bool Waiter::Wait(KernelTimeout t) { } void Waiter::Post() { - wakeups_.fetch_add(1, std::memory_order_release); // Post a wakeup. - Poke(); + // Post a wakeup. + if (wakeups_.fetch_add(1, std::memory_order_release) == 0) { + // We incremented from 0, need to wake a potential waiter. + Poke(); + } } void Waiter::Poke() { diff --git a/absl/synchronization/internal/waiter.h b/absl/synchronization/internal/waiter.h index cac81d5f..9540598b 100644 --- a/absl/synchronization/internal/waiter.h +++ b/absl/synchronization/internal/waiter.h @@ -24,6 +24,10 @@ #include #endif +#ifdef __linux__ +#include +#endif + #ifdef ABSL_HAVE_SEMAPHORE_H #include #endif @@ -44,7 +48,12 @@ #define ABSL_WAITER_MODE ABSL_FORCE_WAITER_MODE #elif defined(_WIN32) && _WIN32_WINNT >= _WIN32_WINNT_VISTA #define ABSL_WAITER_MODE ABSL_WAITER_MODE_WIN32 -#elif defined(__linux__) +#elif defined(__BIONIC__) +// Bionic supports all the futex operations we need even when some of the futex +// definitions are missing. +#define ABSL_WAITER_MODE ABSL_WAITER_MODE_FUTEX +#elif defined(__linux__) && defined(FUTEX_CLOCK_REALTIME) +// FUTEX_CLOCK_REALTIME requires Linux >= 2.6.28. #define ABSL_WAITER_MODE ABSL_WAITER_MODE_FUTEX #elif defined(ABSL_HAVE_SEMAPHORE_H) #define ABSL_WAITER_MODE ABSL_WAITER_MODE_SEM -- cgit v1.2.3 From bcaae6009c0833b73c6fa7bdd972921d8081a724 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 20 Nov 2019 13:55:25 -0800 Subject: Export of internal Abseil changes -- 4503a1945d61540d3f7dd9ee2399297fbd423b82 by Andy Soffer : Releasing absl::MockingBitGen and absl::BitGenRef PiperOrigin-RevId: 281594380 -- 2cb926fd9e39b5fa24c9541bfafcf18916cf7df2 by Abseil Team : Explicitly export files needed by other packages PiperOrigin-RevId: 281482304 GitOrigin-RevId: 4503a1945d61540d3f7dd9ee2399297fbd423b82 Change-Id: Id9f694eaaa23f42de817c8e8a28e6f86444f5637 --- absl/random/BUILD.bazel | 92 ++++++++ absl/random/CMakeLists.txt | 126 ++++++++++ absl/random/bit_gen_ref.h | 151 ++++++++++++ absl/random/bit_gen_ref_test.cc | 99 ++++++++ absl/random/internal/BUILD.bazel | 23 ++ absl/random/internal/mock_overload_set.h | 89 +++++++ absl/random/internal/mocking_bit_gen_base.h | 118 ++++++++++ absl/random/mock_distributions.h | 259 +++++++++++++++++++++ absl/random/mock_distributions_test.cc | 72 ++++++ absl/random/mocking_bit_gen.cc | 28 +++ absl/random/mocking_bit_gen.h | 194 ++++++++++++++++ absl/random/mocking_bit_gen_test.cc | 347 ++++++++++++++++++++++++++++ 12 files changed, 1598 insertions(+) create mode 100644 absl/random/bit_gen_ref.h create mode 100644 absl/random/bit_gen_ref_test.cc create mode 100644 absl/random/internal/mock_overload_set.h create mode 100644 absl/random/internal/mocking_bit_gen_base.h create mode 100644 absl/random/mock_distributions.h create mode 100644 absl/random/mock_distributions_test.cc create mode 100644 absl/random/mocking_bit_gen.cc create mode 100644 absl/random/mocking_bit_gen.h create mode 100644 absl/random/mocking_bit_gen_test.cc (limited to 'absl/random/CMakeLists.txt') diff --git a/absl/random/BUILD.bazel b/absl/random/BUILD.bazel index c3520df8..2585b397 100644 --- a/absl/random/BUILD.bazel +++ b/absl/random/BUILD.bazel @@ -110,6 +110,58 @@ cc_library( ], ) +cc_library( + name = "bit_gen_ref", + hdrs = ["bit_gen_ref.h"], + copts = ABSL_DEFAULT_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + "//absl/base:core_headers", + "//absl/meta:type_traits", + "//absl/random/internal:distribution_caller", + "//absl/random/internal:fast_uniform_bits", + "//absl/random/internal:mocking_bit_gen_base", + ], +) + +cc_library( + name = "mock_distributions", + testonly = 1, + hdrs = ["mock_distributions.h"], + deps = [ + ":distributions", + ":mocking_bit_gen", + "//absl/meta:type_traits", + "//absl/random/internal:mock_overload_set", + "@com_google_googletest//:gtest", + ], +) + +cc_library( + name = "mocking_bit_gen", + testonly = 1, + srcs = [ + "mocking_bit_gen.cc", + ], + hdrs = [ + "mocking_bit_gen.h", + ], + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + ":distributions", + "//absl/base:raw_logging_internal", + "//absl/container:flat_hash_map", + "//absl/meta:type_traits", + "//absl/random/internal:distribution_caller", + "//absl/random/internal:mocking_bit_gen_base", + "//absl/strings", + "//absl/types:span", + "//absl/types:variant", + "//absl/utility", + "@com_google_googletest//:gtest", + ], +) + cc_test( name = "bernoulli_distribution_test", size = "small", @@ -345,6 +397,46 @@ cc_test( ], ) +cc_test( + name = "bit_gen_ref_test", + size = "small", + srcs = ["bit_gen_ref_test.cc"], + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + ":bit_gen_ref", + ":random", + "//absl/random/internal:sequence_urbg", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "mocking_bit_gen_test", + size = "small", + srcs = ["mocking_bit_gen_test.cc"], + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + ":bit_gen_ref", + ":mock_distributions", + ":mocking_bit_gen", + ":random", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "mock_distributions_test", + size = "small", + srcs = ["mock_distributions_test.cc"], + deps = [ + ":mock_distributions", + ":mocking_bit_gen", + ":random", + "@com_google_googletest//:gtest_main", + ], +) + cc_test( name = "examples_test", size = "small", diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt index 264a6f3c..13e96357 100644 --- a/absl/random/CMakeLists.txt +++ b/absl/random/CMakeLists.txt @@ -32,6 +32,132 @@ absl_cc_library( absl::random_seed_sequences ) +absl_cc_library( + NAME + random_bit_gen_ref + HDRS + "bit_gen_ref.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::core_headers + absl::random_internal_distribution_caller + absl::random_internal_fast_uniform_bits + absl::random_internal_mocking_bit_gen_base + absl::type_traits +) + +absl_cc_test( + NAME + random_bit_gen_ref_test + SRCS + "bit_gen_ref_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_bit_gen_ref + absl::random_random + absl::random_internal_sequence_urbg + gmock + gtest_main +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_mocking_bit_gen_base + HDRS + "internal/mocking_bit_gen_base.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_random + absl::strings +) + +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + random_internal_mock_overload_set + HDRS + "internal/mock_overload_set.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_mocking_bit_gen + TESTONLY +) + +absl_cc_library( + NAME + random_mocking_bit_gen + HDRS + "mock_distributions.h" + "mocking_bit_gen.h" + SRCS + "mocking_bit_gen.cc" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::flat_hash_map + absl::raw_logging_internal + absl::random_distributions + absl::random_internal_distribution_caller + absl::random_internal_mocking_bit_gen_base + absl::random_internal_mock_overload_set + absl::strings + absl::span + absl::type_traits + absl::utility + absl::variant + gmock + gtest + TESTONLY +) + +absl_cc_test( + NAME + random_mock_distributions_test + SRCS + "mock_distributions_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_mocking_bit_gen + absl::random_random + gmock + gtest_main +) + +absl_cc_test( + NAME + random_mocking_bit_gen_test + SRCS + "mocking_bit_gen_test.cc" + COPTS + ${ABSL_TEST_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::random_bit_gen_ref + absl::random_mocking_bit_gen + absl::random_random + gmock + gtest_main +) + absl_cc_library( NAME random_distributions diff --git a/absl/random/bit_gen_ref.h b/absl/random/bit_gen_ref.h new file mode 100644 index 00000000..00e904f8 --- /dev/null +++ b/absl/random/bit_gen_ref.h @@ -0,0 +1,151 @@ +// +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ----------------------------------------------------------------------------- +// File: bit_gen_ref.h +// ----------------------------------------------------------------------------- +// +// This header defines a bit generator "reference" class, for use in interfaces +// that take both Abseil (e.g. `absl::BitGen`) and standard library (e.g. +// `std::mt19937`) bit generators. + +#ifndef ABSL_RANDOM_BIT_GEN_REF_H_ +#define ABSL_RANDOM_BIT_GEN_REF_H_ + +#include "absl/base/macros.h" +#include "absl/meta/type_traits.h" +#include "absl/random/internal/distribution_caller.h" +#include "absl/random/internal/fast_uniform_bits.h" +#include "absl/random/internal/mocking_bit_gen_base.h" + +namespace absl { +namespace random_internal { + +template +struct is_urbg : std::false_type {}; + +template +struct is_urbg< + URBG, + absl::enable_if_t::type>::value>, + absl::enable_if_t::type>::value>, + absl::enable_if_t()())>::type>::value>> + : std::true_type {}; + +} // namespace random_internal + +// ----------------------------------------------------------------------------- +// absl::BitGenRef +// ----------------------------------------------------------------------------- +// +// `absl::BitGenRef` is a type-erasing class that provides a generator-agnostic +// non-owning "reference" interface for use in place of any specific uniform +// random bit generator (URBG). This class may be used for both Abseil +// (e.g. `absl::BitGen`, `absl::InsecureBitGen`) and Standard library (e.g +// `std::mt19937`, `std::minstd_rand`) bit generators. +// +// Like other reference classes, `absl::BitGenRef` does not own the +// underlying bit generator, and the underlying instance must outlive the +// `absl::BitGenRef`. +// +// `absl::BitGenRef` is particularly useful when used with an +// `absl::MockingBitGen` to test specific paths in functions which use random +// values. +// +// Example: +// void TakesBitGenRef(absl::BitGenRef gen) { +// int x = absl::Uniform(gen, 0, 1000); +// } +// +class BitGenRef { + public: + using result_type = uint64_t; + + BitGenRef(const absl::BitGenRef&) = default; + BitGenRef(absl::BitGenRef&&) = default; + BitGenRef& operator=(const absl::BitGenRef&) = default; + BitGenRef& operator=(absl::BitGenRef&&) = default; + + template ::value && + random_internal::is_urbg::value)>* = nullptr> + BitGenRef(URBG& gen) // NOLINT + : mocked_gen_ptr_(MakeMockPointer(&gen)), + t_erased_gen_ptr_(reinterpret_cast(&gen)), + generate_impl_fn_(ImplFn) { + } + + static constexpr result_type(min)() { + return (std::numeric_limits::min)(); + } + + static constexpr result_type(max)() { + return (std::numeric_limits::max)(); + } + + result_type operator()() { return generate_impl_fn_(t_erased_gen_ptr_); } + + private: + friend struct absl::random_internal::DistributionCaller; + using impl_fn = result_type (*)(uintptr_t); + using mocker_base_t = absl::random_internal::MockingBitGenBase; + + // Convert an arbitrary URBG pointer into either a valid mocker_base_t + // pointer or a nullptr. + static inline mocker_base_t* MakeMockPointer(mocker_base_t* t) { return t; } + static inline mocker_base_t* MakeMockPointer(void*) { return nullptr; } + + template + static result_type ImplFn(uintptr_t ptr) { + // Ensure that the return values from operator() fill the entire + // range promised by result_type, min() and max(). + absl::random_internal::FastUniformBits fast_uniform_bits; + return fast_uniform_bits(*reinterpret_cast(ptr)); + } + + mocker_base_t* mocked_gen_ptr_; + uintptr_t t_erased_gen_ptr_; + impl_fn generate_impl_fn_; +}; + +namespace random_internal { + +template <> +struct DistributionCaller { + template + static typename DistrT::result_type Call(absl::BitGenRef* gen_ref, + Args&&... args) { + auto* mock_ptr = gen_ref->mocked_gen_ptr_; + if (mock_ptr == nullptr) { + DistrT dist(std::forward(args)...); + return dist(*gen_ref); + } else { + return mock_ptr->template Call( + std::forward(args)...); + } + } +}; + +} // namespace random_internal +} // namespace absl + +#endif // ABSL_RANDOM_BIT_GEN_REF_H_ diff --git a/absl/random/bit_gen_ref_test.cc b/absl/random/bit_gen_ref_test.cc new file mode 100644 index 00000000..bc02ca5c --- /dev/null +++ b/absl/random/bit_gen_ref_test.cc @@ -0,0 +1,99 @@ +// +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "absl/random/bit_gen_ref.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/random/internal/sequence_urbg.h" +#include "absl/random/random.h" + +namespace absl { + +class ConstBitGen : public absl::random_internal::MockingBitGenBase { + bool CallImpl(const std::type_info&, void*, void* result) override { + *static_cast(result) = 42; + return true; + } +}; + +namespace random_internal { +template <> +struct DistributionCaller { + template + static typename DistrT::result_type Call(ConstBitGen* gen, Args&&... args) { + return gen->template Call(std::forward(args)...); + } +}; +} // namespace random_internal + +namespace { +int FnTest(absl::BitGenRef gen_ref) { return absl::Uniform(gen_ref, 1, 7); } + +template +class BitGenRefTest : public testing::Test {}; + +using BitGenTypes = + ::testing::Types; +TYPED_TEST_SUITE(BitGenRefTest, BitGenTypes); + +TYPED_TEST(BitGenRefTest, BasicTest) { + TypeParam gen; + auto x = FnTest(gen); + EXPECT_NEAR(x, 4, 3); +} + +TYPED_TEST(BitGenRefTest, Copyable) { + TypeParam gen; + absl::BitGenRef gen_ref(gen); + FnTest(gen_ref); // Copy +} + +TEST(BitGenRefTest, PassThroughEquivalence) { + // sequence_urbg returns 64-bit results. + absl::random_internal::sequence_urbg urbg( + {0x0003eb76f6f7f755ull, 0xFFCEA50FDB2F953Bull, 0xC332DDEFBE6C5AA5ull, + 0x6558218568AB9702ull, 0x2AEF7DAD5B6E2F84ull, 0x1521B62829076170ull, + 0xECDD4775619F1510ull, 0x13CCA830EB61BD96ull, 0x0334FE1EAA0363CFull, + 0xB5735C904C70A239ull, 0xD59E9E0BCBAADE14ull, 0xEECC86BC60622CA7ull}); + + std::vector output(12); + + { + absl::BitGenRef view(urbg); + for (auto& v : output) { + v = view(); + } + } + + std::vector expected( + {0x0003eb76f6f7f755ull, 0xFFCEA50FDB2F953Bull, 0xC332DDEFBE6C5AA5ull, + 0x6558218568AB9702ull, 0x2AEF7DAD5B6E2F84ull, 0x1521B62829076170ull, + 0xECDD4775619F1510ull, 0x13CCA830EB61BD96ull, 0x0334FE1EAA0363CFull, + 0xB5735C904C70A239ull, 0xD59E9E0BCBAADE14ull, 0xEECC86BC60622CA7ull}); + + EXPECT_THAT(output, testing::Eq(expected)); +} + +TEST(BitGenRefTest, MockingBitGenBaseOverrides) { + ConstBitGen const_gen; + EXPECT_EQ(FnTest(const_gen), 42); + + absl::BitGenRef gen_ref(const_gen); + EXPECT_EQ(FnTest(gen_ref), 42); // Copy +} +} // namespace +} // namespace absl diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel index cc9bc013..5026e2b2 100644 --- a/absl/random/internal/BUILD.bazel +++ b/absl/random/internal/BUILD.bazel @@ -493,6 +493,29 @@ cc_test( ], ) +cc_library( + name = "mocking_bit_gen_base", + hdrs = ["mocking_bit_gen_base.h"], + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + "//absl/random", + "//absl/strings", + ], +) + +cc_library( + name = "mock_overload_set", + testonly = 1, + hdrs = ["mock_overload_set.h"], + visibility = [ + "//absl/random:__pkg__", + ], + deps = [ + "//absl/random:mocking_bit_gen", + "@com_google_googletest//:gtest", + ], +) + cc_test( name = "nonsecure_base_test", size = "small", diff --git a/absl/random/internal/mock_overload_set.h b/absl/random/internal/mock_overload_set.h new file mode 100644 index 00000000..539313d7 --- /dev/null +++ b/absl/random/internal/mock_overload_set.h @@ -0,0 +1,89 @@ +// +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_RANDOM_INTERNAL_MOCK_OVERLOAD_SET_H_ +#define ABSL_RANDOM_INTERNAL_MOCK_OVERLOAD_SET_H_ + +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/random/mocking_bit_gen.h" + +namespace absl { +namespace random_internal { + +template +struct MockSingleOverload; + +// MockSingleOverload +// +// MockSingleOverload hooks in to gMock's `ON_CALL` and `EXPECT_CALL` macros. +// EXPECT_CALL(mock_single_overload, Call(...))` will expand to a call to +// `mock_single_overload.gmock_Call(...)`. Because expectations are stored on +// the MockingBitGen (an argument passed inside `Call(...)`), this forwards to +// arguments to Mocking::Register. +template +struct MockSingleOverload { + static_assert(std::is_same::value, + "Overload signature must have return type matching the " + "distributions result type."); + auto gmock_Call( + absl::MockingBitGen& gen, // NOLINT(google-runtime-references) + const ::testing::Matcher&... args) + -> decltype(gen.Register(args...)) { + return gen.Register(args...); + } +}; + +template +struct MockSingleOverload { + static_assert(std::is_same::value, + "Overload signature must have return type matching the " + "distributions result type."); + auto gmock_Call( + const ::testing::Matcher& arg, + absl::MockingBitGen& gen, // NOLINT(google-runtime-references) + const ::testing::Matcher&... args) + -> decltype(gen.Register(arg, args...)) { + return gen.Register(arg, args...); + } +}; + +// MockOverloadSet +// +// MockOverloadSet takes a distribution and a collection of signatures and +// performs overload resolution amongst all the overloads. This makes +// `EXPECT_CALL(mock_overload_set, Call(...))` expand and do overload resolution +// correctly. +template +struct MockOverloadSet; + +template +struct MockOverloadSet : public MockSingleOverload { + using MockSingleOverload::gmock_Call; +}; + +template +struct MockOverloadSet + : public MockSingleOverload, + public MockOverloadSet { + using MockSingleOverload::gmock_Call; + using MockOverloadSet::gmock_Call; +}; + +} // namespace random_internal +} // namespace absl +#endif // ABSL_RANDOM_INTERNAL_MOCK_OVERLOAD_SET_H_ diff --git a/absl/random/internal/mocking_bit_gen_base.h b/absl/random/internal/mocking_bit_gen_base.h new file mode 100644 index 00000000..aff2ba6d --- /dev/null +++ b/absl/random/internal/mocking_bit_gen_base.h @@ -0,0 +1,118 @@ +// +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef ABSL_RANDOM_INTERNAL_MOCKING_BIT_GEN_BASE_H_ +#define ABSL_RANDOM_INTERNAL_MOCKING_BIT_GEN_BASE_H_ + +#include +#include +#include +#include + +#include "absl/random/random.h" +#include "absl/strings/str_cat.h" + +namespace absl { +namespace random_internal { + +// MockingBitGenExpectationFormatter is invoked to format unsatisfied mocks +// and remaining results into a description string. +template +struct MockingBitGenExpectationFormatter { + std::string operator()(absl::string_view args) { + return absl::StrCat(FormatT::FunctionName(), "(", args, ")"); + } +}; + +// MockingBitGenCallFormatter is invoked to format each distribution call +// into a description string for the mock log. +template +struct MockingBitGenCallFormatter { + std::string operator()(const DistrT& dist, + const typename DistrT::result_type& result) { + return absl::StrCat( + FormatT::FunctionName(), "(", FormatT::FormatArgs(dist), ") => {", + FormatT::FormatResults(absl::MakeSpan(&result, 1)), "}"); + } +}; + +class MockingBitGenBase { + template + friend struct DistributionCaller; + using generator_type = absl::BitGen; + + public: + // URBG interface + using result_type = generator_type::result_type; + static constexpr result_type(min)() { return (generator_type::min)(); } + static constexpr result_type(max)() { return (generator_type::max)(); } + result_type operator()() { return gen_(); } + + MockingBitGenBase() : gen_(), observed_call_log_() {} + virtual ~MockingBitGenBase() = default; + + protected: + const std::deque& observed_call_log() { + return observed_call_log_; + } + + // CallImpl is the type-erased virtual dispatch. + // The type of dist is always distribution, + // The type of result is always distribution::result_type. + virtual bool CallImpl(const std::type_info& distr_type, void* dist_args, + void* result) = 0; + + template + static const std::type_info& GetTypeId() { + return typeid(std::pair, absl::decay_t>); + } + + // Call the generating distribution function. + // Invoked by DistributionCaller<>::Call. + // DistT is the distribution type. + // FormatT is the distribution formatter traits type. + template + typename DistrT::result_type Call(Args&&... args) { + using distr_result_type = typename DistrT::result_type; + using ArgTupleT = std::tuple...>; + + ArgTupleT arg_tuple(std::forward(args)...); + auto dist = absl::make_from_tuple(arg_tuple); + + distr_result_type result{}; + bool found_match = + CallImpl(GetTypeId(), &arg_tuple, &result); + + if (!found_match) { + result = dist(gen_); + } + + // TODO(asoffer): Forwarding the args through means we no longer need to + // extract them from the from the distribution in formatter traits. We can + // just StrJoin them. + observed_call_log_.push_back( + MockingBitGenCallFormatter{}(dist, result)); + return result; + } + + private: + generator_type gen_; + std::deque observed_call_log_; +}; // namespace random_internal + +} // namespace random_internal +} // namespace absl + +#endif // ABSL_RANDOM_INTERNAL_MOCKING_BIT_GEN_BASE_H_ diff --git a/absl/random/mock_distributions.h b/absl/random/mock_distributions.h new file mode 100644 index 00000000..1af98a24 --- /dev/null +++ b/absl/random/mock_distributions.h @@ -0,0 +1,259 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ----------------------------------------------------------------------------- +// File: mock_distributions.h +// ----------------------------------------------------------------------------- +// +// This file contains mock distribution functions for use alongside an +// `absl::MockingBitGen` object within the Googletest testing framework. Such +// mocks are useful to provide deterministic values as return values within +// (otherwise random) Abseil distribution functions. +// +// The return type of each function is a mock expectation object which +// is used to set the match result. +// +// More information about the Googletest testing framework is available at +// https://github.com/google/googletest +// +// Example: +// +// absl::MockingBitGen mock; +// EXPECT_CALL(absl::MockUniform(), Call(mock, 1, 1000)) +// .WillRepeatedly(testing::ReturnRoundRobin({20, 40})); +// +// EXPECT_EQ(absl::Uniform(gen, 1, 1000), 20); +// EXPECT_EQ(absl::Uniform(gen, 1, 1000), 40); +// EXPECT_EQ(absl::Uniform(gen, 1, 1000), 20); +// EXPECT_EQ(absl::Uniform(gen, 1, 1000), 40); + +#ifndef ABSL_RANDOM_MOCK_DISTRIBUTIONS_H_ +#define ABSL_RANDOM_MOCK_DISTRIBUTIONS_H_ + +#include +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/meta/type_traits.h" +#include "absl/random/distributions.h" +#include "absl/random/internal/mock_overload_set.h" +#include "absl/random/mocking_bit_gen.h" + +namespace absl { + +// ----------------------------------------------------------------------------- +// absl::MockUniform +// ----------------------------------------------------------------------------- +// +// Matches calls to absl::Uniform. +// +// `absl::MockUniform` is a class template used in conjunction with Googletest's +// `ON_CALL()` and `EXPECT_CALL()` macros. To use it, default-construct an +// instance of it inside `ON_CALL()` or `EXPECT_CALL()`, and use `Call(...)` the +// same way one would define mocks on a Googletest `MockFunction()`. +// +// Example: +// +// absl::MockingBitGen mock; +// EXPECT_CALL(absl::MockUniform(), Call(mock)) +// .WillOnce(Return(123456)); +// auto x = absl::Uniform(mock); +// assert(x == 123456) +// +template +using MockUniform = random_internal::MockOverloadSet< + random_internal::UniformDistributionWrapper, + R(IntervalClosedOpenTag, MockingBitGen&, R, R), + R(IntervalClosedClosedTag, MockingBitGen&, R, R), + R(IntervalOpenOpenTag, MockingBitGen&, R, R), + R(IntervalOpenClosedTag, MockingBitGen&, R, R), R(MockingBitGen&, R, R), + R(MockingBitGen&)>; + +// ----------------------------------------------------------------------------- +// absl::MockBernoulli +// ----------------------------------------------------------------------------- +// +// Matches calls to absl::Bernoulli. +// +// `absl::MockBernoulli` is a class used in conjunction with Googletest's +// `ON_CALL()` and `EXPECT_CALL()` macros. To use it, default-construct an +// instance of it inside `ON_CALL()` or `EXPECT_CALL()`, and use `Call(...)` the +// same way one would define mocks on a Googletest `MockFunction()`. +// +// Example: +// +// absl::MockingBitGen mock; +// EXPECT_CALL(absl::MockBernoulli(), Call(mock, testing::_)) +// .WillOnce(Return(false)); +// assert(absl::Bernoulli(mock, 0.5) == false); +// +using MockBernoulli = + random_internal::MockOverloadSet; + +// ----------------------------------------------------------------------------- +// absl::MockBeta +// ----------------------------------------------------------------------------- +// +// Matches calls to absl::Beta. +// +// `absl::MockBeta` is a class used in conjunction with Googletest's `ON_CALL()` +// and `EXPECT_CALL()` macros. To use it, default-construct an instance of it +// inside `ON_CALL()` or `EXPECT_CALL()`, and use `Call(...)` the same way one +// would define mocks on a Googletest `MockFunction()`. +// +// Example: +// +// absl::MockingBitGen mock; +// EXPECT_CALL(absl::MockBeta(), Call(mock, 3.0, 2.0)) +// .WillOnce(Return(0.567)); +// auto x = absl::Beta(mock, 3.0, 2.0); +// assert(x == 0.567); +// +template +using MockBeta = + random_internal::MockOverloadSet, + RealType(MockingBitGen&, RealType, + RealType)>; + +// ----------------------------------------------------------------------------- +// absl::MockExponential +// ----------------------------------------------------------------------------- +// +// Matches calls to absl::Exponential. +// +// `absl::MockExponential` is a class template used in conjunction with +// Googletest's `ON_CALL()` and `EXPECT_CALL()` macros. To use it, +// default-construct an instance of it inside `ON_CALL()` or `EXPECT_CALL()`, +// and use `Call(...)` the same way one would define mocks on a +// Googletest `MockFunction()`. +// +// Example: +// +// absl::MockingBitGen mock; +// EXPECT_CALL(absl::MockExponential(), Call(mock, 0.5)) +// .WillOnce(Return(12.3456789)); +// auto x = absl::Exponential(mock, 0.5); +// assert(x == 12.3456789) +// +template +using MockExponential = + random_internal::MockOverloadSet, + RealType(MockingBitGen&, RealType)>; + +// ----------------------------------------------------------------------------- +// absl::MockGaussian +// ----------------------------------------------------------------------------- +// +// Matches calls to absl::Gaussian. +// +// `absl::MockGaussian` is a class template used in conjunction with +// Googletest's `ON_CALL()` and `EXPECT_CALL()` macros. To use it, +// default-construct an instance of it inside `ON_CALL()` or `EXPECT_CALL()`, +// and use `Call(...)` the same way one would define mocks on a +// Googletest `MockFunction()`. +// +// Example: +// +// absl::MockingBitGen mock; +// EXPECT_CALL(absl::MockGaussian(), Call(mock, 16.3, 3.3)) +// .WillOnce(Return(12.3456789)); +// auto x = absl::Gaussian(mock, 16.3, 3.3); +// assert(x == 12.3456789) +// +template +using MockGaussian = + random_internal::MockOverloadSet, + RealType(MockingBitGen&, RealType, + RealType)>; + +// ----------------------------------------------------------------------------- +// absl::MockLogUniform +// ----------------------------------------------------------------------------- +// +// Matches calls to absl::LogUniform. +// +// `absl::MockLogUniform` is a class template used in conjunction with +// Googletest's `ON_CALL()` and `EXPECT_CALL()` macros. To use it, +// default-construct an instance of it inside `ON_CALL()` or `EXPECT_CALL()`, +// and use `Call(...)` the same way one would define mocks on a +// Googletest `MockFunction()`. +// +// Example: +// +// absl::MockingBitGen mock; +// EXPECT_CALL(absl::MockLogUniform(), Call(mock, 10, 10000, 10)) +// .WillOnce(Return(1221)); +// auto x = absl::LogUniform(mock, 10, 10000, 10); +// assert(x == 1221) +// +template +using MockLogUniform = random_internal::MockOverloadSet< + absl::log_uniform_int_distribution, + IntType(MockingBitGen&, IntType, IntType, IntType)>; + +// ----------------------------------------------------------------------------- +// absl::MockPoisson +// ----------------------------------------------------------------------------- +// +// Matches calls to absl::Poisson. +// +// `absl::MockPoisson` is a class template used in conjunction with Googletest's +// `ON_CALL()` and `EXPECT_CALL()` macros. To use it, default-construct an +// instance of it inside `ON_CALL()` or `EXPECT_CALL()`, and use `Call(...)` the +// same way one would define mocks on a Googletest `MockFunction()`. +// +// Example: +// +// absl::MockingBitGen mock; +// EXPECT_CALL(absl::MockPoisson(), Call(mock, 2.0)) +// .WillOnce(Return(1221)); +// auto x = absl::Poisson(mock, 2.0); +// assert(x == 1221) +// +template +using MockPoisson = + random_internal::MockOverloadSet, + IntType(MockingBitGen&, double)>; + +// ----------------------------------------------------------------------------- +// absl::MockZipf +// ----------------------------------------------------------------------------- +// +// Matches calls to absl::Zipf. +// +// `absl::MockZipf` is a class template used in conjunction with Googletest's +// `ON_CALL()` and `EXPECT_CALL()` macros. To use it, default-construct an +// instance of it inside `ON_CALL()` or `EXPECT_CALL()`, and use `Call(...)` the +// same way one would define mocks on a Googletest `MockFunction()`. +// +// Example: +// +// absl::MockingBitGen mock; +// EXPECT_CALL(absl::MockZipf(), Call(mock, 1000000, 2.0, 1.0)) +// .WillOnce(Return(1221)); +// auto x = absl::Zipf(mock, 1000000, 2.0, 1.0); +// assert(x == 1221) +// +template +using MockZipf = + random_internal::MockOverloadSet, + IntType(MockingBitGen&, IntType, double, + double)>; + +} // namespace absl + +#endif // ABSL_RANDOM_MOCK_DISTRIBUTIONS_H_ diff --git a/absl/random/mock_distributions_test.cc b/absl/random/mock_distributions_test.cc new file mode 100644 index 00000000..de23bafe --- /dev/null +++ b/absl/random/mock_distributions_test.cc @@ -0,0 +1,72 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/random/mock_distributions.h" + +#include "gtest/gtest.h" +#include "absl/random/mocking_bit_gen.h" +#include "absl/random/random.h" + +namespace { +using ::testing::Return; + +TEST(MockDistributions, Examples) { + absl::MockingBitGen gen; + + EXPECT_NE(absl::Uniform(gen, 1, 1000000), 20); + EXPECT_CALL(absl::MockUniform(), Call(gen, 1, 1000000)) + .WillOnce(Return(20)); + EXPECT_EQ(absl::Uniform(gen, 1, 1000000), 20); + + EXPECT_NE(absl::Uniform(gen, 0.0, 100.0), 5.0); + EXPECT_CALL(absl::MockUniform(), Call(gen, 0.0, 100.0)) + .WillOnce(Return(5.0)); + EXPECT_EQ(absl::Uniform(gen, 0.0, 100.0), 5.0); + + EXPECT_NE(absl::Exponential(gen, 1.0), 42); + EXPECT_CALL(absl::MockExponential(), Call(gen, 1.0)) + .WillOnce(Return(42)); + EXPECT_EQ(absl::Exponential(gen, 1.0), 42); + + EXPECT_NE(absl::Poisson(gen, 1.0), 500); + EXPECT_CALL(absl::MockPoisson(), Call(gen, 1.0)).WillOnce(Return(500)); + EXPECT_EQ(absl::Poisson(gen, 1.0), 500); + + EXPECT_NE(absl::Bernoulli(gen, 0.000001), true); + EXPECT_CALL(absl::MockBernoulli(), Call(gen, 0.000001)) + .WillOnce(Return(true)); + EXPECT_EQ(absl::Bernoulli(gen, 0.000001), true); + + EXPECT_NE(absl::Beta(gen, 3.0, 2.0), 0.567); + EXPECT_CALL(absl::MockBeta(), Call(gen, 3.0, 2.0)) + .WillOnce(Return(0.567)); + EXPECT_EQ(absl::Beta(gen, 3.0, 2.0), 0.567); + + EXPECT_NE(absl::Zipf(gen, 1000000, 2.0, 1.0), 1221); + EXPECT_CALL(absl::MockZipf(), Call(gen, 1000000, 2.0, 1.0)) + .WillOnce(Return(1221)); + EXPECT_EQ(absl::Zipf(gen, 1000000, 2.0, 1.0), 1221); + + EXPECT_NE(absl::Gaussian(gen, 0.0, 1.0), 0.001); + EXPECT_CALL(absl::MockGaussian(), Call(gen, 0.0, 1.0)) + .WillOnce(Return(0.001)); + EXPECT_EQ(absl::Gaussian(gen, 0.0, 1.0), 0.001); + + EXPECT_NE(absl::LogUniform(gen, 0, 1000000, 2), 2040); + EXPECT_CALL(absl::MockLogUniform(), Call(gen, 0, 1000000, 2)) + .WillOnce(Return(2040)); + EXPECT_EQ(absl::LogUniform(gen, 0, 1000000, 2), 2040); +} + +} // namespace diff --git a/absl/random/mocking_bit_gen.cc b/absl/random/mocking_bit_gen.cc new file mode 100644 index 00000000..73144528 --- /dev/null +++ b/absl/random/mocking_bit_gen.cc @@ -0,0 +1,28 @@ +// +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "absl/random/mocking_bit_gen.h" + +#include + +namespace absl { +MockingBitGen::~MockingBitGen() { + + for (const auto& del : deleters_) { + del(); + } +} + +} // namespace absl diff --git a/absl/random/mocking_bit_gen.h b/absl/random/mocking_bit_gen.h new file mode 100644 index 00000000..d1b524a9 --- /dev/null +++ b/absl/random/mocking_bit_gen.h @@ -0,0 +1,194 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ----------------------------------------------------------------------------- +// mocking_bit_gen.h +// ----------------------------------------------------------------------------- +// +// This file includes an `absl::MockingBitGen` class to use as a mock within the +// Googletest testing framework. Such a mock is useful to provide deterministic +// values as return values within (otherwise random) Abseil distribution +// functions. Such determinism within a mock is useful within testing frameworks +// to test otherwise indeterminate APIs. +// +// More information about the Googletest testing framework is available at +// https://github.com/google/googletest + +#ifndef ABSL_RANDOM_MOCKING_BIT_GEN_H_ +#define ABSL_RANDOM_MOCKING_BIT_GEN_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/container/flat_hash_map.h" +#include "absl/meta/type_traits.h" +#include "absl/random/distributions.h" +#include "absl/random/internal/distribution_caller.h" +#include "absl/random/internal/mocking_bit_gen_base.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/str_join.h" +#include "absl/types/span.h" +#include "absl/types/variant.h" +#include "absl/utility/utility.h" + +namespace absl { + +namespace random_internal { + +template +struct MockSingleOverload; + +} // namespace random_internal + +// MockingBitGen +// +// `absl::MockingBitGen` is a mock Uniform Random Bit Generator (URBG) class +// which can act in place of an `absl::BitGen` URBG within tests using the +// Googletest testing framework. +// +// Usage: +// +// Use an `absl::MockingBitGen` along with a mock distribution object (within +// mock_distributions.h) inside Googletest constructs such as ON_CALL(), +// EXPECT_TRUE(), etc. to produce deterministic results conforming to the +// distribution's API contract. +// +// Example: +// +// // Mock a call to an `absl::Bernoulli` distribution using Googletest +// absl::MockingBitGen bitgen; +// +// ON_CALL(absl::MockBernoulli(), Call(bitgen, 0.5)) +// .WillByDefault(testing::Return(true)); +// EXPECT_TRUE(absl::Bernoulli(bitgen, 0.5)); +// +// // Mock a call to an `absl::Uniform` distribution within Googletest +// absl::MockingBitGen bitgen; +// +// ON_CALL(absl::MockUniform(), Call(bitgen, testing::_, testing::_)) +// .WillByDefault([] (int low, int high) { +// return (low + high) / 2; +// }); +// +// EXPECT_EQ(absl::Uniform(gen, 0, 10), 5); +// EXPECT_EQ(absl::Uniform(gen, 30, 40), 35); +// +// At this time, only mock distributions supplied within the Abseil random +// library are officially supported. +// +class MockingBitGen : public absl::random_internal::MockingBitGenBase { + public: + MockingBitGen() {} + + ~MockingBitGen() override; + + private: + template + using MockFnType = + ::testing::MockFunction; + + // MockingBitGen::Register + // + // Register is the main extension point for + // extending the MockingBitGen framework. It provides a mechanism to install a + // mock expectation for the distribution `distr_t` onto the MockingBitGen + // context. + // + // The returned MockFunction<...> type can be used to setup additional + // distribution parameters of the expectation. + template + decltype(std::declval>().gmock_Call( + std::declval()...)) + Register(Ms&&... matchers) { + auto& mock = + mocks_[std::type_index(GetTypeId>())]; + + if (!mock.mock_fn) { + auto* mock_fn = new MockFnType; + mock.mock_fn = mock_fn; + mock.match_impl = &MatchImpl; + deleters_.emplace_back([mock_fn] { delete mock_fn; }); + } + + return static_cast*>(mock.mock_fn) + ->gmock_Call(std::forward(matchers)...); + } + + mutable std::vector> deleters_; + + using match_impl_fn = void (*)(void* mock_fn, void* t_erased_dist_args, + void* t_erased_result); + struct MockData { + void* mock_fn = nullptr; + match_impl_fn match_impl = nullptr; + }; + + mutable absl::flat_hash_map mocks_; + + template + static void MatchImpl(void* mock_fn, void* dist_args, void* result) { + using result_type = typename DistrT::result_type; + *static_cast(result) = absl::apply( + [mock_fn](Args... args) -> result_type { + return (*static_cast*>(mock_fn)) + .Call(std::move(args)...); + }, + *static_cast*>(dist_args)); + } + + // Looks for an appropriate mock - Returns the mocked result if one is found. + // Otherwise, returns a random value generated by the underlying URBG. + bool CallImpl(const std::type_info& key_type, void* dist_args, + void* result) override { + // Trigger a mock, if there exists one that matches `param`. + auto it = mocks_.find(std::type_index(key_type)); + if (it == mocks_.end()) return false; + auto* mock_data = static_cast(&it->second); + mock_data->match_impl(mock_data->mock_fn, dist_args, result); + return true; + } + + template + friend struct ::absl::random_internal::MockSingleOverload; + friend struct ::absl::random_internal::DistributionCaller< + absl::MockingBitGen>; +}; + +// ----------------------------------------------------------------------------- +// Implementation Details Only Below +// ----------------------------------------------------------------------------- + +namespace random_internal { + +template <> +struct DistributionCaller { + template + static typename DistrT::result_type Call(absl::MockingBitGen* gen, + Args&&... args) { + return gen->template Call(std::forward(args)...); + } +}; + +} // namespace random_internal +} // namespace absl + +#endif // ABSL_RANDOM_MOCKING_BIT_GEN_H_ diff --git a/absl/random/mocking_bit_gen_test.cc b/absl/random/mocking_bit_gen_test.cc new file mode 100644 index 00000000..dcf74fd6 --- /dev/null +++ b/absl/random/mocking_bit_gen_test.cc @@ -0,0 +1,347 @@ +// +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "absl/random/mocking_bit_gen.h" + +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest-spi.h" +#include "gtest/gtest.h" +#include "absl/random/bit_gen_ref.h" +#include "absl/random/mock_distributions.h" +#include "absl/random/random.h" + +namespace { +using ::testing::Ne; +using ::testing::Return; + +TEST(BasicMocking, AllDistributionsAreOverridable) { + absl::MockingBitGen gen; + + EXPECT_NE(absl::Uniform(gen, 1, 1000000), 20); + EXPECT_CALL(absl::MockUniform(), Call(gen, 1, 1000000)) + .WillOnce(Return(20)); + EXPECT_EQ(absl::Uniform(gen, 1, 1000000), 20); + + EXPECT_NE(absl::Uniform(gen, 0.0, 100.0), 5.0); + EXPECT_CALL(absl::MockUniform(), Call(gen, 0.0, 100.0)) + .WillOnce(Return(5.0)); + EXPECT_EQ(absl::Uniform(gen, 0.0, 100.0), 5.0); + + EXPECT_NE(absl::Exponential(gen, 1.0), 42); + EXPECT_CALL(absl::MockExponential(), Call(gen, 1.0)) + .WillOnce(Return(42)); + EXPECT_EQ(absl::Exponential(gen, 1.0), 42); + + EXPECT_NE(absl::Poisson(gen, 1.0), 500); + EXPECT_CALL(absl::MockPoisson(), Call(gen, 1.0)).WillOnce(Return(500)); + EXPECT_EQ(absl::Poisson(gen, 1.0), 500); + + EXPECT_NE(absl::Bernoulli(gen, 0.000001), true); + EXPECT_CALL(absl::MockBernoulli(), Call(gen, 0.000001)) + .WillOnce(Return(true)); + EXPECT_EQ(absl::Bernoulli(gen, 0.000001), true); + + EXPECT_NE(absl::Zipf(gen, 1000000, 2.0, 1.0), 1221); + EXPECT_CALL(absl::MockZipf(), Call(gen, 1000000, 2.0, 1.0)) + .WillOnce(Return(1221)); + EXPECT_EQ(absl::Zipf(gen, 1000000, 2.0, 1.0), 1221); + + EXPECT_NE(absl::Gaussian(gen, 0.0, 1.0), 0.001); + EXPECT_CALL(absl::MockGaussian(), Call(gen, 0.0, 1.0)) + .WillOnce(Return(0.001)); + EXPECT_EQ(absl::Gaussian(gen, 0.0, 1.0), 0.001); + + EXPECT_NE(absl::LogUniform(gen, 0, 1000000, 2), 2040); + EXPECT_CALL(absl::MockLogUniform(), Call(gen, 0, 1000000, 2)) + .WillOnce(Return(2040)); + EXPECT_EQ(absl::LogUniform(gen, 0, 1000000, 2), 2040); +} + +TEST(BasicMocking, OnDistribution) { + absl::MockingBitGen gen; + + EXPECT_NE(absl::Uniform(gen, 1, 1000000), 20); + ON_CALL(absl::MockUniform(), Call(gen, 1, 1000000)) + .WillByDefault(Return(20)); + EXPECT_EQ(absl::Uniform(gen, 1, 1000000), 20); + + EXPECT_NE(absl::Uniform(gen, 0.0, 100.0), 5.0); + ON_CALL(absl::MockUniform(), Call(gen, 0.0, 100.0)) + .WillByDefault(Return(5.0)); + EXPECT_EQ(absl::Uniform(gen, 0.0, 100.0), 5.0); + + EXPECT_NE(absl::Exponential(gen, 1.0), 42); + ON_CALL(absl::MockExponential(), Call(gen, 1.0)) + .WillByDefault(Return(42)); + EXPECT_EQ(absl::Exponential(gen, 1.0), 42); + + EXPECT_NE(absl::Poisson(gen, 1.0), 500); + ON_CALL(absl::MockPoisson(), Call(gen, 1.0)).WillByDefault(Return(500)); + EXPECT_EQ(absl::Poisson(gen, 1.0), 500); + + EXPECT_NE(absl::Bernoulli(gen, 0.000001), true); + ON_CALL(absl::MockBernoulli(), Call(gen, 0.000001)) + .WillByDefault(Return(true)); + EXPECT_EQ(absl::Bernoulli(gen, 0.000001), true); + + EXPECT_NE(absl::Zipf(gen, 1000000, 2.0, 1.0), 1221); + ON_CALL(absl::MockZipf(), Call(gen, 1000000, 2.0, 1.0)) + .WillByDefault(Return(1221)); + EXPECT_EQ(absl::Zipf(gen, 1000000, 2.0, 1.0), 1221); + + EXPECT_NE(absl::Gaussian(gen, 0.0, 1.0), 0.001); + ON_CALL(absl::MockGaussian(), Call(gen, 0.0, 1.0)) + .WillByDefault(Return(0.001)); + EXPECT_EQ(absl::Gaussian(gen, 0.0, 1.0), 0.001); + + EXPECT_NE(absl::LogUniform(gen, 0, 1000000, 2), 2040); + ON_CALL(absl::MockLogUniform(), Call(gen, 0, 1000000, 2)) + .WillByDefault(Return(2040)); + EXPECT_EQ(absl::LogUniform(gen, 0, 1000000, 2), 2040); +} + +TEST(BasicMocking, GMockMatchers) { + absl::MockingBitGen gen; + + EXPECT_NE(absl::Zipf(gen, 1000000, 2.0, 1.0), 1221); + ON_CALL(absl::MockZipf(), Call(gen, 1000000, 2.0, 1.0)) + .WillByDefault(Return(1221)); + EXPECT_EQ(absl::Zipf(gen, 1000000, 2.0, 1.0), 1221); +} + +TEST(BasicMocking, OverridesWithMultipleGMockExpectations) { + absl::MockingBitGen gen; + + EXPECT_CALL(absl::MockUniform(), Call(gen, 1, 10000)) + .WillOnce(Return(20)) + .WillOnce(Return(40)) + .WillOnce(Return(60)); + EXPECT_EQ(absl::Uniform(gen, 1, 10000), 20); + EXPECT_EQ(absl::Uniform(gen, 1, 10000), 40); + EXPECT_EQ(absl::Uniform(gen, 1, 10000), 60); +} + +TEST(BasicMocking, DefaultArgument) { + absl::MockingBitGen gen; + + ON_CALL(absl::MockExponential(), Call(gen, 1.0)) + .WillByDefault(Return(200)); + + EXPECT_EQ(absl::Exponential(gen), 200); + EXPECT_EQ(absl::Exponential(gen, 1.0), 200); +} + +TEST(BasicMocking, MultipleGenerators) { + auto get_value = [](absl::BitGenRef gen_ref) { + return absl::Uniform(gen_ref, 1, 1000000); + }; + absl::MockingBitGen unmocked_generator; + absl::MockingBitGen mocked_with_3; + absl::MockingBitGen mocked_with_11; + + EXPECT_CALL(absl::MockUniform(), Call(mocked_with_3, 1, 1000000)) + .WillOnce(Return(3)) + .WillRepeatedly(Return(17)); + EXPECT_CALL(absl::MockUniform(), Call(mocked_with_11, 1, 1000000)) + .WillOnce(Return(11)) + .WillRepeatedly(Return(17)); + + // Ensure that unmocked generator generates neither value. + int unmocked_value = get_value(unmocked_generator); + EXPECT_NE(unmocked_value, 3); + EXPECT_NE(unmocked_value, 11); + // Mocked generators should generate their mocked values. + EXPECT_EQ(get_value(mocked_with_3), 3); + EXPECT_EQ(get_value(mocked_with_11), 11); + // Ensure that the mocks have expired. + EXPECT_NE(get_value(mocked_with_3), 3); + EXPECT_NE(get_value(mocked_with_11), 11); +} + +TEST(BasicMocking, MocksNotTrigeredForIncorrectTypes) { + absl::MockingBitGen gen; + EXPECT_CALL(absl::MockUniform(), Call(gen)).WillOnce(Return(42)); + + EXPECT_NE(absl::Uniform(gen), 42); // Not mocked + EXPECT_EQ(absl::Uniform(gen), 42); // Mock triggered +} + +TEST(BasicMocking, FailsOnUnsatisfiedMocks) { + EXPECT_NONFATAL_FAILURE( + []() { + absl::MockingBitGen gen; + EXPECT_CALL(absl::MockExponential(), Call(gen, 1.0)) + .WillOnce(Return(3.0)); + // Does not call absl::Exponential(). + }(), + "unsatisfied and active"); +} + +TEST(OnUniform, RespectsUniformIntervalSemantics) { + absl::MockingBitGen gen; + + EXPECT_CALL(absl::MockUniform(), + Call(absl::IntervalClosed, gen, 1, 1000000)) + .WillOnce(Return(301)); + EXPECT_NE(absl::Uniform(gen, 1, 1000000), 301); // Not mocked + EXPECT_EQ(absl::Uniform(absl::IntervalClosed, gen, 1, 1000000), 301); +} + +TEST(OnUniform, RespectsNoArgUnsignedShorthand) { + absl::MockingBitGen gen; + EXPECT_CALL(absl::MockUniform(), Call(gen)).WillOnce(Return(42)); + EXPECT_EQ(absl::Uniform(gen), 42); +} + +TEST(RepeatedlyModifier, ForceSnakeEyesForManyDice) { + auto roll_some_dice = [](absl::BitGenRef gen_ref) { + std::vector results(16); + for (auto& r : results) { + r = absl::Uniform(absl::IntervalClosed, gen_ref, 1, 6); + } + return results; + }; + std::vector results; + absl::MockingBitGen gen; + + // Without any mocked calls, not all dice roll a "6". + results = roll_some_dice(gen); + EXPECT_LT(std::accumulate(std::begin(results), std::end(results), 0), + results.size() * 6); + + // Verify that we can force all "6"-rolls, with mocking. + ON_CALL(absl::MockUniform(), Call(absl::IntervalClosed, gen, 1, 6)) + .WillByDefault(Return(6)); + results = roll_some_dice(gen); + EXPECT_EQ(std::accumulate(std::begin(results), std::end(results), 0), + results.size() * 6); +} + +TEST(WillOnce, DistinctCounters) { + absl::MockingBitGen gen; + EXPECT_CALL(absl::MockUniform(), Call(gen, 1, 1000000)) + .Times(3) + .WillRepeatedly(Return(0)); + EXPECT_CALL(absl::MockUniform(), Call(gen, 1000001, 2000000)) + .Times(3) + .WillRepeatedly(Return(1)); + EXPECT_EQ(absl::Uniform(gen, 1000001, 2000000), 1); + EXPECT_EQ(absl::Uniform(gen, 1, 1000000), 0); + EXPECT_EQ(absl::Uniform(gen, 1000001, 2000000), 1); + EXPECT_EQ(absl::Uniform(gen, 1, 1000000), 0); + EXPECT_EQ(absl::Uniform(gen, 1000001, 2000000), 1); + EXPECT_EQ(absl::Uniform(gen, 1, 1000000), 0); +} + +TEST(TimesModifier, ModifierSaturatesAndExpires) { + EXPECT_NONFATAL_FAILURE( + []() { + absl::MockingBitGen gen; + EXPECT_CALL(absl::MockUniform(), Call(gen, 1, 1000000)) + .Times(3) + .WillRepeatedly(Return(15)) + .RetiresOnSaturation(); + + EXPECT_EQ(absl::Uniform(gen, 1, 1000000), 15); + EXPECT_EQ(absl::Uniform(gen, 1, 1000000), 15); + EXPECT_EQ(absl::Uniform(gen, 1, 1000000), 15); + // Times(3) has expired - Should get a different value now. + + EXPECT_NE(absl::Uniform(gen, 1, 1000000), 15); + }(), + ""); +} + +TEST(TimesModifier, Times0) { + absl::MockingBitGen gen; + EXPECT_CALL(absl::MockBernoulli(), Call(gen, 0.0)).Times(0); + EXPECT_CALL(absl::MockPoisson(), Call(gen, 1.0)).Times(0); +} + +TEST(AnythingMatcher, MatchesAnyArgument) { + using testing::_; + + { + absl::MockingBitGen gen; + ON_CALL(absl::MockUniform(), Call(absl::IntervalClosed, gen, _, 1000)) + .WillByDefault(Return(11)); + ON_CALL(absl::MockUniform(), + Call(absl::IntervalClosed, gen, _, Ne(1000))) + .WillByDefault(Return(99)); + + EXPECT_EQ(absl::Uniform(absl::IntervalClosed, gen, 10, 1000000), 99); + EXPECT_EQ(absl::Uniform(absl::IntervalClosed, gen, 10, 1000), 11); + } + + { + absl::MockingBitGen gen; + ON_CALL(absl::MockUniform(), Call(gen, 1, _)) + .WillByDefault(Return(25)); + ON_CALL(absl::MockUniform(), Call(gen, Ne(1), _)) + .WillByDefault(Return(99)); + EXPECT_EQ(absl::Uniform(gen, 3, 1000000), 99); + EXPECT_EQ(absl::Uniform(gen, 1, 1000000), 25); + } + + { + absl::MockingBitGen gen; + ON_CALL(absl::MockUniform(), Call(gen, _, _)) + .WillByDefault(Return(145)); + EXPECT_EQ(absl::Uniform(gen, 1, 1000), 145); + EXPECT_EQ(absl::Uniform(gen, 10, 1000), 145); + EXPECT_EQ(absl::Uniform(gen, 100, 1000), 145); + } +} + +TEST(AnythingMatcher, WithWillByDefault) { + using testing::_; + absl::MockingBitGen gen; + std::vector values = {11, 22, 33, 44, 55, 66, 77, 88, 99, 1010}; + + ON_CALL(absl::MockUniform(), Call(gen, 0, _)) + .WillByDefault(Return(0)); + for (int i = 0; i < 100; i++) { + auto& elem = values[absl::Uniform(gen, 0u, values.size())]; + EXPECT_EQ(elem, 11); + } +} + +TEST(BasicMocking, WillByDefaultWithArgs) { + using testing::_; + + absl::MockingBitGen gen; + ON_CALL(absl::MockPoisson(), Call(gen, _)) + .WillByDefault( + [](double lambda) { return static_cast(lambda * 10); }); + EXPECT_EQ(absl::Poisson(gen, 1.7), 17); + EXPECT_EQ(absl::Poisson(gen, 0.03), 0); +} + +TEST(MockingBitGen, InSequenceSucceedsInOrder) { + absl::MockingBitGen gen; + + testing::InSequence seq; + + EXPECT_CALL(absl::MockPoisson(), Call(gen, 1.0)).WillOnce(Return(3)); + EXPECT_CALL(absl::MockPoisson(), Call(gen, 2.0)).WillOnce(Return(4)); + + EXPECT_EQ(absl::Poisson(gen, 1.0), 3); + EXPECT_EQ(absl::Poisson(gen, 2.0), 4); +} + +} // namespace -- cgit v1.2.3 From 12bc53e0318d80569270a5b26ccbc62b52022b89 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 12 Dec 2019 10:36:03 -0800 Subject: Export of internal Abseil changes -- c99f979ad34f155fbeeea69b88bdc7458d89a21c by Derek Mauro : Remove a floating point division by zero test. This isn't testing behavior related to the library, and MSVC warns about it in opt mode. PiperOrigin-RevId: 285220804 -- 68b015491f0dbf1ab547994673281abd1f34cd4b by Gennadiy Rozental : This CL introduces following changes to the class FlagImpl: * We eliminate the CommandLineFlagLocks struct. Instead callback guard and callback function are combined into a single CallbackData struct, while primary data lock is stored separately. * CallbackData member of class FlagImpl is initially set to be nullptr and is only allocated and initialized when a flag's callback is being set. For most flags we do not pay for the extra space and extra absl::Mutex now. * Primary data guard is stored in data_guard_ data member. This is a properly aligned character buffer of necessary size. During initialization of the flag we construct absl::Mutex in this space using placement new call. * We now avoid extra value copy after successful attempt to parse value out of string. Instead we swap flag's current value with tentative value we just produced. PiperOrigin-RevId: 285132636 -- ed45d118fb818969eb13094cf7827c885dfc562c by Tom Manshreck : Change null-term* (and nul-term*) to NUL-term* in comments PiperOrigin-RevId: 285036610 -- 729619017944db895ce8d6d29c1995aa2e5628a5 by Derek Mauro : Use the Posix implementation of thread identity on MinGW. Some versions of MinGW suffer from thread_local bugs. PiperOrigin-RevId: 285022920 -- 39a25493503c76885bc3254c28f66a251c5b5bb0 by Greg Falcon : Implementation detail change. Add further ABSL_NAMESPACE_BEGIN and _END annotation macros to files in Abseil. PiperOrigin-RevId: 285012012 GitOrigin-RevId: c99f979ad34f155fbeeea69b88bdc7458d89a21c Change-Id: I4c85d3704e45d11a9ac50d562f39640a6adbedc1 --- absl/algorithm/BUILD.bazel | 1 + absl/algorithm/CMakeLists.txt | 2 + absl/algorithm/algorithm.h | 4 + absl/algorithm/container.h | 2 + absl/base/internal/raw_logging.h | 2 +- absl/base/internal/thread_identity.h | 2 +- absl/container/BUILD.bazel | 8 ++ absl/container/CMakeLists.txt | 8 ++ absl/container/btree_map.h | 2 + absl/container/btree_set.h | 2 + absl/container/btree_test.cc | 2 + absl/container/btree_test.h | 2 + absl/container/fixed_array.h | 2 + .../container/fixed_array_exception_safety_test.cc | 2 + absl/container/flat_hash_map.h | 2 + absl/container/flat_hash_map_test.cc | 2 + absl/container/flat_hash_set.h | 2 + absl/container/flat_hash_set_test.cc | 2 + absl/container/inlined_vector.h | 2 + absl/container/internal/btree.h | 2 + absl/container/internal/btree_container.h | 2 + absl/container/internal/common.h | 2 + absl/container/internal/compressed_tuple.h | 2 + absl/container/internal/compressed_tuple_test.cc | 2 + absl/container/internal/container_memory.h | 2 + absl/container/internal/container_memory_test.cc | 2 + absl/container/internal/counting_allocator.h | 4 + absl/container/internal/hash_function_defaults.h | 2 + .../internal/hash_function_defaults_test.cc | 4 + absl/container/internal/hash_generator_testing.cc | 2 + absl/container/internal/hash_generator_testing.h | 2 + absl/container/internal/hash_policy_testing.h | 2 + .../container/internal/hash_policy_testing_test.cc | 2 + absl/container/internal/hash_policy_traits.h | 2 + absl/container/internal/hash_policy_traits_test.cc | 2 + absl/container/internal/hashtable_debug.h | 2 + absl/container/internal/hashtable_debug_hooks.h | 4 + absl/container/internal/hashtablez_sampler.cc | 2 + absl/container/internal/hashtablez_sampler.h | 2 + .../hashtablez_sampler_force_weak_definition.cc | 2 + absl/container/internal/hashtablez_sampler_test.cc | 2 + absl/container/internal/inlined_vector.h | 2 + absl/container/internal/layout.h | 2 + absl/container/internal/layout_test.cc | 2 + absl/container/internal/node_hash_policy.h | 4 + absl/container/internal/node_hash_policy_test.cc | 2 + absl/container/internal/raw_hash_map.h | 2 + absl/container/internal/raw_hash_set.cc | 2 + absl/container/internal/raw_hash_set.h | 2 + .../internal/raw_hash_set_allocator_test.cc | 2 + absl/container/internal/raw_hash_set_test.cc | 2 + absl/container/internal/test_instance_tracker.cc | 2 + absl/container/internal/test_instance_tracker.h | 2 + absl/container/internal/tracked.h | 5 + .../internal/unordered_map_constructor_test.h | 2 + .../container/internal/unordered_map_lookup_test.h | 2 + .../internal/unordered_map_members_test.h | 2 + .../internal/unordered_map_modifiers_test.h | 2 + absl/container/internal/unordered_map_test.cc | 2 + .../internal/unordered_set_constructor_test.h | 2 + .../container/internal/unordered_set_lookup_test.h | 2 + .../internal/unordered_set_members_test.h | 2 + .../internal/unordered_set_modifiers_test.h | 2 + absl/container/internal/unordered_set_test.cc | 2 + absl/container/node_hash_map.h | 2 + absl/container/node_hash_map_test.cc | 2 + absl/container/node_hash_set.h | 2 + absl/container/node_hash_set_test.cc | 2 + absl/debugging/BUILD.bazel | 18 +++- absl/debugging/CMakeLists.txt | 6 ++ absl/debugging/failure_signal_handler.cc | 2 + absl/debugging/failure_signal_handler.h | 4 + absl/debugging/internal/address_is_readable.cc | 4 + absl/debugging/internal/address_is_readable.h | 4 + absl/debugging/internal/demangle.cc | 2 + absl/debugging/internal/demangle.h | 4 + absl/debugging/internal/demangle_test.cc | 2 + absl/debugging/internal/elf_mem_image.cc | 2 + absl/debugging/internal/elf_mem_image.h | 4 + absl/debugging/internal/examine_stack.cc | 2 + absl/debugging/internal/examine_stack.h | 4 + absl/debugging/internal/stack_consumption.cc | 2 + absl/debugging/internal/stack_consumption.h | 4 + absl/debugging/internal/stack_consumption_test.cc | 2 + absl/debugging/internal/stacktrace_aarch64-inl.inc | 2 + absl/debugging/internal/stacktrace_arm-inl.inc | 2 + absl/debugging/internal/stacktrace_generic-inl.inc | 2 + absl/debugging/internal/stacktrace_powerpc-inl.inc | 2 + .../internal/stacktrace_unimplemented-inl.inc | 2 + absl/debugging/internal/stacktrace_win32-inl.inc | 2 + absl/debugging/internal/stacktrace_x86-inl.inc | 2 + absl/debugging/internal/symbolize.h | 6 ++ absl/debugging/internal/vdso_support.cc | 2 + absl/debugging/internal/vdso_support.h | 2 + absl/debugging/leak_check.cc | 4 + absl/debugging/leak_check.h | 4 + absl/debugging/stacktrace.cc | 2 + absl/debugging/stacktrace.h | 4 + absl/debugging/symbolize.h | 2 + absl/debugging/symbolize_elf.inc | 2 + absl/debugging/symbolize_unimplemented.inc | 2 + absl/debugging/symbolize_win32.inc | 2 + absl/flags/declare.h | 2 + absl/flags/flag.cc | 2 + absl/flags/flag.h | 2 + absl/flags/flag_test_defs.cc | 2 + absl/flags/internal/commandlineflag.cc | 2 + absl/flags/internal/commandlineflag.h | 4 +- absl/flags/internal/flag.cc | 113 ++++++++++++++------- absl/flags/internal/flag.h | 54 +++++----- absl/flags/internal/parse.h | 2 + absl/flags/internal/path_util.h | 2 + absl/flags/internal/program_name.cc | 2 + absl/flags/internal/program_name.h | 2 + absl/flags/internal/registry.cc | 4 +- absl/flags/internal/registry.h | 2 + absl/flags/internal/type_erased.cc | 2 + absl/flags/internal/type_erased.h | 2 + absl/flags/internal/usage.cc | 2 + absl/flags/internal/usage.h | 2 + absl/flags/marshalling.cc | 2 + absl/flags/marshalling.h | 2 + absl/flags/parse.cc | 4 + absl/flags/parse.h | 2 + absl/flags/usage.cc | 2 + absl/flags/usage.h | 2 + absl/flags/usage_config.cc | 2 + absl/flags/usage_config.h | 2 + absl/functional/function_ref.h | 2 + absl/functional/function_ref_benchmark.cc | 2 + absl/functional/function_ref_test.cc | 2 + absl/functional/internal/function_ref.h | 2 + absl/hash/hash.h | 2 + absl/hash/hash_test.cc | 2 + absl/hash/hash_testing.h | 2 + absl/hash/internal/city.cc | 2 + absl/hash/internal/city.h | 5 + absl/hash/internal/city_test.cc | 2 + absl/hash/internal/hash.cc | 2 + absl/hash/internal/hash.h | 2 + absl/hash/internal/spy_hash_state.h | 2 + absl/memory/memory.h | 2 + absl/memory/memory_exception_safety_test.cc | 2 + absl/meta/type_traits.h | 2 + absl/numeric/int128.cc | 2 + absl/numeric/int128.h | 6 ++ absl/random/CMakeLists.txt | 14 +++ absl/random/bernoulli_distribution.h | 2 + absl/random/beta_distribution.h | 2 + absl/random/bit_gen_ref.h | 2 + absl/random/bit_gen_ref_test.cc | 2 + absl/random/discrete_distribution.cc | 2 + absl/random/discrete_distribution.h | 2 + absl/random/distribution_format_traits.h | 2 + absl/random/distributions.h | 2 + absl/random/exponential_distribution.h | 2 + absl/random/gaussian_distribution.cc | 2 + absl/random/gaussian_distribution.h | 2 + absl/random/internal/BUILD.bazel | 9 ++ absl/random/internal/chi_square.cc | 2 + absl/random/internal/chi_square.h | 4 + absl/random/internal/distribution_caller.h | 4 + absl/random/internal/distribution_test_util.cc | 2 + absl/random/internal/distribution_test_util.h | 2 + absl/random/internal/distributions.h | 2 + absl/random/internal/explicit_seed_seq.h | 4 + absl/random/internal/fast_uniform_bits.h | 4 + absl/random/internal/fast_uniform_bits_test.cc | 2 + absl/random/internal/fastmath.h | 2 + .../internal/gaussian_distribution_gentables.cc | 2 + absl/random/internal/generate_real.h | 2 + absl/random/internal/iostream_state_saver.h | 2 + absl/random/internal/mock_overload_set.h | 2 + absl/random/internal/mocking_bit_gen_base.h | 2 + absl/random/internal/nanobenchmark.cc | 2 + absl/random/internal/nanobenchmark.h | 4 + absl/random/internal/nanobenchmark_test.cc | 2 + absl/random/internal/nonsecure_base.h | 2 + absl/random/internal/pcg_engine.h | 2 + absl/random/internal/pool_urbg.cc | 2 + absl/random/internal/pool_urbg.h | 2 + absl/random/internal/randen.cc | 2 + absl/random/internal/randen.h | 2 + absl/random/internal/randen_detect.cc | 2 + absl/random/internal/randen_detect.h | 4 + absl/random/internal/randen_engine.h | 2 + absl/random/internal/randen_hwaes.cc | 4 + absl/random/internal/randen_hwaes.h | 4 + absl/random/internal/randen_slow.cc | 2 + absl/random/internal/randen_slow.h | 4 + absl/random/internal/randen_traits.h | 4 + absl/random/internal/salted_seed_seq.h | 2 + absl/random/internal/seed_material.cc | 2 + absl/random/internal/seed_material.h | 2 + absl/random/internal/sequence_urbg.h | 4 + absl/random/internal/traits.h | 2 + absl/random/internal/uniform_helper.h | 2 + absl/random/internal/wide_multiply.h | 2 + absl/random/log_uniform_int_distribution.h | 2 + absl/random/mock_distributions.h | 2 + absl/random/mocking_bit_gen.cc | 2 + absl/random/mocking_bit_gen.h | 2 + absl/random/poisson_distribution.h | 2 + absl/random/random.h | 2 + absl/random/seed_gen_exception.cc | 2 + absl/random/seed_gen_exception.h | 4 + absl/random/seed_sequences.cc | 2 + absl/random/seed_sequences.h | 2 + absl/random/uniform_int_distribution.h | 2 + absl/random/uniform_real_distribution.h | 2 + absl/random/zipf_distribution.h | 2 + absl/strings/BUILD.bazel | 5 + absl/strings/CMakeLists.txt | 6 ++ absl/strings/ascii.cc | 2 + absl/strings/ascii.h | 2 + absl/strings/charconv.cc | 2 + absl/strings/charconv.h | 4 + absl/strings/escaping.cc | 2 + absl/strings/escaping.h | 2 + absl/strings/internal/char_map.h | 2 + absl/strings/internal/charconv_bigint.cc | 2 + absl/strings/internal/charconv_bigint.h | 2 + absl/strings/internal/charconv_bigint_test.cc | 2 + absl/strings/internal/charconv_parse.cc | 2 + absl/strings/internal/charconv_parse.h | 3 + absl/strings/internal/escaping_test_common.h | 2 + absl/strings/internal/memutil.cc | 2 + absl/strings/internal/memutil.h | 2 + absl/strings/internal/numbers_test_common.h | 4 + absl/strings/internal/ostringstream.cc | 2 + absl/strings/internal/ostringstream.h | 2 + absl/strings/internal/pow10_helper.cc | 2 + absl/strings/internal/pow10_helper.h | 4 + absl/strings/internal/pow10_helper_test.cc | 2 + absl/strings/internal/resize_uninitialized.h | 2 + absl/strings/internal/stl_type_traits.h | 2 + absl/strings/internal/str_format/arg.cc | 2 + absl/strings/internal/str_format/arg.h | 2 + absl/strings/internal/str_format/arg_test.cc | 2 + absl/strings/internal/str_format/bind.cc | 2 + absl/strings/internal/str_format/bind.h | 2 + absl/strings/internal/str_format/bind_test.cc | 2 + absl/strings/internal/str_format/checker.h | 2 + absl/strings/internal/str_format/checker_test.cc | 2 + absl/strings/internal/str_format/convert_test.cc | 2 + absl/strings/internal/str_format/extension.cc | 2 + absl/strings/internal/str_format/extension.h | 2 + .../internal/str_format/float_conversion.cc | 2 + .../strings/internal/str_format/float_conversion.h | 2 + absl/strings/internal/str_format/output.cc | 2 + absl/strings/internal/str_format/output.h | 2 + absl/strings/internal/str_format/output_test.cc | 2 + absl/strings/internal/str_format/parser.cc | 2 + absl/strings/internal/str_format/parser.h | 2 + absl/strings/internal/str_format/parser_test.cc | 2 + absl/strings/internal/str_join_internal.h | 2 + absl/strings/internal/str_split_internal.h | 2 + absl/strings/internal/utf8.cc | 2 + absl/strings/internal/utf8.h | 4 + absl/strings/match.cc | 2 + absl/strings/match.h | 4 +- absl/strings/numbers.cc | 2 + absl/strings/numbers.h | 4 + absl/strings/str_cat.cc | 2 + absl/strings/str_cat.h | 2 + absl/strings/str_format.h | 2 + absl/strings/str_format_test.cc | 2 + absl/strings/str_join.h | 2 + absl/strings/str_replace.cc | 2 + absl/strings/str_replace.h | 2 + absl/strings/str_split.cc | 2 + absl/strings/str_split.h | 2 + absl/strings/string_view.cc | 2 + absl/strings/string_view.h | 20 ++-- absl/strings/strip.h | 2 + absl/strings/substitute.cc | 2 + absl/strings/substitute.h | 2 + absl/synchronization/BUILD.bazel | 1 + absl/synchronization/CMakeLists.txt | 1 + absl/synchronization/barrier.cc | 2 + absl/synchronization/barrier.h | 2 + absl/synchronization/blocking_counter.cc | 2 + absl/synchronization/blocking_counter.h | 2 + absl/synchronization/blocking_counter_test.cc | 2 + .../internal/create_thread_identity.cc | 2 + .../internal/create_thread_identity.h | 2 + absl/synchronization/internal/graphcycles.cc | 2 + absl/synchronization/internal/graphcycles.h | 4 + absl/synchronization/internal/graphcycles_test.cc | 2 + absl/synchronization/internal/kernel_timeout.h | 2 + absl/synchronization/internal/mutex_nonprod.cc | 2 + absl/synchronization/internal/mutex_nonprod.inc | 2 + absl/synchronization/internal/per_thread_sem.cc | 2 + absl/synchronization/internal/per_thread_sem.h | 2 + .../internal/per_thread_sem_test.cc | 2 + absl/synchronization/internal/thread_pool.h | 2 + absl/synchronization/internal/waiter.cc | 2 + absl/synchronization/internal/waiter.h | 2 + absl/synchronization/mutex.cc | 4 +- absl/synchronization/mutex.h | 4 +- absl/synchronization/notification.cc | 2 + absl/synchronization/notification.h | 2 + absl/synchronization/notification_test.cc | 2 + absl/time/civil_time.cc | 2 + absl/time/civil_time.h | 2 + absl/time/clock.cc | 8 ++ absl/time/clock.h | 2 + absl/time/duration.cc | 2 + absl/time/duration_test.cc | 5 - absl/time/format.cc | 2 + absl/time/internal/get_current_time_chrono.inc | 2 + absl/time/internal/get_current_time_posix.inc | 2 + absl/time/internal/test_util.cc | 4 + absl/time/internal/test_util.h | 2 + absl/time/time.cc | 2 + absl/time/time.h | 2 + absl/types/any.h | 4 + absl/types/bad_any_cast.cc | 2 + absl/types/bad_any_cast.h | 4 + absl/types/bad_optional_access.cc | 2 + absl/types/bad_optional_access.h | 4 + absl/types/bad_variant_access.cc | 2 + absl/types/bad_variant_access.h | 4 + absl/types/compare.h | 2 + absl/types/compare_test.cc | 2 + absl/types/internal/conformance_aliases.h | 2 + absl/types/internal/conformance_archetype.h | 2 + absl/types/internal/conformance_profile.h | 2 + absl/types/internal/optional.h | 2 + absl/types/internal/span.h | 2 + absl/types/internal/variant.h | 2 + absl/types/optional.h | 4 + absl/types/optional_exception_safety_test.cc | 2 + absl/types/span.h | 2 + absl/types/variant.h | 6 ++ absl/types/variant_benchmark.cc | 2 + absl/types/variant_exception_safety_test.cc | 2 + absl/types/variant_test.cc | 2 + absl/utility/utility.h | 2 + 339 files changed, 949 insertions(+), 83 deletions(-) (limited to 'absl/random/CMakeLists.txt') diff --git a/absl/algorithm/BUILD.bazel b/absl/algorithm/BUILD.bazel index 2ee8c09e..6a96420b 100644 --- a/absl/algorithm/BUILD.bazel +++ b/absl/algorithm/BUILD.bazel @@ -31,6 +31,7 @@ cc_library( hdrs = ["algorithm.h"], copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, + deps = ["//absl/base:config"], ) cc_test( diff --git a/absl/algorithm/CMakeLists.txt b/absl/algorithm/CMakeLists.txt index 9fbe36f6..56cd0fb8 100644 --- a/absl/algorithm/CMakeLists.txt +++ b/absl/algorithm/CMakeLists.txt @@ -21,6 +21,8 @@ absl_cc_library( "algorithm.h" COPTS ${ABSL_DEFAULT_COPTS} + DEPS + absl::config PUBLIC ) diff --git a/absl/algorithm/algorithm.h b/absl/algorithm/algorithm.h index 771228a0..e9b47338 100644 --- a/absl/algorithm/algorithm.h +++ b/absl/algorithm/algorithm.h @@ -26,7 +26,10 @@ #include #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace algorithm_internal { @@ -150,6 +153,7 @@ ForwardIterator rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator>()); } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_ALGORITHM_ALGORITHM_H_ diff --git a/absl/algorithm/container.h b/absl/algorithm/container.h index 5dae9fd6..d72532de 100644 --- a/absl/algorithm/container.h +++ b/absl/algorithm/container.h @@ -55,6 +55,7 @@ #include "absl/meta/type_traits.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_algorithm_internal { // NOTE: it is important to defer to ADL lookup for building with C++ modules, @@ -1720,6 +1721,7 @@ OutputIt c_partial_sum(const InputSequence& input, OutputIt output_first, output_first, std::forward(op)); } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_ALGORITHM_CONTAINER_H_ diff --git a/absl/base/internal/raw_logging.h b/absl/base/internal/raw_logging.h index 12145c48..cff45058 100644 --- a/absl/base/internal/raw_logging.h +++ b/absl/base/internal/raw_logging.h @@ -154,7 +154,7 @@ using LogPrefixHook = bool (*)(absl::LogSeverity severity, const char* file, // // 'file' and 'line' are the file and line number where the ABSL_RAW_LOG macro // was located. -// The null-terminated logged message lives in the buffer between 'buf_start' +// The NUL-terminated logged message lives in the buffer between 'buf_start' // and 'buf_end'. 'prefix_end' points to the first non-prefix character of the // buffer (as written by the LogPrefixHook.) using AbortHook = void (*)(const char* file, int line, const char* buf_start, diff --git a/absl/base/internal/thread_identity.h b/absl/base/internal/thread_identity.h index a1aa45ff..5dfd0715 100644 --- a/absl/base/internal/thread_identity.h +++ b/absl/base/internal/thread_identity.h @@ -209,7 +209,7 @@ void ClearCurrentThreadIdentity(); #error ABSL_THREAD_IDENTITY_MODE cannot be direcly set #elif defined(ABSL_FORCE_THREAD_IDENTITY_MODE) #define ABSL_THREAD_IDENTITY_MODE ABSL_FORCE_THREAD_IDENTITY_MODE -#elif defined(_WIN32) +#elif defined(_WIN32) && !defined(__MINGW32__) #define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_CPP11 #elif ABSL_PER_THREAD_TLS && defined(__GOOGLE_GRTE_VERSION__) && \ (__GOOGLE_GRTE_VERSION__ >= 20140228L) diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index e60979b2..1f7abe07 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -141,6 +141,7 @@ cc_library( copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, visibility = ["//visibility:private"], + deps = ["//absl/base:config"], ) cc_test( @@ -478,6 +479,9 @@ cc_library( hdrs = ["internal/hashtable_debug_hooks.h"], copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + "//absl/base:config", + ], ) cc_library( @@ -521,6 +525,7 @@ cc_library( hdrs = ["internal/node_hash_policy.h"], copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, + deps = ["//absl/base:config"], ) cc_test( @@ -662,6 +667,9 @@ cc_library( hdrs = ["internal/tracked.h"], copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + "//absl/base:config", + ], ) cc_library( diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index aa33659b..a931f334 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt @@ -204,6 +204,8 @@ absl_cc_library( "internal/counting_allocator.h" COPTS ${ABSL_DEFAULT_COPTS} + DEPS + absl::config ) absl_cc_test( @@ -574,6 +576,8 @@ absl_cc_library( "internal/hashtable_debug_hooks.h" COPTS ${ABSL_DEFAULT_COPTS} + DEPS + absl::config PUBLIC ) @@ -593,6 +597,8 @@ absl_cc_library( "internal/node_hash_policy.h" COPTS ${ABSL_DEFAULT_COPTS} + DEPS + absl::config PUBLIC ) @@ -735,6 +741,8 @@ absl_cc_library( "internal/tracked.h" COPTS ${ABSL_TEST_COPTS} + DEPS + absl::config TESTONLY ) diff --git a/absl/container/btree_map.h b/absl/container/btree_map.h index 9f35f639..470e3197 100644 --- a/absl/container/btree_map.h +++ b/absl/container/btree_map.h @@ -51,6 +51,7 @@ #include "absl/container/internal/btree_container.h" // IWYU pragma: export namespace absl { +ABSL_NAMESPACE_BEGIN // absl::btree_map<> // @@ -700,6 +701,7 @@ void swap(btree_multimap &x, btree_multimap &y) { return x.swap(y); } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_BTREE_MAP_H_ diff --git a/absl/container/btree_set.h b/absl/container/btree_set.h index 6e47b4aa..2a4d0ace 100644 --- a/absl/container/btree_set.h +++ b/absl/container/btree_set.h @@ -51,6 +51,7 @@ #include "absl/container/internal/btree_container.h" // IWYU pragma: export namespace absl { +ABSL_NAMESPACE_BEGIN // absl::btree_set<> // @@ -648,6 +649,7 @@ void swap(btree_multiset &x, btree_multiset &y) { return x.swap(y); } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_BTREE_SET_H_ diff --git a/absl/container/btree_test.cc b/absl/container/btree_test.cc index ea73f032..f8aadd62 100644 --- a/absl/container/btree_test.cc +++ b/absl/container/btree_test.cc @@ -42,6 +42,7 @@ ABSL_FLAG(int, test_values, 10000, "The number of values to use for tests"); namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace { @@ -2304,4 +2305,5 @@ TEST(Btree, EmptyTree) { } // namespace } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/btree_test.h b/absl/container/btree_test.h index 5ecf43ce..218ba41d 100644 --- a/absl/container/btree_test.h +++ b/absl/container/btree_test.h @@ -28,6 +28,7 @@ #include "absl/time/time.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { // Like remove_const but propagates the removal through std::pair. @@ -148,6 +149,7 @@ std::vector GenerateValuesWithSeed(int n, int maxval, int seed) { } } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_BTREE_TEST_H_ diff --git a/absl/container/fixed_array.h b/absl/container/fixed_array.h index 70e94ad5..a9ce99ba 100644 --- a/absl/container/fixed_array.h +++ b/absl/container/fixed_array.h @@ -50,6 +50,7 @@ #include "absl/memory/memory.h" namespace absl { +ABSL_NAMESPACE_BEGIN constexpr static auto kFixedArrayUseDefault = static_cast(-1); @@ -508,6 +509,7 @@ void FixedArray::NonEmptyInlinedStorage::AnnotateDestruct( #endif // ADDRESS_SANITIZER static_cast(n); // Mark used when not in asan mode } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_FIXED_ARRAY_H_ diff --git a/absl/container/fixed_array_exception_safety_test.cc b/absl/container/fixed_array_exception_safety_test.cc index 5ebeac05..a5bb009d 100644 --- a/absl/container/fixed_array_exception_safety_test.cc +++ b/absl/container/fixed_array_exception_safety_test.cc @@ -23,6 +23,7 @@ #include "absl/base/internal/exception_safety_testing.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace { @@ -195,6 +196,7 @@ TEST(FixedArrayExceptionSafety, FillWithAlloc) { } // namespace +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HAVE_EXCEPTIONS diff --git a/absl/container/flat_hash_map.h b/absl/container/flat_hash_map.h index 283f2439..fb570cd4 100644 --- a/absl/container/flat_hash_map.h +++ b/absl/container/flat_hash_map.h @@ -42,6 +42,7 @@ #include "absl/memory/memory.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { template struct FlatHashMapPolicy; @@ -584,6 +585,7 @@ struct IsUnorderedContainer< } // namespace container_algorithm_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_FLAT_HASH_MAP_H_ diff --git a/absl/container/flat_hash_map_test.cc b/absl/container/flat_hash_map_test.cc index 02d1f879..dae8e003 100644 --- a/absl/container/flat_hash_map_test.cc +++ b/absl/container/flat_hash_map_test.cc @@ -24,6 +24,7 @@ #include "absl/types/any.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace { using ::absl::container_internal::hash_internal::Enum; @@ -251,4 +252,5 @@ TEST(FlatHashMap, Any) { } // namespace } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/flat_hash_set.h b/absl/container/flat_hash_set.h index 2a51c341..930107ea 100644 --- a/absl/container/flat_hash_set.h +++ b/absl/container/flat_hash_set.h @@ -40,6 +40,7 @@ #include "absl/memory/memory.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { template struct FlatHashSetPolicy; @@ -488,6 +489,7 @@ struct IsUnorderedContainer> } // namespace container_algorithm_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_FLAT_HASH_SET_H_ diff --git a/absl/container/flat_hash_set_test.cc b/absl/container/flat_hash_set_test.cc index b55be59b..6eacb1bb 100644 --- a/absl/container/flat_hash_set_test.cc +++ b/absl/container/flat_hash_set_test.cc @@ -25,6 +25,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace { @@ -125,4 +126,5 @@ TEST(FlatHashSet, MergeExtractInsert) { } // namespace } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h index d5c67db5..2388d471 100644 --- a/absl/container/inlined_vector.h +++ b/absl/container/inlined_vector.h @@ -54,6 +54,7 @@ #include "absl/memory/memory.h" namespace absl { +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // InlinedVector // ----------------------------------------------------------------------------- @@ -841,6 +842,7 @@ H AbslHashValue(H h, const absl::InlinedVector& a) { return H::combine(H::combine_contiguous(std::move(h), a.data(), size), size); } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INLINED_VECTOR_H_ diff --git a/absl/container/internal/btree.h b/absl/container/internal/btree.h index 40217dd5..aef861dc 100644 --- a/absl/container/internal/btree.h +++ b/absl/container/internal/btree.h @@ -70,6 +70,7 @@ #include "absl/utility/utility.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { // A helper class that indicates if the Compare parameter is a key-compare-to @@ -2606,6 +2607,7 @@ int btree

::internal_verify( } } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_BTREE_H_ diff --git a/absl/container/internal/btree_container.h b/absl/container/internal/btree_container.h index 774412d9..04795c2e 100644 --- a/absl/container/internal/btree_container.h +++ b/absl/container/internal/btree_container.h @@ -26,6 +26,7 @@ #include "absl/meta/type_traits.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { // A common base class for btree_set, btree_map, btree_multiset, and @@ -602,6 +603,7 @@ class btree_multimap_container : public btree_multiset_container { }; } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_BTREE_CONTAINER_H_ diff --git a/absl/container/internal/common.h b/absl/container/internal/common.h index cc7633dc..853a5b21 100644 --- a/absl/container/internal/common.h +++ b/absl/container/internal/common.h @@ -22,6 +22,7 @@ #include "absl/types/optional.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { template @@ -196,6 +197,7 @@ struct InsertReturnType { }; } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_CONTAINER_H_ diff --git a/absl/container/internal/compressed_tuple.h b/absl/container/internal/compressed_tuple.h index 7d08e370..4bfe92fd 100644 --- a/absl/container/internal/compressed_tuple.h +++ b/absl/container/internal/compressed_tuple.h @@ -48,6 +48,7 @@ #endif namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { template @@ -256,6 +257,7 @@ template <> class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple<> {}; } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #undef ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC diff --git a/absl/container/internal/compressed_tuple_test.cc b/absl/container/internal/compressed_tuple_test.cc index 19af8f10..76bc9213 100644 --- a/absl/container/internal/compressed_tuple_test.cc +++ b/absl/container/internal/compressed_tuple_test.cc @@ -48,6 +48,7 @@ struct TwoValues { namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace { @@ -408,4 +409,5 @@ TEST(CompressedTupleTest, EmptyFinalClass) { } // namespace } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/internal/container_memory.h b/absl/container/internal/container_memory.h index e5bb9773..d24b0f84 100644 --- a/absl/container/internal/container_memory.h +++ b/absl/container/internal/container_memory.h @@ -34,6 +34,7 @@ #include "absl/utility/utility.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { // Allocates at least n bytes aligned to the specified alignment. @@ -433,6 +434,7 @@ struct map_slot_policy { }; } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_CONTAINER_MEMORY_H_ diff --git a/absl/container/internal/container_memory_test.cc b/absl/container/internal/container_memory_test.cc index d6b0495f..7942c7be 100644 --- a/absl/container/internal/container_memory_test.cc +++ b/absl/container/internal/container_memory_test.cc @@ -23,6 +23,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace { @@ -185,4 +186,5 @@ TEST(DecomposePair, NotDecomposable) { } // namespace } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/internal/counting_allocator.h b/absl/container/internal/counting_allocator.h index 4e717bef..9efdc662 100644 --- a/absl/container/internal/counting_allocator.h +++ b/absl/container/internal/counting_allocator.h @@ -19,7 +19,10 @@ #include #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { // This is a stateful allocator, but the state lives outside of the @@ -74,6 +77,7 @@ class CountingAllocator : public std::allocator { }; } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_COUNTING_ALLOCATOR_H_ diff --git a/absl/container/internal/hash_function_defaults.h b/absl/container/internal/hash_function_defaults.h index cb8f03c8..401ddf4d 100644 --- a/absl/container/internal/hash_function_defaults.h +++ b/absl/container/internal/hash_function_defaults.h @@ -56,6 +56,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { // The hash of an object of type T is computed by using absl::Hash. @@ -139,6 +140,7 @@ template using hash_default_eq = typename container_internal::HashEq::Eq; } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_HASH_FUNCTION_DEFAULTS_H_ diff --git a/absl/container/internal/hash_function_defaults_test.cc b/absl/container/internal/hash_function_defaults_test.cc index 82708dbe..2eefc7e0 100644 --- a/absl/container/internal/hash_function_defaults_test.cc +++ b/absl/container/internal/hash_function_defaults_test.cc @@ -22,6 +22,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace { @@ -248,6 +249,7 @@ TYPED_TEST_SUITE(StringLikeTest, StringTypesCartesianProduct); } // namespace } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl enum Hash : size_t { @@ -278,6 +280,7 @@ struct hash> { } // namespace std namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace { @@ -292,4 +295,5 @@ TEST(Delegate, HashDispatch) { } // namespace } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/internal/hash_generator_testing.cc b/absl/container/internal/hash_generator_testing.cc index 37a23d60..75c4db6c 100644 --- a/absl/container/internal/hash_generator_testing.cc +++ b/absl/container/internal/hash_generator_testing.cc @@ -17,6 +17,7 @@ #include namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace hash_internal { namespace { @@ -69,4 +70,5 @@ absl::string_view Generator::operator()() const { } // namespace hash_internal } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/internal/hash_generator_testing.h b/absl/container/internal/hash_generator_testing.h index 477215cd..6869fe45 100644 --- a/absl/container/internal/hash_generator_testing.h +++ b/absl/container/internal/hash_generator_testing.h @@ -33,6 +33,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace hash_internal { namespace generator_internal { @@ -154,6 +155,7 @@ using GeneratedType = decltype( } // namespace hash_internal } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_HASH_GENERATOR_TESTING_H_ diff --git a/absl/container/internal/hash_policy_testing.h b/absl/container/internal/hash_policy_testing.h index c57407a0..01c40d2e 100644 --- a/absl/container/internal/hash_policy_testing.h +++ b/absl/container/internal/hash_policy_testing.h @@ -30,6 +30,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace hash_testing_internal { @@ -162,6 +163,7 @@ auto keys(const Set& s) } } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl // ABSL_UNORDERED_SUPPORTS_ALLOC_CTORS is false for glibcxx versions diff --git a/absl/container/internal/hash_policy_testing_test.cc b/absl/container/internal/hash_policy_testing_test.cc index 0c95eb5e..f0b20fe3 100644 --- a/absl/container/internal/hash_policy_testing_test.cc +++ b/absl/container/internal/hash_policy_testing_test.cc @@ -17,6 +17,7 @@ #include "gtest/gtest.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace { @@ -40,4 +41,5 @@ TEST(_, Hash) { } // namespace } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/internal/hash_policy_traits.h b/absl/container/internal/hash_policy_traits.h index fd007de7..3e1209c6 100644 --- a/absl/container/internal/hash_policy_traits.h +++ b/absl/container/internal/hash_policy_traits.h @@ -23,6 +23,7 @@ #include "absl/meta/type_traits.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { // Defines how slots are initialized/destroyed/moved. @@ -184,6 +185,7 @@ struct hash_policy_traits { }; } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_HASH_POLICY_TRAITS_H_ diff --git a/absl/container/internal/hash_policy_traits_test.cc b/absl/container/internal/hash_policy_traits_test.cc index e643d189..6ef8b9e0 100644 --- a/absl/container/internal/hash_policy_traits_test.cc +++ b/absl/container/internal/hash_policy_traits_test.cc @@ -22,6 +22,7 @@ #include "gtest/gtest.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace { @@ -139,4 +140,5 @@ TEST_F(Test, with_transfer) { } // namespace } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/internal/hashtable_debug.h b/absl/container/internal/hashtable_debug.h index 71930004..19d52121 100644 --- a/absl/container/internal/hashtable_debug.h +++ b/absl/container/internal/hashtable_debug.h @@ -38,6 +38,7 @@ #include "absl/container/internal/hashtable_debug_hooks.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { // Returns the number of probes required to lookup `key`. Returns 0 for a @@ -103,6 +104,7 @@ size_t LowerBoundAllocatedByteSize(size_t num_elements) { } } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_HASHTABLE_DEBUG_H_ diff --git a/absl/container/internal/hashtable_debug_hooks.h b/absl/container/internal/hashtable_debug_hooks.h index 371ce81f..3e9ea595 100644 --- a/absl/container/internal/hashtable_debug_hooks.h +++ b/absl/container/internal/hashtable_debug_hooks.h @@ -23,7 +23,10 @@ #include #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace hashtable_debug_internal { @@ -76,6 +79,7 @@ struct HashtableDebugAccess { } // namespace hashtable_debug_internal } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_HASHTABLE_DEBUG_HOOKS_H_ diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc index 6deeca44..e15f4444 100644 --- a/absl/container/internal/hashtablez_sampler.cc +++ b/absl/container/internal/hashtablez_sampler.cc @@ -28,6 +28,7 @@ #include "absl/synchronization/mutex.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { constexpr int HashtablezInfo::kMaxStackDepth; @@ -265,4 +266,5 @@ void SetHashtablezMaxSamples(int32_t max) { } } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/internal/hashtablez_sampler.h b/absl/container/internal/hashtablez_sampler.h index c694df05..c4f9629f 100644 --- a/absl/container/internal/hashtablez_sampler.h +++ b/absl/container/internal/hashtablez_sampler.h @@ -51,6 +51,7 @@ #include "absl/utility/utility.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { // Stores information about a sampled hashtable. All mutations to this *must* @@ -281,6 +282,7 @@ void SetHashtablezMaxSamples(int32_t max); extern "C" bool AbslContainerInternalSampleEverything(); } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_HASHTABLEZ_SAMPLER_H_ diff --git a/absl/container/internal/hashtablez_sampler_force_weak_definition.cc b/absl/container/internal/hashtablez_sampler_force_weak_definition.cc index 984dce5d..78b9d362 100644 --- a/absl/container/internal/hashtablez_sampler_force_weak_definition.cc +++ b/absl/container/internal/hashtablez_sampler_force_weak_definition.cc @@ -17,6 +17,7 @@ #include "absl/base/attributes.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { // See hashtablez_sampler.h for details. @@ -25,4 +26,5 @@ extern "C" ABSL_ATTRIBUTE_WEAK bool AbslContainerInternalSampleEverything() { } } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/internal/hashtablez_sampler_test.cc b/absl/container/internal/hashtablez_sampler_test.cc index af4b5ee1..102b2375 100644 --- a/absl/container/internal/hashtablez_sampler_test.cc +++ b/absl/container/internal/hashtablez_sampler_test.cc @@ -36,6 +36,7 @@ constexpr int kProbeLength = 8; #endif namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { class HashtablezInfoHandlePeer { public: @@ -354,4 +355,5 @@ TEST(HashtablezSamplerTest, Callback) { } // namespace } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/internal/inlined_vector.h b/absl/container/internal/inlined_vector.h index 84aa785a..4d80b727 100644 --- a/absl/container/internal/inlined_vector.h +++ b/absl/container/internal/inlined_vector.h @@ -30,6 +30,7 @@ #include "absl/types/span.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace inlined_vector_internal { template @@ -885,6 +886,7 @@ auto Storage::Swap(Storage* other_storage_ptr) -> void { } } // namespace inlined_vector_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_INLINED_VECTOR_INTERNAL_H_ diff --git a/absl/container/internal/layout.h b/absl/container/internal/layout.h index bbdde507..69cc85dd 100644 --- a/absl/container/internal/layout.h +++ b/absl/container/internal/layout.h @@ -188,6 +188,7 @@ #endif namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { // A type wrapper that instructs `Layout` to use the specific alignment for the @@ -734,6 +735,7 @@ class Layout : public internal_layout::LayoutType { }; } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_LAYOUT_H_ diff --git a/absl/container/internal/layout_test.cc b/absl/container/internal/layout_test.cc index 33b72bd3..8f3628a1 100644 --- a/absl/container/internal/layout_test.cc +++ b/absl/container/internal/layout_test.cc @@ -28,6 +28,7 @@ #include "absl/types/span.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace { @@ -1562,4 +1563,5 @@ TEST(CompactString, Works) { } // namespace } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/internal/node_hash_policy.h b/absl/container/internal/node_hash_policy.h index 19b4fc09..4617162f 100644 --- a/absl/container/internal/node_hash_policy.h +++ b/absl/container/internal/node_hash_policy.h @@ -39,7 +39,10 @@ #include #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { template @@ -83,6 +86,7 @@ struct node_hash_policy { }; } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_NODE_HASH_POLICY_H_ diff --git a/absl/container/internal/node_hash_policy_test.cc b/absl/container/internal/node_hash_policy_test.cc index f1d3ec30..84aabba9 100644 --- a/absl/container/internal/node_hash_policy_test.cc +++ b/absl/container/internal/node_hash_policy_test.cc @@ -21,6 +21,7 @@ #include "absl/container/internal/hash_policy_traits.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace { @@ -64,4 +65,5 @@ TEST_F(NodeTest, transfer) { } // namespace } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/internal/raw_hash_map.h b/absl/container/internal/raw_hash_map.h index 7dad120a..0a02757d 100644 --- a/absl/container/internal/raw_hash_map.h +++ b/absl/container/internal/raw_hash_map.h @@ -24,6 +24,7 @@ #include "absl/container/internal/raw_hash_set.h" // IWYU pragma: export namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { template @@ -190,6 +191,7 @@ class raw_hash_map : public raw_hash_set { }; } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_RAW_HASH_MAP_H_ diff --git a/absl/container/internal/raw_hash_set.cc b/absl/container/internal/raw_hash_set.cc index ac2d10a7..919ac074 100644 --- a/absl/container/internal/raw_hash_set.cc +++ b/absl/container/internal/raw_hash_set.cc @@ -20,6 +20,7 @@ #include "absl/base/config.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { constexpr size_t Group::kWidth; @@ -43,4 +44,5 @@ bool ShouldInsertBackwards(size_t hash, ctrl_t* ctrl) { } } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 469226fe..4103e02a 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -118,6 +118,7 @@ #include "absl/utility/utility.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { template @@ -1861,6 +1862,7 @@ struct HashtableDebugAccess> { } // namespace hashtable_debug_internal } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_ diff --git a/absl/container/internal/raw_hash_set_allocator_test.cc b/absl/container/internal/raw_hash_set_allocator_test.cc index a5eff0b3..7ac4b9f7 100644 --- a/absl/container/internal/raw_hash_set_allocator_test.cc +++ b/absl/container/internal/raw_hash_set_allocator_test.cc @@ -20,6 +20,7 @@ #include "absl/container/internal/tracked.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace { @@ -425,4 +426,5 @@ TEST_F(PropagateOnAll, Swap) { } // namespace } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc index ec8f9231..38e5e0e8 100644 --- a/absl/container/internal/raw_hash_set_test.cc +++ b/absl/container/internal/raw_hash_set_test.cc @@ -35,6 +35,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { struct RawHashSetTestOnlyAccess { @@ -1913,4 +1914,5 @@ TEST(Sanitizer, PoisoningOnErase) { } // namespace } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/internal/test_instance_tracker.cc b/absl/container/internal/test_instance_tracker.cc index 5a66cb4d..f9947f04 100644 --- a/absl/container/internal/test_instance_tracker.cc +++ b/absl/container/internal/test_instance_tracker.cc @@ -15,6 +15,7 @@ #include "absl/container/internal/test_instance_tracker.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace test_internal { int BaseCountedInstance::num_instances_ = 0; int BaseCountedInstance::num_live_instances_ = 0; @@ -24,4 +25,5 @@ int BaseCountedInstance::num_swaps_ = 0; int BaseCountedInstance::num_comparisons_ = 0; } // namespace test_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/internal/test_instance_tracker.h b/absl/container/internal/test_instance_tracker.h index c4731dbe..5ff6fd71 100644 --- a/absl/container/internal/test_instance_tracker.h +++ b/absl/container/internal/test_instance_tracker.h @@ -21,6 +21,7 @@ #include "absl/types/compare.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace test_internal { // A type that counts number of occurrences of the type, the live occurrences of @@ -267,6 +268,7 @@ class MovableOnlyInstance : public BaseCountedInstance { }; } // namespace test_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_TEST_INSTANCE_TRACKER_H_ diff --git a/absl/container/internal/tracked.h b/absl/container/internal/tracked.h index 75173ab0..29f5829f 100644 --- a/absl/container/internal/tracked.h +++ b/absl/container/internal/tracked.h @@ -16,10 +16,14 @@ #define ABSL_CONTAINER_INTERNAL_TRACKED_H_ #include + #include #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { // A class that tracks its copies and moves so that it can be queried in tests. @@ -73,6 +77,7 @@ class Tracked { }; } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_TRACKED_H_ diff --git a/absl/container/internal/unordered_map_constructor_test.h b/absl/container/internal/unordered_map_constructor_test.h index 68817e4e..76ee95e6 100644 --- a/absl/container/internal/unordered_map_constructor_test.h +++ b/absl/container/internal/unordered_map_constructor_test.h @@ -24,6 +24,7 @@ #include "absl/container/internal/hash_policy_testing.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { template @@ -482,6 +483,7 @@ REGISTER_TYPED_TEST_CASE_P( AssignmentFromInitializerListOverwritesExisting, AssignmentOnSelf); } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_CONSTRUCTOR_TEST_H_ diff --git a/absl/container/internal/unordered_map_lookup_test.h b/absl/container/internal/unordered_map_lookup_test.h index ebd3612b..e76421e5 100644 --- a/absl/container/internal/unordered_map_lookup_test.h +++ b/absl/container/internal/unordered_map_lookup_test.h @@ -21,6 +21,7 @@ #include "absl/container/internal/hash_policy_testing.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { template @@ -110,6 +111,7 @@ REGISTER_TYPED_TEST_CASE_P(LookupTest, At, OperatorBracket, Count, Find, EqualRange); } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_LOOKUP_TEST_H_ diff --git a/absl/container/internal/unordered_map_members_test.h b/absl/container/internal/unordered_map_members_test.h index 1bf31ab4..7d48cdb8 100644 --- a/absl/container/internal/unordered_map_members_test.h +++ b/absl/container/internal/unordered_map_members_test.h @@ -21,6 +21,7 @@ #include "absl/meta/type_traits.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { template @@ -80,6 +81,7 @@ TYPED_TEST_P(MembersTest, BeginEnd) { REGISTER_TYPED_TEST_SUITE_P(MembersTest, Typedefs, SimpleFunctions, BeginEnd); } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_MEMBERS_TEST_H_ diff --git a/absl/container/internal/unordered_map_modifiers_test.h b/absl/container/internal/unordered_map_modifiers_test.h index f6aff542..b8c513f1 100644 --- a/absl/container/internal/unordered_map_modifiers_test.h +++ b/absl/container/internal/unordered_map_modifiers_test.h @@ -23,6 +23,7 @@ #include "absl/container/internal/hash_policy_testing.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { template @@ -309,6 +310,7 @@ TYPED_TEST_P(UniquePtrModifiersTest, TryEmplace) { REGISTER_TYPED_TEST_SUITE_P(UniquePtrModifiersTest, TryEmplace); } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_MODIFIERS_TEST_H_ diff --git a/absl/container/internal/unordered_map_test.cc b/absl/container/internal/unordered_map_test.cc index 114b342d..9cbf512f 100644 --- a/absl/container/internal/unordered_map_test.cc +++ b/absl/container/internal/unordered_map_test.cc @@ -21,6 +21,7 @@ #include "absl/container/internal/unordered_map_modifiers_test.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace { @@ -45,4 +46,5 @@ INSTANTIATE_TYPED_TEST_SUITE_P(UnorderedMap, UniquePtrModifiersTest, } // namespace } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/internal/unordered_set_constructor_test.h b/absl/container/internal/unordered_set_constructor_test.h index f4844683..41165b05 100644 --- a/absl/container/internal/unordered_set_constructor_test.h +++ b/absl/container/internal/unordered_set_constructor_test.h @@ -26,6 +26,7 @@ #include "absl/meta/type_traits.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { template @@ -489,6 +490,7 @@ REGISTER_TYPED_TEST_CASE_P( AssignmentFromInitializerListOverwritesExisting, AssignmentOnSelf); } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_SET_CONSTRUCTOR_TEST_H_ diff --git a/absl/container/internal/unordered_set_lookup_test.h b/absl/container/internal/unordered_set_lookup_test.h index 05b32b5d..8f2f4b20 100644 --- a/absl/container/internal/unordered_set_lookup_test.h +++ b/absl/container/internal/unordered_set_lookup_test.h @@ -21,6 +21,7 @@ #include "absl/container/internal/hash_policy_testing.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { template @@ -84,6 +85,7 @@ TYPED_TEST_P(LookupTest, EqualRange) { REGISTER_TYPED_TEST_CASE_P(LookupTest, Count, Find, EqualRange); } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_SET_LOOKUP_TEST_H_ diff --git a/absl/container/internal/unordered_set_members_test.h b/absl/container/internal/unordered_set_members_test.h index b96c945a..4c5e104a 100644 --- a/absl/container/internal/unordered_set_members_test.h +++ b/absl/container/internal/unordered_set_members_test.h @@ -21,6 +21,7 @@ #include "absl/meta/type_traits.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { template @@ -79,6 +80,7 @@ TYPED_TEST_P(MembersTest, BeginEnd) { REGISTER_TYPED_TEST_SUITE_P(MembersTest, Typedefs, SimpleFunctions, BeginEnd); } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_SET_MEMBERS_TEST_H_ diff --git a/absl/container/internal/unordered_set_modifiers_test.h b/absl/container/internal/unordered_set_modifiers_test.h index 79a8d422..26be58d9 100644 --- a/absl/container/internal/unordered_set_modifiers_test.h +++ b/absl/container/internal/unordered_set_modifiers_test.h @@ -21,6 +21,7 @@ #include "absl/container/internal/hash_policy_testing.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { template @@ -183,6 +184,7 @@ REGISTER_TYPED_TEST_CASE_P(ModifiersTest, Clear, Insert, InsertHint, EraseKey, Swap); } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_SET_MODIFIERS_TEST_H_ diff --git a/absl/container/internal/unordered_set_test.cc b/absl/container/internal/unordered_set_test.cc index 6478fac1..a134b539 100644 --- a/absl/container/internal/unordered_set_test.cc +++ b/absl/container/internal/unordered_set_test.cc @@ -20,6 +20,7 @@ #include "absl/container/internal/unordered_set_modifiers_test.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace { @@ -36,4 +37,5 @@ INSTANTIATE_TYPED_TEST_SUITE_P(UnorderedSet, ModifiersTest, SetTypes); } // namespace } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/node_hash_map.h b/absl/container/node_hash_map.h index a718842b..e8065a98 100644 --- a/absl/container/node_hash_map.h +++ b/absl/container/node_hash_map.h @@ -48,6 +48,7 @@ #include "absl/memory/memory.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { template class NodeHashMapPolicy; @@ -581,6 +582,7 @@ struct IsUnorderedContainer< } // namespace container_algorithm_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_NODE_HASH_MAP_H_ diff --git a/absl/container/node_hash_map_test.cc b/absl/container/node_hash_map_test.cc index 0f2714a7..f923e915 100644 --- a/absl/container/node_hash_map_test.cc +++ b/absl/container/node_hash_map_test.cc @@ -21,6 +21,7 @@ #include "absl/container/internal/unordered_map_modifiers_test.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace { @@ -217,4 +218,5 @@ TEST(NodeHashMap, MergeExtractInsert) { } // namespace } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/container/node_hash_set.h b/absl/container/node_hash_set.h index 0cd1fe57..43ada3f9 100644 --- a/absl/container/node_hash_set.h +++ b/absl/container/node_hash_set.h @@ -44,6 +44,7 @@ #include "absl/memory/memory.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { template struct NodeHashSetPolicy; @@ -483,6 +484,7 @@ struct IsUnorderedContainer> : std::true_type {}; } // namespace container_algorithm_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_NODE_HASH_SET_H_ diff --git a/absl/container/node_hash_set_test.cc b/absl/container/node_hash_set_test.cc index 0ea76e7c..e1d544ff 100644 --- a/absl/container/node_hash_set_test.cc +++ b/absl/container/node_hash_set_test.cc @@ -20,6 +20,7 @@ #include "absl/container/internal/unordered_set_modifiers_test.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace { using ::absl::container_internal::hash_internal::Enum; @@ -102,4 +103,5 @@ TEST(NodeHashSet, MergeExtractInsert) { } // namespace } // namespace container_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel index 2601090b..32cacefd 100644 --- a/absl/debugging/BUILD.bazel +++ b/absl/debugging/BUILD.bazel @@ -38,6 +38,7 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":debugging_internal", + "//absl/base:config", "//absl/base:core_headers", ], ) @@ -63,6 +64,7 @@ cc_library( ":debugging_internal", ":demangle_internal", "//absl/base", + "//absl/base:config", "//absl/base:core_headers", "//absl/base:dynamic_annotations", "//absl/base:malloc_internal", @@ -106,6 +108,7 @@ cc_library( deps = [ ":stacktrace", ":symbolize", + "//absl/base:config", "//absl/base:core_headers", "//absl/base:raw_logging_internal", ], @@ -168,6 +171,7 @@ cc_library( copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ + "//absl/base:config", "//absl/base:core_headers", "//absl/base:dynamic_annotations", "//absl/base:raw_logging_internal", @@ -181,6 +185,7 @@ cc_library( copts = ABSL_DEFAULT_COPTS, deps = [ "//absl/base", + "//absl/base:config", "//absl/base:core_headers", ], ) @@ -205,7 +210,10 @@ cc_library( srcs = ["leak_check.cc"], hdrs = ["leak_check.h"], linkopts = ABSL_DEFAULT_LINKOPTS, - deps = ["//absl/base:core_headers"], + deps = [ + "//absl/base:config", + "//absl/base:core_headers", + ], ) # Adding a dependency to leak_check_disable will disable @@ -216,6 +224,7 @@ cc_library( srcs = ["leak_check_disable.cc"], linkopts = ABSL_DEFAULT_LINKOPTS, linkstatic = 1, + deps = ["//absl/base:config"], alwayslink = 1, ) @@ -237,6 +246,9 @@ cc_library( }), linkopts = ABSL_DEFAULT_LINKOPTS, visibility = ["//visibility:private"], + deps = [ + "//absl/base:config", + ], ) cc_library( @@ -247,6 +259,9 @@ cc_library( copts = ["-ULEAK_SANITIZER"], linkopts = ABSL_DEFAULT_LINKOPTS, visibility = ["//visibility:private"], + deps = [ + "//absl/base:config", + ], ) cc_test( @@ -304,6 +319,7 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, visibility = ["//visibility:private"], deps = [ + "//absl/base:config", "//absl/base:core_headers", "//absl/base:raw_logging_internal", ], diff --git a/absl/debugging/CMakeLists.txt b/absl/debugging/CMakeLists.txt index eff504b4..ef9e71fc 100644 --- a/absl/debugging/CMakeLists.txt +++ b/absl/debugging/CMakeLists.txt @@ -25,6 +25,7 @@ absl_cc_library( ${ABSL_DEFAULT_COPTS} DEPS absl::debugging_internal + absl::config absl::core_headers PUBLIC ) @@ -49,6 +50,7 @@ absl_cc_library( absl::debugging_internal absl::demangle_internal absl::base + absl::config absl::core_headers absl::dynamic_annotations absl::malloc_internal @@ -88,6 +90,7 @@ absl_cc_library( DEPS absl::stacktrace absl::symbolize + absl::config absl::core_headers absl::raw_logging_internal ) @@ -151,6 +154,7 @@ absl_cc_library( ${ABSL_DEFAULT_COPTS} DEPS absl::core_headers + absl::config absl::dynamic_annotations absl::raw_logging_internal ) @@ -196,6 +200,7 @@ absl_cc_library( COPTS ${ABSL_DEFAULT_COPTS} DEPS + absl::config absl::core_headers PUBLIC ) @@ -293,6 +298,7 @@ absl_cc_library( COPTS ${ABSL_DEFAULT_COPTS} DEPS + absl::config absl::core_headers absl::raw_logging_internal TESTONLY diff --git a/absl/debugging/failure_signal_handler.cc b/absl/debugging/failure_signal_handler.cc index c6a4d962..470d6768 100644 --- a/absl/debugging/failure_signal_handler.cc +++ b/absl/debugging/failure_signal_handler.cc @@ -47,6 +47,7 @@ #endif namespace absl { +ABSL_NAMESPACE_BEGIN ABSL_CONST_INIT static FailureSignalHandlerOptions fsh_options; @@ -356,4 +357,5 @@ void InstallFailureSignalHandler(const FailureSignalHandlerOptions& options) { } } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/debugging/failure_signal_handler.h b/absl/debugging/failure_signal_handler.h index 1beb78b9..f5a83962 100644 --- a/absl/debugging/failure_signal_handler.h +++ b/absl/debugging/failure_signal_handler.h @@ -44,7 +44,10 @@ #ifndef ABSL_DEBUGGING_FAILURE_SIGNAL_HANDLER_H_ #define ABSL_DEBUGGING_FAILURE_SIGNAL_HANDLER_H_ +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN // FailureSignalHandlerOptions // @@ -112,6 +115,7 @@ namespace debugging_internal { const char* FailureSignalToString(int signo); } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_FAILURE_SIGNAL_HANDLER_H_ diff --git a/absl/debugging/internal/address_is_readable.cc b/absl/debugging/internal/address_is_readable.cc index 99c4c64b..f45e59b3 100644 --- a/absl/debugging/internal/address_is_readable.cc +++ b/absl/debugging/internal/address_is_readable.cc @@ -20,12 +20,14 @@ #if !defined(__linux__) || defined(__ANDROID__) namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // On platforms other than Linux, just return true. bool AddressIsReadable(const void* /* addr */) { return true; } } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #else @@ -40,6 +42,7 @@ bool AddressIsReadable(const void* /* addr */) { return true; } #include "absl/base/internal/raw_logging.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // Pack a pid and two file descriptors into a 64-bit word, @@ -128,6 +131,7 @@ bool AddressIsReadable(const void *addr) { } } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif diff --git a/absl/debugging/internal/address_is_readable.h b/absl/debugging/internal/address_is_readable.h index ca8003e6..4bbaf4d6 100644 --- a/absl/debugging/internal/address_is_readable.h +++ b/absl/debugging/internal/address_is_readable.h @@ -15,7 +15,10 @@ #ifndef ABSL_DEBUGGING_INTERNAL_ADDRESS_IS_READABLE_H_ #define ABSL_DEBUGGING_INTERNAL_ADDRESS_IS_READABLE_H_ +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // Return whether the byte at *addr is readable, without faulting. @@ -23,6 +26,7 @@ namespace debugging_internal { bool AddressIsReadable(const void *addr); } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_ADDRESS_IS_READABLE_H_ diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc index 3809e496..fc615c3f 100644 --- a/absl/debugging/internal/demangle.cc +++ b/absl/debugging/internal/demangle.cc @@ -24,6 +24,7 @@ #include namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { typedef struct { @@ -1890,4 +1891,5 @@ bool Demangle(const char *mangled, char *out, int out_size) { } } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/debugging/internal/demangle.h b/absl/debugging/internal/demangle.h index 81bb0dfd..c314d9bc 100644 --- a/absl/debugging/internal/demangle.h +++ b/absl/debugging/internal/demangle.h @@ -53,7 +53,10 @@ #ifndef ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_ #define ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_ +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // Demangle `mangled`. On success, return true and write the @@ -62,6 +65,7 @@ namespace debugging_internal { bool Demangle(const char *mangled, char *out, int out_size); } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_ diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc index a68ce324..c6f1ce18 100644 --- a/absl/debugging/internal/demangle_test.cc +++ b/absl/debugging/internal/demangle_test.cc @@ -23,6 +23,7 @@ #include "absl/memory/memory.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { namespace { @@ -190,4 +191,5 @@ TEST(DemangleRegression, DeeplyNestedArrayType) { } // namespace } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/debugging/internal/elf_mem_image.cc b/absl/debugging/internal/elf_mem_image.cc index e7408bca..24cc0130 100644 --- a/absl/debugging/internal/elf_mem_image.cc +++ b/absl/debugging/internal/elf_mem_image.cc @@ -38,6 +38,7 @@ #define VERSYM_VERSION 0x7fff namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { namespace { @@ -375,6 +376,7 @@ void ElfMemImage::SymbolIterator::Update(int increment) { } } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HAVE_ELF_MEM_IMAGE diff --git a/absl/debugging/internal/elf_mem_image.h b/absl/debugging/internal/elf_mem_image.h index d84200db..46bfade3 100644 --- a/absl/debugging/internal/elf_mem_image.h +++ b/absl/debugging/internal/elf_mem_image.h @@ -23,6 +23,8 @@ // used. #include +#include "absl/base/config.h" + // Maybe one day we can rewrite this file not to require the elf // symbol extensions in glibc, but for right now we need them. #ifdef ABSL_HAVE_ELF_MEM_IMAGE @@ -39,6 +41,7 @@ #include // for ElfW namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // An in-memory ELF image (may not exist on disk). @@ -123,6 +126,7 @@ class ElfMemImage { }; } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HAVE_ELF_MEM_IMAGE diff --git a/absl/debugging/internal/examine_stack.cc b/absl/debugging/internal/examine_stack.cc index 1ebc788f..22f41b46 100644 --- a/absl/debugging/internal/examine_stack.cc +++ b/absl/debugging/internal/examine_stack.cc @@ -30,6 +30,7 @@ #include "absl/debugging/symbolize.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // Returns the program counter from signal context, nullptr if @@ -150,4 +151,5 @@ void DumpPCAndFrameSizesAndStackTrace( } } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/debugging/internal/examine_stack.h b/absl/debugging/internal/examine_stack.h index 56c9763e..39336913 100644 --- a/absl/debugging/internal/examine_stack.h +++ b/absl/debugging/internal/examine_stack.h @@ -17,7 +17,10 @@ #ifndef ABSL_DEBUGGING_INTERNAL_EXAMINE_STACK_H_ #define ABSL_DEBUGGING_INTERNAL_EXAMINE_STACK_H_ +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // Returns the program counter from signal context, or nullptr if @@ -33,6 +36,7 @@ void DumpPCAndFrameSizesAndStackTrace( void (*writerfn)(const char*, void*), void* writerfn_arg); } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_EXAMINE_STACK_H_ diff --git a/absl/debugging/internal/stack_consumption.cc b/absl/debugging/internal/stack_consumption.cc index d4703264..875ca6d9 100644 --- a/absl/debugging/internal/stack_consumption.cc +++ b/absl/debugging/internal/stack_consumption.cc @@ -27,6 +27,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { namespace { @@ -177,6 +178,7 @@ int GetSignalHandlerStackConsumption(void (*signal_handler)(int)) { } } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION diff --git a/absl/debugging/internal/stack_consumption.h b/absl/debugging/internal/stack_consumption.h index b860a3c1..5e60ec42 100644 --- a/absl/debugging/internal/stack_consumption.h +++ b/absl/debugging/internal/stack_consumption.h @@ -18,6 +18,8 @@ #ifndef ABSL_DEBUGGING_INTERNAL_STACK_CONSUMPTION_H_ #define ABSL_DEBUGGING_INTERNAL_STACK_CONSUMPTION_H_ +#include "absl/base/config.h" + // The code in this module is not portable. // Use this feature test macro to detect its availability. #ifdef ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION @@ -27,6 +29,7 @@ #define ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION 1 namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // Returns the stack consumption in bytes for the code exercised by @@ -38,6 +41,7 @@ namespace debugging_internal { int GetSignalHandlerStackConsumption(void (*signal_handler)(int)); } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION diff --git a/absl/debugging/internal/stack_consumption_test.cc b/absl/debugging/internal/stack_consumption_test.cc index 68bfa126..80445bf4 100644 --- a/absl/debugging/internal/stack_consumption_test.cc +++ b/absl/debugging/internal/stack_consumption_test.cc @@ -23,6 +23,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { namespace { @@ -43,6 +44,7 @@ TEST(SignalHandlerStackConsumptionTest, MeasuresStackConsumption) { } // namespace } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION diff --git a/absl/debugging/internal/stacktrace_aarch64-inl.inc b/absl/debugging/internal/stacktrace_aarch64-inl.inc index 7ed6b3eb..411ea308 100644 --- a/absl/debugging/internal/stacktrace_aarch64-inl.inc +++ b/absl/debugging/internal/stacktrace_aarch64-inl.inc @@ -180,11 +180,13 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, } namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { bool StackTraceWorksForTest() { return true; } } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_AARCH64_INL_H_ diff --git a/absl/debugging/internal/stacktrace_arm-inl.inc b/absl/debugging/internal/stacktrace_arm-inl.inc index c8408337..fffda968 100644 --- a/absl/debugging/internal/stacktrace_arm-inl.inc +++ b/absl/debugging/internal/stacktrace_arm-inl.inc @@ -113,11 +113,13 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, } namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { bool StackTraceWorksForTest() { return false; } } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_ARM_INL_H_ diff --git a/absl/debugging/internal/stacktrace_generic-inl.inc b/absl/debugging/internal/stacktrace_generic-inl.inc index 81a49ef2..ac034c9f 100644 --- a/absl/debugging/internal/stacktrace_generic-inl.inc +++ b/absl/debugging/internal/stacktrace_generic-inl.inc @@ -87,11 +87,13 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, } namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { bool StackTraceWorksForTest() { return true; } } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_GENERIC_INL_H_ diff --git a/absl/debugging/internal/stacktrace_powerpc-inl.inc b/absl/debugging/internal/stacktrace_powerpc-inl.inc index 3a070ee4..2e7c2f40 100644 --- a/absl/debugging/internal/stacktrace_powerpc-inl.inc +++ b/absl/debugging/internal/stacktrace_powerpc-inl.inc @@ -236,11 +236,13 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, } namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { bool StackTraceWorksForTest() { return true; } } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_POWERPC_INL_H_ diff --git a/absl/debugging/internal/stacktrace_unimplemented-inl.inc b/absl/debugging/internal/stacktrace_unimplemented-inl.inc index e256fdd4..5b8fb191 100644 --- a/absl/debugging/internal/stacktrace_unimplemented-inl.inc +++ b/absl/debugging/internal/stacktrace_unimplemented-inl.inc @@ -12,11 +12,13 @@ static int UnwindImpl(void** /* result */, int* /* sizes */, } namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { bool StackTraceWorksForTest() { return false; } } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_UNIMPLEMENTED_INL_H_ diff --git a/absl/debugging/internal/stacktrace_win32-inl.inc b/absl/debugging/internal/stacktrace_win32-inl.inc index 247e7428..9c2c5580 100644 --- a/absl/debugging/internal/stacktrace_win32-inl.inc +++ b/absl/debugging/internal/stacktrace_win32-inl.inc @@ -73,11 +73,13 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, } namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { bool StackTraceWorksForTest() { return false; } } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_WIN32_INL_H_ diff --git a/absl/debugging/internal/stacktrace_x86-inl.inc b/absl/debugging/internal/stacktrace_x86-inl.inc index 9494441e..972febdd 100644 --- a/absl/debugging/internal/stacktrace_x86-inl.inc +++ b/absl/debugging/internal/stacktrace_x86-inl.inc @@ -330,11 +330,13 @@ static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count, } namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { bool StackTraceWorksForTest() { return true; } } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_X86_INL_INC_ diff --git a/absl/debugging/internal/symbolize.h b/absl/debugging/internal/symbolize.h index 3e537893..5d0858b5 100644 --- a/absl/debugging/internal/symbolize.h +++ b/absl/debugging/internal/symbolize.h @@ -21,6 +21,8 @@ #include #include +#include "absl/base/config.h" + #ifdef ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE #error ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE cannot be directly set #elif defined(__ELF__) && defined(__GLIBC__) && !defined(__native_client__) && \ @@ -33,6 +35,7 @@ #include namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // Iterates over all sections, invoking callback on each with the section name @@ -51,11 +54,13 @@ bool GetSectionHeaderByName(int fd, const char *name, size_t name_len, ElfW(Shdr) *out); } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { struct SymbolDecoratorArgs { @@ -117,6 +122,7 @@ bool GetFileMappingHint(const void** start, const char** filename); } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_ diff --git a/absl/debugging/internal/vdso_support.cc b/absl/debugging/internal/vdso_support.cc index d13ef25d..1e8a78ac 100644 --- a/absl/debugging/internal/vdso_support.cc +++ b/absl/debugging/internal/vdso_support.cc @@ -38,6 +38,7 @@ #endif namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { ABSL_CONST_INIT @@ -187,6 +188,7 @@ static class VDSOInitHelper { } vdso_init_helper; } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HAVE_VDSO_SUPPORT diff --git a/absl/debugging/internal/vdso_support.h b/absl/debugging/internal/vdso_support.h index 9895b48d..6562c6c2 100644 --- a/absl/debugging/internal/vdso_support.h +++ b/absl/debugging/internal/vdso_support.h @@ -53,6 +53,7 @@ #endif namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // NOTE: this class may be used from within tcmalloc, and can not @@ -149,6 +150,7 @@ class VDSOSupport { int GetCPU(); } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HAVE_ELF_MEM_IMAGE diff --git a/absl/debugging/leak_check.cc b/absl/debugging/leak_check.cc index ffe3d1bd..ff904955 100644 --- a/absl/debugging/leak_check.cc +++ b/absl/debugging/leak_check.cc @@ -21,12 +21,14 @@ #ifndef LEAK_SANITIZER namespace absl { +ABSL_NAMESPACE_BEGIN bool HaveLeakSanitizer() { return false; } void DoIgnoreLeak(const void*) { } void RegisterLivePointers(const void*, size_t) { } void UnRegisterLivePointers(const void*, size_t) { } LeakCheckDisabler::LeakCheckDisabler() { } LeakCheckDisabler::~LeakCheckDisabler() { } +ABSL_NAMESPACE_END } // namespace absl #else @@ -34,6 +36,7 @@ LeakCheckDisabler::~LeakCheckDisabler() { } #include namespace absl { +ABSL_NAMESPACE_BEGIN bool HaveLeakSanitizer() { return true; } void DoIgnoreLeak(const void* ptr) { __lsan_ignore_object(ptr); } void RegisterLivePointers(const void* ptr, size_t size) { @@ -44,6 +47,7 @@ void UnRegisterLivePointers(const void* ptr, size_t size) { } LeakCheckDisabler::LeakCheckDisabler() { __lsan_disable(); } LeakCheckDisabler::~LeakCheckDisabler() { __lsan_enable(); } +ABSL_NAMESPACE_END } // namespace absl #endif // LEAK_SANITIZER diff --git a/absl/debugging/leak_check.h b/absl/debugging/leak_check.h index 4d489c58..7a5a22dd 100644 --- a/absl/debugging/leak_check.h +++ b/absl/debugging/leak_check.h @@ -32,7 +32,10 @@ #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN // HaveLeakSanitizer() // @@ -104,6 +107,7 @@ void RegisterLivePointers(const void* ptr, size_t size); // `RegisterLivePointers()`, enabling leak checking of those pointers. void UnRegisterLivePointers(const void* ptr, size_t size); +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_LEAK_CHECK_H_ diff --git a/absl/debugging/stacktrace.cc b/absl/debugging/stacktrace.cc index 9de8782f..1f7c7d82 100644 --- a/absl/debugging/stacktrace.cc +++ b/absl/debugging/stacktrace.cc @@ -57,6 +57,7 @@ #endif namespace absl { +ABSL_NAMESPACE_BEGIN namespace { typedef int (*Unwinder)(void**, int*, int, int, const void*, int*); @@ -135,4 +136,5 @@ int DefaultStackUnwinder(void** pcs, int* sizes, int depth, int skip, return n; } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/debugging/stacktrace.h b/absl/debugging/stacktrace.h index cd8fae76..0ec0ffda 100644 --- a/absl/debugging/stacktrace.h +++ b/absl/debugging/stacktrace.h @@ -31,7 +31,10 @@ #ifndef ABSL_DEBUGGING_STACKTRACE_H_ #define ABSL_DEBUGGING_STACKTRACE_H_ +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN // GetStackFrames() // @@ -222,6 +225,7 @@ namespace debugging_internal { // working. extern bool StackTraceWorksForTest(); } // namespace debugging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_STACKTRACE_H_ diff --git a/absl/debugging/symbolize.h b/absl/debugging/symbolize.h index a73dbd9e..a8ff3740 100644 --- a/absl/debugging/symbolize.h +++ b/absl/debugging/symbolize.h @@ -55,6 +55,7 @@ #include "absl/debugging/internal/symbolize.h" namespace absl { +ABSL_NAMESPACE_BEGIN // InitializeSymbolizer() // @@ -92,6 +93,7 @@ void InitializeSymbolizer(const char* argv0); // } bool Symbolize(const void *pc, char *out, int out_size); +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_SYMBOLIZE_H_ diff --git a/absl/debugging/symbolize_elf.inc b/absl/debugging/symbolize_elf.inc index 14f0c972..c371635f 100644 --- a/absl/debugging/symbolize_elf.inc +++ b/absl/debugging/symbolize_elf.inc @@ -76,6 +76,7 @@ #include "absl/debugging/internal/vdso_support.h" namespace absl { +ABSL_NAMESPACE_BEGIN // Value of argv[0]. Used by MaybeInitializeObjFile(). static char *argv0_value = nullptr; @@ -1475,4 +1476,5 @@ bool Symbolize(const void *pc, char *out, int out_size) { return ok; } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/debugging/symbolize_unimplemented.inc b/absl/debugging/symbolize_unimplemented.inc index 7c580fe4..db24456b 100644 --- a/absl/debugging/symbolize_unimplemented.inc +++ b/absl/debugging/symbolize_unimplemented.inc @@ -17,6 +17,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace debugging_internal { @@ -35,4 +36,5 @@ bool GetFileMappingHint(const void **, const void **, uint64_t *, const char **) void InitializeSymbolizer(const char*) {} bool Symbolize(const void *, char *, int) { return false; } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/debugging/symbolize_win32.inc b/absl/debugging/symbolize_win32.inc index bd6fbd5e..c3df46f6 100644 --- a/absl/debugging/symbolize_win32.inc +++ b/absl/debugging/symbolize_win32.inc @@ -31,6 +31,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { +ABSL_NAMESPACE_BEGIN static HANDLE process = NULL; @@ -76,4 +77,5 @@ bool Symbolize(const void* pc, char* out, int out_size) { return true; } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/flags/declare.h b/absl/flags/declare.h index 4926a09e..f7509ce7 100644 --- a/absl/flags/declare.h +++ b/absl/flags/declare.h @@ -28,6 +28,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { // absl::Flag represents a flag of type 'T' created by ABSL_FLAG. @@ -47,6 +48,7 @@ template using Flag = flags_internal::Flag; #endif +ABSL_NAMESPACE_END } // namespace absl // ABSL_DECLARE_FLAG() diff --git a/absl/flags/flag.cc b/absl/flags/flag.cc index 37bbce23..7faa7ade 100644 --- a/absl/flags/flag.cc +++ b/absl/flags/flag.cc @@ -18,6 +18,7 @@ #include namespace absl { +ABSL_NAMESPACE_BEGIN // We want to validate the type mismatch between type definition and // declaration. The lock-free implementation does not allow us to do it, @@ -55,4 +56,5 @@ absl::Mutex* GetGlobalConstructionGuard() { return &construction_guard; } #endif +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/flags/flag.h b/absl/flags/flag.h index 52c3cede..b6fbd116 100644 --- a/absl/flags/flag.h +++ b/absl/flags/flag.h @@ -38,6 +38,7 @@ #include "absl/flags/marshalling.h" namespace absl { +ABSL_NAMESPACE_BEGIN // Flag // @@ -219,6 +220,7 @@ void SetFlag(absl::Flag* flag, const V& v) { flag->Set(value); } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/flags/flag_test_defs.cc b/absl/flags/flag_test_defs.cc index 3366c580..49f91dee 100644 --- a/absl/flags/flag_test_defs.cc +++ b/absl/flags/flag_test_defs.cc @@ -20,3 +20,5 @@ ABSL_FLAG(int, mistyped_int_flag, 0, ""); ABSL_FLAG(std::string, mistyped_string_flag, "", ""); +ABSL_RETIRED_FLAG(bool, old_bool_flag, true, + "repetition of retired flag definition"); diff --git a/absl/flags/internal/commandlineflag.cc b/absl/flags/internal/commandlineflag.cc index 88f91e16..09249274 100644 --- a/absl/flags/internal/commandlineflag.cc +++ b/absl/flags/internal/commandlineflag.cc @@ -18,6 +18,7 @@ #include "absl/flags/usage_config.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { // The help message indicating that the commandline flag has been @@ -57,4 +58,5 @@ std::string CommandLineFlag::Filename() const { } } // namespace flags_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/flags/internal/commandlineflag.h b/absl/flags/internal/commandlineflag.h index 7964f1bf..49e13d1e 100644 --- a/absl/flags/internal/commandlineflag.h +++ b/absl/flags/internal/commandlineflag.h @@ -23,6 +23,7 @@ #include "absl/types/optional.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { // Type-specific operations, eg., parsing, copying, etc. are provided @@ -158,7 +159,7 @@ class CommandLineFlag { : name_(name), filename_(filename) {} // Virtual destructor - virtual void Destroy() const = 0; + virtual void Destroy() = 0; // Not copyable/assignable. CommandLineFlag(const CommandLineFlag&) = delete; @@ -280,6 +281,7 @@ class CommandLineFlag { A(float) } // namespace flags_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FLAGS_INTERNAL_COMMANDLINEFLAG_H_ diff --git a/absl/flags/internal/flag.cc b/absl/flags/internal/flag.cc index 435cc362..599bd7a4 100644 --- a/absl/flags/internal/flag.cc +++ b/absl/flags/internal/flag.cc @@ -19,6 +19,7 @@ #include "absl/synchronization/mutex.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { namespace { @@ -34,20 +35,40 @@ bool ShouldValidateFlagValue(const CommandLineFlag& flag) { return true; } +// RAII helper used to temporarily unlock and relock `absl::Mutex`. +// This is used when we need to ensure that locks are released while +// invoking user supplied callbacks and then reacquired, since callbacks may +// need to acquire these locks themselves. +class MutexRelock { + public: + explicit MutexRelock(absl::Mutex* mu) : mu_(mu) { mu_->Unlock(); } + ~MutexRelock() { mu_->Lock(); } + + MutexRelock(const MutexRelock&) = delete; + MutexRelock& operator=(const MutexRelock&) = delete; + + private: + absl::Mutex* mu_; +}; + +// This global lock guards the initialization and destruction of data_guard_, +// which is used to guard the other Flag data. +ABSL_CONST_INIT static absl::Mutex flag_mutex_lifetime_guard(absl::kConstInit); + } // namespace void FlagImpl::Init() { - ABSL_CONST_INIT static absl::Mutex init_lock(absl::kConstInit); - { - absl::MutexLock lock(&init_lock); + absl::MutexLock lock(&flag_mutex_lifetime_guard); - if (locks_ == nullptr) { // Must initialize Mutexes for this flag. - locks_ = new FlagImpl::CommandLineFlagLocks; + // Must initialize data guard for this flag. + if (!is_data_guard_inited_) { + new (&data_guard_) absl::Mutex; + is_data_guard_inited_ = true; } } - absl::MutexLock lock(&locks_->primary_mu); + absl::MutexLock lock(reinterpret_cast(&data_guard_)); if (cur_ != nullptr) { inited_.store(true, std::memory_order_release); @@ -67,21 +88,29 @@ absl::Mutex* FlagImpl::DataGuard() const { const_cast(this)->Init(); } - // All fields initialized; locks_ is therefore safe to read. - return &locks_->primary_mu; + // data_guard_ is initialized. + return reinterpret_cast(&data_guard_); } -void FlagImpl::Destroy() const { +void FlagImpl::Destroy() { { absl::MutexLock l(DataGuard()); // Values are heap allocated for Abseil Flags. if (cur_) Delete(op_, cur_); - if (def_kind_ == FlagDefaultSrcKind::kDynamicValue) + + // Release the dynamically allocated default value if any. + if (def_kind_ == FlagDefaultSrcKind::kDynamicValue) { Delete(op_, default_src_.dynamic_value); + } + + // If this flag has an assigned callback, release callback data. + if (callback_data_) delete callback_data_; } - delete locks_; + absl::MutexLock l(&flag_mutex_lifetime_guard); + DataGuard()->~Mutex(); + is_data_guard_inited_ = false; } std::unique_ptr FlagImpl::MakeInitValue() const { @@ -126,13 +155,20 @@ void FlagImpl::SetCallback( const flags_internal::FlagCallback mutation_callback) { absl::MutexLock l(DataGuard()); - callback_ = mutation_callback; + if (callback_data_ == nullptr) { + callback_data_ = new CallbackData; + } + callback_data_->func = mutation_callback; InvokeCallback(); } void FlagImpl::InvokeCallback() const { - if (!callback_) return; + if (!callback_data_) return; + + // Make a copy of the C-style function pointer that we are about to invoke + // before we release the lock guarding it. + FlagCallback cb = callback_data_->func; // If the flag has a mutation callback this function invokes it. While the // callback is being invoked the primary flag's mutex is unlocked and it is @@ -145,14 +181,9 @@ void FlagImpl::InvokeCallback() const { // and it also can be different by the time the callback invocation is // completed. Requires that *primary_lock be held in exclusive mode; it may be // released and reacquired by the implementation. - DataGuard()->Unlock(); - - { - absl::MutexLock lock(&locks_->callback_mu); - callback_(); - } - - DataGuard()->Lock(); + MutexRelock relock(DataGuard()); + absl::MutexLock lock(&callback_data_->guard); + cb(); } bool FlagImpl::RestoreState(const CommandLineFlag& flag, const void* value, @@ -177,12 +208,13 @@ bool FlagImpl::RestoreState(const CommandLineFlag& flag, const void* value, } // Attempts to parse supplied `value` string using parsing routine in the `flag` -// argument. If parsing successful, this function stores the parsed value in -// 'dst' assuming it is a pointer to the flag's value type. In case if any error -// is encountered in either step, the error message is stored in 'err' -bool FlagImpl::TryParse(const CommandLineFlag& flag, void* dst, +// argument. If parsing successful, this function replaces the dst with newly +// parsed value. In case if any error is encountered in either step, the error +// message is stored in 'err' +bool FlagImpl::TryParse(const CommandLineFlag& flag, void** dst, absl::string_view value, std::string* err) const { auto tentative_value = MakeInitValue(); + std::string parse_err; if (!Parse(marshalling_op_, value, tentative_value.get(), &parse_err)) { auto type_name = flag.Typename(); @@ -194,7 +226,10 @@ bool FlagImpl::TryParse(const CommandLineFlag& flag, void* dst, return false; } - Copy(op_, tentative_value.get(), dst); + void* old_val = *dst; + *dst = tentative_value.release(); + tentative_value.reset(old_val); + return true; } @@ -274,7 +309,7 @@ bool FlagImpl::SetFromString(const CommandLineFlag& flag, switch (set_mode) { case SET_FLAGS_VALUE: { // set or modify the flag's value - if (!TryParse(flag, cur_, value, err)) return false; + if (!TryParse(flag, &cur_, value, err)) return false; modified_ = true; counter_++; StoreAtomic(); @@ -288,7 +323,7 @@ bool FlagImpl::SetFromString(const CommandLineFlag& flag, case SET_FLAG_IF_DEFAULT: { // set the flag's value, but only if it hasn't been set by someone else if (!modified_) { - if (!TryParse(flag, cur_, value, err)) return false; + if (!TryParse(flag, &cur_, value, err)) return false; modified_ = true; counter_++; StoreAtomic(); @@ -305,18 +340,19 @@ bool FlagImpl::SetFromString(const CommandLineFlag& flag, break; } case SET_FLAGS_DEFAULT: { - // Flag's new default-value. - auto new_default_value = MakeInitValue(); - - if (!TryParse(flag, new_default_value.get(), value, err)) return false; - if (def_kind_ == FlagDefaultSrcKind::kDynamicValue) { - // Release old default value. - Delete(op_, default_src_.dynamic_value); - } + if (!TryParse(flag, &default_src_.dynamic_value, value, err)) { + return false; + } + } else { + void* new_default_val = nullptr; + if (!TryParse(flag, &new_default_val, value, err)) { + return false; + } - default_src_.dynamic_value = new_default_value.release(); - def_kind_ = FlagDefaultSrcKind::kDynamicValue; + default_src_.dynamic_value = new_default_val; + def_kind_ = FlagDefaultSrcKind::kDynamicValue; + } if (!modified_) { // Need to set both default value *and* current, in this case @@ -361,4 +397,5 @@ bool FlagImpl::ValidateInputValue(absl::string_view value) const { } } // namespace flags_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h index 947a8cad..20de406f 100644 --- a/absl/flags/internal/flag.h +++ b/absl/flags/internal/flag.h @@ -27,6 +27,7 @@ #include "absl/synchronization/mutex.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { constexpr int64_t AtomicInit() { return 0xababababababababll; } @@ -156,10 +157,11 @@ class FlagImpl { help_(help.source), help_source_kind_(help.kind), def_kind_(flags_internal::FlagDefaultSrcKind::kGenFunc), - default_src_(default_value_gen) {} + default_src_(default_value_gen), + data_guard_{} {} // Forces destruction of the Flag's data. - void Destroy() const; + void Destroy(); // Constant access methods std::string Help() const; @@ -170,9 +172,10 @@ class FlagImpl { void Read(const CommandLineFlag& flag, void* dst, const flags_internal::FlagOpFn dst_op) const ABSL_LOCKS_EXCLUDED(*DataGuard()); - // Attempts to parse supplied `value` std::string. - bool TryParse(const CommandLineFlag& flag, void* dst, absl::string_view value, - std::string* err) const + // Attempts to parse supplied `value` std::string. If parsing is successful, then + // it replaces `dst` with the new value. + bool TryParse(const CommandLineFlag& flag, void** dst, + absl::string_view value, std::string* err) const ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); template bool AtomicGet(T* v) const { @@ -226,8 +229,7 @@ class FlagImpl { void Init(); // Ensures that the lazily initialized data is initialized, // and returns pointer to the mutex guarding flags data. - absl::Mutex* DataGuard() const ABSL_LOCK_RETURNED(locks_->primary_mu); - + absl::Mutex* DataGuard() const ABSL_LOCK_RETURNED((absl::Mutex*)&data_guard_); // Returns heap allocated value of type T initialized with default value. std::unique_ptr MakeInitValue() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); @@ -239,9 +241,12 @@ class FlagImpl { // Indicates if help message was supplied as literal or generator func. const FlagHelpSrcKind help_source_kind_; - // Mutable Flag's data. (guarded by DataGuard()). - // Indicates that locks_ and cur_ fields have been lazily initialized. + // Indicates that the Flag state is initialized. std::atomic inited_{false}; + // Mutable Flag state (guarded by data_guard_). + // Additional bool to protect against multiple concurrent constructions + // of `data_guard_`. + bool is_data_guard_inited_ = false; // Has flag value been modified? bool modified_ ABSL_GUARDED_BY(*DataGuard()) = false; // Specified on command line. @@ -261,22 +266,20 @@ class FlagImpl { // For some types, a copy of the current value is kept in an atomically // accessible field. std::atomic atomic_{flags_internal::AtomicInit()}; - // Mutation callback - FlagCallback callback_ = nullptr; - - // Lazily initialized mutexes for this flag value. We cannot inline a - // SpinLock or Mutex here because those have non-constexpr constructors and - // so would prevent constant initialization of this type. - // TODO(rogeeff): fix it once Mutex has constexpr constructor - // The following struct contains the locks in a CommandLineFlag struct. - // They are in a separate struct that is lazily allocated to avoid problems - // with static initialization and to avoid multiple allocations. - struct CommandLineFlagLocks { - absl::Mutex primary_mu; // protects several fields in CommandLineFlag - absl::Mutex callback_mu; // used to serialize callbacks - }; - CommandLineFlagLocks* locks_ = nullptr; // locks, laziliy allocated. + struct CallbackData { + FlagCallback func; + absl::Mutex guard; // Guard for concurrent callback invocations. + }; + CallbackData* callback_data_ ABSL_GUARDED_BY(*DataGuard()) = nullptr; + // This is reserved space for an absl::Mutex to guard flag data. It will be + // initialized in FlagImpl::Init via placement new. + // We can't use "absl::Mutex data_guard_", since this class is not literal. + // We do not want to use "absl::Mutex* data_guard_", since this would require + // heap allocation during initialization, which is both slows program startup + // and can fail. Using reserved space + placement new allows us to avoid both + // problems. + alignas(absl::Mutex) mutable char data_guard_[sizeof(absl::Mutex)]; }; // This is "unspecified" implementation of absl::Flag type. @@ -354,7 +357,7 @@ class Flag final : public flags_internal::CommandLineFlag { private: friend class FlagState; - void Destroy() const override { impl_.Destroy(); } + void Destroy() override { impl_.Destroy(); } void Read(void* dst) const override { impl_.Read(*this, dst, &flags_internal::FlagOps); @@ -414,6 +417,7 @@ T* MakeFromDefaultValue(EmptyBraces) { } } // namespace flags_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FLAGS_INTERNAL_FLAG_H_ diff --git a/absl/flags/internal/parse.h b/absl/flags/internal/parse.h index fd3aca61..e534635b 100644 --- a/absl/flags/internal/parse.h +++ b/absl/flags/internal/parse.h @@ -27,6 +27,7 @@ ABSL_DECLARE_FLAG(std::vector, tryfromenv); ABSL_DECLARE_FLAG(std::vector, undefok); namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { enum class ArgvListAction { kRemoveParsedArgs, kKeepParsedArgs }; @@ -43,6 +44,7 @@ std::vector ParseCommandLineImpl(int argc, char* argv[], OnUndefinedFlag on_undef_flag); } // namespace flags_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FLAGS_INTERNAL_PARSE_H_ diff --git a/absl/flags/internal/path_util.h b/absl/flags/internal/path_util.h index 5615c0e6..41696377 100644 --- a/absl/flags/internal/path_util.h +++ b/absl/flags/internal/path_util.h @@ -20,6 +20,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { // A portable interface that returns the basename of the filename passed as an @@ -55,6 +56,7 @@ inline absl::string_view Package(absl::string_view filename) { } } // namespace flags_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FLAGS_INTERNAL_PATH_UTIL_H_ diff --git a/absl/flags/internal/program_name.cc b/absl/flags/internal/program_name.cc index f0811f14..df0c3309 100644 --- a/absl/flags/internal/program_name.cc +++ b/absl/flags/internal/program_name.cc @@ -21,6 +21,7 @@ #include "absl/synchronization/mutex.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { ABSL_CONST_INIT static absl::Mutex program_name_guard(absl::kConstInit); @@ -50,4 +51,5 @@ void SetProgramInvocationName(absl::string_view prog_name_str) { } } // namespace flags_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/flags/internal/program_name.h b/absl/flags/internal/program_name.h index 326f24bb..317a7c5c 100644 --- a/absl/flags/internal/program_name.h +++ b/absl/flags/internal/program_name.h @@ -24,6 +24,7 @@ // Program name namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { // Returns program invocation name or "UNKNOWN" if `SetProgramInvocationName()` @@ -42,6 +43,7 @@ std::string ShortProgramInvocationName(); void SetProgramInvocationName(absl::string_view prog_name_str); } // namespace flags_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FLAGS_INTERNAL_PROGRAM_NAME_H_ diff --git a/absl/flags/internal/registry.cc b/absl/flags/internal/registry.cc index 52d9f3c7..5eae933c 100644 --- a/absl/flags/internal/registry.cc +++ b/absl/flags/internal/registry.cc @@ -30,6 +30,7 @@ // set it. namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { // -------------------------------------------------------------------- @@ -281,7 +282,7 @@ class RetiredFlagObj final : public flags_internal::CommandLineFlag { op_(ops) {} private: - void Destroy() const override { + void Destroy() override { // Values are heap allocated for Retired Flags. delete this; } @@ -336,4 +337,5 @@ bool IsRetiredFlag(absl::string_view name, bool* type_is_bool) { } } // namespace flags_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/flags/internal/registry.h b/absl/flags/internal/registry.h index 1889f3a0..d2145a8a 100644 --- a/absl/flags/internal/registry.h +++ b/absl/flags/internal/registry.h @@ -27,6 +27,7 @@ // Global flags registry API. namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { CommandLineFlag* FindCommandLineFlag(absl::string_view name); @@ -115,6 +116,7 @@ class FlagSaver { }; } // namespace flags_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FLAGS_INTERNAL_REGISTRY_H_ diff --git a/absl/flags/internal/type_erased.cc b/absl/flags/internal/type_erased.cc index a1650fcf..7910db8f 100644 --- a/absl/flags/internal/type_erased.cc +++ b/absl/flags/internal/type_erased.cc @@ -21,6 +21,7 @@ #include "absl/strings/str_cat.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { bool GetCommandLineOption(absl::string_view name, std::string* value) { @@ -79,4 +80,5 @@ bool SpecifiedOnCommandLine(absl::string_view name) { } } // namespace flags_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/flags/internal/type_erased.h b/absl/flags/internal/type_erased.h index a9551166..6cbd84cd 100644 --- a/absl/flags/internal/type_erased.h +++ b/absl/flags/internal/type_erased.h @@ -25,6 +25,7 @@ // Registry interfaces operating on type erased handles. namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { // If a flag named "name" exists, store its current value in *OUTPUT @@ -81,6 +82,7 @@ inline bool GetByName(absl::string_view name, T* dst) { } } // namespace flags_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FLAGS_INTERNAL_TYPE_ERASED_H_ diff --git a/absl/flags/internal/usage.cc b/absl/flags/internal/usage.cc index dc12e32f..4602c019 100644 --- a/absl/flags/internal/usage.cc +++ b/absl/flags/internal/usage.cc @@ -44,6 +44,7 @@ ABSL_FLAG(std::string, helpmatch, "", "show help on modules whose name contains the specified substr"); namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { namespace { @@ -404,4 +405,5 @@ int HandleUsageFlags(std::ostream& out, } } // namespace flags_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/flags/internal/usage.h b/absl/flags/internal/usage.h index 76075b08..5e8ca6a1 100644 --- a/absl/flags/internal/usage.h +++ b/absl/flags/internal/usage.h @@ -27,6 +27,7 @@ // Usage reporting interfaces namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { // The format to report the help messages in. @@ -64,6 +65,7 @@ int HandleUsageFlags(std::ostream& out, absl::string_view program_usage_message); } // namespace flags_internal +ABSL_NAMESPACE_END } // namespace absl ABSL_DECLARE_FLAG(bool, help); diff --git a/absl/flags/marshalling.cc b/absl/flags/marshalling.cc index f4ebe0e3..87020a27 100644 --- a/absl/flags/marshalling.cc +++ b/absl/flags/marshalling.cc @@ -27,6 +27,7 @@ #include "absl/strings/str_split.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { // -------------------------------------------------------------------- @@ -226,4 +227,5 @@ std::string AbslUnparseFlag(absl::LogSeverity v) { return absl::UnparseFlag(static_cast(v)); } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/flags/marshalling.h b/absl/flags/marshalling.h index 6d391804..b9fca752 100644 --- a/absl/flags/marshalling.h +++ b/absl/flags/marshalling.h @@ -168,6 +168,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { // Overloads of `AbslParseFlag()` and `AbslUnparseFlag()` for fundamental types. @@ -256,6 +257,7 @@ enum class LogSeverity : int; bool AbslParseFlag(absl::string_view, absl::LogSeverity*, std::string*); std::string AbslUnparseFlag(absl::LogSeverity); +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FLAGS_MARSHALLING_H_ diff --git a/absl/flags/parse.cc b/absl/flags/parse.cc index 16c4d68f..5a56a356 100644 --- a/absl/flags/parse.cc +++ b/absl/flags/parse.cc @@ -38,6 +38,7 @@ // -------------------------------------------------------------------- namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { namespace { @@ -52,6 +53,7 @@ ABSL_CONST_INIT bool tryfromenv_needs_processing } // namespace } // namespace flags_internal +ABSL_NAMESPACE_END } // namespace absl ABSL_FLAG(std::vector, flagfile, {}, @@ -109,6 +111,7 @@ ABSL_FLAG(std::vector, undefok, {}, "with that name"); namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { namespace { @@ -748,4 +751,5 @@ std::vector ParseCommandLine(int argc, char* argv[]) { flags_internal::OnUndefinedFlag::kAbortIfUndefined); } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/flags/parse.h b/absl/flags/parse.h index dbb75101..871fc993 100644 --- a/absl/flags/parse.h +++ b/absl/flags/parse.h @@ -29,6 +29,7 @@ #include "absl/flags/internal/parse.h" namespace absl { +ABSL_NAMESPACE_BEGIN // ParseCommandLine() // @@ -53,6 +54,7 @@ namespace absl { // help messages and then exits the program. std::vector ParseCommandLine(int argc, char* argv[]); +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FLAGS_PARSE_H_ diff --git a/absl/flags/usage.cc b/absl/flags/usage.cc index dff7a3da..60459bc2 100644 --- a/absl/flags/usage.cc +++ b/absl/flags/usage.cc @@ -20,6 +20,7 @@ #include "absl/synchronization/mutex.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { namespace { ABSL_CONST_INIT absl::Mutex usage_message_guard(absl::kConstInit); @@ -53,4 +54,5 @@ absl::string_view ProgramUsageMessage() { : "Warning: SetProgramUsageMessage() never called"; } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/flags/usage.h b/absl/flags/usage.h index 3a121071..299e5c34 100644 --- a/absl/flags/usage.h +++ b/absl/flags/usage.h @@ -22,6 +22,7 @@ // Usage reporting interfaces namespace absl { +ABSL_NAMESPACE_BEGIN // Sets the "usage" message to be used by help reporting routines. // For example: @@ -35,6 +36,7 @@ void SetProgramUsageMessage(absl::string_view new_usage_message); // Returns the usage message set by SetProgramUsageMessage(). absl::string_view ProgramUsageMessage(); +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FLAGS_USAGE_H_ diff --git a/absl/flags/usage_config.cc b/absl/flags/usage_config.cc index f97bf300..21a2dd01 100644 --- a/absl/flags/usage_config.cc +++ b/absl/flags/usage_config.cc @@ -34,6 +34,7 @@ ABSL_ATTRIBUTE_WEAK void AbslInternalReportFatalUsageError(absl::string_view) {} } // extern "C" namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { namespace { @@ -149,4 +150,5 @@ void SetFlagsUsageConfig(FlagsUsageConfig usage_config) { flags_internal::custom_usage_config = new FlagsUsageConfig(usage_config); } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/flags/usage_config.h b/absl/flags/usage_config.h index bfd0eedb..e6428e0a 100644 --- a/absl/flags/usage_config.h +++ b/absl/flags/usage_config.h @@ -54,6 +54,7 @@ // Shows help on modules whose name contains the specified substring namespace absl { +ABSL_NAMESPACE_BEGIN namespace flags_internal { using FlagKindFilter = std::function; @@ -118,6 +119,7 @@ FlagsUsageConfig GetUsageConfig(); void ReportUsageError(absl::string_view msg, bool is_fatal); } // namespace flags_internal +ABSL_NAMESPACE_END } // namespace absl extern "C" { diff --git a/absl/functional/function_ref.h b/absl/functional/function_ref.h index 42d9f16f..370acc55 100644 --- a/absl/functional/function_ref.h +++ b/absl/functional/function_ref.h @@ -54,6 +54,7 @@ #include "absl/meta/type_traits.h" namespace absl { +ABSL_NAMESPACE_BEGIN // FunctionRef // @@ -132,6 +133,7 @@ class FunctionRef { absl::functional_internal::Invoker invoker_; }; +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FUNCTIONAL_FUNCTION_REF_H_ diff --git a/absl/functional/function_ref_benchmark.cc b/absl/functional/function_ref_benchmark.cc index f6dfcabf..045305bf 100644 --- a/absl/functional/function_ref_benchmark.cc +++ b/absl/functional/function_ref_benchmark.cc @@ -20,6 +20,7 @@ #include "absl/base/attributes.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace { int dummy = 0; @@ -137,4 +138,5 @@ void BM_NonTrivialArgsFunctionRef(benchmark::State& state) { BENCHMARK(BM_NonTrivialArgsFunctionRef); } // namespace +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/functional/function_ref_test.cc b/absl/functional/function_ref_test.cc index 90829db0..3aa59745 100644 --- a/absl/functional/function_ref_test.cc +++ b/absl/functional/function_ref_test.cc @@ -22,6 +22,7 @@ #include "absl/memory/memory.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace { void RunFun(FunctionRef f) { f(); } @@ -252,4 +253,5 @@ TEST(FunctionRef, PassByValueTypes) { } } // namespace +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/functional/internal/function_ref.h b/absl/functional/internal/function_ref.h index fcb0496c..d1575054 100644 --- a/absl/functional/internal/function_ref.h +++ b/absl/functional/internal/function_ref.h @@ -23,6 +23,7 @@ #include "absl/meta/type_traits.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace functional_internal { // Like a void* that can handle function pointers as well. The standard does not @@ -99,6 +100,7 @@ template using EnableIf = typename ::std::enable_if::type; } // namespace functional_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FUNCTIONAL_INTERNAL_FUNCTION_REF_H_ diff --git a/absl/hash/hash.h b/absl/hash/hash.h index 297dc9cb..23a65ea8 100644 --- a/absl/hash/hash.h +++ b/absl/hash/hash.h @@ -73,6 +73,7 @@ #include "absl/hash/internal/hash.h" namespace absl { +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // `absl::Hash` @@ -317,6 +318,7 @@ class HashState : public hash_internal::HashStateBase { void (*combine_contiguous_)(void*, const unsigned char*, size_t); }; +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HASH_HASH_H_ diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc index 42c0c3d8..7a9d57f7 100644 --- a/absl/hash/hash_test.cc +++ b/absl/hash/hash_test.cc @@ -681,6 +681,7 @@ H AbslHashValue(H state, CustomHashType t) { } // namespace namespace absl { +ABSL_NAMESPACE_BEGIN namespace hash_internal { template struct is_uniquely_represented< @@ -688,6 +689,7 @@ struct is_uniquely_represented< typename EnableIfContained::type> : std::true_type {}; } // namespace hash_internal +ABSL_NAMESPACE_END } // namespace absl #if ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ diff --git a/absl/hash/hash_testing.h b/absl/hash/hash_testing.h index c45bc154..1e1c5741 100644 --- a/absl/hash/hash_testing.h +++ b/absl/hash/hash_testing.h @@ -28,6 +28,7 @@ #include "absl/types/variant.h" namespace absl { +ABSL_NAMESPACE_BEGIN // Run the absl::Hash algorithm over all the elements passed in and verify that // their hash expansion is congruent with their `==` operator. @@ -371,6 +372,7 @@ VerifyTypeImplementsAbslHashCorrectly(std::initializer_list values, equals); } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HASH_HASH_TESTING_H_ diff --git a/absl/hash/internal/city.cc b/absl/hash/internal/city.cc index dc7650a7..e122c184 100644 --- a/absl/hash/internal/city.cc +++ b/absl/hash/internal/city.cc @@ -30,6 +30,7 @@ #include "absl/base/optimization.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace hash_internal { #ifdef ABSL_IS_BIG_ENDIAN @@ -341,4 +342,5 @@ uint64_t CityHash64WithSeeds(const char *s, size_t len, uint64_t seed0, } } // namespace hash_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/hash/internal/city.h b/absl/hash/internal/city.h index b43d3407..161c7748 100644 --- a/absl/hash/internal/city.h +++ b/absl/hash/internal/city.h @@ -47,9 +47,13 @@ #include #include // for size_t. + #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace hash_internal { typedef std::pair uint128; @@ -86,6 +90,7 @@ inline uint64_t Hash128to64(const uint128 &x) { } } // namespace hash_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HASH_INTERNAL_CITY_H_ diff --git a/absl/hash/internal/city_test.cc b/absl/hash/internal/city_test.cc index 71b4ecce..251d381d 100644 --- a/absl/hash/internal/city_test.cc +++ b/absl/hash/internal/city_test.cc @@ -20,6 +20,7 @@ #include "gtest/gtest.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace hash_internal { static const uint64_t k0 = 0xc3a5c85c97cb3127ULL; @@ -590,4 +591,5 @@ TEST(CityHashTest, Unchanging) { } } // namespace hash_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/hash/internal/hash.cc b/absl/hash/internal/hash.cc index c17f3be1..b44ecb3a 100644 --- a/absl/hash/internal/hash.cc +++ b/absl/hash/internal/hash.cc @@ -15,6 +15,7 @@ #include "absl/hash/internal/hash.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace hash_internal { uint64_t CityHashState::CombineLargeContiguousImpl32(uint64_t state, @@ -50,4 +51,5 @@ uint64_t CityHashState::CombineLargeContiguousImpl64(uint64_t state, ABSL_CONST_INIT const void* const CityHashState::kSeed = &kSeed; } // namespace hash_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h index 7d44f57d..2564978a 100644 --- a/absl/hash/internal/hash.h +++ b/absl/hash/internal/hash.h @@ -50,6 +50,7 @@ #include "absl/hash/internal/city.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace hash_internal { class PiecewiseCombiner; @@ -980,6 +981,7 @@ H PiecewiseCombiner::finalize(H state) { } } // namespace hash_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HASH_INTERNAL_HASH_H_ diff --git a/absl/hash/internal/spy_hash_state.h b/absl/hash/internal/spy_hash_state.h index 05c7cafe..c0831208 100644 --- a/absl/hash/internal/spy_hash_state.h +++ b/absl/hash/internal/spy_hash_state.h @@ -25,6 +25,7 @@ #include "absl/strings/str_join.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace hash_internal { // SpyHashState is an implementation of the HashState API that simply @@ -224,6 +225,7 @@ void AbslHashValue(SpyHashStateImpl, const U&); using SpyHashState = SpyHashStateImpl; } // namespace hash_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HASH_INTERNAL_SPY_HASH_STATE_H_ diff --git a/absl/memory/memory.h b/absl/memory/memory.h index 243a5dda..513f7103 100644 --- a/absl/memory/memory.h +++ b/absl/memory/memory.h @@ -34,6 +34,7 @@ #include "absl/meta/type_traits.h" namespace absl { +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // Function Template: WrapUnique() @@ -688,6 +689,7 @@ void CopyRange(Allocator& alloc, Iterator destination, InputIterator first, } } } // namespace memory_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_MEMORY_MEMORY_H_ diff --git a/absl/memory/memory_exception_safety_test.cc b/absl/memory/memory_exception_safety_test.cc index 729507e9..c0910dc7 100644 --- a/absl/memory/memory_exception_safety_test.cc +++ b/absl/memory/memory_exception_safety_test.cc @@ -22,6 +22,7 @@ #include "absl/base/internal/exception_safety_testing.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace { constexpr int kLength = 50; @@ -53,6 +54,7 @@ TEST(MakeUnique, CheckForLeaks) { } } // namespace +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HAVE_EXCEPTIONS diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h index 8cd5f043..ba87d2f0 100644 --- a/absl/meta/type_traits.h +++ b/absl/meta/type_traits.h @@ -48,6 +48,7 @@ #endif namespace absl { +ABSL_NAMESPACE_BEGIN // Defined and documented later on in this file. template @@ -752,6 +753,7 @@ using swap_internal::Swap; using swap_internal::StdSwapIsUnconstrained; } // namespace type_traits_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_META_TYPE_TRAITS_H_ diff --git a/absl/numeric/int128.cc b/absl/numeric/int128.cc index 1eba09de..a20a77e7 100644 --- a/absl/numeric/int128.cc +++ b/absl/numeric/int128.cc @@ -23,6 +23,7 @@ #include namespace absl { +ABSL_NAMESPACE_BEGIN const uint128 kuint128max = MakeUint128(std::numeric_limits::max(), std::numeric_limits::max()); @@ -349,6 +350,7 @@ std::ostream& operator<<(std::ostream& os, int128 v) { return os << rep; } +ABSL_NAMESPACE_END } // namespace absl namespace std { diff --git a/absl/numeric/int128.h b/absl/numeric/int128.h index 50617612..718f70b1 100644 --- a/absl/numeric/int128.h +++ b/absl/numeric/int128.h @@ -49,6 +49,7 @@ #endif // defined(_MSC_VER) namespace absl { +ABSL_NAMESPACE_BEGIN class int128; @@ -245,6 +246,7 @@ constexpr uint128 Uint128Max() { (std::numeric_limits::max)()); } +ABSL_NAMESPACE_END } // namespace absl // Specialized numeric_limits for uint128. @@ -293,6 +295,7 @@ class numeric_limits { } // namespace std namespace absl { +ABSL_NAMESPACE_BEGIN // int128 // @@ -478,6 +481,7 @@ constexpr int128 Int128Min() { return int128((std::numeric_limits::min)(), 0); } +ABSL_NAMESPACE_END } // namespace absl // Specialized numeric_limits for int128. @@ -529,6 +533,7 @@ class numeric_limits { // Implementation details follow // -------------------------------------------------------------------------- namespace absl { +ABSL_NAMESPACE_BEGIN constexpr uint128 MakeUint128(uint64_t high, uint64_t low) { return uint128(high, low); @@ -1078,6 +1083,7 @@ constexpr int64_t BitCastToSigned(uint64_t v) { #include "absl/numeric/int128_no_intrinsic.inc" // IWYU pragma: export #endif // ABSL_HAVE_INTRINSIC_INT128 +ABSL_NAMESPACE_END } // namespace absl #undef ABSL_INTERNAL_WCHAR_T diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt index 13e96357..46dbc3ef 100644 --- a/absl/random/CMakeLists.txt +++ b/absl/random/CMakeLists.txt @@ -526,6 +526,8 @@ absl_cc_library( ${ABSL_DEFAULT_COPTS} LINKOPTS ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::config ) # Internal-only target, do not depend on directly. @@ -559,6 +561,8 @@ absl_cc_library( ${ABSL_DEFAULT_COPTS} LINKOPTS ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::config ) # Internal-only target, do not depend on directly. @@ -618,6 +622,8 @@ absl_cc_library( ${ABSL_DEFAULT_COPTS} LINKOPTS ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::config TESTONLY ) @@ -631,6 +637,8 @@ absl_cc_library( ${ABSL_DEFAULT_COPTS} LINKOPTS ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::config TESTONLY ) @@ -782,6 +790,8 @@ absl_cc_library( ${ABSL_DEFAULT_COPTS} LINKOPTS ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::config ) # Internal-only target, do not depend on directly. @@ -816,6 +826,7 @@ absl_cc_library( ${ABSL_DEFAULT_LINKOPTS} DEPS absl::random_internal_platform + absl::config ) # Internal-only target, do not depend on directly. @@ -835,6 +846,7 @@ absl_cc_library( DEPS absl::random_internal_platform absl::random_internal_randen_hwaes_impl + absl::config ) # Internal-only target, do not depend on directly. @@ -851,6 +863,7 @@ absl_cc_library( ${ABSL_DEFAULT_LINKOPTS} DEPS absl::random_internal_platform + absl::config ) # Internal-only target, do not depend on directly. @@ -868,6 +881,7 @@ absl_cc_library( LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS + absl::config absl::core_headers absl::raw_logging_internal absl::strings diff --git a/absl/random/bernoulli_distribution.h b/absl/random/bernoulli_distribution.h index 326fcb6e..25bd0d5c 100644 --- a/absl/random/bernoulli_distribution.h +++ b/absl/random/bernoulli_distribution.h @@ -24,6 +24,7 @@ #include "absl/random/internal/iostream_state_saver.h" namespace absl { +ABSL_NAMESPACE_BEGIN // absl::bernoulli_distribution is a drop in replacement for // std::bernoulli_distribution. It guarantees that (given a perfect @@ -193,6 +194,7 @@ bool bernoulli_distribution::Generate(double p, } } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_BERNOULLI_DISTRIBUTION_H_ diff --git a/absl/random/beta_distribution.h b/absl/random/beta_distribution.h index b09b02f0..c154066f 100644 --- a/absl/random/beta_distribution.h +++ b/absl/random/beta_distribution.h @@ -29,6 +29,7 @@ #include "absl/random/internal/iostream_state_saver.h" namespace absl { +ABSL_NAMESPACE_BEGIN // absl::beta_distribution: // Generate a floating-point variate conforming to a Beta distribution: @@ -420,6 +421,7 @@ std::basic_istream& operator>>( return is; } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_BETA_DISTRIBUTION_H_ diff --git a/absl/random/bit_gen_ref.h b/absl/random/bit_gen_ref.h index 00e904f8..e8771162 100644 --- a/absl/random/bit_gen_ref.h +++ b/absl/random/bit_gen_ref.h @@ -31,6 +31,7 @@ #include "absl/random/internal/mocking_bit_gen_base.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { template @@ -146,6 +147,7 @@ struct DistributionCaller { }; } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_BIT_GEN_REF_H_ diff --git a/absl/random/bit_gen_ref_test.cc b/absl/random/bit_gen_ref_test.cc index bc02ca5c..ca0e4d70 100644 --- a/absl/random/bit_gen_ref_test.cc +++ b/absl/random/bit_gen_ref_test.cc @@ -21,6 +21,7 @@ #include "absl/random/random.h" namespace absl { +ABSL_NAMESPACE_BEGIN class ConstBitGen : public absl::random_internal::MockingBitGenBase { bool CallImpl(const std::type_info&, void*, void* result) override { @@ -96,4 +97,5 @@ TEST(BitGenRefTest, MockingBitGenBaseOverrides) { EXPECT_EQ(FnTest(gen_ref), 42); // Copy } } // namespace +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/random/discrete_distribution.cc b/absl/random/discrete_distribution.cc index e6c09c51..081accee 100644 --- a/absl/random/discrete_distribution.cc +++ b/absl/random/discrete_distribution.cc @@ -15,6 +15,7 @@ #include "absl/random/discrete_distribution.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // Initializes the distribution table for Walker's Aliasing algorithm, described @@ -93,4 +94,5 @@ std::vector> InitDiscreteDistribution( } } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/random/discrete_distribution.h b/absl/random/discrete_distribution.h index 1560f03c..171aa11a 100644 --- a/absl/random/discrete_distribution.h +++ b/absl/random/discrete_distribution.h @@ -29,6 +29,7 @@ #include "absl/random/uniform_int_distribution.h" namespace absl { +ABSL_NAMESPACE_BEGIN // absl::discrete_distribution // @@ -240,6 +241,7 @@ std::basic_istream& operator>>( return is; } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_DISCRETE_DISTRIBUTION_H_ diff --git a/absl/random/distribution_format_traits.h b/absl/random/distribution_format_traits.h index f9f07058..22b358cc 100644 --- a/absl/random/distribution_format_traits.h +++ b/absl/random/distribution_format_traits.h @@ -36,6 +36,7 @@ #include "absl/types/span.h" namespace absl { +ABSL_NAMESPACE_BEGIN struct IntervalClosedClosedTag; struct IntervalClosedOpenTag; @@ -271,6 +272,7 @@ struct DistributionFormatTraits> { }; } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_DISTRIBUTION_FORMAT_TRAITS_H_ diff --git a/absl/random/distributions.h b/absl/random/distributions.h index 6ced6061..c1fb6650 100644 --- a/absl/random/distributions.h +++ b/absl/random/distributions.h @@ -67,6 +67,7 @@ #include "absl/random/zipf_distribution.h" namespace absl { +ABSL_NAMESPACE_BEGIN ABSL_INTERNAL_INLINE_CONSTEXPR(IntervalClosedClosedTag, IntervalClosedClosed, {}); @@ -458,6 +459,7 @@ IntType Zipf(URBG&& urbg, // NOLINT(runtime/references) distribution_t, format_t>(&urbg, hi, q, v); } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_DISTRIBUTIONS_H_ diff --git a/absl/random/exponential_distribution.h b/absl/random/exponential_distribution.h index 24abf57e..b5caf8a1 100644 --- a/absl/random/exponential_distribution.h +++ b/absl/random/exponential_distribution.h @@ -27,6 +27,7 @@ #include "absl/random/internal/iostream_state_saver.h" namespace absl { +ABSL_NAMESPACE_BEGIN // absl::exponential_distribution: // Generates a number conforming to an exponential distribution and is @@ -158,6 +159,7 @@ std::basic_istream& operator>>( return is; } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_EXPONENTIAL_DISTRIBUTION_H_ diff --git a/absl/random/gaussian_distribution.cc b/absl/random/gaussian_distribution.cc index 5dd84619..c7a72cb2 100644 --- a/absl/random/gaussian_distribution.cc +++ b/absl/random/gaussian_distribution.cc @@ -4,6 +4,7 @@ #include "absl/random/gaussian_distribution.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { const gaussian_distribution_base::Tables @@ -96,6 +97,7 @@ const gaussian_distribution_base::Tables 0.9362826816850632339, 0.9635996931270905952, 1}}; } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl // clang-format on diff --git a/absl/random/gaussian_distribution.h b/absl/random/gaussian_distribution.h index c299e944..c1427b06 100644 --- a/absl/random/gaussian_distribution.h +++ b/absl/random/gaussian_distribution.h @@ -33,6 +33,7 @@ #include "absl/random/internal/iostream_state_saver.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // absl::gaussian_distribution_base implements the underlying ziggurat algorithm @@ -267,6 +268,7 @@ inline double gaussian_distribution_base::zignor( } } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_GAUSSIAN_DISTRIBUTION_H_ diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel index 952929ea..d7ad4efe 100644 --- a/absl/random/internal/BUILD.bazel +++ b/absl/random/internal/BUILD.bazel @@ -51,6 +51,7 @@ cc_library( visibility = [ "//absl/random:__pkg__", ], + deps = ["//absl/base:config"], ) cc_library( @@ -78,6 +79,7 @@ cc_library( visibility = [ "//absl/random:__pkg__", ], + deps = ["//absl/base:config"], ) cc_library( @@ -138,6 +140,7 @@ cc_library( ], copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, + deps = ["//absl/base:config"], ) cc_library( @@ -148,6 +151,7 @@ cc_library( ], copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, + deps = ["//absl/base:config"], ) cc_library( @@ -269,6 +273,7 @@ cc_library( "randen-keys.inc", "platform.h", ], + deps = ["//absl/base:config"], ) cc_library( @@ -297,6 +302,7 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":platform", + "//absl/base:config", "//absl/base:core_headers", ], ) @@ -317,6 +323,7 @@ cc_library( deps = [ ":platform", ":randen_hwaes_impl", + "//absl/base:config", ], ) @@ -338,6 +345,7 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":platform", + "//absl/base:config", "//absl/base:core_headers", ], ) @@ -368,6 +376,7 @@ cc_library( copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ + "//absl/base:config", "//absl/base:core_headers", "//absl/base:raw_logging_internal", "//absl/strings", diff --git a/absl/random/internal/chi_square.cc b/absl/random/internal/chi_square.cc index c0acc947..640d48ce 100644 --- a/absl/random/internal/chi_square.cc +++ b/absl/random/internal/chi_square.cc @@ -19,6 +19,7 @@ #include "absl/random/internal/distribution_test_util.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { namespace { @@ -227,4 +228,5 @@ double ChiSquarePValue(double chi_square, int dof) { } } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/random/internal/chi_square.h b/absl/random/internal/chi_square.h index fa8646f2..07f4fbe5 100644 --- a/absl/random/internal/chi_square.h +++ b/absl/random/internal/chi_square.h @@ -26,7 +26,10 @@ #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { constexpr const char kChiSquared[] = "chi-squared"; @@ -80,6 +83,7 @@ double ChiSquareValue(int dof, double p); double ChiSquarePValue(double chi_square, int dof); } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_CHI_SQUARE_H_ diff --git a/absl/random/internal/distribution_caller.h b/absl/random/internal/distribution_caller.h index 0318e1f8..02603cf8 100644 --- a/absl/random/internal/distribution_caller.h +++ b/absl/random/internal/distribution_caller.h @@ -19,7 +19,10 @@ #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // DistributionCaller provides an opportunity to overload the general @@ -51,6 +54,7 @@ struct DistributionCaller { }; } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_DISTRIBUTION_CALLER_H_ diff --git a/absl/random/internal/distribution_test_util.cc b/absl/random/internal/distribution_test_util.cc index 85c8d596..e9005658 100644 --- a/absl/random/internal/distribution_test_util.cc +++ b/absl/random/internal/distribution_test_util.cc @@ -25,6 +25,7 @@ #include "absl/strings/str_format.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { namespace { @@ -413,4 +414,5 @@ double MaxErrorTolerance(double acceptance_probability) { } } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/random/internal/distribution_test_util.h b/absl/random/internal/distribution_test_util.h index b5ba49fa..6d94cf6c 100644 --- a/absl/random/internal/distribution_test_util.h +++ b/absl/random/internal/distribution_test_util.h @@ -26,6 +26,7 @@ // non-test code. namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // http://webspace.ship.edu/pgmarr/Geo441/Lectures/Lec%205%20-%20Normality%20Testing.pdf @@ -106,6 +107,7 @@ double BetaIncomplete(double x, double p, double q); double BetaIncompleteInv(double p, double q, double alpha); } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_DISTRIBUTION_TEST_UTIL_H_ diff --git a/absl/random/internal/distributions.h b/absl/random/internal/distributions.h index c8cec02b..d7e3c016 100644 --- a/absl/random/internal/distributions.h +++ b/absl/random/internal/distributions.h @@ -23,6 +23,7 @@ #include "absl/random/internal/uniform_helper.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // In the absence of an explicitly provided return-type, the template @@ -45,6 +46,7 @@ using uniform_inferred_return_t = is_widening_convertible::value, B, A>::type>; } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_DISTRIBUTIONS_H_ diff --git a/absl/random/internal/explicit_seed_seq.h b/absl/random/internal/explicit_seed_seq.h index b660ece5..6a743eaf 100644 --- a/absl/random/internal/explicit_seed_seq.h +++ b/absl/random/internal/explicit_seed_seq.h @@ -22,7 +22,10 @@ #include #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // This class conforms to the C++ Standard "Seed Sequence" concept @@ -82,6 +85,7 @@ class ExplicitSeedSeq { }; } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_EXPLICIT_SEED_SEQ_H_ diff --git a/absl/random/internal/fast_uniform_bits.h b/absl/random/internal/fast_uniform_bits.h index e8df92f3..f13c8729 100644 --- a/absl/random/internal/fast_uniform_bits.h +++ b/absl/random/internal/fast_uniform_bits.h @@ -20,7 +20,10 @@ #include #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // Returns true if the input value is zero or a power of two. Useful for // determining if the range of output values in a URBG @@ -255,6 +258,7 @@ FastUniformBits::Generate(URBG& g, // NOLINT(runtime/references) } } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_FAST_UNIFORM_BITS_H_ diff --git a/absl/random/internal/fast_uniform_bits_test.cc b/absl/random/internal/fast_uniform_bits_test.cc index 9f2e8268..f5b837e5 100644 --- a/absl/random/internal/fast_uniform_bits_test.cc +++ b/absl/random/internal/fast_uniform_bits_test.cc @@ -19,6 +19,7 @@ #include "gtest/gtest.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { namespace { @@ -269,4 +270,5 @@ TEST(FastUniformBitsTest, URBG32bitRegression) { } // namespace } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/random/internal/fastmath.h b/absl/random/internal/fastmath.h index 4bd18410..6baeb5a7 100644 --- a/absl/random/internal/fastmath.h +++ b/absl/random/internal/fastmath.h @@ -25,6 +25,7 @@ #include "absl/base/internal/bits.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // Returns the position of the first bit set. @@ -67,6 +68,7 @@ inline constexpr uint64_t rotr(uint64_t value, uint8_t bits) { } } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_FASTMATH_H_ diff --git a/absl/random/internal/gaussian_distribution_gentables.cc b/absl/random/internal/gaussian_distribution_gentables.cc index 16a23cb2..a2bf0394 100644 --- a/absl/random/internal/gaussian_distribution_gentables.cc +++ b/absl/random/internal/gaussian_distribution_gentables.cc @@ -27,6 +27,7 @@ #include "absl/base/macros.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { namespace { @@ -135,6 +136,7 @@ void TableGenerator::Print(std::ostream* os) { } } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl int main(int, char**) { diff --git a/absl/random/internal/generate_real.h b/absl/random/internal/generate_real.h index 246d863e..20f6d208 100644 --- a/absl/random/internal/generate_real.h +++ b/absl/random/internal/generate_real.h @@ -29,6 +29,7 @@ #include "absl/random/internal/traits.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // Tristate tag types controlling the output of GenerateRealFromBits. @@ -139,6 +140,7 @@ inline RealType GenerateRealFromBits(uint64_t bits, int exp_bias = 0) { } } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_ diff --git a/absl/random/internal/iostream_state_saver.h b/absl/random/internal/iostream_state_saver.h index df88fa76..7378829a 100644 --- a/absl/random/internal/iostream_state_saver.h +++ b/absl/random/internal/iostream_state_saver.h @@ -24,6 +24,7 @@ #include "absl/numeric/int128.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // The null_state_saver does nothing. @@ -238,6 +239,7 @@ inline FloatType read_floating_point(IStream& is) { } } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_IOSTREAM_STATE_SAVER_H_ diff --git a/absl/random/internal/mock_overload_set.h b/absl/random/internal/mock_overload_set.h index 539313d7..c2a30d89 100644 --- a/absl/random/internal/mock_overload_set.h +++ b/absl/random/internal/mock_overload_set.h @@ -23,6 +23,7 @@ #include "absl/random/mocking_bit_gen.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { template @@ -85,5 +86,6 @@ struct MockOverloadSet }; } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_MOCK_OVERLOAD_SET_H_ diff --git a/absl/random/internal/mocking_bit_gen_base.h b/absl/random/internal/mocking_bit_gen_base.h index aff2ba6d..eeeae9d2 100644 --- a/absl/random/internal/mocking_bit_gen_base.h +++ b/absl/random/internal/mocking_bit_gen_base.h @@ -25,6 +25,7 @@ #include "absl/strings/str_cat.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // MockingBitGenExpectationFormatter is invoked to format unsatisfied mocks @@ -113,6 +114,7 @@ class MockingBitGenBase { }; // namespace random_internal } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_MOCKING_BIT_GEN_BASE_H_ diff --git a/absl/random/internal/nanobenchmark.cc b/absl/random/internal/nanobenchmark.cc index feb81c85..8fee77fc 100644 --- a/absl/random/internal/nanobenchmark.cc +++ b/absl/random/internal/nanobenchmark.cc @@ -70,6 +70,7 @@ #endif namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal_nanobenchmark { namespace { @@ -799,4 +800,5 @@ size_t Measure(const Func func, const void* arg, const FuncInput* inputs, } } // namespace random_internal_nanobenchmark +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/random/internal/nanobenchmark.h b/absl/random/internal/nanobenchmark.h index c2b650d1..a5097ba2 100644 --- a/absl/random/internal/nanobenchmark.h +++ b/absl/random/internal/nanobenchmark.h @@ -50,7 +50,10 @@ #include #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal_nanobenchmark { // Input influencing the function being measured (e.g. number of bytes to copy). @@ -163,6 +166,7 @@ static inline size_t MeasureClosure(const Closure& closure, } } // namespace random_internal_nanobenchmark +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_NANOBENCHMARK_H_ diff --git a/absl/random/internal/nanobenchmark_test.cc b/absl/random/internal/nanobenchmark_test.cc index 383345a8..ab824ef5 100644 --- a/absl/random/internal/nanobenchmark_test.cc +++ b/absl/random/internal/nanobenchmark_test.cc @@ -18,6 +18,7 @@ #include "absl/strings/numbers.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal_nanobenchmark { namespace { @@ -67,6 +68,7 @@ void RunAll(const int argc, char* argv[]) { } // namespace } // namespace random_internal_nanobenchmark +ABSL_NAMESPACE_END } // namespace absl int main(int argc, char* argv[]) { diff --git a/absl/random/internal/nonsecure_base.h b/absl/random/internal/nonsecure_base.h index 8847e74b..730fa2ea 100644 --- a/absl/random/internal/nonsecure_base.h +++ b/absl/random/internal/nonsecure_base.h @@ -33,6 +33,7 @@ #include "absl/types/span.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // Each instance of NonsecureURBGBase will be seeded by variates produced @@ -143,6 +144,7 @@ class NonsecureURBGBase { }; } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_NONSECURE_BASE_H_ diff --git a/absl/random/internal/pcg_engine.h b/absl/random/internal/pcg_engine.h index b5df4eaf..53c23fe1 100644 --- a/absl/random/internal/pcg_engine.h +++ b/absl/random/internal/pcg_engine.h @@ -24,6 +24,7 @@ #include "absl/random/internal/iostream_state_saver.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // pcg_engine is a simplified implementation of Melissa O'Neil's PCG engine in @@ -300,6 +301,7 @@ using pcg32_2018_engine = pcg_engine< random_internal::pcg_xsh_rr_64_32>; } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_PCG_ENGINE_H_ diff --git a/absl/random/internal/pool_urbg.cc b/absl/random/internal/pool_urbg.cc index f2e1c1f6..5bee5307 100644 --- a/absl/random/internal/pool_urbg.cc +++ b/absl/random/internal/pool_urbg.cc @@ -37,6 +37,7 @@ using absl::base_internal::SpinLock; using absl::base_internal::SpinLockHolder; namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { namespace { @@ -249,4 +250,5 @@ template class RandenPool; template class RandenPool; } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/random/internal/pool_urbg.h b/absl/random/internal/pool_urbg.h index 9b2dd4bf..05721929 100644 --- a/absl/random/internal/pool_urbg.h +++ b/absl/random/internal/pool_urbg.h @@ -22,6 +22,7 @@ #include "absl/types/span.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // RandenPool is a thread-safe random number generator [random.req.urbg] that @@ -124,6 +125,7 @@ class PoolURBG { }; } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_POOL_URBG_H_ diff --git a/absl/random/internal/randen.cc b/absl/random/internal/randen.cc index bab8075a..78a1e00c 100644 --- a/absl/random/internal/randen.cc +++ b/absl/random/internal/randen.cc @@ -41,6 +41,7 @@ // structured/low-entropy counters to digits of Pi. namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { namespace { @@ -86,4 +87,5 @@ Randen::Randen() { } } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/random/internal/randen.h b/absl/random/internal/randen.h index a4ff2545..c2834aaf 100644 --- a/absl/random/internal/randen.h +++ b/absl/random/internal/randen.h @@ -23,6 +23,7 @@ #include "absl/random/internal/randen_traits.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // RANDen = RANDom generator or beetroots in Swiss German. @@ -95,6 +96,7 @@ class Randen { }; } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_RANDEN_H_ diff --git a/absl/random/internal/randen_detect.cc b/absl/random/internal/randen_detect.cc index d5946b21..d63230c2 100644 --- a/absl/random/internal/randen_detect.cc +++ b/absl/random/internal/randen_detect.cc @@ -95,6 +95,7 @@ static uint32_t GetAuxval(uint32_t hwcap_type) { #endif namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // The default return at the end of the function might be unreachable depending @@ -216,4 +217,5 @@ bool CPUSupportsRandenHwAes() { #endif } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/random/internal/randen_detect.h b/absl/random/internal/randen_detect.h index 44c5c667..f283f432 100644 --- a/absl/random/internal/randen_detect.h +++ b/absl/random/internal/randen_detect.h @@ -15,7 +15,10 @@ #ifndef ABSL_RANDOM_INTERNAL_RANDEN_DETECT_H_ #define ABSL_RANDOM_INTERNAL_RANDEN_DETECT_H_ +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // Returns whether the current CPU supports RandenHwAes implementation. @@ -24,6 +27,7 @@ namespace random_internal { bool CPUSupportsRandenHwAes(); } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_RANDEN_DETECT_H_ diff --git a/absl/random/internal/randen_engine.h b/absl/random/internal/randen_engine.h index 02212a13..6b337313 100644 --- a/absl/random/internal/randen_engine.h +++ b/absl/random/internal/randen_engine.h @@ -28,6 +28,7 @@ #include "absl/random/internal/randen.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // Deterministic pseudorandom byte generator with backtracking resistance @@ -223,6 +224,7 @@ class alignas(16) randen_engine { }; } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_RANDEN_ENGINE_H_ diff --git a/absl/random/internal/randen_hwaes.cc b/absl/random/internal/randen_hwaes.cc index 6cc36fd3..e23844f1 100644 --- a/absl/random/internal/randen_hwaes.cc +++ b/absl/random/internal/randen_hwaes.cc @@ -75,6 +75,7 @@ #include namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // No accelerated implementation. @@ -106,6 +107,7 @@ void RandenHwAes::Generate(const void*, void*) { } } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #else // defined(ABSL_RANDEN_HWAES_IMPL) @@ -518,6 +520,7 @@ inline ABSL_TARGET_CRYPTO void Permute( } // namespace namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { bool HasRandenHwAesImplementation() { return true; } @@ -629,6 +632,7 @@ void ABSL_TARGET_CRYPTO RandenHwAes::Generate(const void* keys, #endif } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // (ABSL_RANDEN_HWAES_IMPL) diff --git a/absl/random/internal/randen_hwaes.h b/absl/random/internal/randen_hwaes.h index d8e6055f..bce36b52 100644 --- a/absl/random/internal/randen_hwaes.h +++ b/absl/random/internal/randen_hwaes.h @@ -15,12 +15,15 @@ #ifndef ABSL_RANDOM_INTERNAL_RANDEN_HWAES_H_ #define ABSL_RANDOM_INTERNAL_RANDEN_HWAES_H_ +#include "absl/base/config.h" + // HERMETIC NOTE: The randen_hwaes target must not introduce duplicate // symbols from arbitrary system and other headers, since it may be built // with different flags from other targets, using different levels of // optimization, potentially introducing ODR violations. namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // RANDen = RANDom generator or beetroots in Swiss German. @@ -41,6 +44,7 @@ class RandenHwAes { bool HasRandenHwAesImplementation(); } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_RANDEN_HWAES_H_ diff --git a/absl/random/internal/randen_slow.cc b/absl/random/internal/randen_slow.cc index e7959c7e..8d074582 100644 --- a/absl/random/internal/randen_slow.cc +++ b/absl/random/internal/randen_slow.cc @@ -462,6 +462,7 @@ inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void Permute( } // namespace namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { const void* RandenSlow::GetKeys() { @@ -501,4 +502,5 @@ void RandenSlow::Generate(const void* keys, void* state_void) { } } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/random/internal/randen_slow.h b/absl/random/internal/randen_slow.h index 30586130..72f92b54 100644 --- a/absl/random/internal/randen_slow.h +++ b/absl/random/internal/randen_slow.h @@ -17,7 +17,10 @@ #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // RANDen = RANDom generator or beetroots in Swiss German. @@ -38,6 +41,7 @@ class RandenSlow { }; } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_RANDEN_SLOW_H_ diff --git a/absl/random/internal/randen_traits.h b/absl/random/internal/randen_traits.h index 4f1f408d..2b8bbe73 100644 --- a/absl/random/internal/randen_traits.h +++ b/absl/random/internal/randen_traits.h @@ -22,7 +22,10 @@ #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // RANDen = RANDom generator or beetroots in Swiss German. @@ -54,6 +57,7 @@ struct RandenTraits { }; } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_RANDEN_TRAITS_H_ diff --git a/absl/random/internal/salted_seed_seq.h b/absl/random/internal/salted_seed_seq.h index 86487006..5953a090 100644 --- a/absl/random/internal/salted_seed_seq.h +++ b/absl/random/internal/salted_seed_seq.h @@ -30,6 +30,7 @@ #include "absl/types/span.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // This class conforms to the C++ Standard "Seed Sequence" concept @@ -160,6 +161,7 @@ SaltedSeedSeq::type> MakeSaltedSeedSeq(SSeq&& seq) { } } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_SALTED_SEED_SEQ_H_ diff --git a/absl/random/internal/seed_material.cc b/absl/random/internal/seed_material.cc index ab4dd0c2..4d38a574 100644 --- a/absl/random/internal/seed_material.cc +++ b/absl/random/internal/seed_material.cc @@ -61,6 +61,7 @@ #endif namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { namespace { @@ -214,4 +215,5 @@ absl::optional GetSaltMaterial() { } } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/random/internal/seed_material.h b/absl/random/internal/seed_material.h index 57de8a24..4be10e92 100644 --- a/absl/random/internal/seed_material.h +++ b/absl/random/internal/seed_material.h @@ -27,6 +27,7 @@ #include "absl/types/span.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // Returns the number of 32-bit blocks needed to contain the given number of @@ -97,6 +98,7 @@ void MixIntoSeedMaterial(absl::Span sequence, absl::optional GetSaltMaterial(); } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_SEED_MATERIAL_H_ diff --git a/absl/random/internal/sequence_urbg.h b/absl/random/internal/sequence_urbg.h index 9a9b5773..bc96a12c 100644 --- a/absl/random/internal/sequence_urbg.h +++ b/absl/random/internal/sequence_urbg.h @@ -21,7 +21,10 @@ #include #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // `sequence_urbg` is a simple random number generator which meets the @@ -51,6 +54,7 @@ class sequence_urbg { }; } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_SEQUENCE_URBG_H_ diff --git a/absl/random/internal/traits.h b/absl/random/internal/traits.h index 40eb011f..75772bd9 100644 --- a/absl/random/internal/traits.h +++ b/absl/random/internal/traits.h @@ -22,6 +22,7 @@ #include "absl/base/config.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // random_internal::is_widening_convertible @@ -94,6 +95,7 @@ struct make_unsigned_bits { }; } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_TRAITS_H_ diff --git a/absl/random/internal/uniform_helper.h b/absl/random/internal/uniform_helper.h index f68b1823..663107cb 100644 --- a/absl/random/internal/uniform_helper.h +++ b/absl/random/internal/uniform_helper.h @@ -22,6 +22,7 @@ #include "absl/meta/type_traits.h" namespace absl { +ABSL_NAMESPACE_BEGIN template class uniform_int_distribution; @@ -173,6 +174,7 @@ struct UniformDistributionWrapper : public UniformDistribution { }; } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_UNIFORM_HELPER_H_ diff --git a/absl/random/internal/wide_multiply.h b/absl/random/internal/wide_multiply.h index ebbfa1f2..6e4cf1be 100644 --- a/absl/random/internal/wide_multiply.h +++ b/absl/random/internal/wide_multiply.h @@ -31,6 +31,7 @@ #include "absl/random/internal/traits.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { // Helper object to multiply two 64-bit values to a 128-bit value. @@ -104,6 +105,7 @@ struct wide_multiply { #endif } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_WIDE_MULTIPLY_H_ diff --git a/absl/random/log_uniform_int_distribution.h b/absl/random/log_uniform_int_distribution.h index de58bdbe..960816e2 100644 --- a/absl/random/log_uniform_int_distribution.h +++ b/absl/random/log_uniform_int_distribution.h @@ -30,6 +30,7 @@ #include "absl/random/uniform_int_distribution.h" namespace absl { +ABSL_NAMESPACE_BEGIN // log_uniform_int_distribution: // @@ -247,6 +248,7 @@ std::basic_istream& operator>>( return is; } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_LOG_UNIFORM_INT_DISTRIBUTION_H_ diff --git a/absl/random/mock_distributions.h b/absl/random/mock_distributions.h index 1af98a24..d36d5ba0 100644 --- a/absl/random/mock_distributions.h +++ b/absl/random/mock_distributions.h @@ -53,6 +53,7 @@ #include "absl/random/mocking_bit_gen.h" namespace absl { +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // absl::MockUniform @@ -254,6 +255,7 @@ using MockZipf = IntType(MockingBitGen&, IntType, double, double)>; +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_MOCK_DISTRIBUTIONS_H_ diff --git a/absl/random/mocking_bit_gen.cc b/absl/random/mocking_bit_gen.cc index 73144528..6bb1e414 100644 --- a/absl/random/mocking_bit_gen.cc +++ b/absl/random/mocking_bit_gen.cc @@ -18,6 +18,7 @@ #include namespace absl { +ABSL_NAMESPACE_BEGIN MockingBitGen::~MockingBitGen() { for (const auto& del : deleters_) { @@ -25,4 +26,5 @@ MockingBitGen::~MockingBitGen() { } } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/random/mocking_bit_gen.h b/absl/random/mocking_bit_gen.h index d1b524a9..36cef911 100644 --- a/absl/random/mocking_bit_gen.h +++ b/absl/random/mocking_bit_gen.h @@ -51,6 +51,7 @@ #include "absl/utility/utility.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace random_internal { @@ -189,6 +190,7 @@ struct DistributionCaller { }; } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_MOCKING_BIT_GEN_H_ diff --git a/absl/random/poisson_distribution.h b/absl/random/poisson_distribution.h index 23a953ff..cb5f5d5d 100644 --- a/absl/random/poisson_distribution.h +++ b/absl/random/poisson_distribution.h @@ -28,6 +28,7 @@ #include "absl/random/internal/iostream_state_saver.h" namespace absl { +ABSL_NAMESPACE_BEGIN // absl::poisson_distribution: // Generates discrete variates conforming to a Poisson distribution. @@ -251,6 +252,7 @@ std::basic_istream& operator>>( return is; } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_POISSON_DISTRIBUTION_H_ diff --git a/absl/random/random.h b/absl/random/random.h index dc6852f4..c8f326e6 100644 --- a/absl/random/random.h +++ b/absl/random/random.h @@ -41,6 +41,7 @@ #include "absl/random/seed_sequences.h" // IWYU pragma: export namespace absl { +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // absl::BitGen @@ -182,6 +183,7 @@ using InsecureBitGen = // discards the intermediate results. // --------------------------------------------------------------------------- +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_RANDOM_H_ diff --git a/absl/random/seed_gen_exception.cc b/absl/random/seed_gen_exception.cc index e4271baa..fdcb54a8 100644 --- a/absl/random/seed_gen_exception.cc +++ b/absl/random/seed_gen_exception.cc @@ -19,6 +19,7 @@ #include "absl/base/config.h" namespace absl { +ABSL_NAMESPACE_BEGIN static constexpr const char kExceptionMessage[] = "Failed generating seed-material for URBG."; @@ -41,4 +42,5 @@ void ThrowSeedGenException() { } } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/random/seed_gen_exception.h b/absl/random/seed_gen_exception.h index b464d52f..53539005 100644 --- a/absl/random/seed_gen_exception.h +++ b/absl/random/seed_gen_exception.h @@ -28,7 +28,10 @@ #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN //------------------------------------------------------------------------------ // SeedGenException @@ -46,6 +49,7 @@ namespace random_internal { [[noreturn]] void ThrowSeedGenException(); } // namespace random_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_SEED_GEN_EXCEPTION_H_ diff --git a/absl/random/seed_sequences.cc b/absl/random/seed_sequences.cc index 9f319615..426eafd3 100644 --- a/absl/random/seed_sequences.cc +++ b/absl/random/seed_sequences.cc @@ -17,6 +17,7 @@ #include "absl/random/internal/pool_urbg.h" namespace absl { +ABSL_NAMESPACE_BEGIN SeedSeq MakeSeedSeq() { SeedSeq::result_type seed_material[8]; @@ -24,4 +25,5 @@ SeedSeq MakeSeedSeq() { return SeedSeq(std::begin(seed_material), std::end(seed_material)); } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/random/seed_sequences.h b/absl/random/seed_sequences.h index 631d1ecd..ff1340cc 100644 --- a/absl/random/seed_sequences.h +++ b/absl/random/seed_sequences.h @@ -34,6 +34,7 @@ #include "absl/types/span.h" namespace absl { +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // absl::SeedSeq @@ -103,6 +104,7 @@ SeedSeq CreateSeedSeqFrom(URBG* urbg) { // SeedSeq MakeSeedSeq(); +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_SEED_SEQUENCES_H_ diff --git a/absl/random/uniform_int_distribution.h b/absl/random/uniform_int_distribution.h index dc8ba8c1..da66564a 100644 --- a/absl/random/uniform_int_distribution.h +++ b/absl/random/uniform_int_distribution.h @@ -40,6 +40,7 @@ #include "absl/random/internal/wide_multiply.h" namespace absl { +ABSL_NAMESPACE_BEGIN // absl::uniform_int_distribution // @@ -268,6 +269,7 @@ uniform_int_distribution::Generate( return helper::hi(product); } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_UNIFORM_INT_DISTRIBUTION_H_ diff --git a/absl/random/uniform_real_distribution.h b/absl/random/uniform_real_distribution.h index bf2ed2c5..5ba17b23 100644 --- a/absl/random/uniform_real_distribution.h +++ b/absl/random/uniform_real_distribution.h @@ -45,6 +45,7 @@ #include "absl/random/internal/iostream_state_saver.h" namespace absl { +ABSL_NAMESPACE_BEGIN // absl::uniform_real_distribution // @@ -195,6 +196,7 @@ std::basic_istream& operator>>( } return is; } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_UNIFORM_REAL_DISTRIBUTION_H_ diff --git a/absl/random/zipf_distribution.h b/absl/random/zipf_distribution.h index d7b4ac38..22ebc756 100644 --- a/absl/random/zipf_distribution.h +++ b/absl/random/zipf_distribution.h @@ -26,6 +26,7 @@ #include "absl/random/uniform_real_distribution.h" namespace absl { +ABSL_NAMESPACE_BEGIN // absl::zipf_distribution produces random integer-values in the range [0, k], // distributed according to the discrete probability function: @@ -264,6 +265,7 @@ std::basic_istream& operator>>( return is; } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_ZIPF_DISTRIBUTION_H_ diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel index e38c8ad6..8d0a6b6d 100644 --- a/absl/strings/BUILD.bazel +++ b/absl/strings/BUILD.bazel @@ -94,6 +94,7 @@ cc_library( ], copts = ABSL_DEFAULT_COPTS, deps = [ + "//absl/base:config", "//absl/base:core_headers", "//absl/base:endian", "//absl/meta:type_traits", @@ -413,6 +414,7 @@ cc_test( deps = [ ":pow10_helper", ":strings", + "//absl/base:config", "//absl/base:raw_logging_internal", "//absl/random", "//absl/random:distributions", @@ -489,6 +491,7 @@ cc_test( copts = ABSL_TEST_COPTS, deps = [ ":strings", + "//absl/base:config", "//absl/base:raw_logging_internal", "@com_google_googletest//:gtest_main", ], @@ -504,6 +507,7 @@ cc_test( copts = ABSL_TEST_COPTS, deps = [ ":strings", + "//absl/base:config", "@com_google_googletest//:gtest_main", ], ) @@ -668,6 +672,7 @@ cc_library( srcs = ["internal/pow10_helper.cc"], hdrs = ["internal/pow10_helper.h"], visibility = ["//visibility:private"], + deps = ["//absl/base:config"], ) cc_test( diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt index cd52a472..98101573 100644 --- a/absl/strings/CMakeLists.txt +++ b/absl/strings/CMakeLists.txt @@ -81,6 +81,7 @@ absl_cc_library( COPTS ${ABSL_DEFAULT_COPTS} DEPS + absl::config absl::core_headers absl::endian absl::type_traits @@ -276,6 +277,7 @@ absl_cc_test( absl::strings absl::core_headers absl::pow10_helper + absl::config absl::raw_logging_internal absl::random_random absl::random_distributions @@ -331,6 +333,7 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::strings + absl::config absl::raw_logging_internal gmock_main ) @@ -346,6 +349,7 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::strings + absl::config gmock_main ) @@ -502,6 +506,8 @@ absl_cc_library( "internal/pow10_helper.cc" COPTS ${ABSL_TEST_COPTS} + DEPS + absl::config TESTONLY ) diff --git a/absl/strings/ascii.cc b/absl/strings/ascii.cc index 3f7c581f..abea3e4f 100644 --- a/absl/strings/ascii.cc +++ b/absl/strings/ascii.cc @@ -15,6 +15,7 @@ #include "absl/strings/ascii.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace ascii_internal { // # Table generated by this Python code (bit 0x02 is currently unused): @@ -195,4 +196,5 @@ void RemoveExtraAsciiWhitespace(std::string* str) { str->erase(output_it - &(*str)[0]); } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/ascii.h b/absl/strings/ascii.h index f9e4fd1d..792aabe5 100644 --- a/absl/strings/ascii.h +++ b/absl/strings/ascii.h @@ -59,6 +59,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace ascii_internal { // Declaration for an array of bitfields holding character information. @@ -234,6 +235,7 @@ inline void StripAsciiWhitespace(std::string* str) { // Removes leading, trailing, and consecutive internal whitespace. void RemoveExtraAsciiWhitespace(std::string*); +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_ASCII_H_ diff --git a/absl/strings/charconv.cc b/absl/strings/charconv.cc index bc07e7ab..d9bc2dd2 100644 --- a/absl/strings/charconv.cc +++ b/absl/strings/charconv.cc @@ -57,6 +57,7 @@ // narrower mantissas. namespace absl { +ABSL_NAMESPACE_BEGIN namespace { template @@ -980,4 +981,5 @@ const int16_t kPower10ExponentTable[] = { }; } // namespace +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/charconv.h b/absl/strings/charconv.h index 3f5891ba..e04be32f 100644 --- a/absl/strings/charconv.h +++ b/absl/strings/charconv.h @@ -17,7 +17,10 @@ #include // NOLINT(build/c++11) +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN // Workalike compatibilty version of std::chars_format from C++17. // @@ -110,6 +113,7 @@ inline chars_format& operator^=(chars_format& lhs, chars_format rhs) { return lhs; } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_CHARCONV_H_ diff --git a/absl/strings/escaping.cc b/absl/strings/escaping.cc index 18b746e3..d2fcd9c1 100644 --- a/absl/strings/escaping.cc +++ b/absl/strings/escaping.cc @@ -33,6 +33,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace { // These are used for the leave_nulls_escaped argument to CUnescapeInternal(). @@ -1106,4 +1107,5 @@ std::string BytesToHexString(absl::string_view from) { return result; } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/escaping.h b/absl/strings/escaping.h index 198b9348..f5ca26c5 100644 --- a/absl/strings/escaping.h +++ b/absl/strings/escaping.h @@ -33,6 +33,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN // CUnescape() // @@ -157,6 +158,7 @@ std::string HexStringToBytes(absl::string_view from); // `2*from.size()`. std::string BytesToHexString(absl::string_view from); +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_ESCAPING_H_ diff --git a/absl/strings/internal/char_map.h b/absl/strings/internal/char_map.h index b9108b8c..a76e6036 100644 --- a/absl/strings/internal/char_map.h +++ b/absl/strings/internal/char_map.h @@ -28,6 +28,7 @@ #include "absl/base/port.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { class Charmap { @@ -149,6 +150,7 @@ constexpr Charmap GraphCharmap() { return PrintCharmap() & ~SpaceCharmap(); } constexpr Charmap PunctCharmap() { return GraphCharmap() & ~AlnumCharmap(); } } // namespace strings_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_CHAR_MAP_H_ diff --git a/absl/strings/internal/charconv_bigint.cc b/absl/strings/internal/charconv_bigint.cc index 95d471d9..860c27b2 100644 --- a/absl/strings/internal/charconv_bigint.cc +++ b/absl/strings/internal/charconv_bigint.cc @@ -19,6 +19,7 @@ #include namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { namespace { @@ -354,4 +355,5 @@ template class BigUnsigned<4>; template class BigUnsigned<84>; } // namespace strings_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/internal/charconv_bigint.h b/absl/strings/internal/charconv_bigint.h index 7da9a7e7..108e1eb2 100644 --- a/absl/strings/internal/charconv_bigint.h +++ b/absl/strings/internal/charconv_bigint.h @@ -25,6 +25,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { // The largest power that 5 that can be raised to, and still fit in a uint32_t. @@ -414,6 +415,7 @@ extern template class BigUnsigned<4>; extern template class BigUnsigned<84>; } // namespace strings_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_CHARCONV_BIGINT_H_ diff --git a/absl/strings/internal/charconv_bigint_test.cc b/absl/strings/internal/charconv_bigint_test.cc index 745714ac..363bcb03 100644 --- a/absl/strings/internal/charconv_bigint_test.cc +++ b/absl/strings/internal/charconv_bigint_test.cc @@ -19,6 +19,7 @@ #include "gtest/gtest.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { TEST(BigUnsigned, ShiftLeft) { @@ -200,4 +201,5 @@ TEST(BigUnsigned, TenToTheNth) { } // namespace strings_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/internal/charconv_parse.cc b/absl/strings/internal/charconv_parse.cc index fa9a8965..d9a57a78 100644 --- a/absl/strings/internal/charconv_parse.cc +++ b/absl/strings/internal/charconv_parse.cc @@ -22,6 +22,7 @@ #include "absl/strings/internal/memutil.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace { // ParseFloat<10> will read the first 19 significant digits of the mantissa. @@ -499,4 +500,5 @@ template ParsedFloat ParseFloat<16>(const char* begin, const char* end, chars_format format_flags); } // namespace strings_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/internal/charconv_parse.h b/absl/strings/internal/charconv_parse.h index 44d06b2e..505998b5 100644 --- a/absl/strings/internal/charconv_parse.h +++ b/absl/strings/internal/charconv_parse.h @@ -17,9 +17,11 @@ #include +#include "absl/base/config.h" #include "absl/strings/charconv.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { // Enum indicating whether a parsed float is a number or special value. @@ -92,5 +94,6 @@ extern template ParsedFloat ParseFloat<16>(const char* begin, const char* end, absl::chars_format format_flags); } // namespace strings_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_CHARCONV_PARSE_H_ diff --git a/absl/strings/internal/escaping_test_common.h b/absl/strings/internal/escaping_test_common.h index bd803031..7b18017a 100644 --- a/absl/strings/internal/escaping_test_common.h +++ b/absl/strings/internal/escaping_test_common.h @@ -22,6 +22,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { struct base64_testcase { @@ -126,6 +127,7 @@ inline const std::array& base64_strings() { } } // namespace strings_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_ESCAPING_TEST_COMMON_H_ diff --git a/absl/strings/internal/memutil.cc b/absl/strings/internal/memutil.cc index 77aa63c2..2519c688 100644 --- a/absl/strings/internal/memutil.cc +++ b/absl/strings/internal/memutil.cc @@ -17,6 +17,7 @@ #include namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { int memcasecmp(const char* s1, const char* s2, size_t len) { @@ -107,4 +108,5 @@ const char* memmatch(const char* phaystack, size_t haylen, const char* pneedle, } } // namespace strings_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/internal/memutil.h b/absl/strings/internal/memutil.h index 7c071a82..9ad05358 100644 --- a/absl/strings/internal/memutil.h +++ b/absl/strings/internal/memutil.h @@ -69,6 +69,7 @@ #include "absl/strings/ascii.h" // for absl::ascii_tolower namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { inline char* memcat(char* dest, size_t destlen, const char* src, @@ -141,6 +142,7 @@ const char* memmatch(const char* phaystack, size_t haylen, const char* pneedle, size_t neelen); } // namespace strings_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_MEMUTIL_H_ diff --git a/absl/strings/internal/numbers_test_common.h b/absl/strings/internal/numbers_test_common.h index a263219e..1a1e50c4 100644 --- a/absl/strings/internal/numbers_test_common.h +++ b/absl/strings/internal/numbers_test_common.h @@ -23,7 +23,10 @@ #include #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { template @@ -175,6 +178,7 @@ inline const std::array& strtouint64_test_cases() { } } // namespace strings_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_NUMBERS_TEST_COMMON_H_ diff --git a/absl/strings/internal/ostringstream.cc b/absl/strings/internal/ostringstream.cc index d0f0f84b..05324c78 100644 --- a/absl/strings/internal/ostringstream.cc +++ b/absl/strings/internal/ostringstream.cc @@ -15,6 +15,7 @@ #include "absl/strings/internal/ostringstream.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { OStringStream::Buf::int_type OStringStream::overflow(int c) { @@ -31,4 +32,5 @@ std::streamsize OStringStream::xsputn(const char* s, std::streamsize n) { } } // namespace strings_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/internal/ostringstream.h b/absl/strings/internal/ostringstream.h index 20792015..d25d6047 100644 --- a/absl/strings/internal/ostringstream.h +++ b/absl/strings/internal/ostringstream.h @@ -23,6 +23,7 @@ #include "absl/base/port.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { // The same as std::ostringstream but appends to a user-specified std::string, @@ -82,6 +83,7 @@ class OStringStream : private std::basic_streambuf, public std::ostream { }; } // namespace strings_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_OSTRINGSTREAM_H_ diff --git a/absl/strings/internal/pow10_helper.cc b/absl/strings/internal/pow10_helper.cc index 03ed8d07..42e96c34 100644 --- a/absl/strings/internal/pow10_helper.cc +++ b/absl/strings/internal/pow10_helper.cc @@ -17,6 +17,7 @@ #include namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { namespace { @@ -117,4 +118,5 @@ double Pow10(int exp) { } } // namespace strings_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/internal/pow10_helper.h b/absl/strings/internal/pow10_helper.h index 9d1aa710..c37c2c3f 100644 --- a/absl/strings/internal/pow10_helper.h +++ b/absl/strings/internal/pow10_helper.h @@ -22,7 +22,10 @@ #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { // Computes the precise value of 10^exp. (I.e. the nearest representable @@ -31,6 +34,7 @@ namespace strings_internal { double Pow10(int exp); } // namespace strings_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_POW10_HELPER_H_ diff --git a/absl/strings/internal/pow10_helper_test.cc b/absl/strings/internal/pow10_helper_test.cc index a4a68b5d..a4ff76d3 100644 --- a/absl/strings/internal/pow10_helper_test.cc +++ b/absl/strings/internal/pow10_helper_test.cc @@ -20,6 +20,7 @@ #include "absl/strings/str_format.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { namespace { @@ -117,4 +118,5 @@ TEST(Pow10HelperTest, Works) { } // namespace } // namespace strings_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/internal/resize_uninitialized.h b/absl/strings/internal/resize_uninitialized.h index 0f5e964d..e42628e3 100644 --- a/absl/strings/internal/resize_uninitialized.h +++ b/absl/strings/internal/resize_uninitialized.h @@ -25,6 +25,7 @@ #include "absl/meta/type_traits.h" // for void_t namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { // Is a subclass of true_type or false_type, depending on whether or not @@ -66,6 +67,7 @@ inline void STLStringResizeUninitialized(string_type* s, size_t new_size) { } } // namespace strings_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_RESIZE_UNINITIALIZED_H_ diff --git a/absl/strings/internal/stl_type_traits.h b/absl/strings/internal/stl_type_traits.h index 202ab374..6035ca45 100644 --- a/absl/strings/internal/stl_type_traits.h +++ b/absl/strings/internal/stl_type_traits.h @@ -40,6 +40,7 @@ #include "absl/meta/type_traits.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { template class T> @@ -242,5 +243,6 @@ struct IsStrictlyBaseOfAndConvertibleToSTLContainer IsConvertibleToSTLContainer> {}; } // namespace strings_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_STL_TYPE_TRAITS_H_ diff --git a/absl/strings/internal/str_format/arg.cc b/absl/strings/internal/str_format/arg.cc index b567a5c5..875bd99c 100644 --- a/absl/strings/internal/str_format/arg.cc +++ b/absl/strings/internal/str_format/arg.cc @@ -14,6 +14,7 @@ #include "absl/strings/internal/str_format/float_conversion.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace str_format_internal { namespace { @@ -386,4 +387,5 @@ ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_(); } // namespace str_format_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/internal/str_format/arg.h b/absl/strings/internal/str_format/arg.h index a209a927..b672a229 100644 --- a/absl/strings/internal/str_format/arg.h +++ b/absl/strings/internal/str_format/arg.h @@ -19,6 +19,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN class Cord; class FormatCountCapture; @@ -426,6 +427,7 @@ ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_(extern); } // namespace str_format_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_ARG_H_ diff --git a/absl/strings/internal/str_format/arg_test.cc b/absl/strings/internal/str_format/arg_test.cc index 3421fac1..96c9cfd3 100644 --- a/absl/strings/internal/str_format/arg_test.cc +++ b/absl/strings/internal/str_format/arg_test.cc @@ -14,6 +14,7 @@ #include "absl/strings/str_format.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace str_format_internal { namespace { @@ -108,4 +109,5 @@ const char kMyArray[] = "ABCDE"; } // namespace } // namespace str_format_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/internal/str_format/bind.cc b/absl/strings/internal/str_format/bind.cc index 45e335a3..1ee281af 100644 --- a/absl/strings/internal/str_format/bind.cc +++ b/absl/strings/internal/str_format/bind.cc @@ -6,6 +6,7 @@ #include namespace absl { +ABSL_NAMESPACE_BEGIN namespace str_format_internal { namespace { @@ -236,4 +237,5 @@ int SnprintF(char* output, size_t size, const UntypedFormatSpecImpl format, } } // namespace str_format_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/internal/str_format/bind.h b/absl/strings/internal/str_format/bind.h index dafcd610..2bf0c085 100644 --- a/absl/strings/internal/str_format/bind.h +++ b/absl/strings/internal/str_format/bind.h @@ -13,6 +13,7 @@ #include "absl/types/span.h" namespace absl { +ABSL_NAMESPACE_BEGIN class UntypedFormatSpec; @@ -202,6 +203,7 @@ class StreamedWrapper { }; } // namespace str_format_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_BIND_H_ diff --git a/absl/strings/internal/str_format/bind_test.cc b/absl/strings/internal/str_format/bind_test.cc index 2574801a..f6817419 100644 --- a/absl/strings/internal/str_format/bind_test.cc +++ b/absl/strings/internal/str_format/bind_test.cc @@ -6,6 +6,7 @@ #include "gtest/gtest.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace str_format_internal { namespace { @@ -138,4 +139,5 @@ TEST_F(FormatBindTest, FormatPack) { } // namespace } // namespace str_format_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/internal/str_format/checker.h b/absl/strings/internal/str_format/checker.h index 04a88827..8993a79b 100644 --- a/absl/strings/internal/str_format/checker.h +++ b/absl/strings/internal/str_format/checker.h @@ -14,6 +14,7 @@ #endif // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER namespace absl { +ABSL_NAMESPACE_BEGIN namespace str_format_internal { constexpr bool AllOf() { return true; } @@ -319,6 +320,7 @@ constexpr bool ValidFormatImpl(string_view format) { #endif // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER } // namespace str_format_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_ diff --git a/absl/strings/internal/str_format/checker_test.cc b/absl/strings/internal/str_format/checker_test.cc index 7aa194a7..c309e203 100644 --- a/absl/strings/internal/str_format/checker_test.cc +++ b/absl/strings/internal/str_format/checker_test.cc @@ -5,6 +5,7 @@ #include "absl/strings/str_format.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace str_format_internal { namespace { @@ -147,4 +148,5 @@ TEST(StrFormatChecker, LongFormat) { } // namespace } // namespace str_format_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/internal/str_format/convert_test.cc b/absl/strings/internal/str_format/convert_test.cc index 5f198059..ca994346 100644 --- a/absl/strings/internal/str_format/convert_test.cc +++ b/absl/strings/internal/str_format/convert_test.cc @@ -11,6 +11,7 @@ #include "absl/strings/internal/str_format/bind.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace str_format_internal { namespace { @@ -646,4 +647,5 @@ TEST_F(FormatConvertTest, ExpectedFailures) { } // namespace } // namespace str_format_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/internal/str_format/extension.cc b/absl/strings/internal/str_format/extension.cc index d7f58159..559011bf 100644 --- a/absl/strings/internal/str_format/extension.cc +++ b/absl/strings/internal/str_format/extension.cc @@ -20,6 +20,7 @@ #include namespace absl { +ABSL_NAMESPACE_BEGIN namespace str_format_internal { namespace { // clang-format off @@ -81,4 +82,5 @@ bool FormatSinkImpl::PutPaddedString(string_view v, int w, int p, bool l) { } } // namespace str_format_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/internal/str_format/extension.h b/absl/strings/internal/str_format/extension.h index 3f4788c9..5726ea5c 100644 --- a/absl/strings/internal/str_format/extension.h +++ b/absl/strings/internal/str_format/extension.h @@ -26,6 +26,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN class Cord; @@ -406,6 +407,7 @@ inline size_t Excess(size_t used, size_t capacity) { } // namespace str_format_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_ diff --git a/absl/strings/internal/str_format/float_conversion.cc b/absl/strings/internal/str_format/float_conversion.cc index 9236acdc..ebe4da5b 100644 --- a/absl/strings/internal/str_format/float_conversion.cc +++ b/absl/strings/internal/str_format/float_conversion.cc @@ -9,6 +9,7 @@ #include "absl/base/config.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace str_format_internal { namespace { @@ -482,4 +483,5 @@ bool ConvertFloatImpl(double v, const ConversionSpec &conv, } } // namespace str_format_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/internal/str_format/float_conversion.h b/absl/strings/internal/str_format/float_conversion.h index 8ba5566d..49a6a636 100644 --- a/absl/strings/internal/str_format/float_conversion.h +++ b/absl/strings/internal/str_format/float_conversion.h @@ -4,6 +4,7 @@ #include "absl/strings/internal/str_format/extension.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace str_format_internal { bool ConvertFloatImpl(float v, const ConversionSpec &conv, @@ -16,6 +17,7 @@ bool ConvertFloatImpl(long double v, const ConversionSpec &conv, FormatSinkImpl *sink); } // namespace str_format_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_FLOAT_CONVERSION_H_ diff --git a/absl/strings/internal/str_format/output.cc b/absl/strings/internal/str_format/output.cc index 38987b63..c4b24706 100644 --- a/absl/strings/internal/str_format/output.cc +++ b/absl/strings/internal/str_format/output.cc @@ -18,6 +18,7 @@ #include namespace absl { +ABSL_NAMESPACE_BEGIN namespace str_format_internal { namespace { @@ -67,4 +68,5 @@ void FILERawSink::Write(string_view v) { } } // namespace str_format_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/internal/str_format/output.h b/absl/strings/internal/str_format/output.h index 6dc2f3f7..28b288b7 100644 --- a/absl/strings/internal/str_format/output.h +++ b/absl/strings/internal/str_format/output.h @@ -29,6 +29,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN class Cord; @@ -97,6 +98,7 @@ auto InvokeFlush(T* out, string_view s) } } // namespace str_format_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_OUTPUT_H_ diff --git a/absl/strings/internal/str_format/output_test.cc b/absl/strings/internal/str_format/output_test.cc index 6e04abef..e54e6f70 100644 --- a/absl/strings/internal/str_format/output_test.cc +++ b/absl/strings/internal/str_format/output_test.cc @@ -21,6 +21,7 @@ #include "gtest/gtest.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace { TEST(InvokeFlush, String) { @@ -67,5 +68,6 @@ TEST(BufferRawSink, Limits) { } } // namespace +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/internal/str_format/parser.cc b/absl/strings/internal/str_format/parser.cc index 9ef5615c..eff68f35 100644 --- a/absl/strings/internal/str_format/parser.cc +++ b/absl/strings/internal/str_format/parser.cc @@ -14,6 +14,7 @@ #include namespace absl { +ABSL_NAMESPACE_BEGIN namespace str_format_internal { using CC = ConversionChar::Id; @@ -300,4 +301,5 @@ bool ParsedFormatBase::MatchesConversions( } } // namespace str_format_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/internal/str_format/parser.h b/absl/strings/internal/str_format/parser.h index 4b441f71..116dda06 100644 --- a/absl/strings/internal/str_format/parser.h +++ b/absl/strings/internal/str_format/parser.h @@ -16,6 +16,7 @@ #include "absl/strings/internal/str_format/extension.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace str_format_internal { // The analyzed properties of a single specified conversion. @@ -317,6 +318,7 @@ class ExtendedParsedFormat : public str_format_internal::ParsedFormatBase { : ParsedFormatBase(s, allow_ignored, {C...}) {} }; } // namespace str_format_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_PARSER_H_ diff --git a/absl/strings/internal/str_format/parser_test.cc b/absl/strings/internal/str_format/parser_test.cc index 6d356093..33ed8f09 100644 --- a/absl/strings/internal/str_format/parser_test.cc +++ b/absl/strings/internal/str_format/parser_test.cc @@ -7,6 +7,7 @@ #include "absl/base/macros.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace str_format_internal { namespace { @@ -389,4 +390,5 @@ TEST_F(ParsedFormatTest, ParsingFlagOrder) { } // namespace } // namespace str_format_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/internal/str_join_internal.h b/absl/strings/internal/str_join_internal.h index 7c35f4de..31dbf672 100644 --- a/absl/strings/internal/str_join_internal.h +++ b/absl/strings/internal/str_join_internal.h @@ -43,6 +43,7 @@ #include "absl/strings/str_cat.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { // @@ -307,6 +308,7 @@ std::string JoinRange(const Range& range, absl::string_view separator) { } } // namespace strings_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_STR_JOIN_INTERNAL_H_ diff --git a/absl/strings/internal/str_split_internal.h b/absl/strings/internal/str_split_internal.h index 52f62226..b54f6ebe 100644 --- a/absl/strings/internal/str_split_internal.h +++ b/absl/strings/internal/str_split_internal.h @@ -47,6 +47,7 @@ #endif // _GLIBCXX_DEBUG namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { // This class is implicitly constructible from everything that absl::string_view @@ -448,6 +449,7 @@ class Splitter { }; } // namespace strings_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_STR_SPLIT_INTERNAL_H_ diff --git a/absl/strings/internal/utf8.cc b/absl/strings/internal/utf8.cc index 82d36c24..8fd8edc1 100644 --- a/absl/strings/internal/utf8.cc +++ b/absl/strings/internal/utf8.cc @@ -17,6 +17,7 @@ #include "absl/strings/internal/utf8.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { size_t EncodeUTF8Char(char *buffer, char32_t utf8_char) { @@ -48,4 +49,5 @@ size_t EncodeUTF8Char(char *buffer, char32_t utf8_char) { } } // namespace strings_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/internal/utf8.h b/absl/strings/internal/utf8.h index 04236304..32fb1093 100644 --- a/absl/strings/internal/utf8.h +++ b/absl/strings/internal/utf8.h @@ -20,7 +20,10 @@ #include #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { // For Unicode code points 0 through 0x10FFFF, EncodeUTF8Char writes @@ -41,6 +44,7 @@ enum { kMaxEncodedUTF8Size = 4 }; size_t EncodeUTF8Char(char *buffer, char32_t utf8_char); } // namespace strings_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_UTF8_H_ diff --git a/absl/strings/match.cc b/absl/strings/match.cc index 7b24241a..8127cb0c 100644 --- a/absl/strings/match.cc +++ b/absl/strings/match.cc @@ -17,6 +17,7 @@ #include "absl/strings/internal/memutil.h" namespace absl { +ABSL_NAMESPACE_BEGIN bool EqualsIgnoreCase(absl::string_view piece1, absl::string_view piece2) { return (piece1.size() == piece2.size() && @@ -35,4 +36,5 @@ bool EndsWithIgnoreCase(absl::string_view text, absl::string_view suffix) { EqualsIgnoreCase(text.substr(text.size() - suffix.size()), suffix); } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/match.h b/absl/strings/match.h index 762f359f..90fca98a 100644 --- a/absl/strings/match.h +++ b/absl/strings/match.h @@ -20,7 +20,7 @@ // This file contains simple utilities for performing string matching checks. // All of these function parameters are specified as `absl::string_view`, // meaning that these functions can accept `std::string`, `absl::string_view` or -// nul-terminated C-style strings. +// NUL-terminated C-style strings. // // Examples: // std::string s = "foo"; @@ -38,6 +38,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN // StrContains() // @@ -83,6 +84,7 @@ bool StartsWithIgnoreCase(absl::string_view text, absl::string_view prefix); // case in the comparison. bool EndsWithIgnoreCase(absl::string_view text, absl::string_view suffix); +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_MATCH_H_ diff --git a/absl/strings/numbers.cc b/absl/strings/numbers.cc index 4890bd54..caab4631 100644 --- a/absl/strings/numbers.cc +++ b/absl/strings/numbers.cc @@ -40,6 +40,7 @@ #include "absl/strings/str_cat.h" namespace absl { +ABSL_NAMESPACE_BEGIN bool SimpleAtof(absl::string_view str, float* out) { *out = 0.0; @@ -911,4 +912,5 @@ bool safe_strtou128_base(absl::string_view text, uint128* value, int base) { } } // namespace numbers_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/numbers.h b/absl/strings/numbers.h index 7a0d6f50..61204683 100644 --- a/absl/strings/numbers.h +++ b/absl/strings/numbers.h @@ -51,6 +51,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN // SimpleAtoi() // @@ -95,11 +96,13 @@ ABSL_MUST_USE_RESULT bool SimpleAtod(absl::string_view str, double* out); // unspecified state. ABSL_MUST_USE_RESULT bool SimpleAtob(absl::string_view str, bool* out); +ABSL_NAMESPACE_END } // namespace absl // End of public API. Implementation details follow. namespace absl { +ABSL_NAMESPACE_BEGIN namespace numbers_internal { // Digit conversion. @@ -254,6 +257,7 @@ ABSL_MUST_USE_RESULT inline bool SimpleAtoi(absl::string_view str, return numbers_internal::safe_strtou128_base(str, out, 10); } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_NUMBERS_H_ diff --git a/absl/strings/str_cat.cc b/absl/strings/str_cat.cc index 4bd56f5f..d9afe2f3 100644 --- a/absl/strings/str_cat.cc +++ b/absl/strings/str_cat.cc @@ -25,6 +25,7 @@ #include "absl/strings/numbers.h" namespace absl { +ABSL_NAMESPACE_BEGIN AlphaNum::AlphaNum(Hex hex) { static_assert(numbers_internal::kFastToBufferSize >= 32, @@ -241,4 +242,5 @@ void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b, assert(out == begin + dest->size()); } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/str_cat.h b/absl/strings/str_cat.h index 663a1945..292fa235 100644 --- a/absl/strings/str_cat.h +++ b/absl/strings/str_cat.h @@ -64,6 +64,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { // AlphaNumBuffer allows a way to pass a string to StrCat without having to do @@ -401,6 +402,7 @@ SixDigits(double d) { return result; } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_STR_CAT_H_ diff --git a/absl/strings/str_format.h b/absl/strings/str_format.h index c11c93a2..fbbfe43d 100644 --- a/absl/strings/str_format.h +++ b/absl/strings/str_format.h @@ -82,6 +82,7 @@ #include "absl/strings/internal/str_format/parser.h" // IWYU pragma: export namespace absl { +ABSL_NAMESPACE_BEGIN // UntypedFormatSpec // @@ -530,6 +531,7 @@ ABSL_MUST_USE_RESULT inline bool FormatUntyped( str_format_internal::UntypedFormatSpecImpl::Extract(format), args); } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_STR_FORMAT_H_ diff --git a/absl/strings/str_format_test.cc b/absl/strings/str_format_test.cc index cfd81bb3..d33bcaa2 100644 --- a/absl/strings/str_format_test.cc +++ b/absl/strings/str_format_test.cc @@ -10,6 +10,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace { using str_format_internal::FormatArgImpl; @@ -622,6 +623,7 @@ TEST_F(FormatWrapperTest, ParsedFormat) { } } // namespace +ABSL_NAMESPACE_END } // namespace absl // Some codegen thunks that we can use to easily dump the generated assembly for diff --git a/absl/strings/str_join.h b/absl/strings/str_join.h index 4772f5d1..ae5731a4 100644 --- a/absl/strings/str_join.h +++ b/absl/strings/str_join.h @@ -60,6 +60,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // Concept: Formatter @@ -286,6 +287,7 @@ std::string StrJoin(const std::tuple& value, return strings_internal::JoinAlgorithm(value, separator, AlphaNumFormatter()); } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_STR_JOIN_H_ diff --git a/absl/strings/str_replace.cc b/absl/strings/str_replace.cc index 280f63d3..2bd5fa98 100644 --- a/absl/strings/str_replace.cc +++ b/absl/strings/str_replace.cc @@ -17,6 +17,7 @@ #include "absl/strings/str_cat.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace strings_internal { using FixedMapping = @@ -77,4 +78,5 @@ int StrReplaceAll(strings_internal::FixedMapping replacements, return StrReplaceAll(replacements, target); } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/str_replace.h b/absl/strings/str_replace.h index 30540d02..273c7077 100644 --- a/absl/strings/str_replace.h +++ b/absl/strings/str_replace.h @@ -46,6 +46,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN // StrReplaceAll() // @@ -212,6 +213,7 @@ int StrReplaceAll(const StrToStrMapping& replacements, std::string* target) { return substitutions; } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_STR_REPLACE_H_ diff --git a/absl/strings/str_split.cc b/absl/strings/str_split.cc index 25931307..d0f86669 100644 --- a/absl/strings/str_split.cc +++ b/absl/strings/str_split.cc @@ -27,6 +27,7 @@ #include "absl/strings/ascii.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace { @@ -134,4 +135,5 @@ absl::string_view ByLength::Find(absl::string_view text, return absl::string_view(substr.data() + length_, 0); } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/str_split.h b/absl/strings/str_split.h index 73330789..a79cd4a0 100644 --- a/absl/strings/str_split.h +++ b/absl/strings/str_split.h @@ -49,6 +49,7 @@ #include "absl/strings/strip.h" namespace absl { +ABSL_NAMESPACE_BEGIN //------------------------------------------------------------------------------ // Delimiters @@ -506,6 +507,7 @@ StrSplit(strings_internal::ConvertibleToStringView text, Delimiter d, std::move(text), DelimiterType(d), std::move(p)); } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_STR_SPLIT_H_ diff --git a/absl/strings/string_view.cc b/absl/strings/string_view.cc index d5e1a3de..c5f5de93 100644 --- a/absl/strings/string_view.cc +++ b/absl/strings/string_view.cc @@ -24,6 +24,7 @@ #include "absl/strings/internal/memutil.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace { void WritePadding(std::ostream& o, size_t pad) { @@ -228,6 +229,7 @@ constexpr string_view::size_type string_view::npos; ABSL_STRING_VIEW_SELECTANY constexpr string_view::size_type string_view::kMaxSize; +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_USES_STD_STRING_VIEW diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h index 6a650874..4b34e563 100644 --- a/absl/strings/string_view.h +++ b/absl/strings/string_view.h @@ -35,7 +35,9 @@ #include // IWYU pragma: export namespace absl { +ABSL_NAMESPACE_BEGIN using std::string_view; +ABSL_NAMESPACE_END } // namespace absl #else // ABSL_USES_STD_STRING_VIEW @@ -61,6 +63,7 @@ using std::string_view; #include "absl/base/port.h" namespace absl { +ABSL_NAMESPACE_BEGIN // absl::string_view // @@ -109,10 +112,10 @@ namespace absl { // example, when splitting a string, `std::vector` is a // natural data type for the output. // -// When constructed from a source which is nul-terminated, the `string_view` -// itself will not include the nul-terminator unless a specific size (including -// the nul) is passed to the constructor. As a result, common idioms that work -// on nul-terminated strings do not work on `string_view` objects. If you write +// When constructed from a source which is NUL-terminated, the `string_view` +// itself will not include the NUL-terminator unless a specific size (including +// the NUL) is passed to the constructor. As a result, common idioms that work +// on NUL-terminated strings do not work on `string_view` objects. If you write // code that scans a `string_view`, you must check its length rather than test // for nul, for example. Note, however, that nuls may still be embedded within // a `string_view` explicitly. @@ -179,7 +182,7 @@ class string_view { // doesn't need to be reevaluated after `ptr_` is set. : string_view(str.data(), str.size()) {} - // Implicit constructor of a `string_view` from nul-terminated `str`. When + // Implicit constructor of a `string_view` from NUL-terminated `str`. When // accepting possibly null strings, use `absl::NullSafeStringView(str)` // instead (see below). constexpr string_view(const char* str) // NOLINT(runtime/explicit) @@ -309,8 +312,8 @@ class string_view { // // Returns a pointer to the underlying character array (which is of course // stored elsewhere). Note that `string_view::data()` may contain embedded nul - // characters, but the returned buffer may or may not be nul-terminated; - // therefore, do not pass `data()` to a routine that expects a nul-terminated + // characters, but the returned buffer may or may not be NUL-terminated; + // therefore, do not pass `data()` to a routine that expects a NUL-terminated // std::string. constexpr const_pointer data() const noexcept { return ptr_; } @@ -577,6 +580,7 @@ constexpr bool operator>=(string_view x, string_view y) noexcept { // IO Insertion Operator std::ostream& operator<<(std::ostream& o, string_view piece); +ABSL_NAMESPACE_END } // namespace absl #undef ABSL_INTERNAL_STRING_VIEW_MEMCMP @@ -584,6 +588,7 @@ std::ostream& operator<<(std::ostream& o, string_view piece); #endif // ABSL_USES_STD_STRING_VIEW namespace absl { +ABSL_NAMESPACE_BEGIN // ClippedSubstr() // @@ -604,6 +609,7 @@ inline string_view NullSafeStringView(const char* p) { return p ? string_view(p) : string_view(); } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_STRING_VIEW_H_ diff --git a/absl/strings/strip.h b/absl/strings/strip.h index e1341e08..111872ca 100644 --- a/absl/strings/strip.h +++ b/absl/strings/strip.h @@ -30,6 +30,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN // ConsumePrefix() // @@ -84,6 +85,7 @@ ABSL_MUST_USE_RESULT inline absl::string_view StripSuffix( return str; } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_STRIP_H_ diff --git a/absl/strings/substitute.cc b/absl/strings/substitute.cc index 5d28c528..5b69a3ef 100644 --- a/absl/strings/substitute.cc +++ b/absl/strings/substitute.cc @@ -23,6 +23,7 @@ #include "absl/strings/string_view.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace substitute_internal { void SubstituteAndAppendArray(std::string* output, absl::string_view format, @@ -166,4 +167,5 @@ Arg::Arg(Dec dec) { } } // namespace substitute_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/strings/substitute.h b/absl/strings/substitute.h index 233e9dcf..766aca42 100644 --- a/absl/strings/substitute.h +++ b/absl/strings/substitute.h @@ -86,6 +86,7 @@ #include "absl/strings/strip.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace substitute_internal { // Arg @@ -681,6 +682,7 @@ std::string Substitute( "format std::string doesn't contain all of $0 through $9"); #endif // ABSL_BAD_CALL_IF +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_SUBSTITUTE_H_ diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel index 36dc98f3..3f876b9f 100644 --- a/absl/synchronization/BUILD.bazel +++ b/absl/synchronization/BUILD.bazel @@ -43,6 +43,7 @@ cc_library( deps = [ "//absl/base", "//absl/base:base_internal", + "//absl/base:config", "//absl/base:core_headers", "//absl/base:malloc_internal", "//absl/base:raw_logging_internal", diff --git a/absl/synchronization/CMakeLists.txt b/absl/synchronization/CMakeLists.txt index 3c47a1bc..dfe5d05d 100644 --- a/absl/synchronization/CMakeLists.txt +++ b/absl/synchronization/CMakeLists.txt @@ -26,6 +26,7 @@ absl_cc_library( DEPS absl::base absl::base_internal + absl::config absl::core_headers absl::malloc_internal absl::raw_logging_internal diff --git a/absl/synchronization/barrier.cc b/absl/synchronization/barrier.cc index c2c539ac..0dfd795e 100644 --- a/absl/synchronization/barrier.cc +++ b/absl/synchronization/barrier.cc @@ -18,6 +18,7 @@ #include "absl/synchronization/mutex.h" namespace absl { +ABSL_NAMESPACE_BEGIN // Return whether int *arg is zero. static bool IsZero(void *arg) { @@ -47,4 +48,5 @@ bool Barrier::Block() { return this->num_to_exit_ == 0; } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/synchronization/barrier.h b/absl/synchronization/barrier.h index cb5d821a..d8e75440 100644 --- a/absl/synchronization/barrier.h +++ b/absl/synchronization/barrier.h @@ -23,6 +23,7 @@ #include "absl/synchronization/mutex.h" namespace absl { +ABSL_NAMESPACE_BEGIN // Barrier // @@ -73,5 +74,6 @@ class Barrier { int num_to_exit_ ABSL_GUARDED_BY(lock_); }; +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_SYNCHRONIZATION_BARRIER_H_ diff --git a/absl/synchronization/blocking_counter.cc b/absl/synchronization/blocking_counter.cc index 481a06b2..3cea7aed 100644 --- a/absl/synchronization/blocking_counter.cc +++ b/absl/synchronization/blocking_counter.cc @@ -17,6 +17,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { +ABSL_NAMESPACE_BEGIN // Return whether int *arg is zero. static bool IsZero(void *arg) { @@ -52,4 +53,5 @@ void BlockingCounter::Wait() { // after we return from this method. } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/synchronization/blocking_counter.h b/absl/synchronization/blocking_counter.h index 77560fc0..1f53f9f2 100644 --- a/absl/synchronization/blocking_counter.h +++ b/absl/synchronization/blocking_counter.h @@ -24,6 +24,7 @@ #include "absl/synchronization/mutex.h" namespace absl { +ABSL_NAMESPACE_BEGIN // BlockingCounter // @@ -92,6 +93,7 @@ class BlockingCounter { int num_waiting_ ABSL_GUARDED_BY(lock_); }; +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_SYNCHRONIZATION_BLOCKING_COUNTER_H_ diff --git a/absl/synchronization/blocking_counter_test.cc b/absl/synchronization/blocking_counter_test.cc index c63e3392..2926224a 100644 --- a/absl/synchronization/blocking_counter_test.cc +++ b/absl/synchronization/blocking_counter_test.cc @@ -22,6 +22,7 @@ #include "absl/time/time.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace { void PauseAndDecreaseCounter(BlockingCounter* counter, int* done) { @@ -63,4 +64,5 @@ TEST(BlockingCounterTest, BasicFunctionality) { } } // namespace +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/synchronization/internal/create_thread_identity.cc b/absl/synchronization/internal/create_thread_identity.cc index ec49d1ca..fa0070a9 100644 --- a/absl/synchronization/internal/create_thread_identity.cc +++ b/absl/synchronization/internal/create_thread_identity.cc @@ -27,6 +27,7 @@ #include "absl/synchronization/internal/per_thread_sem.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace synchronization_internal { // ThreadIdentity storage is persistent, we maintain a free-list of previously @@ -133,6 +134,7 @@ base_internal::ThreadIdentity* CreateThreadIdentity() { } } // namespace synchronization_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_LOW_LEVEL_ALLOC_MISSING diff --git a/absl/synchronization/internal/create_thread_identity.h b/absl/synchronization/internal/create_thread_identity.h index 97237a6e..e121f683 100644 --- a/absl/synchronization/internal/create_thread_identity.h +++ b/absl/synchronization/internal/create_thread_identity.h @@ -29,6 +29,7 @@ #include "absl/base/port.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace synchronization_internal { // Allocates and attaches a ThreadIdentity object for the calling thread. @@ -53,6 +54,7 @@ inline base_internal::ThreadIdentity* GetOrCreateCurrentThreadIdentity() { } } // namespace synchronization_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_SYNCHRONIZATION_INTERNAL_CREATE_THREAD_IDENTITY_H_ diff --git a/absl/synchronization/internal/graphcycles.cc b/absl/synchronization/internal/graphcycles.cc index 0c8c7564..6a2bcdf6 100644 --- a/absl/synchronization/internal/graphcycles.cc +++ b/absl/synchronization/internal/graphcycles.cc @@ -44,6 +44,7 @@ // Do not use STL. This module does not use standard memory allocation. namespace absl { +ABSL_NAMESPACE_BEGIN namespace synchronization_internal { namespace { @@ -690,6 +691,7 @@ int GraphCycles::GetStackTrace(GraphId id, void*** ptr) { } } // namespace synchronization_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_LOW_LEVEL_ALLOC_MISSING diff --git a/absl/synchronization/internal/graphcycles.h b/absl/synchronization/internal/graphcycles.h index e08dc09d..ceba33e4 100644 --- a/absl/synchronization/internal/graphcycles.h +++ b/absl/synchronization/internal/graphcycles.h @@ -40,7 +40,10 @@ #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace synchronization_internal { // Opaque identifier for a graph node. @@ -132,6 +135,7 @@ class GraphCycles { }; } // namespace synchronization_internal +ABSL_NAMESPACE_END } // namespace absl #endif diff --git a/absl/synchronization/internal/graphcycles_test.cc b/absl/synchronization/internal/graphcycles_test.cc index 58e8477b..74eaffe7 100644 --- a/absl/synchronization/internal/graphcycles_test.cc +++ b/absl/synchronization/internal/graphcycles_test.cc @@ -25,6 +25,7 @@ #include "absl/base/macros.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace synchronization_internal { // We emulate a GraphCycles object with a node vector and an edge vector. @@ -459,4 +460,5 @@ TEST_F(GraphCyclesTest, ManyEdges) { } } // namespace synchronization_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/synchronization/internal/kernel_timeout.h b/absl/synchronization/internal/kernel_timeout.h index 61c72e75..d6ac5db0 100644 --- a/absl/synchronization/internal/kernel_timeout.h +++ b/absl/synchronization/internal/kernel_timeout.h @@ -34,6 +34,7 @@ #include "absl/time/time.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace synchronization_internal { class Futex; @@ -148,6 +149,7 @@ class KernelTimeout { }; } // namespace synchronization_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_SYNCHRONIZATION_INTERNAL_KERNEL_TIMEOUT_H_ diff --git a/absl/synchronization/internal/mutex_nonprod.cc b/absl/synchronization/internal/mutex_nonprod.cc index 267deaff..4590b98d 100644 --- a/absl/synchronization/internal/mutex_nonprod.cc +++ b/absl/synchronization/internal/mutex_nonprod.cc @@ -31,6 +31,7 @@ #include "absl/time/time.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace synchronization_internal { namespace { @@ -315,4 +316,5 @@ bool Condition::Eval() const { void RegisterSymbolizer(bool (*)(const void*, char*, int)) {} +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/synchronization/internal/mutex_nonprod.inc b/absl/synchronization/internal/mutex_nonprod.inc index b8d5af79..85dae0ff 100644 --- a/absl/synchronization/internal/mutex_nonprod.inc +++ b/absl/synchronization/internal/mutex_nonprod.inc @@ -36,6 +36,7 @@ #endif namespace absl { +ABSL_NAMESPACE_BEGIN class Condition; namespace synchronization_internal { @@ -256,4 +257,5 @@ class SynchronizationStorage { }; } // namespace synchronization_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/synchronization/internal/per_thread_sem.cc b/absl/synchronization/internal/per_thread_sem.cc index 2a78b20f..821ca9b4 100644 --- a/absl/synchronization/internal/per_thread_sem.cc +++ b/absl/synchronization/internal/per_thread_sem.cc @@ -25,6 +25,7 @@ #include "absl/synchronization/internal/waiter.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace synchronization_internal { void PerThreadSem::SetThreadBlockedCounter(std::atomic *counter) { @@ -62,6 +63,7 @@ void PerThreadSem::Tick(base_internal::ThreadIdentity *identity) { } } // namespace synchronization_internal +ABSL_NAMESPACE_END } // namespace absl extern "C" { diff --git a/absl/synchronization/internal/per_thread_sem.h b/absl/synchronization/internal/per_thread_sem.h index 113cdfb7..8ab43915 100644 --- a/absl/synchronization/internal/per_thread_sem.h +++ b/absl/synchronization/internal/per_thread_sem.h @@ -32,6 +32,7 @@ #include "absl/synchronization/internal/kernel_timeout.h" namespace absl { +ABSL_NAMESPACE_BEGIN class Mutex; @@ -85,6 +86,7 @@ class PerThreadSem { }; } // namespace synchronization_internal +ABSL_NAMESPACE_END } // namespace absl // In some build configurations we pass --detect-odr-violations to the diff --git a/absl/synchronization/internal/per_thread_sem_test.cc b/absl/synchronization/internal/per_thread_sem_test.cc index dba72390..b5a2f6d4 100644 --- a/absl/synchronization/internal/per_thread_sem_test.cc +++ b/absl/synchronization/internal/per_thread_sem_test.cc @@ -33,6 +33,7 @@ // primitives which might use PerThreadSem, most notably absl::Mutex. namespace absl { +ABSL_NAMESPACE_BEGIN namespace synchronization_internal { class SimpleSemaphore { @@ -175,4 +176,5 @@ TEST_F(PerThreadSemTest, Timeouts) { } // namespace } // namespace synchronization_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/synchronization/internal/thread_pool.h b/absl/synchronization/internal/thread_pool.h index a00f2be8..0cb96dac 100644 --- a/absl/synchronization/internal/thread_pool.h +++ b/absl/synchronization/internal/thread_pool.h @@ -26,6 +26,7 @@ #include "absl/synchronization/mutex.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace synchronization_internal { // A simple ThreadPool implementation for tests. @@ -86,6 +87,7 @@ class ThreadPool { }; } // namespace synchronization_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_SYNCHRONIZATION_INTERNAL_THREAD_POOL_H_ diff --git a/absl/synchronization/internal/waiter.cc b/absl/synchronization/internal/waiter.cc index e7000d3a..ddd6081e 100644 --- a/absl/synchronization/internal/waiter.cc +++ b/absl/synchronization/internal/waiter.cc @@ -49,6 +49,7 @@ #include "absl/synchronization/internal/kernel_timeout.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace synchronization_internal { static void MaybeBecomeIdle() { @@ -481,4 +482,5 @@ void Waiter::InternalCondVarPoke() { #endif } // namespace synchronization_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/synchronization/internal/waiter.h b/absl/synchronization/internal/waiter.h index 9540598b..5af5c282 100644 --- a/absl/synchronization/internal/waiter.h +++ b/absl/synchronization/internal/waiter.h @@ -62,6 +62,7 @@ #endif namespace absl { +ABSL_NAMESPACE_BEGIN namespace synchronization_internal { // Waiter is an OS-specific semaphore. @@ -157,6 +158,7 @@ class Waiter { }; } // namespace synchronization_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_SYNCHRONIZATION_INTERNAL_WAITER_H_ diff --git a/absl/synchronization/mutex.cc b/absl/synchronization/mutex.cc index 100def2d..46af8a52 100644 --- a/absl/synchronization/mutex.cc +++ b/absl/synchronization/mutex.cc @@ -71,6 +71,7 @@ ABSL_ATTRIBUTE_WEAK void AbslInternalMutexYield() { std::this_thread::yield(); } } // extern "C" namespace absl { +ABSL_NAMESPACE_BEGIN namespace { @@ -295,7 +296,7 @@ static struct SynchEvent { // this is a trivial hash table for the events bool log; // logging turned on // Constant after initialization - char name[1]; // actually longer---null-terminated std::string + char name[1]; // actually longer---NUL-terminated std::string } * synch_event[kNSynchEvent] ABSL_GUARDED_BY(synch_event_mu); // Ensure that the object at "addr" has a SynchEvent struct associated with it, @@ -2720,4 +2721,5 @@ bool Condition::GuaranteedEqual(const Condition *a, const Condition *b) { a->arg_ == b->arg_ && a->method_ == b->method_; } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h index ccd94618..8c70c4ce 100644 --- a/absl/synchronization/mutex.h +++ b/absl/synchronization/mutex.h @@ -82,6 +82,7 @@ #endif namespace absl { +ABSL_NAMESPACE_BEGIN class Condition; struct SynchWaitParams; @@ -1000,7 +1001,7 @@ void RegisterCondVarTracer(void (*fn)(const char *msg, const void *cv)); // // 'pc' is the program counter being symbolized, 'out' is the buffer to write // into, and 'out_size' is the size of the buffer. This function can return -// false if symbolizing failed, or true if a null-terminated symbol was written +// false if symbolizing failed, or true if a NUL-terminated symbol was written // to 'out.' // // This has the same memory ordering concerns as RegisterMutexProfiler() above. @@ -1039,6 +1040,7 @@ enum class OnDeadlockCycle { // the manner chosen here. void SetMutexDeadlockDetectionMode(OnDeadlockCycle mode); +ABSL_NAMESPACE_END } // namespace absl // In some build configurations we pass --detect-odr-violations to the diff --git a/absl/synchronization/notification.cc b/absl/synchronization/notification.cc index 1eb7f416..e91b9038 100644 --- a/absl/synchronization/notification.cc +++ b/absl/synchronization/notification.cc @@ -22,6 +22,7 @@ #include "absl/time/time.h" namespace absl { +ABSL_NAMESPACE_BEGIN void Notification::Notify() { MutexLock l(&this->mutex_); @@ -73,4 +74,5 @@ bool Notification::WaitForNotificationWithDeadline(absl::Time deadline) const { return notified; } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/synchronization/notification.h b/absl/synchronization/notification.h index 36c2ce3d..9a354ca2 100644 --- a/absl/synchronization/notification.h +++ b/absl/synchronization/notification.h @@ -57,6 +57,7 @@ #include "absl/time/time.h" namespace absl { +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // Notification @@ -116,6 +117,7 @@ class Notification { std::atomic notified_yet_; // written under mutex_ }; +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_SYNCHRONIZATION_NOTIFICATION_H_ diff --git a/absl/synchronization/notification_test.cc b/absl/synchronization/notification_test.cc index 059d4cd2..100ea76f 100644 --- a/absl/synchronization/notification_test.cc +++ b/absl/synchronization/notification_test.cc @@ -21,6 +21,7 @@ #include "absl/synchronization/mutex.h" namespace absl { +ABSL_NAMESPACE_BEGIN // A thread-safe class that holds a counter. class ThreadSafeCounter { @@ -128,4 +129,5 @@ TEST(NotificationTest, SanityTest) { BasicTests(true, &local_notification2); } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/time/civil_time.cc b/absl/time/civil_time.cc index 7b86fa8b..ada82cbc 100644 --- a/absl/time/civil_time.cc +++ b/absl/time/civil_time.cc @@ -21,6 +21,7 @@ #include "absl/time/time.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace { @@ -170,4 +171,5 @@ std::ostream& operator<<(std::ostream& os, CivilSecond s) { } // namespace time_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/time/civil_time.h b/absl/time/civil_time.h index 77c3be2e..bb460044 100644 --- a/absl/time/civil_time.h +++ b/absl/time/civil_time.h @@ -76,6 +76,7 @@ #include "absl/time/internal/cctz/include/cctz/civil_time.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace time_internal { struct second_tag : cctz::detail::second_tag {}; @@ -531,6 +532,7 @@ std::ostream& operator<<(std::ostream& os, CivilSecond s); } // namespace time_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TIME_CIVIL_TIME_H_ diff --git a/absl/time/clock.cc b/absl/time/clock.cc index bc6f5ccf..9e9a0386 100644 --- a/absl/time/clock.cc +++ b/absl/time/clock.cc @@ -34,6 +34,7 @@ #include "absl/base/thread_annotations.h" namespace absl { +ABSL_NAMESPACE_BEGIN Time Now() { // TODO(bww): Get a timespec instead so we don't have to divide. int64_t n = absl::GetCurrentTimeNanos(); @@ -43,6 +44,7 @@ Time Now() { } return time_internal::FromUnixDuration(absl::Nanoseconds(n)); } +ABSL_NAMESPACE_END } // namespace absl // Decide if we should use the fast GetCurrentTimeNanos() algorithm @@ -71,9 +73,11 @@ Time Now() { #if !ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS namespace absl { +ABSL_NAMESPACE_BEGIN int64_t GetCurrentTimeNanos() { return GET_CURRENT_TIME_NANOS_FROM_SYSTEM(); } +ABSL_NAMESPACE_END } // namespace absl #else // Use the cyclecounter-based implementation below. @@ -91,6 +95,7 @@ static int64_t stats_slow_paths; static int64_t stats_fast_slow_paths; namespace absl { +ABSL_NAMESPACE_BEGIN namespace time_internal { // This is a friend wrapper around UnscaledCycleClock::Now() // (needed to access UnscaledCycleClock). @@ -515,10 +520,12 @@ static uint64_t UpdateLastSample(uint64_t now_cycles, uint64_t now_ns, return estimated_base_ns; } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS namespace absl { +ABSL_NAMESPACE_BEGIN namespace { // Returns the maximum duration that SleepOnce() can sleep for. @@ -546,6 +553,7 @@ void SleepOnce(absl::Duration to_sleep) { } } // namespace +ABSL_NAMESPACE_END } // namespace absl extern "C" { diff --git a/absl/time/clock.h b/absl/time/clock.h index bb52e4f6..27764a92 100644 --- a/absl/time/clock.h +++ b/absl/time/clock.h @@ -26,6 +26,7 @@ #include "absl/time/time.h" namespace absl { +ABSL_NAMESPACE_BEGIN // Now() // @@ -49,6 +50,7 @@ int64_t GetCurrentTimeNanos(); // * Returns immediately when passed a nonpositive duration. void SleepFor(absl::Duration duration); +ABSL_NAMESPACE_END } // namespace absl // ----------------------------------------------------------------------------- diff --git a/absl/time/duration.cc b/absl/time/duration.cc index f0b4631d..b1af8406 100644 --- a/absl/time/duration.cc +++ b/absl/time/duration.cc @@ -71,6 +71,7 @@ #include "absl/time/time.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace { @@ -917,4 +918,5 @@ bool ParseFlag(const std::string& text, Duration* dst, std::string* ) { std::string UnparseFlag(Duration d) { return FormatDuration(d); } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/time/duration_test.cc b/absl/time/duration_test.cc index 5dce9ac8..49ebd118 100644 --- a/absl/time/duration_test.cc +++ b/absl/time/duration_test.cc @@ -762,11 +762,6 @@ TEST(Duration, DivisionByZero) { const double dbl_inf = std::numeric_limits::infinity(); const double dbl_denorm = std::numeric_limits::denorm_min(); - // IEEE 754 behavior - double z = 0.0, two = 2.0; - EXPECT_TRUE(std::isinf(two / z)); - EXPECT_TRUE(std::isnan(z / z)); // We'll return inf - // Operator/(Duration, double) EXPECT_EQ(inf, zero / 0.0); EXPECT_EQ(-inf, zero / -0.0); diff --git a/absl/time/format.cc b/absl/time/format.cc index ebe872cf..5997ef0c 100644 --- a/absl/time/format.cc +++ b/absl/time/format.cc @@ -22,6 +22,7 @@ namespace cctz = absl::time_internal::cctz; namespace absl { +ABSL_NAMESPACE_BEGIN extern const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez"; extern const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez"; @@ -145,4 +146,5 @@ std::string UnparseFlag(absl::Time t) { return absl::FormatTime(RFC3339_full, t, absl::UTCTimeZone()); } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/time/internal/get_current_time_chrono.inc b/absl/time/internal/get_current_time_chrono.inc index 5180230d..5eeb6406 100644 --- a/absl/time/internal/get_current_time_chrono.inc +++ b/absl/time/internal/get_current_time_chrono.inc @@ -16,6 +16,7 @@ #include namespace absl { +ABSL_NAMESPACE_BEGIN namespace time_internal { static int64_t GetCurrentTimeNanosFromSystem() { @@ -26,4 +27,5 @@ static int64_t GetCurrentTimeNanosFromSystem() { } } // namespace time_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/time/internal/get_current_time_posix.inc b/absl/time/internal/get_current_time_posix.inc index 65474ca6..42072000 100644 --- a/absl/time/internal/get_current_time_posix.inc +++ b/absl/time/internal/get_current_time_posix.inc @@ -7,6 +7,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace time_internal { static int64_t GetCurrentTimeNanosFromSystem() { @@ -19,4 +20,5 @@ static int64_t GetCurrentTimeNanosFromSystem() { } } // namespace time_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/time/internal/test_util.cc b/absl/time/internal/test_util.cc index fbddbb73..9bffe121 100644 --- a/absl/time/internal/test_util.cc +++ b/absl/time/internal/test_util.cc @@ -24,6 +24,7 @@ namespace cctz = absl::time_internal::cctz; namespace absl { +ABSL_NAMESPACE_BEGIN namespace time_internal { TimeZone LoadTimeZone(const std::string& name) { @@ -33,9 +34,11 @@ TimeZone LoadTimeZone(const std::string& name) { } } // namespace time_internal +ABSL_NAMESPACE_END } // namespace absl namespace absl { +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz_extension { namespace { @@ -123,4 +126,5 @@ ZoneInfoSourceFactory zone_info_source_factory = TestFactory; } // namespace cctz_extension } // namespace time_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/time/internal/test_util.h b/absl/time/internal/test_util.h index d7319ea8..5c4bf1f6 100644 --- a/absl/time/internal/test_util.h +++ b/absl/time/internal/test_util.h @@ -20,12 +20,14 @@ #include "absl/time/time.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace time_internal { // Loads the named timezone, but dies on any failure. absl::TimeZone LoadTimeZone(const std::string& name); } // namespace time_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TIME_INTERNAL_TEST_UTIL_H_ diff --git a/absl/time/time.cc b/absl/time/time.cc index 60382be7..6bb36cb3 100644 --- a/absl/time/time.cc +++ b/absl/time/time.cc @@ -47,6 +47,7 @@ namespace cctz = absl::time_internal::cctz; namespace absl { +ABSL_NAMESPACE_BEGIN namespace { @@ -494,4 +495,5 @@ struct tm ToTM(absl::Time t, absl::TimeZone tz) { return tm; } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/time/time.h b/absl/time/time.h index be064813..7507b0cd 100644 --- a/absl/time/time.h +++ b/absl/time/time.h @@ -89,6 +89,7 @@ struct timeval; #include "absl/time/internal/cctz/include/cctz/time_zone.h" namespace absl { +ABSL_NAMESPACE_BEGIN class Duration; // Defined below class Time; // Defined below @@ -1574,6 +1575,7 @@ constexpr Time FromTimeT(time_t t) { return time_internal::FromUnixDuration(Seconds(t)); } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TIME_TIME_H_ diff --git a/absl/types/any.h b/absl/types/any.h index f7967694..16bda79c 100644 --- a/absl/types/any.h +++ b/absl/types/any.h @@ -61,10 +61,12 @@ #include // IWYU pragma: export namespace absl { +ABSL_NAMESPACE_BEGIN using std::any; using std::any_cast; using std::bad_any_cast; using std::make_any; +ABSL_NAMESPACE_END } // namespace absl #else // ABSL_USES_STD_ANY @@ -91,6 +93,7 @@ using std::make_any; #endif // !defined(__GNUC__) || defined(__GXX_RTTI) namespace absl { +ABSL_NAMESPACE_BEGIN namespace any_internal { @@ -534,6 +537,7 @@ T* any_cast(any* operand) noexcept { : nullptr; } +ABSL_NAMESPACE_END } // namespace absl #undef ABSL_ANY_DETAIL_HAS_RTTI diff --git a/absl/types/bad_any_cast.cc b/absl/types/bad_any_cast.cc index 2a538126..b0592cc9 100644 --- a/absl/types/bad_any_cast.cc +++ b/absl/types/bad_any_cast.cc @@ -22,6 +22,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { +ABSL_NAMESPACE_BEGIN bad_any_cast::~bad_any_cast() = default; @@ -39,6 +40,7 @@ void ThrowBadAnyCast() { } } // namespace any_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_USES_STD_ANY diff --git a/absl/types/bad_any_cast.h b/absl/types/bad_any_cast.h index 6a53c010..114cef80 100644 --- a/absl/types/bad_any_cast.h +++ b/absl/types/bad_any_cast.h @@ -30,12 +30,15 @@ #include namespace absl { +ABSL_NAMESPACE_BEGIN using std::bad_any_cast; +ABSL_NAMESPACE_END } // namespace absl #else // ABSL_USES_STD_ANY namespace absl { +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // bad_any_cast @@ -64,6 +67,7 @@ namespace any_internal { [[noreturn]] void ThrowBadAnyCast(); } // namespace any_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_USES_STD_ANY diff --git a/absl/types/bad_optional_access.cc b/absl/types/bad_optional_access.cc index d9ec21bf..26aca70d 100644 --- a/absl/types/bad_optional_access.cc +++ b/absl/types/bad_optional_access.cc @@ -22,6 +22,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { +ABSL_NAMESPACE_BEGIN bad_optional_access::~bad_optional_access() = default; @@ -41,6 +42,7 @@ void throw_bad_optional_access() { } } // namespace optional_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_USES_STD_OPTIONAL diff --git a/absl/types/bad_optional_access.h b/absl/types/bad_optional_access.h index 32dd6a91..a500286a 100644 --- a/absl/types/bad_optional_access.h +++ b/absl/types/bad_optional_access.h @@ -30,12 +30,15 @@ #include namespace absl { +ABSL_NAMESPACE_BEGIN using std::bad_optional_access; +ABSL_NAMESPACE_END } // namespace absl #else // ABSL_USES_STD_OPTIONAL namespace absl { +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // bad_optional_access @@ -67,6 +70,7 @@ namespace optional_internal { [[noreturn]] void throw_bad_optional_access(); } // namespace optional_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_USES_STD_OPTIONAL diff --git a/absl/types/bad_variant_access.cc b/absl/types/bad_variant_access.cc index dbaea9e9..3dc88cc0 100644 --- a/absl/types/bad_variant_access.cc +++ b/absl/types/bad_variant_access.cc @@ -23,6 +23,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { +ABSL_NAMESPACE_BEGIN ////////////////////////// // [variant.bad.access] // @@ -57,6 +58,7 @@ void Rethrow() { } } // namespace variant_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_USES_STD_VARIANT diff --git a/absl/types/bad_variant_access.h b/absl/types/bad_variant_access.h index 6935d01b..095969f9 100644 --- a/absl/types/bad_variant_access.h +++ b/absl/types/bad_variant_access.h @@ -30,12 +30,15 @@ #include namespace absl { +ABSL_NAMESPACE_BEGIN using std::bad_variant_access; +ABSL_NAMESPACE_END } // namespace absl #else // ABSL_USES_STD_VARIANT namespace absl { +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // bad_variant_access @@ -71,6 +74,7 @@ namespace variant_internal { [[noreturn]] void Rethrow(); } // namespace variant_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_USES_STD_VARIANT diff --git a/absl/types/compare.h b/absl/types/compare.h index a213e0b0..c29ced52 100644 --- a/absl/types/compare.h +++ b/absl/types/compare.h @@ -39,6 +39,7 @@ #include "absl/meta/type_traits.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace compare_internal { using value_type = int8_t; @@ -551,6 +552,7 @@ constexpr absl::weak_ordering do_three_way_comparison(const Compare &compare, } } // namespace compare_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TYPES_COMPARE_H_ diff --git a/absl/types/compare_test.cc b/absl/types/compare_test.cc index ee396fc5..955844b5 100644 --- a/absl/types/compare_test.cc +++ b/absl/types/compare_test.cc @@ -18,6 +18,7 @@ #include "absl/base/casts.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace { // This is necessary to avoid a bunch of lint warnings suggesting that we use @@ -334,4 +335,5 @@ TEST(Compare, StaticAsserts) { #endif // __cpp_inline_variables } // namespace +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/types/internal/conformance_aliases.h b/absl/types/internal/conformance_aliases.h index 7d5d0e09..0cc6884e 100644 --- a/absl/types/internal/conformance_aliases.h +++ b/absl/types/internal/conformance_aliases.h @@ -26,6 +26,7 @@ #include "absl/types/internal/conformance_profile.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace types_internal { // Creates both a Profile and a corresponding Archetype with root name "name". @@ -438,6 +439,7 @@ using ExpandSupportedProfiles = Receiver< // (potentially) non-noexcept moves. } // namespace types_internal +ABSL_NAMESPACE_END } // namespace absl #undef ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS diff --git a/absl/types/internal/conformance_archetype.h b/absl/types/internal/conformance_archetype.h index 97ee7265..2349e0f7 100644 --- a/absl/types/internal/conformance_archetype.h +++ b/absl/types/internal/conformance_archetype.h @@ -43,6 +43,7 @@ #include "absl/types/internal/conformance_profile.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace types_internal { // A minimum-conforming implementation of a type with properties specified in @@ -961,6 +962,7 @@ struct EnabledHash { }; } // namespace types_internal +ABSL_NAMESPACE_END } // namespace absl namespace std { diff --git a/absl/types/internal/conformance_profile.h b/absl/types/internal/conformance_profile.h index dce3bbee..e62004fd 100644 --- a/absl/types/internal/conformance_profile.h +++ b/absl/types/internal/conformance_profile.h @@ -44,6 +44,7 @@ // TODO(calabrese) Add support for extending profiles. namespace absl { +ABSL_NAMESPACE_BEGIN namespace types_internal { template @@ -369,6 +370,7 @@ template struct IsProfile : IsProfileImpl::type {}; } // namespace types_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TYPES_INTERNAL_CONFORMANCE_PROFILE_H_ diff --git a/absl/types/internal/optional.h b/absl/types/internal/optional.h index d41ccc75..92932b60 100644 --- a/absl/types/internal/optional.h +++ b/absl/types/internal/optional.h @@ -54,6 +54,7 @@ #endif namespace absl { +ABSL_NAMESPACE_BEGIN // Forward declaration template @@ -387,6 +388,7 @@ struct optional_hash_base >()( }; } // namespace optional_internal +ABSL_NAMESPACE_END } // namespace absl #undef ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS diff --git a/absl/types/internal/span.h b/absl/types/internal/span.h index d203aad5..112612f4 100644 --- a/absl/types/internal/span.h +++ b/absl/types/internal/span.h @@ -26,6 +26,7 @@ #include "absl/meta/type_traits.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace span_internal { // A constexpr min function @@ -121,6 +122,7 @@ template using EnableIfConvertibleTo = typename std::enable_if::value>::type; } // namespace span_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TYPES_INTERNAL_SPAN_H_ diff --git a/absl/types/internal/variant.h b/absl/types/internal/variant.h index 58b38592..71bd3adf 100644 --- a/absl/types/internal/variant.h +++ b/absl/types/internal/variant.h @@ -40,6 +40,7 @@ #if !defined(ABSL_USES_STD_VARIANT) namespace absl { +ABSL_NAMESPACE_BEGIN template class variant; @@ -1638,6 +1639,7 @@ struct VariantHashBase // IWYU pragma: export namespace absl { +ABSL_NAMESPACE_BEGIN using std::bad_optional_access; using std::optional; using std::make_optional; using std::nullopt_t; using std::nullopt; +ABSL_NAMESPACE_END } // namespace absl #else // ABSL_USES_STD_OPTIONAL @@ -65,6 +67,7 @@ using std::nullopt; #include "absl/types/internal/optional.h" namespace absl { +ABSL_NAMESPACE_BEGIN // nullopt_t // @@ -754,6 +757,7 @@ constexpr auto operator>=(const U& v, const optional& x) return static_cast(x) ? static_cast(v >= *x) : true; } +ABSL_NAMESPACE_END } // namespace absl namespace std { diff --git a/absl/types/optional_exception_safety_test.cc b/absl/types/optional_exception_safety_test.cc index 0f7fae6c..8e5fe851 100644 --- a/absl/types/optional_exception_safety_test.cc +++ b/absl/types/optional_exception_safety_test.cc @@ -24,6 +24,7 @@ #include "absl/base/internal/exception_safety_testing.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace { @@ -285,6 +286,7 @@ TEST(OptionalExceptionSafety, NothrowMoveAssign) { } // namespace +ABSL_NAMESPACE_END } // namespace absl #endif // #if !defined(ABSL_USES_STD_OPTIONAL) && defined(ABSL_HAVE_EXCEPTIONS) diff --git a/absl/types/span.h b/absl/types/span.h index b007fc1f..3283145a 100644 --- a/absl/types/span.h +++ b/absl/types/span.h @@ -71,6 +71,7 @@ #include "absl/types/internal/span.h" namespace absl { +ABSL_NAMESPACE_BEGIN //------------------------------------------------------------------------------ // Span @@ -707,5 +708,6 @@ template constexpr Span MakeConstSpan(const T (&array)[N]) noexcept { return Span(array, N); } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TYPES_SPAN_H_ diff --git a/absl/types/variant.h b/absl/types/variant.h index f3558703..776d19a1 100644 --- a/absl/types/variant.h +++ b/absl/types/variant.h @@ -50,6 +50,7 @@ #include // IWYU pragma: export namespace absl { +ABSL_NAMESPACE_BEGIN using std::bad_variant_access; using std::get; using std::get_if; @@ -62,6 +63,7 @@ using std::variant_npos; using std::variant_size; using std::variant_size_v; using std::visit; +ABSL_NAMESPACE_END } // namespace absl #else // ABSL_USES_STD_VARIANT @@ -77,6 +79,7 @@ using std::visit; #include "absl/types/internal/variant.h" namespace absl { +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // absl::variant @@ -795,6 +798,7 @@ operator>=(const variant& a, const variant& b) { a.index()); } +ABSL_NAMESPACE_END } // namespace absl namespace std { @@ -815,6 +819,7 @@ struct hash> #endif // ABSL_USES_STD_VARIANT namespace absl { +ABSL_NAMESPACE_BEGIN namespace variant_internal { // Helper visitor for converting a variant` into another type (mostly @@ -850,6 +855,7 @@ To ConvertVariantTo(Variant&& variant) { std::forward(variant)); } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TYPES_VARIANT_H_ diff --git a/absl/types/variant_benchmark.cc b/absl/types/variant_benchmark.cc index a5f52164..350b1753 100644 --- a/absl/types/variant_benchmark.cc +++ b/absl/types/variant_benchmark.cc @@ -28,6 +28,7 @@ #include "absl/utility/utility.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace { template @@ -217,4 +218,5 @@ BENCHMARK_TEMPLATE(BM_RedundantVisit, 4, 2) ->DenseRange(0, integral_pow(4, 2) - 1); } // namespace +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/types/variant_exception_safety_test.cc b/absl/types/variant_exception_safety_test.cc index b486a71e..439c6e1d 100644 --- a/absl/types/variant_exception_safety_test.cc +++ b/absl/types/variant_exception_safety_test.cc @@ -34,6 +34,7 @@ #if !defined(ABSL_INTERNAL_MSVC_2017_DBG_MODE) namespace absl { +ABSL_NAMESPACE_BEGIN namespace { using ::testing::MakeExceptionSafetyTester; @@ -523,6 +524,7 @@ TEST(VariantExceptionSafetyTest, Swap) { } } // namespace +ABSL_NAMESPACE_END } // namespace absl #endif // !defined(ABSL_INTERNAL_MSVC_2017_DBG_MODE) diff --git a/absl/types/variant_test.cc b/absl/types/variant_test.cc index 2913775a..96393333 100644 --- a/absl/types/variant_test.cc +++ b/absl/types/variant_test.cc @@ -70,6 +70,7 @@ struct hash { struct NonHashable {}; namespace absl { +ABSL_NAMESPACE_BEGIN namespace { using ::testing::DoubleEq; @@ -2709,6 +2710,7 @@ TEST(VariantTest, MoveCtorBug) { } } // namespace +ABSL_NAMESPACE_END } // namespace absl #endif // #if !defined(ABSL_USES_STD_VARIANT) diff --git a/absl/utility/utility.h b/absl/utility/utility.h index 5a98c2c3..e6647c7b 100644 --- a/absl/utility/utility.h +++ b/absl/utility/utility.h @@ -51,6 +51,7 @@ #include "absl/meta/type_traits.h" namespace absl { +ABSL_NAMESPACE_BEGIN // integer_sequence // @@ -343,6 +344,7 @@ constexpr T make_from_tuple(Tuple&& tup) { std::tuple_size>::value>{}); } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_UTILITY_UTILITY_H_ -- cgit v1.2.3 From a048203a881f11f4b7b8df5fb563aec85522f8db Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 6 Jan 2020 11:41:27 -0800 Subject: Export of internal Abseil changes -- d3a10a071226497cd34be0f41cb55449193b7172 by Andy Soffer : Removing formatting traits that were only used internally. ON_CALL/EXPECT_CALL do a sufficient job here. PiperOrigin-RevId: 288342973 -- df8180038ea36a0876a84fdc163d1319a611f9db by Greg Falcon : Add CI testing for alternate options.h settings. PiperOrigin-RevId: 288323951 GitOrigin-RevId: d3a10a071226497cd34be0f41cb55449193b7172 Change-Id: I26c75a1ededd52dd2c5a4c50e220d0b8a52d5c7c --- absl/random/BUILD.bazel | 1 - absl/random/CMakeLists.txt | 2 - absl/random/bit_gen_ref.h | 5 +- absl/random/distribution_format_traits.h | 278 ---------------------------- absl/random/distributions.h | 41 ++-- absl/random/internal/BUILD.bazel | 1 - absl/random/internal/distribution_caller.h | 18 +- absl/random/internal/mocking_bit_gen_base.h | 42 +---- absl/random/mocking_bit_gen.cc | 1 - absl/random/mocking_bit_gen.h | 6 +- absl/strings/BUILD.bazel | 1 + absl/strings/CMakeLists.txt | 1 + absl/strings/numbers_test.cc | 1 + ci/absl_types_options.h | 27 +++ ci/linux_clang-latest_libcxx_bazel.sh | 32 ++-- 15 files changed, 72 insertions(+), 385 deletions(-) delete mode 100644 absl/random/distribution_format_traits.h create mode 100644 ci/absl_types_options.h (limited to 'absl/random/CMakeLists.txt') diff --git a/absl/random/BUILD.bazel b/absl/random/BUILD.bazel index 2585b397..43ed9840 100644 --- a/absl/random/BUILD.bazel +++ b/absl/random/BUILD.bazel @@ -53,7 +53,6 @@ cc_library( "bernoulli_distribution.h", "beta_distribution.h", "discrete_distribution.h", - "distribution_format_traits.h", "distributions.h", "exponential_distribution.h", "gaussian_distribution.h", diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt index 46dbc3ef..53f1aa5c 100644 --- a/absl/random/CMakeLists.txt +++ b/absl/random/CMakeLists.txt @@ -78,7 +78,6 @@ absl_cc_library( ${ABSL_DEFAULT_LINKOPTS} DEPS absl::random_random - absl::strings ) # Internal-only target, do not depend on directly. @@ -168,7 +167,6 @@ absl_cc_library( "bernoulli_distribution.h" "beta_distribution.h" "discrete_distribution.h" - "distribution_format_traits.h" "distributions.h" "exponential_distribution.h" "gaussian_distribution.h" diff --git a/absl/random/bit_gen_ref.h b/absl/random/bit_gen_ref.h index e8771162..59591a47 100644 --- a/absl/random/bit_gen_ref.h +++ b/absl/random/bit_gen_ref.h @@ -132,7 +132,7 @@ namespace random_internal { template <> struct DistributionCaller { - template + template static typename DistrT::result_type Call(absl::BitGenRef* gen_ref, Args&&... args) { auto* mock_ptr = gen_ref->mocked_gen_ptr_; @@ -140,8 +140,7 @@ struct DistributionCaller { DistrT dist(std::forward(args)...); return dist(*gen_ref); } else { - return mock_ptr->template Call( - std::forward(args)...); + return mock_ptr->template Call(std::forward(args)...); } } }; diff --git a/absl/random/distribution_format_traits.h b/absl/random/distribution_format_traits.h deleted file mode 100644 index 22b358cc..00000000 --- a/absl/random/distribution_format_traits.h +++ /dev/null @@ -1,278 +0,0 @@ -// -// Copyright 2018 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef ABSL_RANDOM_DISTRIBUTION_FORMAT_TRAITS_H_ -#define ABSL_RANDOM_DISTRIBUTION_FORMAT_TRAITS_H_ - -#include -#include -#include - -#include "absl/meta/type_traits.h" -#include "absl/random/bernoulli_distribution.h" -#include "absl/random/beta_distribution.h" -#include "absl/random/exponential_distribution.h" -#include "absl/random/gaussian_distribution.h" -#include "absl/random/log_uniform_int_distribution.h" -#include "absl/random/poisson_distribution.h" -#include "absl/random/uniform_int_distribution.h" -#include "absl/random/uniform_real_distribution.h" -#include "absl/random/zipf_distribution.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/str_join.h" -#include "absl/strings/string_view.h" -#include "absl/types/span.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -struct IntervalClosedClosedTag; -struct IntervalClosedOpenTag; -struct IntervalOpenClosedTag; -struct IntervalOpenOpenTag; - -namespace random_internal { - -// ScalarTypeName defines a preferred hierarchy of preferred type names for -// scalars, and is evaluated at compile time for the specific type -// specialization. -template -constexpr const char* ScalarTypeName() { - static_assert(std::is_integral() || std::is_floating_point(), ""); - // clang-format off - return - std::is_same::value ? "float" : - std::is_same::value ? "double" : - std::is_same::value ? "long double" : - std::is_same::value ? "bool" : - std::is_signed::value && sizeof(T) == 1 ? "int8_t" : - std::is_signed::value && sizeof(T) == 2 ? "int16_t" : - std::is_signed::value && sizeof(T) == 4 ? "int32_t" : - std::is_signed::value && sizeof(T) == 8 ? "int64_t" : - std::is_unsigned::value && sizeof(T) == 1 ? "uint8_t" : - std::is_unsigned::value && sizeof(T) == 2 ? "uint16_t" : - std::is_unsigned::value && sizeof(T) == 4 ? "uint32_t" : - std::is_unsigned::value && sizeof(T) == 8 ? "uint64_t" : - "undefined"; - // clang-format on - - // NOTE: It would be nice to use typeid(T).name(), but that's an - // implementation-defined attribute which does not necessarily - // correspond to a name. We could potentially demangle it - // using, e.g. abi::__cxa_demangle. -} - -// Distribution traits used by DistributionCaller and internal implementation -// details of the mocking framework. -/* -struct DistributionFormatTraits { - // Returns the parameterized name of the distribution function. - static constexpr const char* FunctionName() - // Format DistrT parameters. - static std::string FormatArgs(DistrT& dist); - // Format DistrT::result_type results. - static std::string FormatResults(DistrT& dist); -}; -*/ -template -struct DistributionFormatTraits; - -template -struct DistributionFormatTraits> { - using distribution_t = absl::uniform_int_distribution; - using result_t = typename distribution_t::result_type; - - static constexpr const char* Name() { return "Uniform"; } - - static std::string FunctionName() { - return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); - } - static std::string FormatArgs(const distribution_t& d) { - return absl::StrCat("absl::IntervalClosedClosed, ", (d.min)(), ", ", - (d.max)()); - } - static std::string FormatResults(absl::Span results) { - return absl::StrJoin(results, ", "); - } -}; - -template -struct DistributionFormatTraits> { - using distribution_t = absl::uniform_real_distribution; - using result_t = typename distribution_t::result_type; - - static constexpr const char* Name() { return "Uniform"; } - - static std::string FunctionName() { - return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); - } - static std::string FormatArgs(const distribution_t& d) { - return absl::StrCat((d.min)(), ", ", (d.max)()); - } - static std::string FormatResults(absl::Span results) { - return absl::StrJoin(results, ", "); - } -}; - -template -struct DistributionFormatTraits> { - using distribution_t = absl::exponential_distribution; - using result_t = typename distribution_t::result_type; - - static constexpr const char* Name() { return "Exponential"; } - - static std::string FunctionName() { - return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); - } - static std::string FormatArgs(const distribution_t& d) { - return absl::StrCat(d.lambda()); - } - static std::string FormatResults(absl::Span results) { - return absl::StrJoin(results, ", "); - } -}; - -template -struct DistributionFormatTraits> { - using distribution_t = absl::poisson_distribution; - using result_t = typename distribution_t::result_type; - - static constexpr const char* Name() { return "Poisson"; } - - static std::string FunctionName() { - return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); - } - static std::string FormatArgs(const distribution_t& d) { - return absl::StrCat(d.mean()); - } - static std::string FormatResults(absl::Span results) { - return absl::StrJoin(results, ", "); - } -}; - -template <> -struct DistributionFormatTraits { - using distribution_t = absl::bernoulli_distribution; - using result_t = typename distribution_t::result_type; - - static constexpr const char* Name() { return "Bernoulli"; } - - static constexpr const char* FunctionName() { return Name(); } - static std::string FormatArgs(const distribution_t& d) { - return absl::StrCat(d.p()); - } - static std::string FormatResults(absl::Span results) { - return absl::StrJoin(results, ", "); - } -}; - -template -struct DistributionFormatTraits> { - using distribution_t = absl::beta_distribution; - using result_t = typename distribution_t::result_type; - - static constexpr const char* Name() { return "Beta"; } - - static std::string FunctionName() { - return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); - } - static std::string FormatArgs(const distribution_t& d) { - return absl::StrCat(d.alpha(), ", ", d.beta()); - } - static std::string FormatResults(absl::Span results) { - return absl::StrJoin(results, ", "); - } -}; - -template -struct DistributionFormatTraits> { - using distribution_t = absl::zipf_distribution; - using result_t = typename distribution_t::result_type; - - static constexpr const char* Name() { return "Zipf"; } - - static std::string FunctionName() { - return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); - } - static std::string FormatArgs(const distribution_t& d) { - return absl::StrCat(d.k(), ", ", d.v(), ", ", d.q()); - } - static std::string FormatResults(absl::Span results) { - return absl::StrJoin(results, ", "); - } -}; - -template -struct DistributionFormatTraits> { - using distribution_t = absl::gaussian_distribution; - using result_t = typename distribution_t::result_type; - - static constexpr const char* Name() { return "Gaussian"; } - - static std::string FunctionName() { - return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); - } - static std::string FormatArgs(const distribution_t& d) { - return absl::StrJoin(std::make_tuple(d.mean(), d.stddev()), ", "); - } - static std::string FormatResults(absl::Span results) { - return absl::StrJoin(results, ", "); - } -}; - -template -struct DistributionFormatTraits> { - using distribution_t = absl::log_uniform_int_distribution; - using result_t = typename distribution_t::result_type; - - static constexpr const char* Name() { return "LogUniform"; } - - static std::string FunctionName() { - return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); - } - static std::string FormatArgs(const distribution_t& d) { - return absl::StrJoin(std::make_tuple((d.min)(), (d.max)(), d.base()), ", "); - } - static std::string FormatResults(absl::Span results) { - return absl::StrJoin(results, ", "); - } -}; - -template -struct UniformDistributionWrapper; - -template -struct DistributionFormatTraits> { - using distribution_t = UniformDistributionWrapper; - using result_t = NumType; - - static constexpr const char* Name() { return "Uniform"; } - - static std::string FunctionName() { - return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); - } - static std::string FormatArgs(const distribution_t& d) { - return absl::StrCat((d.min)(), ", ", (d.max)()); - } - static std::string FormatResults(absl::Span results) { - return absl::StrJoin(results, ", "); - } -}; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_DISTRIBUTION_FORMAT_TRAITS_H_ diff --git a/absl/random/distributions.h b/absl/random/distributions.h index c1fb6650..7abdfa8f 100644 --- a/absl/random/distributions.h +++ b/absl/random/distributions.h @@ -55,7 +55,6 @@ #include "absl/base/internal/inline_variable.h" #include "absl/random/bernoulli_distribution.h" #include "absl/random/beta_distribution.h" -#include "absl/random/distribution_format_traits.h" #include "absl/random/exponential_distribution.h" #include "absl/random/gaussian_distribution.h" #include "absl/random/internal/distributions.h" // IWYU pragma: export @@ -126,14 +125,13 @@ Uniform(TagType tag, R lo, R hi) { using gen_t = absl::decay_t; using distribution_t = random_internal::UniformDistributionWrapper; - using format_t = random_internal::DistributionFormatTraits; auto a = random_internal::uniform_lower_bound(tag, lo, hi); auto b = random_internal::uniform_upper_bound(tag, lo, hi); if (a > b) return a; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, tag, lo, hi); + distribution_t>(&urbg, tag, lo, hi); } // absl::Uniform(bitgen, lo, hi) @@ -146,7 +144,6 @@ Uniform(URBG&& urbg, // NOLINT(runtime/references) R lo, R hi) { using gen_t = absl::decay_t; using distribution_t = random_internal::UniformDistributionWrapper; - using format_t = random_internal::DistributionFormatTraits; constexpr auto tag = absl::IntervalClosedOpen; auto a = random_internal::uniform_lower_bound(tag, lo, hi); @@ -154,7 +151,7 @@ Uniform(URBG&& urbg, // NOLINT(runtime/references) if (a > b) return a; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, lo, hi); + distribution_t>(&urbg, lo, hi); } // absl::Uniform(tag, bitgen, lo, hi) @@ -172,15 +169,14 @@ Uniform(TagType tag, using gen_t = absl::decay_t; using return_t = typename random_internal::uniform_inferred_return_t; using distribution_t = random_internal::UniformDistributionWrapper; - using format_t = random_internal::DistributionFormatTraits; auto a = random_internal::uniform_lower_bound(tag, lo, hi); auto b = random_internal::uniform_upper_bound(tag, lo, hi); if (a > b) return a; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, tag, static_cast(lo), - static_cast(hi)); + distribution_t>(&urbg, tag, static_cast(lo), + static_cast(hi)); } // absl::Uniform(bitgen, lo, hi) @@ -196,7 +192,6 @@ Uniform(URBG&& urbg, // NOLINT(runtime/references) using gen_t = absl::decay_t; using return_t = typename random_internal::uniform_inferred_return_t; using distribution_t = random_internal::UniformDistributionWrapper; - using format_t = random_internal::DistributionFormatTraits; constexpr auto tag = absl::IntervalClosedOpen; auto a = random_internal::uniform_lower_bound(tag, lo, hi); @@ -204,8 +199,8 @@ Uniform(URBG&& urbg, // NOLINT(runtime/references) if (a > b) return a; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, static_cast(lo), - static_cast(hi)); + distribution_t>(&urbg, static_cast(lo), + static_cast(hi)); } // absl::Uniform(bitgen) @@ -217,10 +212,9 @@ typename absl::enable_if_t::value, R> // Uniform(URBG&& urbg) { // NOLINT(runtime/references) using gen_t = absl::decay_t; using distribution_t = random_internal::UniformDistributionWrapper; - using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg); + distribution_t>(&urbg); } // ----------------------------------------------------------------------------- @@ -248,10 +242,9 @@ bool Bernoulli(URBG&& urbg, // NOLINT(runtime/references) double p) { using gen_t = absl::decay_t; using distribution_t = absl::bernoulli_distribution; - using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, p); + distribution_t>(&urbg, p); } // ----------------------------------------------------------------------------- @@ -281,10 +274,9 @@ RealType Beta(URBG&& urbg, // NOLINT(runtime/references) using gen_t = absl::decay_t; using distribution_t = typename absl::beta_distribution; - using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, alpha, beta); + distribution_t>(&urbg, alpha, beta); } // ----------------------------------------------------------------------------- @@ -314,10 +306,9 @@ RealType Exponential(URBG&& urbg, // NOLINT(runtime/references) using gen_t = absl::decay_t; using distribution_t = typename absl::exponential_distribution; - using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, lambda); + distribution_t>(&urbg, lambda); } // ----------------------------------------------------------------------------- @@ -346,10 +337,9 @@ RealType Gaussian(URBG&& urbg, // NOLINT(runtime/references) using gen_t = absl::decay_t; using distribution_t = typename absl::gaussian_distribution; - using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, mean, stddev); + distribution_t>(&urbg, mean, stddev); } // ----------------------------------------------------------------------------- @@ -389,10 +379,9 @@ IntType LogUniform(URBG&& urbg, // NOLINT(runtime/references) using gen_t = absl::decay_t; using distribution_t = typename absl::log_uniform_int_distribution; - using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, lo, hi, base); + distribution_t>(&urbg, lo, hi, base); } // ----------------------------------------------------------------------------- @@ -420,10 +409,9 @@ IntType Poisson(URBG&& urbg, // NOLINT(runtime/references) using gen_t = absl::decay_t; using distribution_t = typename absl::poisson_distribution; - using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, mean); + distribution_t>(&urbg, mean); } // ----------------------------------------------------------------------------- @@ -453,10 +441,9 @@ IntType Zipf(URBG&& urbg, // NOLINT(runtime/references) using gen_t = absl::decay_t; using distribution_t = typename absl::zipf_distribution; - using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, hi, q, v); + distribution_t>(&urbg, hi, q, v); } ABSL_NAMESPACE_END diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel index d7ad4efe..8839078f 100644 --- a/absl/random/internal/BUILD.bazel +++ b/absl/random/internal/BUILD.bazel @@ -509,7 +509,6 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ "//absl/random", - "//absl/strings", ], ) diff --git a/absl/random/internal/distribution_caller.h b/absl/random/internal/distribution_caller.h index 02603cf8..ae2680dd 100644 --- a/absl/random/internal/distribution_caller.h +++ b/absl/random/internal/distribution_caller.h @@ -31,22 +31,8 @@ namespace random_internal { template struct DistributionCaller { // Call the provided distribution type. The parameters are expected - // to be explicitly specified. - // DistrT is the distribution type. - // FormatT is the formatter type: - // - // struct FormatT { - // using result_type = distribution_t::result_type; - // static std::string FormatCall( - // const distribution_t& distr, - // absl::Span); - // - // static std::string FormatExpectation( - // absl::string_view match_args, - // absl::Span results); - // } - // - template + // to be explicitly specified. DistrT is the distribution type. + template static typename DistrT::result_type Call(URBG* urbg, Args&&... args) { DistrT dist(std::forward(args)...); return dist(*urbg); diff --git a/absl/random/internal/mocking_bit_gen_base.h b/absl/random/internal/mocking_bit_gen_base.h index eeeae9d2..acd63872 100644 --- a/absl/random/internal/mocking_bit_gen_base.h +++ b/absl/random/internal/mocking_bit_gen_base.h @@ -16,39 +16,14 @@ #ifndef ABSL_RANDOM_INTERNAL_MOCKING_BIT_GEN_BASE_H_ #define ABSL_RANDOM_INTERNAL_MOCKING_BIT_GEN_BASE_H_ -#include -#include -#include #include #include "absl/random/random.h" -#include "absl/strings/str_cat.h" namespace absl { ABSL_NAMESPACE_BEGIN namespace random_internal { -// MockingBitGenExpectationFormatter is invoked to format unsatisfied mocks -// and remaining results into a description string. -template -struct MockingBitGenExpectationFormatter { - std::string operator()(absl::string_view args) { - return absl::StrCat(FormatT::FunctionName(), "(", args, ")"); - } -}; - -// MockingBitGenCallFormatter is invoked to format each distribution call -// into a description string for the mock log. -template -struct MockingBitGenCallFormatter { - std::string operator()(const DistrT& dist, - const typename DistrT::result_type& result) { - return absl::StrCat( - FormatT::FunctionName(), "(", FormatT::FormatArgs(dist), ") => {", - FormatT::FormatResults(absl::MakeSpan(&result, 1)), "}"); - } -}; - class MockingBitGenBase { template friend struct DistributionCaller; @@ -61,14 +36,9 @@ class MockingBitGenBase { static constexpr result_type(max)() { return (generator_type::max)(); } result_type operator()() { return gen_(); } - MockingBitGenBase() : gen_(), observed_call_log_() {} virtual ~MockingBitGenBase() = default; protected: - const std::deque& observed_call_log() { - return observed_call_log_; - } - // CallImpl is the type-erased virtual dispatch. // The type of dist is always distribution, // The type of result is always distribution::result_type. @@ -81,10 +51,9 @@ class MockingBitGenBase { } // Call the generating distribution function. - // Invoked by DistributionCaller<>::Call. + // Invoked by DistributionCaller<>::Call. // DistT is the distribution type. - // FormatT is the distribution formatter traits type. - template + template typename DistrT::result_type Call(Args&&... args) { using distr_result_type = typename DistrT::result_type; using ArgTupleT = std::tuple...>; @@ -99,18 +68,11 @@ class MockingBitGenBase { if (!found_match) { result = dist(gen_); } - - // TODO(asoffer): Forwarding the args through means we no longer need to - // extract them from the from the distribution in formatter traits. We can - // just StrJoin them. - observed_call_log_.push_back( - MockingBitGenCallFormatter{}(dist, result)); return result; } private: generator_type gen_; - std::deque observed_call_log_; }; // namespace random_internal } // namespace random_internal diff --git a/absl/random/mocking_bit_gen.cc b/absl/random/mocking_bit_gen.cc index 6bb1e414..02209115 100644 --- a/absl/random/mocking_bit_gen.cc +++ b/absl/random/mocking_bit_gen.cc @@ -20,7 +20,6 @@ namespace absl { ABSL_NAMESPACE_BEGIN MockingBitGen::~MockingBitGen() { - for (const auto& del : deleters_) { del(); } diff --git a/absl/random/mocking_bit_gen.h b/absl/random/mocking_bit_gen.h index 36cef911..246c5b1e 100644 --- a/absl/random/mocking_bit_gen.h +++ b/absl/random/mocking_bit_gen.h @@ -109,7 +109,7 @@ class MockingBitGen : public absl::random_internal::MockingBitGenBase { // MockingBitGen::Register // - // Register is the main extension point for + // Register is the main extension point for // extending the MockingBitGen framework. It provides a mechanism to install a // mock expectation for the distribution `distr_t` onto the MockingBitGen // context. @@ -182,10 +182,10 @@ namespace random_internal { template <> struct DistributionCaller { - template + template static typename DistrT::result_type Call(absl::MockingBitGen* gen, Args&&... args) { - return gen->template Call(std::forward(args)...); + return gen->template Call(std::forward(args)...); } }; diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel index 8d0a6b6d..b5547f71 100644 --- a/absl/strings/BUILD.bazel +++ b/absl/strings/BUILD.bazel @@ -412,6 +412,7 @@ cc_test( copts = ABSL_TEST_COPTS, visibility = ["//visibility:private"], deps = [ + ":internal", ":pow10_helper", ":strings", "//absl/base:config", diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt index 98101573..5366fb65 100644 --- a/absl/strings/CMakeLists.txt +++ b/absl/strings/CMakeLists.txt @@ -275,6 +275,7 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::strings + absl::strings_internal absl::core_headers absl::pow10_helper absl::config diff --git a/absl/strings/numbers_test.cc b/absl/strings/numbers_test.cc index 68229b15..f66d9c36 100644 --- a/absl/strings/numbers_test.cc +++ b/absl/strings/numbers_test.cc @@ -40,6 +40,7 @@ #include "absl/random/distributions.h" #include "absl/random/random.h" #include "absl/strings/internal/numbers_test_common.h" +#include "absl/strings/internal/ostringstream.h" #include "absl/strings/internal/pow10_helper.h" #include "absl/strings/str_cat.h" diff --git a/ci/absl_types_options.h b/ci/absl_types_options.h new file mode 100644 index 00000000..8f8ed34a --- /dev/null +++ b/ci/absl_types_options.h @@ -0,0 +1,27 @@ +#ifndef ABSL_BASE_OPTIONS_H_ +#define ABSL_BASE_OPTIONS_H_ + +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Alternate options.h file, requesting to always use Abseil implementations +// of the workalike types, regardless of language version. + +#define ABSL_OPTION_USE_STD_ANY 0 +#define ABSL_OPTION_USE_STD_OPTIONAL 0 +#define ABSL_OPTION_USE_STD_STRING_VIEW 0 +#define ABSL_OPTION_USE_STD_VARIANT 0 + + +#endif // ABSL_BASE_OPTIONS_H_ diff --git a/ci/linux_clang-latest_libcxx_bazel.sh b/ci/linux_clang-latest_libcxx_bazel.sh index 40a27c0b..127e7bc7 100755 --- a/ci/linux_clang-latest_libcxx_bazel.sh +++ b/ci/linux_clang-latest_libcxx_bazel.sh @@ -55,7 +55,8 @@ for std in ${STD}; do for exceptions_mode in ${EXCEPTIONS_MODE}; do echo "--------------------------------------------------------------------" time docker run \ - --volume="${ABSEIL_ROOT}:/abseil-cpp:ro" \ + --volume="${ABSEIL_ROOT}:/abseil-cpp-ro:ro" \ + --tmpfs=/abseil-cpp \ --workdir=/abseil-cpp \ --cap-add=SYS_PTRACE \ --rm \ @@ -66,18 +67,23 @@ for std in ${STD}; do -e CPLUS_INCLUDE_PATH="/opt/llvm/libcxx/include/c++/v1" \ ${DOCKER_EXTRA_ARGS:-} \ ${DOCKER_CONTAINER} \ - /usr/local/bin/bazel test ... \ - --compilation_mode="${compilation_mode}" \ - --copt="${exceptions_mode}" \ - --copt=-Werror \ - --define="absl=1" \ - --keep_going \ - --show_timestamps \ - --test_env="GTEST_INSTALL_FAILURE_SIGNAL_HANDLER=1" \ - --test_env="TZDIR=/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo" \ - --test_output=errors \ - --test_tag_filters=-benchmark \ - ${BAZEL_EXTRA_ARGS:-} + /bin/sh -c " + cp -r /abseil-cpp-ro/* /abseil-cpp/ + if [ -n \"${ALTERNATE_OPTIONS:-}\" ]; then + cp ${ALTERNATE_OPTIONS:-} absl/base/options.h || exit 1 + fi + /usr/local/bin/bazel test ... \ + --compilation_mode=\"${compilation_mode}\" \ + --copt=\"${exceptions_mode}\" \ + --copt=-Werror \ + --define=\"absl=1\" \ + --keep_going \ + --show_timestamps \ + --test_env=\"GTEST_INSTALL_FAILURE_SIGNAL_HANDLER=1\" \ + --test_env=\"TZDIR=/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo\" \ + --test_output=errors \ + --test_tag_filters=-benchmark \ + ${BAZEL_EXTRA_ARGS:-}" done done done -- cgit v1.2.3 From 63ee2f8877915a3565c29707dba8fe4d7822596a Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 7 Jan 2020 06:56:49 -0800 Subject: Export of internal Abseil changes -- 7f6c15aadc4d97e217dd446518dbb4fdc86b36a3 by Derek Mauro : Upgrade GCC automated testing to use GCC 9.2 and Cmake 3.16.2 PiperOrigin-RevId: 288488783 -- a978cee848d3cf65b0826c981bfd81022fc36660 by Abseil Team : Removing formatting traits that were only used internally. ON_CALL/EXPECT_CALL do a sufficient job here. PiperOrigin-RevId: 288386509 -- fdec6f40293d5883220f1f0ea1261f7c5b60a66e by Derek Mauro : Upgrade MacOS tests to use Bazel 2.0.0 PiperOrigin-RevId: 288373298 -- 465865c4123e9481ab50ea0527e92b39519704dd by Derek Mauro : Changes to support GCC 9 * Fix several -Wredundant-move warnings * Remove FlatHashMap.Any test, which basically doesn't work on any platform any more (see https://cplusplus.github.io/LWG/lwg-active.html#3121) * Fix a constant sign-compare warning * Conditionally compile out the PoisonHash test which doesn't build PiperOrigin-RevId: 288360204 -- 57c4bb07fc58e7dd2a04f3c45027aab5ecaccf25 by Andy Soffer : Deflaking MockingBitGen test. Because MockingBitGen can return random values, it is inherently flaky. For log-unifrom, 2040 is a common enough value that tests failed unreasonably frequently. Replacing it with a significantly larger value so as to be much less common. 50000 is a good choice because it is (tied for) the least likely to occur randomly from this distribution, but is still in the distribution. PiperOrigin-RevId: 288360112 -- 86f38e4109899d972de353b1c556c018cfe37956 by Matt Calabrese : Remove construction tests for the internal `CompressedTuple` instantiation. This was not guaranteed to work for the reasons that `std::tuple` copy construction does not actually work by standard specification (some implementations introduce workarounds for this). In GCC9, `CompressedTuple` and `std::tuple` both fail for the same reasons, and a proper "fix" requires updating `std::any`, which is out of our control. PiperOrigin-RevId: 288351977 GitOrigin-RevId: 7f6c15aadc4d97e217dd446518dbb4fdc86b36a3 Change-Id: I5d5c62bd297dc0ff1f2970ff076bb5cd088a7e4c --- absl/container/flat_hash_map_test.cc | 35 --- absl/container/internal/compressed_tuple_test.cc | 4 - absl/hash/hash_test.cc | 5 +- absl/hash/internal/hash.h | 6 +- absl/random/BUILD.bazel | 1 + absl/random/CMakeLists.txt | 2 + absl/random/bit_gen_ref.h | 5 +- absl/random/distribution_format_traits.h | 278 +++++++++++++++++++++++ absl/random/distributions.h | 41 ++-- absl/random/internal/BUILD.bazel | 1 + absl/random/internal/distribution_caller.h | 18 +- absl/random/internal/mocking_bit_gen_base.h | 42 +++- absl/random/mocking_bit_gen.cc | 1 + absl/random/mocking_bit_gen.h | 6 +- absl/random/mocking_bit_gen_test.cc | 6 +- absl/strings/BUILD.bazel | 1 - absl/strings/CMakeLists.txt | 1 - absl/strings/numbers_test.cc | 1 - ci/cmake_install_test.sh | 2 +- ci/linux_gcc-latest_libstdcxx_bazel.sh | 2 +- ci/linux_gcc-latest_libstdcxx_cmake.sh | 2 +- ci/macos_xcode_bazel.sh | 2 +- 22 files changed, 386 insertions(+), 76 deletions(-) create mode 100644 absl/random/distribution_format_traits.h (limited to 'absl/random/CMakeLists.txt') diff --git a/absl/container/flat_hash_map_test.cc b/absl/container/flat_hash_map_test.cc index fd9c5604..728b693a 100644 --- a/absl/container/flat_hash_map_test.cc +++ b/absl/container/flat_hash_map_test.cc @@ -253,41 +253,6 @@ TEST(FlatHashMap, EraseIf) { } } -#if (defined(ABSL_USES_STD_ANY) || !defined(_LIBCPP_VERSION)) && \ - !defined(__EMSCRIPTEN__) -TEST(FlatHashMap, Any) { - absl::flat_hash_map m; - m.emplace(1, 7); - auto it = m.find(1); - ASSERT_NE(it, m.end()); - EXPECT_EQ(7, absl::any_cast(it->second)); - - m.emplace(std::piecewise_construct, std::make_tuple(2), std::make_tuple(8)); - it = m.find(2); - ASSERT_NE(it, m.end()); - EXPECT_EQ(8, absl::any_cast(it->second)); - - m.emplace(std::piecewise_construct, std::make_tuple(3), - std::make_tuple(absl::any(9))); - it = m.find(3); - ASSERT_NE(it, m.end()); - EXPECT_EQ(9, absl::any_cast(it->second)); - - struct H { - size_t operator()(const absl::any&) const { return 0; } - }; - struct E { - bool operator()(const absl::any&, const absl::any&) const { return true; } - }; - absl::flat_hash_map m2; - m2.emplace(1, 7); - auto it2 = m2.find(1); - ASSERT_NE(it2, m2.end()); - EXPECT_EQ(7, it2->second); -} -#endif // (defined(ABSL_USES_STD_ANY) || !defined(_LIBCPP_VERSION)) && - // !defined(__EMSCRIPTEN__) - } // namespace } // namespace container_internal ABSL_NAMESPACE_END diff --git a/absl/container/internal/compressed_tuple_test.cc b/absl/container/internal/compressed_tuple_test.cc index 76bc9213..1dae12db 100644 --- a/absl/container/internal/compressed_tuple_test.cc +++ b/absl/container/internal/compressed_tuple_test.cc @@ -333,10 +333,6 @@ TEST(CompressedTupleTest, AnyElements) { a = 0.5f; EXPECT_EQ(absl::any_cast(x.get<1>()), 0.5); - - // Ensure copy construction work in the face of a type with a universal - // implicit constructor; - CompressedTuple c{}, d(c); // NOLINT } TEST(CompressedTupleTest, Constexpr) { diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc index 7a9d57f7..f02a537a 100644 --- a/absl/hash/hash_test.cc +++ b/absl/hash/hash_test.cc @@ -460,7 +460,7 @@ struct DummyFooBar { const char* bar = "bar"; h = H::combine_contiguous(std::move(h), foo, 3); h = H::combine_contiguous(std::move(h), bar, 3); - return std::move(h); + return h; } }; @@ -595,7 +595,10 @@ TEST(IsHashableTest, PoisonHash) { EXPECT_FALSE(absl::is_copy_assignable>::value); EXPECT_FALSE(absl::is_move_assignable>::value); EXPECT_FALSE(IsHashCallable::value); +#if !defined(__GNUC__) || __GNUC__ < 9 + // This doesn't compile on GCC 9. EXPECT_FALSE(IsAggregateInitializable>::value); +#endif } #endif // ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h index 2564978a..8639181f 100644 --- a/absl/hash/internal/hash.h +++ b/absl/hash/internal/hash.h @@ -57,7 +57,7 @@ class PiecewiseCombiner; // Internal detail: Large buffers are hashed in smaller chunks. This function // returns the size of these chunks. -constexpr int PiecewiseChunkSize() { return 1024; } +constexpr size_t PiecewiseChunkSize() { return 1024; } // HashStateBase // @@ -951,7 +951,7 @@ H PiecewiseCombiner::add_buffer(H state, const unsigned char* data, // This partial chunk does not fill our existing buffer memcpy(buf_ + position_, data, size); position_ += size; - return std::move(state); + return state; } // Complete the buffer and hash it @@ -970,7 +970,7 @@ H PiecewiseCombiner::add_buffer(H state, const unsigned char* data, // Fill the buffer with the remainder memcpy(buf_, data, size); position_ = size; - return std::move(state); + return state; } // HashStateBase::PiecewiseCombiner::finalize() diff --git a/absl/random/BUILD.bazel b/absl/random/BUILD.bazel index 43ed9840..2585b397 100644 --- a/absl/random/BUILD.bazel +++ b/absl/random/BUILD.bazel @@ -53,6 +53,7 @@ cc_library( "bernoulli_distribution.h", "beta_distribution.h", "discrete_distribution.h", + "distribution_format_traits.h", "distributions.h", "exponential_distribution.h", "gaussian_distribution.h", diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt index 53f1aa5c..46dbc3ef 100644 --- a/absl/random/CMakeLists.txt +++ b/absl/random/CMakeLists.txt @@ -78,6 +78,7 @@ absl_cc_library( ${ABSL_DEFAULT_LINKOPTS} DEPS absl::random_random + absl::strings ) # Internal-only target, do not depend on directly. @@ -167,6 +168,7 @@ absl_cc_library( "bernoulli_distribution.h" "beta_distribution.h" "discrete_distribution.h" + "distribution_format_traits.h" "distributions.h" "exponential_distribution.h" "gaussian_distribution.h" diff --git a/absl/random/bit_gen_ref.h b/absl/random/bit_gen_ref.h index 59591a47..e8771162 100644 --- a/absl/random/bit_gen_ref.h +++ b/absl/random/bit_gen_ref.h @@ -132,7 +132,7 @@ namespace random_internal { template <> struct DistributionCaller { - template + template static typename DistrT::result_type Call(absl::BitGenRef* gen_ref, Args&&... args) { auto* mock_ptr = gen_ref->mocked_gen_ptr_; @@ -140,7 +140,8 @@ struct DistributionCaller { DistrT dist(std::forward(args)...); return dist(*gen_ref); } else { - return mock_ptr->template Call(std::forward(args)...); + return mock_ptr->template Call( + std::forward(args)...); } } }; diff --git a/absl/random/distribution_format_traits.h b/absl/random/distribution_format_traits.h new file mode 100644 index 00000000..22b358cc --- /dev/null +++ b/absl/random/distribution_format_traits.h @@ -0,0 +1,278 @@ +// +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef ABSL_RANDOM_DISTRIBUTION_FORMAT_TRAITS_H_ +#define ABSL_RANDOM_DISTRIBUTION_FORMAT_TRAITS_H_ + +#include +#include +#include + +#include "absl/meta/type_traits.h" +#include "absl/random/bernoulli_distribution.h" +#include "absl/random/beta_distribution.h" +#include "absl/random/exponential_distribution.h" +#include "absl/random/gaussian_distribution.h" +#include "absl/random/log_uniform_int_distribution.h" +#include "absl/random/poisson_distribution.h" +#include "absl/random/uniform_int_distribution.h" +#include "absl/random/uniform_real_distribution.h" +#include "absl/random/zipf_distribution.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/str_join.h" +#include "absl/strings/string_view.h" +#include "absl/types/span.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +struct IntervalClosedClosedTag; +struct IntervalClosedOpenTag; +struct IntervalOpenClosedTag; +struct IntervalOpenOpenTag; + +namespace random_internal { + +// ScalarTypeName defines a preferred hierarchy of preferred type names for +// scalars, and is evaluated at compile time for the specific type +// specialization. +template +constexpr const char* ScalarTypeName() { + static_assert(std::is_integral() || std::is_floating_point(), ""); + // clang-format off + return + std::is_same::value ? "float" : + std::is_same::value ? "double" : + std::is_same::value ? "long double" : + std::is_same::value ? "bool" : + std::is_signed::value && sizeof(T) == 1 ? "int8_t" : + std::is_signed::value && sizeof(T) == 2 ? "int16_t" : + std::is_signed::value && sizeof(T) == 4 ? "int32_t" : + std::is_signed::value && sizeof(T) == 8 ? "int64_t" : + std::is_unsigned::value && sizeof(T) == 1 ? "uint8_t" : + std::is_unsigned::value && sizeof(T) == 2 ? "uint16_t" : + std::is_unsigned::value && sizeof(T) == 4 ? "uint32_t" : + std::is_unsigned::value && sizeof(T) == 8 ? "uint64_t" : + "undefined"; + // clang-format on + + // NOTE: It would be nice to use typeid(T).name(), but that's an + // implementation-defined attribute which does not necessarily + // correspond to a name. We could potentially demangle it + // using, e.g. abi::__cxa_demangle. +} + +// Distribution traits used by DistributionCaller and internal implementation +// details of the mocking framework. +/* +struct DistributionFormatTraits { + // Returns the parameterized name of the distribution function. + static constexpr const char* FunctionName() + // Format DistrT parameters. + static std::string FormatArgs(DistrT& dist); + // Format DistrT::result_type results. + static std::string FormatResults(DistrT& dist); +}; +*/ +template +struct DistributionFormatTraits; + +template +struct DistributionFormatTraits> { + using distribution_t = absl::uniform_int_distribution; + using result_t = typename distribution_t::result_type; + + static constexpr const char* Name() { return "Uniform"; } + + static std::string FunctionName() { + return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); + } + static std::string FormatArgs(const distribution_t& d) { + return absl::StrCat("absl::IntervalClosedClosed, ", (d.min)(), ", ", + (d.max)()); + } + static std::string FormatResults(absl::Span results) { + return absl::StrJoin(results, ", "); + } +}; + +template +struct DistributionFormatTraits> { + using distribution_t = absl::uniform_real_distribution; + using result_t = typename distribution_t::result_type; + + static constexpr const char* Name() { return "Uniform"; } + + static std::string FunctionName() { + return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); + } + static std::string FormatArgs(const distribution_t& d) { + return absl::StrCat((d.min)(), ", ", (d.max)()); + } + static std::string FormatResults(absl::Span results) { + return absl::StrJoin(results, ", "); + } +}; + +template +struct DistributionFormatTraits> { + using distribution_t = absl::exponential_distribution; + using result_t = typename distribution_t::result_type; + + static constexpr const char* Name() { return "Exponential"; } + + static std::string FunctionName() { + return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); + } + static std::string FormatArgs(const distribution_t& d) { + return absl::StrCat(d.lambda()); + } + static std::string FormatResults(absl::Span results) { + return absl::StrJoin(results, ", "); + } +}; + +template +struct DistributionFormatTraits> { + using distribution_t = absl::poisson_distribution; + using result_t = typename distribution_t::result_type; + + static constexpr const char* Name() { return "Poisson"; } + + static std::string FunctionName() { + return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); + } + static std::string FormatArgs(const distribution_t& d) { + return absl::StrCat(d.mean()); + } + static std::string FormatResults(absl::Span results) { + return absl::StrJoin(results, ", "); + } +}; + +template <> +struct DistributionFormatTraits { + using distribution_t = absl::bernoulli_distribution; + using result_t = typename distribution_t::result_type; + + static constexpr const char* Name() { return "Bernoulli"; } + + static constexpr const char* FunctionName() { return Name(); } + static std::string FormatArgs(const distribution_t& d) { + return absl::StrCat(d.p()); + } + static std::string FormatResults(absl::Span results) { + return absl::StrJoin(results, ", "); + } +}; + +template +struct DistributionFormatTraits> { + using distribution_t = absl::beta_distribution; + using result_t = typename distribution_t::result_type; + + static constexpr const char* Name() { return "Beta"; } + + static std::string FunctionName() { + return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); + } + static std::string FormatArgs(const distribution_t& d) { + return absl::StrCat(d.alpha(), ", ", d.beta()); + } + static std::string FormatResults(absl::Span results) { + return absl::StrJoin(results, ", "); + } +}; + +template +struct DistributionFormatTraits> { + using distribution_t = absl::zipf_distribution; + using result_t = typename distribution_t::result_type; + + static constexpr const char* Name() { return "Zipf"; } + + static std::string FunctionName() { + return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); + } + static std::string FormatArgs(const distribution_t& d) { + return absl::StrCat(d.k(), ", ", d.v(), ", ", d.q()); + } + static std::string FormatResults(absl::Span results) { + return absl::StrJoin(results, ", "); + } +}; + +template +struct DistributionFormatTraits> { + using distribution_t = absl::gaussian_distribution; + using result_t = typename distribution_t::result_type; + + static constexpr const char* Name() { return "Gaussian"; } + + static std::string FunctionName() { + return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); + } + static std::string FormatArgs(const distribution_t& d) { + return absl::StrJoin(std::make_tuple(d.mean(), d.stddev()), ", "); + } + static std::string FormatResults(absl::Span results) { + return absl::StrJoin(results, ", "); + } +}; + +template +struct DistributionFormatTraits> { + using distribution_t = absl::log_uniform_int_distribution; + using result_t = typename distribution_t::result_type; + + static constexpr const char* Name() { return "LogUniform"; } + + static std::string FunctionName() { + return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); + } + static std::string FormatArgs(const distribution_t& d) { + return absl::StrJoin(std::make_tuple((d.min)(), (d.max)(), d.base()), ", "); + } + static std::string FormatResults(absl::Span results) { + return absl::StrJoin(results, ", "); + } +}; + +template +struct UniformDistributionWrapper; + +template +struct DistributionFormatTraits> { + using distribution_t = UniformDistributionWrapper; + using result_t = NumType; + + static constexpr const char* Name() { return "Uniform"; } + + static std::string FunctionName() { + return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); + } + static std::string FormatArgs(const distribution_t& d) { + return absl::StrCat((d.min)(), ", ", (d.max)()); + } + static std::string FormatResults(absl::Span results) { + return absl::StrJoin(results, ", "); + } +}; + +} // namespace random_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_RANDOM_DISTRIBUTION_FORMAT_TRAITS_H_ diff --git a/absl/random/distributions.h b/absl/random/distributions.h index 7abdfa8f..c1fb6650 100644 --- a/absl/random/distributions.h +++ b/absl/random/distributions.h @@ -55,6 +55,7 @@ #include "absl/base/internal/inline_variable.h" #include "absl/random/bernoulli_distribution.h" #include "absl/random/beta_distribution.h" +#include "absl/random/distribution_format_traits.h" #include "absl/random/exponential_distribution.h" #include "absl/random/gaussian_distribution.h" #include "absl/random/internal/distributions.h" // IWYU pragma: export @@ -125,13 +126,14 @@ Uniform(TagType tag, R lo, R hi) { using gen_t = absl::decay_t; using distribution_t = random_internal::UniformDistributionWrapper; + using format_t = random_internal::DistributionFormatTraits; auto a = random_internal::uniform_lower_bound(tag, lo, hi); auto b = random_internal::uniform_upper_bound(tag, lo, hi); if (a > b) return a; return random_internal::DistributionCaller::template Call< - distribution_t>(&urbg, tag, lo, hi); + distribution_t, format_t>(&urbg, tag, lo, hi); } // absl::Uniform(bitgen, lo, hi) @@ -144,6 +146,7 @@ Uniform(URBG&& urbg, // NOLINT(runtime/references) R lo, R hi) { using gen_t = absl::decay_t; using distribution_t = random_internal::UniformDistributionWrapper; + using format_t = random_internal::DistributionFormatTraits; constexpr auto tag = absl::IntervalClosedOpen; auto a = random_internal::uniform_lower_bound(tag, lo, hi); @@ -151,7 +154,7 @@ Uniform(URBG&& urbg, // NOLINT(runtime/references) if (a > b) return a; return random_internal::DistributionCaller::template Call< - distribution_t>(&urbg, lo, hi); + distribution_t, format_t>(&urbg, lo, hi); } // absl::Uniform(tag, bitgen, lo, hi) @@ -169,14 +172,15 @@ Uniform(TagType tag, using gen_t = absl::decay_t; using return_t = typename random_internal::uniform_inferred_return_t; using distribution_t = random_internal::UniformDistributionWrapper; + using format_t = random_internal::DistributionFormatTraits; auto a = random_internal::uniform_lower_bound(tag, lo, hi); auto b = random_internal::uniform_upper_bound(tag, lo, hi); if (a > b) return a; return random_internal::DistributionCaller::template Call< - distribution_t>(&urbg, tag, static_cast(lo), - static_cast(hi)); + distribution_t, format_t>(&urbg, tag, static_cast(lo), + static_cast(hi)); } // absl::Uniform(bitgen, lo, hi) @@ -192,6 +196,7 @@ Uniform(URBG&& urbg, // NOLINT(runtime/references) using gen_t = absl::decay_t; using return_t = typename random_internal::uniform_inferred_return_t; using distribution_t = random_internal::UniformDistributionWrapper; + using format_t = random_internal::DistributionFormatTraits; constexpr auto tag = absl::IntervalClosedOpen; auto a = random_internal::uniform_lower_bound(tag, lo, hi); @@ -199,8 +204,8 @@ Uniform(URBG&& urbg, // NOLINT(runtime/references) if (a > b) return a; return random_internal::DistributionCaller::template Call< - distribution_t>(&urbg, static_cast(lo), - static_cast(hi)); + distribution_t, format_t>(&urbg, static_cast(lo), + static_cast(hi)); } // absl::Uniform(bitgen) @@ -212,9 +217,10 @@ typename absl::enable_if_t::value, R> // Uniform(URBG&& urbg) { // NOLINT(runtime/references) using gen_t = absl::decay_t; using distribution_t = random_internal::UniformDistributionWrapper; + using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t>(&urbg); + distribution_t, format_t>(&urbg); } // ----------------------------------------------------------------------------- @@ -242,9 +248,10 @@ bool Bernoulli(URBG&& urbg, // NOLINT(runtime/references) double p) { using gen_t = absl::decay_t; using distribution_t = absl::bernoulli_distribution; + using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t>(&urbg, p); + distribution_t, format_t>(&urbg, p); } // ----------------------------------------------------------------------------- @@ -274,9 +281,10 @@ RealType Beta(URBG&& urbg, // NOLINT(runtime/references) using gen_t = absl::decay_t; using distribution_t = typename absl::beta_distribution; + using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t>(&urbg, alpha, beta); + distribution_t, format_t>(&urbg, alpha, beta); } // ----------------------------------------------------------------------------- @@ -306,9 +314,10 @@ RealType Exponential(URBG&& urbg, // NOLINT(runtime/references) using gen_t = absl::decay_t; using distribution_t = typename absl::exponential_distribution; + using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t>(&urbg, lambda); + distribution_t, format_t>(&urbg, lambda); } // ----------------------------------------------------------------------------- @@ -337,9 +346,10 @@ RealType Gaussian(URBG&& urbg, // NOLINT(runtime/references) using gen_t = absl::decay_t; using distribution_t = typename absl::gaussian_distribution; + using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t>(&urbg, mean, stddev); + distribution_t, format_t>(&urbg, mean, stddev); } // ----------------------------------------------------------------------------- @@ -379,9 +389,10 @@ IntType LogUniform(URBG&& urbg, // NOLINT(runtime/references) using gen_t = absl::decay_t; using distribution_t = typename absl::log_uniform_int_distribution; + using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t>(&urbg, lo, hi, base); + distribution_t, format_t>(&urbg, lo, hi, base); } // ----------------------------------------------------------------------------- @@ -409,9 +420,10 @@ IntType Poisson(URBG&& urbg, // NOLINT(runtime/references) using gen_t = absl::decay_t; using distribution_t = typename absl::poisson_distribution; + using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t>(&urbg, mean); + distribution_t, format_t>(&urbg, mean); } // ----------------------------------------------------------------------------- @@ -441,9 +453,10 @@ IntType Zipf(URBG&& urbg, // NOLINT(runtime/references) using gen_t = absl::decay_t; using distribution_t = typename absl::zipf_distribution; + using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t>(&urbg, hi, q, v); + distribution_t, format_t>(&urbg, hi, q, v); } ABSL_NAMESPACE_END diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel index 8839078f..d7ad4efe 100644 --- a/absl/random/internal/BUILD.bazel +++ b/absl/random/internal/BUILD.bazel @@ -509,6 +509,7 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ "//absl/random", + "//absl/strings", ], ) diff --git a/absl/random/internal/distribution_caller.h b/absl/random/internal/distribution_caller.h index ae2680dd..02603cf8 100644 --- a/absl/random/internal/distribution_caller.h +++ b/absl/random/internal/distribution_caller.h @@ -31,8 +31,22 @@ namespace random_internal { template struct DistributionCaller { // Call the provided distribution type. The parameters are expected - // to be explicitly specified. DistrT is the distribution type. - template + // to be explicitly specified. + // DistrT is the distribution type. + // FormatT is the formatter type: + // + // struct FormatT { + // using result_type = distribution_t::result_type; + // static std::string FormatCall( + // const distribution_t& distr, + // absl::Span); + // + // static std::string FormatExpectation( + // absl::string_view match_args, + // absl::Span results); + // } + // + template static typename DistrT::result_type Call(URBG* urbg, Args&&... args) { DistrT dist(std::forward(args)...); return dist(*urbg); diff --git a/absl/random/internal/mocking_bit_gen_base.h b/absl/random/internal/mocking_bit_gen_base.h index acd63872..eeeae9d2 100644 --- a/absl/random/internal/mocking_bit_gen_base.h +++ b/absl/random/internal/mocking_bit_gen_base.h @@ -16,14 +16,39 @@ #ifndef ABSL_RANDOM_INTERNAL_MOCKING_BIT_GEN_BASE_H_ #define ABSL_RANDOM_INTERNAL_MOCKING_BIT_GEN_BASE_H_ +#include +#include +#include #include #include "absl/random/random.h" +#include "absl/strings/str_cat.h" namespace absl { ABSL_NAMESPACE_BEGIN namespace random_internal { +// MockingBitGenExpectationFormatter is invoked to format unsatisfied mocks +// and remaining results into a description string. +template +struct MockingBitGenExpectationFormatter { + std::string operator()(absl::string_view args) { + return absl::StrCat(FormatT::FunctionName(), "(", args, ")"); + } +}; + +// MockingBitGenCallFormatter is invoked to format each distribution call +// into a description string for the mock log. +template +struct MockingBitGenCallFormatter { + std::string operator()(const DistrT& dist, + const typename DistrT::result_type& result) { + return absl::StrCat( + FormatT::FunctionName(), "(", FormatT::FormatArgs(dist), ") => {", + FormatT::FormatResults(absl::MakeSpan(&result, 1)), "}"); + } +}; + class MockingBitGenBase { template friend struct DistributionCaller; @@ -36,9 +61,14 @@ class MockingBitGenBase { static constexpr result_type(max)() { return (generator_type::max)(); } result_type operator()() { return gen_(); } + MockingBitGenBase() : gen_(), observed_call_log_() {} virtual ~MockingBitGenBase() = default; protected: + const std::deque& observed_call_log() { + return observed_call_log_; + } + // CallImpl is the type-erased virtual dispatch. // The type of dist is always distribution, // The type of result is always distribution::result_type. @@ -51,9 +81,10 @@ class MockingBitGenBase { } // Call the generating distribution function. - // Invoked by DistributionCaller<>::Call. + // Invoked by DistributionCaller<>::Call. // DistT is the distribution type. - template + // FormatT is the distribution formatter traits type. + template typename DistrT::result_type Call(Args&&... args) { using distr_result_type = typename DistrT::result_type; using ArgTupleT = std::tuple...>; @@ -68,11 +99,18 @@ class MockingBitGenBase { if (!found_match) { result = dist(gen_); } + + // TODO(asoffer): Forwarding the args through means we no longer need to + // extract them from the from the distribution in formatter traits. We can + // just StrJoin them. + observed_call_log_.push_back( + MockingBitGenCallFormatter{}(dist, result)); return result; } private: generator_type gen_; + std::deque observed_call_log_; }; // namespace random_internal } // namespace random_internal diff --git a/absl/random/mocking_bit_gen.cc b/absl/random/mocking_bit_gen.cc index 02209115..6bb1e414 100644 --- a/absl/random/mocking_bit_gen.cc +++ b/absl/random/mocking_bit_gen.cc @@ -20,6 +20,7 @@ namespace absl { ABSL_NAMESPACE_BEGIN MockingBitGen::~MockingBitGen() { + for (const auto& del : deleters_) { del(); } diff --git a/absl/random/mocking_bit_gen.h b/absl/random/mocking_bit_gen.h index 246c5b1e..36cef911 100644 --- a/absl/random/mocking_bit_gen.h +++ b/absl/random/mocking_bit_gen.h @@ -109,7 +109,7 @@ class MockingBitGen : public absl::random_internal::MockingBitGenBase { // MockingBitGen::Register // - // Register is the main extension point for + // Register is the main extension point for // extending the MockingBitGen framework. It provides a mechanism to install a // mock expectation for the distribution `distr_t` onto the MockingBitGen // context. @@ -182,10 +182,10 @@ namespace random_internal { template <> struct DistributionCaller { - template + template static typename DistrT::result_type Call(absl::MockingBitGen* gen, Args&&... args) { - return gen->template Call(std::forward(args)...); + return gen->template Call(std::forward(args)...); } }; diff --git a/absl/random/mocking_bit_gen_test.cc b/absl/random/mocking_bit_gen_test.cc index dcf74fd6..f0ffc9ac 100644 --- a/absl/random/mocking_bit_gen_test.cc +++ b/absl/random/mocking_bit_gen_test.cc @@ -66,10 +66,10 @@ TEST(BasicMocking, AllDistributionsAreOverridable) { .WillOnce(Return(0.001)); EXPECT_EQ(absl::Gaussian(gen, 0.0, 1.0), 0.001); - EXPECT_NE(absl::LogUniform(gen, 0, 1000000, 2), 2040); + EXPECT_NE(absl::LogUniform(gen, 0, 1000000, 2), 500000); EXPECT_CALL(absl::MockLogUniform(), Call(gen, 0, 1000000, 2)) - .WillOnce(Return(2040)); - EXPECT_EQ(absl::LogUniform(gen, 0, 1000000, 2), 2040); + .WillOnce(Return(500000)); + EXPECT_EQ(absl::LogUniform(gen, 0, 1000000, 2), 500000); } TEST(BasicMocking, OnDistribution) { diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel index b5547f71..8d0a6b6d 100644 --- a/absl/strings/BUILD.bazel +++ b/absl/strings/BUILD.bazel @@ -412,7 +412,6 @@ cc_test( copts = ABSL_TEST_COPTS, visibility = ["//visibility:private"], deps = [ - ":internal", ":pow10_helper", ":strings", "//absl/base:config", diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt index 5366fb65..98101573 100644 --- a/absl/strings/CMakeLists.txt +++ b/absl/strings/CMakeLists.txt @@ -275,7 +275,6 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::strings - absl::strings_internal absl::core_headers absl::pow10_helper absl::config diff --git a/absl/strings/numbers_test.cc b/absl/strings/numbers_test.cc index f66d9c36..68229b15 100644 --- a/absl/strings/numbers_test.cc +++ b/absl/strings/numbers_test.cc @@ -40,7 +40,6 @@ #include "absl/random/distributions.h" #include "absl/random/random.h" #include "absl/strings/internal/numbers_test_common.h" -#include "absl/strings/internal/ostringstream.h" #include "absl/strings/internal/pow10_helper.h" #include "absl/strings/str_cat.h" diff --git a/ci/cmake_install_test.sh b/ci/cmake_install_test.sh index e85474c2..55fb4f12 100755 --- a/ci/cmake_install_test.sh +++ b/ci/cmake_install_test.sh @@ -28,5 +28,5 @@ time docker run \ --rm \ -e CFLAGS="-Werror" \ -e CXXFLAGS="-Werror" \ - gcr.io/google.com/absl-177019/linux_gcc-latest:20200102 \ + gcr.io/google.com/absl-177019/linux_gcc-latest:20200106 \ /bin/bash CMake/install_test_project/test.sh $@ diff --git a/ci/linux_gcc-latest_libstdcxx_bazel.sh b/ci/linux_gcc-latest_libstdcxx_bazel.sh index 70d24d79..2d41d511 100755 --- a/ci/linux_gcc-latest_libstdcxx_bazel.sh +++ b/ci/linux_gcc-latest_libstdcxx_bazel.sh @@ -36,7 +36,7 @@ if [ -z ${EXCEPTIONS_MODE:-} ]; then EXCEPTIONS_MODE="-fno-exceptions -fexceptions" fi -readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-latest:20200102" +readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-latest:20200106" # USE_BAZEL_CACHE=1 only works on Kokoro. # Without access to the credentials this won't work. diff --git a/ci/linux_gcc-latest_libstdcxx_cmake.sh b/ci/linux_gcc-latest_libstdcxx_cmake.sh index 7effa0c0..38ad99f7 100755 --- a/ci/linux_gcc-latest_libstdcxx_cmake.sh +++ b/ci/linux_gcc-latest_libstdcxx_cmake.sh @@ -47,7 +47,7 @@ for std in ${ABSL_CMAKE_CXX_STANDARDS}; do --rm \ -e CFLAGS="-Werror" \ -e CXXFLAGS="-Werror" \ - gcr.io/google.com/absl-177019/linux_gcc-latest:20200102 \ + gcr.io/google.com/absl-177019/linux_gcc-latest:20200106 \ /bin/bash -c " cd /buildfs && \ cmake /abseil-cpp \ diff --git a/ci/macos_xcode_bazel.sh b/ci/macos_xcode_bazel.sh index 3e13b153..3cf1be4a 100755 --- a/ci/macos_xcode_bazel.sh +++ b/ci/macos_xcode_bazel.sh @@ -24,7 +24,7 @@ if [ -z ${ABSEIL_ROOT:-} ]; then fi # If we are running on Kokoro, check for a versioned Bazel binary. -KOKORO_GFILE_BAZEL_BIN="bazel-0.28.1-darwin-x86_64" +KOKORO_GFILE_BAZEL_BIN="bazel-2.0.0-darwin-x86_64" if [ ${KOKORO_GFILE_DIR:-} ] && [ -f ${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN} ]; then BAZEL_BIN="${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN}" chmod +x ${BAZEL_BIN} -- cgit v1.2.3 From 37dd2562ec830d547a1524bb306be313ac3f2556 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 28 Jan 2020 11:50:11 -0800 Subject: Export of internal Abseil changes -- 8bdb2020150ed0fd4a4e520e454dc5f54e33f776 by Eric Fiselier : Workaround bug in GCC 9.2 and after. PiperOrigin-RevId: 291982551 -- 47ff4820e595f96c082a90d733725f6882d83e3b by Abseil Team : 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 : Internal change PiperOrigin-RevId: 291963048 -- bb3bd3247e376d53a3080b105f13ec7566d3ae50 by Abseil Team : Support the C++17 insert_or_assign() API in btree_map. PiperOrigin-RevId: 291945474 -- ff3b3cfcbbc64f086f95501f48d49426bcde356f by Gennadiy Rozental : Import of CCTZ from GitHub. PiperOrigin-RevId: 291861110 -- fd465cd9cbbacd3962f67a7346d6462edaddd809 by Derek Mauro : Add flaky=1 to beta_distribution_test. PiperOrigin-RevId: 291757364 -- 3603adfb59c4128c542b670952cce250d59e1f67 by Derek Mauro : 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 : Change the cmake library names not to have a redundant `absl_` prefix. PiperOrigin-RevId: 291640501 -- 501b602ef260cd7c8c527342581ceffb3c5b6d4c by Gennadiy Rozental : Introducing benchmark for absl::GetFlag. PiperOrigin-RevId: 291433394 -- 4eeaddc788da4b91c272a8adca77ca6dbbbc1d44 by Xiaoyi Zhang : 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 : Removes the flaky raw_hash_set prefetch test PiperOrigin-RevId: 291197079 -- aad6c2121c102ac36216e771c83227cf3e3bfd66 by Andy Soffer : 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 : 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 : Internal Change. PiperOrigin-RevId: 291012718 -- 996ddb3dffda02440fa93f30ca5d71b14b688875 by Abseil Team : Fix shared libraries log spam for built-in types in absl::GetFlag PiperOrigin-RevId: 290772743 GitOrigin-RevId: 8bdb2020150ed0fd4a4e520e454dc5f54e33f776 Change-Id: I8bf2265dd14ebbace220a1b6b982bb5040ad2a26 --- CMake/AbseilDll.cmake | 492 +++++++++++++++++++++ CMake/AbseilHelpers.cmake | 231 +++++++--- CMake/Googletest/DownloadGTest.cmake | 10 + CMakeLists.txt | 7 + absl/CMakeLists.txt | 6 +- absl/base/attributes.h | 14 +- absl/base/config.h | 19 + absl/base/internal/raw_logging.cc | 5 +- absl/base/internal/raw_logging.h | 5 +- absl/base/internal/sysinfo.cc | 28 +- absl/base/internal/thread_identity.cc | 12 + absl/base/internal/thread_identity.h | 9 + absl/base/options.h | 9 +- absl/container/btree_map.h | 24 + absl/container/btree_test.cc | 59 +++ absl/container/internal/btree_container.h | 65 ++- absl/container/internal/hashtablez_sampler.cc | 9 +- absl/container/internal/hashtablez_sampler.h | 13 +- absl/container/internal/hashtablez_sampler_test.cc | 2 +- absl/container/internal/raw_hash_set_test.cc | 51 +-- absl/copts/AbseilConfigureCopts.cmake | 7 + absl/debugging/symbolize_test.cc | 2 + absl/flags/BUILD.bazel | 17 + absl/flags/flag.cc | 9 +- absl/flags/flag.h | 24 +- absl/flags/flag_benchmark.cc | 111 +++++ absl/hash/internal/hash.h | 3 +- absl/numeric/int128.cc | 4 +- absl/numeric/int128.h | 2 +- absl/random/BUILD.bazel | 2 + absl/random/CMakeLists.txt | 1 + absl/random/gaussian_distribution.h | 3 +- absl/strings/BUILD.bazel | 5 +- absl/strings/CMakeLists.txt | 5 +- absl/strings/ascii.cc | 6 +- absl/strings/ascii.h | 7 +- absl/strings/internal/charconv_bigint.cc | 4 +- absl/strings/internal/charconv_bigint.h | 6 +- absl/strings/internal/str_format/bind.h | 4 +- absl/strings/internal/str_format/extension.h | 6 +- absl/strings/numbers.cc | 7 +- absl/strings/numbers.h | 9 +- absl/strings/string_view.h | 25 +- absl/time/format.cc | 13 +- absl/time/internal/cctz/src/time_zone_fixed.cc | 28 +- .../internal/cctz/src/time_zone_format_test.cc | 4 +- absl/time/internal/cctz/src/time_zone_info.cc | 6 +- .../internal/cctz/src/time_zone_lookup_test.cc | 15 +- absl/time/time.h | 87 ++-- 49 files changed, 1197 insertions(+), 295 deletions(-) create mode 100644 CMake/AbseilDll.cmake create mode 100644 absl/flags/flag_benchmark.cc (limited to 'absl/random/CMakeLists.txt') diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake new file mode 100644 index 00000000..8184d500 --- /dev/null +++ b/CMake/AbseilDll.cmake @@ -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 + "$" + $ + ) + + 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() diff --git a/CMake/AbseilHelpers.cmake b/CMake/AbseilHelpers.cmake index 28fefaa6..7571ef1b 100644 --- a/CMake/AbseilHelpers.cmake +++ b/CMake/AbseilHelpers.cmake @@ -16,6 +16,7 @@ include(CMakeParseArguments) include(AbseilConfigureCopts) +include(AbseilDll) include(AbseilInstallDirs) # The IDE folder for Abseil that will be used if Abseil is included in a CMake @@ -80,98 +81,169 @@ function(absl_cc_library) ${ARGN} ) - if(NOT ABSL_CC_LIB_TESTONLY OR ABSL_RUN_TESTS) - if(ABSL_ENABLE_INSTALL) - set(_NAME "${ABSL_CC_LIB_NAME}") - else() - set(_NAME "absl_${ABSL_CC_LIB_NAME}") + if(ABSL_CC_LIB_TESTONLY AND NOT ABSL_RUN_TESTS) + return() + endif() + + if(ABSL_ENABLE_INSTALL) + set(_NAME "${ABSL_CC_LIB_NAME}") + else() + set(_NAME "absl_${ABSL_CC_LIB_NAME}") + endif() + + # Check if this is a header-only library + # Note that as of February 2019, many popular OS's (for example, Ubuntu + # 16.04 LTS) only come with cmake 3.5 by default. For this reason, we can't + # use list(FILTER...) + set(ABSL_CC_SRCS "${ABSL_CC_LIB_SRCS}") + foreach(src_file IN LISTS ABSL_CC_SRCS) + if(${src_file} MATCHES ".*\\.(h|inc)") + list(REMOVE_ITEM ABSL_CC_SRCS "${src_file}") endif() + endforeach() - # Check if this is a header-only library - # Note that as of February 2019, many popular OS's (for example, Ubuntu - # 16.04 LTS) only come with cmake 3.5 by default. For this reason, we can't - # use list(FILTER...) - set(ABSL_CC_SRCS "${ABSL_CC_LIB_SRCS}") - foreach(src_file IN LISTS ABSL_CC_SRCS) - if(${src_file} MATCHES ".*\\.(h|inc)") - list(REMOVE_ITEM ABSL_CC_SRCS "${src_file}") - endif() - endforeach() - if("${ABSL_CC_SRCS}" STREQUAL "") + if("${ABSL_CC_SRCS}" STREQUAL "") + set(ABSL_CC_LIB_IS_INTERFACE 1) + else() + set(ABSL_CC_LIB_IS_INTERFACE 0) + 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() - set(ABSL_CC_LIB_IS_INTERFACE 0) + # 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) - # CMake creates static libraries by default. Users can specify - # -DBUILD_SHARED_LIBS=ON during initial configuration to build shared - # libraries instead. - add_library(${_NAME} "") + if(NOT ABSL_CC_LIB_IS_INTERFACE) + if(${_build_type} STREQUAL "dll_dep") + # This target depends on the DLL. When adding dependencies to this target, + # any depended-on-target which is contained inside the DLL is replaced + # with a dependency on the DLL. + add_library(${_NAME} STATIC "") target_sources(${_NAME} PRIVATE ${ABSL_CC_LIB_SRCS} ${ABSL_CC_LIB_HDRS}) - target_include_directories(${_NAME} - PUBLIC - "$" - $ + absl_internal_dll_targets( + DEPS ${ABSL_CC_LIB_DEPS} + OUTPUT _dll_deps ) - target_compile_options(${_NAME} - PRIVATE ${ABSL_CC_LIB_COPTS}) target_link_libraries(${_NAME} - PUBLIC ${ABSL_CC_LIB_DEPS} + PUBLIC ${_dll_deps} PRIVATE ${ABSL_CC_LIB_LINKOPTS} ${ABSL_DEFAULT_LINKOPTS} ) - target_compile_definitions(${_NAME} PUBLIC ${ABSL_CC_LIB_DEFINES}) - # Add all Abseil targets to a a folder in the IDE for organization. - if(ABSL_CC_LIB_PUBLIC) - set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}) - elseif(ABSL_CC_LIB_TESTONLY) - set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/test) + if (ABSL_CC_LIB_TESTONLY) + set(_gtest_link_define "GTEST_LINKED_AS_SHARED_LIBRARY=1") else() - set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/internal) + set(_gtest_link_define) endif() - # INTERFACE libraries can't have the CXX_STANDARD property set - set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${ABSL_CXX_STANDARD}) - set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) - - # 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 - # installed. - set_target_properties(${_NAME} PROPERTIES - OUTPUT_NAME "absl_${_NAME}" + target_compile_definitions(${_NAME} + PUBLIC + ABSL_CONSUME_DLL + "${_gtest_link_define}" ) - else() - # Generating header-only library - add_library(${_NAME} INTERFACE) - target_include_directories(${_NAME} - INTERFACE - "$" - $ - ) + + 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} - INTERFACE - ${ABSL_CC_LIB_DEPS} - ${ABSL_CC_LIB_LINKOPTS} - ${ABSL_DEFAULT_LINKOPTS} + PUBLIC ${ABSL_CC_LIB_DEPS} + PRIVATE + ${ABSL_CC_LIB_LINKOPTS} + ${ABSL_DEFAULT_LINKOPTS} ) - target_compile_definitions(${_NAME} INTERFACE ${ABSL_CC_LIB_DEFINES}) + else() + message(FATAL_ERROR "Invalid build type: ${_build_type}") endif() - # TODO currently we don't install googletest alongside abseil sources, so - # installed abseil can't be tested. - if(NOT ABSL_CC_LIB_TESTONLY AND ABSL_ENABLE_INSTALL) - install(TARGETS ${_NAME} EXPORT ${PROJECT_NAME}Targets - RUNTIME DESTINATION ${ABSL_INSTALL_BINDIR} - LIBRARY DESTINATION ${ABSL_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${ABSL_INSTALL_LIBDIR} + # 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} + PUBLIC + "$" + $ + ) + target_compile_options(${_NAME} + PRIVATE ${ABSL_CC_LIB_COPTS}) + target_compile_definitions(${_NAME} PUBLIC ${ABSL_CC_LIB_DEFINES}) + + # Add all Abseil targets to a a folder in the IDE for organization. + if(ABSL_CC_LIB_PUBLIC) + set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}) + elseif(ABSL_CC_LIB_TESTONLY) + set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/test) + else() + set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/internal) + endif() + + # INTERFACE libraries can't have the CXX_STANDARD property set + set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${ABSL_CXX_STANDARD}) + set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) + + # 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 + # installed. + if(ABSL_ENABLE_INSTALL) + set_target_properties(${_NAME} PROPERTIES + OUTPUT_NAME "absl_${_NAME}" ) endif() + else() + # Generating header-only library + add_library(${_NAME} INTERFACE) + target_include_directories(${_NAME} + INTERFACE + "$" + $ + ) - add_library(absl::${ABSL_CC_LIB_NAME} ALIAS ${_NAME}) + if (${_build_type} STREQUAL "dll") + set(ABSL_CC_LIB_DEPS abseil_dll) + endif() + + target_link_libraries(${_NAME} + INTERFACE + ${ABSL_CC_LIB_DEPS} + ${ABSL_CC_LIB_LINKOPTS} + ${ABSL_DEFAULT_LINKOPTS} + ) + target_compile_definitions(${_NAME} INTERFACE ${ABSL_CC_LIB_DEFINES}) + endif() + + # TODO currently we don't install googletest alongside abseil sources, so + # installed abseil can't be tested. + if(NOT ABSL_CC_LIB_TESTONLY AND ABSL_ENABLE_INSTALL) + install(TARGETS ${_NAME} EXPORT ${PROJECT_NAME}Targets + RUNTIME DESTINATION ${ABSL_INSTALL_BINDIR} + LIBRARY DESTINATION ${ABSL_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${ABSL_INSTALL_LIBDIR} + ) endif() + + add_library(absl::${ABSL_CC_LIB_NAME} ALIAS ${_NAME}) endfunction() # absl_cc_test() @@ -224,23 +296,42 @@ function(absl_cc_test) ) set(_NAME "absl_${ABSL_CC_TEST_NAME}") + add_executable(${_NAME} "") target_sources(${_NAME} PRIVATE ${ABSL_CC_TEST_SRCS}) target_include_directories(${_NAME} PUBLIC ${ABSL_COMMON_INCLUDE_DIRS} PRIVATE ${GMOCK_INCLUDE_DIRS} ${GTEST_INCLUDE_DIRS} ) - target_compile_definitions(${_NAME} - PUBLIC ${ABSL_CC_TEST_DEFINES} - ) + + if (${ABSL_BUILD_DLL}) + target_compile_definitions(${_NAME} + 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} PRIVATE ${ABSL_CC_TEST_COPTS} ) + target_link_libraries(${_NAME} PUBLIC ${ABSL_CC_TEST_DEPS} 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 CXX_STANDARD ${ABSL_CXX_STANDARD}) diff --git a/CMake/Googletest/DownloadGTest.cmake b/CMake/Googletest/DownloadGTest.cmake index 3c682aef..8a00b455 100644 --- a/CMake/Googletest/DownloadGTest.cmake +++ b/CMake/Googletest/DownloadGTest.cmake @@ -7,6 +7,13 @@ configure_file( ${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 execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . RESULT_VARIABLE result @@ -22,6 +29,9 @@ if(result) message(FATAL_ERROR "Build step for googletest failed: ${result}") 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 set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) diff --git a/CMakeLists.txt b/CMakeLists.txt index 86f56344..fdfb2cfa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,12 @@ cmake_policy(SET CMP0048 NEW) 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)) # in the source tree of a project that uses it, install rules are disabled. if(NOT "^${CMAKE_SOURCE_DIR}$" STREQUAL "^${PROJECT_SOURCE_DIR}$") @@ -47,6 +53,7 @@ list(APPEND CMAKE_MODULE_PATH include(AbseilInstallDirs) include(CMakePackageConfigHelpers) +include(AbseilDll) include(AbseilHelpers) diff --git a/absl/CMakeLists.txt b/absl/CMakeLists.txt index 3e78397c..a1b1f8d8 100644 --- a/absl/CMakeLists.txt +++ b/absl/CMakeLists.txt @@ -14,8 +14,6 @@ # limitations under the License. # - - add_subdirectory(base) add_subdirectory(algorithm) add_subdirectory(container) @@ -31,3 +29,7 @@ add_subdirectory(synchronization) add_subdirectory(time) add_subdirectory(types) add_subdirectory(utility) + +if (${ABSL_BUILD_DLL}) + absl_make_dll() +endif() diff --git a/absl/base/attributes.h b/absl/base/attributes.h index acd1c526..8f77db77 100644 --- a/absl/base/attributes.h +++ b/absl/base/attributes.h @@ -563,7 +563,19 @@ // 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__)) #define ABSL_ATTRIBUTE_PACKED __attribute__((__packed__)) #else diff --git a/absl/base/config.h b/absl/base/config.h index c4e8dce4..eac5d268 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -643,4 +643,23 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #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_ diff --git a/absl/base/internal/raw_logging.cc b/absl/base/internal/raw_logging.cc index d79c5486..e36eb29a 100644 --- a/absl/base/internal/raw_logging.cc +++ b/absl/base/internal/raw_logging.cc @@ -225,8 +225,9 @@ bool RawLoggingFullySupported() { #endif // !ABSL_LOW_LEVEL_WRITE_SUPPORTED } -ABSL_CONST_INIT absl::base_internal::AtomicHook - internal_log_function(DefaultInternalLog); +ABSL_CONST_INIT ABSL_DLL + absl::base_internal::AtomicHook + internal_log_function(DefaultInternalLog); void RegisterInternalLogFunction(InternalLogFunction func) { internal_log_function.Store(func); diff --git a/absl/base/internal/raw_logging.h b/absl/base/internal/raw_logging.h index cff45058..ac74f97d 100644 --- a/absl/base/internal/raw_logging.h +++ b/absl/base/internal/raw_logging.h @@ -22,9 +22,11 @@ #include #include "absl/base/attributes.h" +#include "absl/base/config.h" #include "absl/base/internal/atomic_hook.h" #include "absl/base/log_severity.h" #include "absl/base/macros.h" +#include "absl/base/optimization.h" #include "absl/base/port.h" // This is similar to LOG(severity) << format..., but @@ -168,7 +170,8 @@ using InternalLogFunction = void (*)(absl::LogSeverity severity, const char* file, int line, const std::string& message); -extern base_internal::AtomicHook internal_log_function; +ABSL_DLL extern base_internal::AtomicHook + internal_log_function; void RegisterInternalLogFunction(InternalLogFunction func); diff --git a/absl/base/internal/sysinfo.cc b/absl/base/internal/sysinfo.cc index 7945322f..a0930e97 100644 --- a/absl/base/internal/sysinfo.cc +++ b/absl/base/internal/sysinfo.cc @@ -58,10 +58,6 @@ namespace absl { ABSL_NAMESPACE_BEGIN 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() { #if defined(__myriad2__) return 1; @@ -265,21 +261,27 @@ static double GetNominalCPUFrequency() { #endif -// InitializeSystemInfo() may be called before main() and before -// malloc is properly initialized, therefore this must not allocate -// memory. -static void InitializeSystemInfo() { - num_cpus = GetNumCPUs(); - nominal_cpu_frequency = GetNominalCPUFrequency(); -} +ABSL_CONST_INIT static once_flag init_num_cpus_once; +ABSL_CONST_INIT static int num_cpus = 0; +// NumCPUs() may be called before main() and before malloc is properly +// initialized, therefore this must not allocate memory. int NumCPUs() { - base_internal::LowLevelCallOnce(&init_system_info_once, InitializeSystemInfo); + base_internal::LowLevelCallOnce( + &init_num_cpus_once, []() { num_cpus = GetNumCPUs(); }); 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() { - base_internal::LowLevelCallOnce(&init_system_info_once, InitializeSystemInfo); + base_internal::LowLevelCallOnce( + &init_nominal_cpu_frequency_once, + []() { nominal_cpu_frequency = GetNominalCPUFrequency(); }); return nominal_cpu_frequency; } diff --git a/absl/base/internal/thread_identity.cc b/absl/base/internal/thread_identity.cc index 6a28f246..d63a04ae 100644 --- a/absl/base/internal/thread_identity.cc +++ b/absl/base/internal/thread_identity.cc @@ -113,6 +113,18 @@ void SetCurrentThreadIdentity( #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() { #if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \ ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11 diff --git a/absl/base/internal/thread_identity.h b/absl/base/internal/thread_identity.h index 5dfd0715..ceb109b4 100644 --- a/absl/base/internal/thread_identity.h +++ b/absl/base/internal/thread_identity.h @@ -30,6 +30,7 @@ #include #include +#include "absl/base/config.h" #include "absl/base/internal/per_thread_tls.h" 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 #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() { return thread_identity_ptr; } +#endif #elif ABSL_THREAD_IDENTITY_MODE != \ ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC diff --git a/absl/base/options.h b/absl/base/options.h index 592b33b7..6868c77b 100644 --- a/absl/base/options.h +++ b/absl/base/options.h @@ -66,7 +66,13 @@ // NOTE: the defaults within this file all assume that Abseil can select the // proper Abseil implementation at compile-time, which will not be sufficient // to guarantee ABI stability to package managers. -// + +// Include a standard library header to allow configuration based on the +// standard library in use. +#ifdef __cplusplus +#include +#endif + // ----------------------------------------------------------------------------- // Type Compatibility Options // ----------------------------------------------------------------------------- @@ -158,7 +164,6 @@ #define ABSL_OPTION_USE_STD_STRING_VIEW 2 - // ABSL_OPTION_USE_STD_VARIANT // // This option controls whether absl::variant is implemented as an alias to diff --git a/absl/container/btree_map.h b/absl/container/btree_map.h index cbfcb58c..d23f4ee5 100644 --- a/absl/container/btree_map.h +++ b/absl/container/btree_map.h @@ -226,6 +226,30 @@ class btree_map // Inserts the elements within the initializer list `ilist`. using Base::insert; + // btree_map::insert_or_assign() + // + // Inserts an element of the specified value into the `btree_map` provided + // that a value with the given key does not already exist, or replaces the + // corresponding mapped type with the forwarded `obj` argument if a key for + // that value already exists, returning an iterator pointing to the newly + // inserted element. Overloads are listed below. + // + // pair insert_or_assign(const key_type& k, M&& obj): + // pair insert_or_assign(key_type&& k, M&& obj): + // + // Inserts/Assigns (or moves) the element of the specified key into the + // `btree_map`. If the returned bool is true, insertion took place, and if + // it's false, assignment took place. + // + // iterator insert_or_assign(const_iterator hint, + // const key_type& k, M&& obj): + // iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj): + // + // Inserts/Assigns (or moves) the element of the specified key into the + // `btree_map` using the position of `hint` as a non-binding suggestion + // for where to begin the insertion search. + using Base::insert_or_assign; + // btree_map::emplace() // // Inserts an element of the specified value by constructing it in-place diff --git a/absl/container/btree_test.cc b/absl/container/btree_test.cc index 8692b9c2..af8ee00b 100644 --- a/absl/container/btree_test.cc +++ b/absl/container/btree_test.cc @@ -2345,6 +2345,65 @@ TEST(Btree, EraseIf) { } } +TEST(Btree, InsertOrAssign) { + absl::btree_map 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 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 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 container_internal ABSL_NAMESPACE_END diff --git a/absl/container/internal/btree_container.h b/absl/container/internal/btree_container.h index 04795c2e..3e6ff4b8 100644 --- a/absl/container/internal/btree_container.h +++ b/absl/container/internal/btree_container.h @@ -372,7 +372,7 @@ class btree_map_container : public btree_set_container { using super_type = btree_set_container; using params_type = typename Tree::params_type; - protected: + private: template using key_arg = typename super_type::template key_arg; @@ -390,6 +390,69 @@ class btree_map_container : public btree_set_container { btree_map_container() {} // Insertion routines. + // Note: the nullptr template arguments and extra `const M&` overloads allow + // for supporting bitfield arguments. + // Note: when we call `std::forward(obj)` twice, it's safe because + // insert_unique/insert_hint_unique are guaranteed to not consume `obj` when + // `ret.second` is false. + template + std::pair insert_or_assign(const key_type &k, const M &obj) { + const std::pair ret = this->tree_.insert_unique(k, k, obj); + if (!ret.second) ret.first->second = obj; + return ret; + } + template + std::pair insert_or_assign(key_type &&k, const M &obj) { + const std::pair ret = + this->tree_.insert_unique(k, std::move(k), obj); + if (!ret.second) ret.first->second = obj; + return ret; + } + template + std::pair insert_or_assign(const key_type &k, M &&obj) { + const std::pair ret = + this->tree_.insert_unique(k, k, std::forward(obj)); + if (!ret.second) ret.first->second = std::forward(obj); + return ret; + } + template + std::pair insert_or_assign(key_type &&k, M &&obj) { + const std::pair ret = + this->tree_.insert_unique(k, std::move(k), std::forward(obj)); + if (!ret.second) ret.first->second = std::forward(obj); + return ret; + } + template + iterator insert_or_assign(const_iterator position, const key_type &k, + const M &obj) { + const std::pair ret = + this->tree_.insert_hint_unique(iterator(position), k, k, obj); + if (!ret.second) ret.first->second = obj; + return ret.first; + } + template + iterator insert_or_assign(const_iterator position, key_type &&k, + const M &obj) { + const std::pair ret = this->tree_.insert_hint_unique( + iterator(position), k, std::move(k), obj); + if (!ret.second) ret.first->second = obj; + return ret.first; + } + template + iterator insert_or_assign(const_iterator position, const key_type &k, + M &&obj) { + const std::pair ret = this->tree_.insert_hint_unique( + iterator(position), k, k, std::forward(obj)); + if (!ret.second) ret.first->second = std::forward(obj); + return ret.first; + } + template + iterator insert_or_assign(const_iterator position, key_type &&k, M &&obj) { + const std::pair ret = this->tree_.insert_hint_unique( + iterator(position), k, std::move(k), std::forward(obj)); + if (!ret.second) ret.first->second = std::forward(obj); + return ret.first; + } template std::pair try_emplace(const key_type &k, Args &&... args) { return this->tree_.insert_unique( diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc index e15f4444..56447251 100644 --- a/absl/container/internal/hashtablez_sampler.cc +++ b/absl/container/internal/hashtablez_sampler.cc @@ -39,17 +39,16 @@ ABSL_CONST_INIT std::atomic g_hashtablez_enabled{ ABSL_CONST_INIT std::atomic g_hashtablez_sample_parameter{1 << 10}; ABSL_CONST_INIT std::atomic 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 g_exponential_biased_generator; #endif } // namespace -#if ABSL_PER_THREAD_TLS == 1 +#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) 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() { static auto* sampler = new HashtablezSampler(); @@ -192,7 +191,7 @@ HashtablezInfo* SampleSlow(int64_t* next_sample) { return HashtablezSampler::Global().Register(); } -#if ABSL_PER_THREAD_TLS == 0 +#if !defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) *next_sample = std::numeric_limits::max(); return nullptr; #else diff --git a/absl/container/internal/hashtablez_sampler.h b/absl/container/internal/hashtablez_sampler.h index c4f9629f..34d5e572 100644 --- a/absl/container/internal/hashtablez_sampler.h +++ b/absl/container/internal/hashtablez_sampler.h @@ -180,14 +180,23 @@ class HashtablezInfoHandle { 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; #endif // ABSL_PER_THREAD_TLS // Returns an RAII sampling handle that manages registration and unregistation // with the global sampler. inline HashtablezInfoHandle Sample() { -#if ABSL_PER_THREAD_TLS == 1 +#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) if (ABSL_PREDICT_TRUE(--global_next_sample > 0)) { return HashtablezInfoHandle(nullptr); } diff --git a/absl/container/internal/hashtablez_sampler_test.cc b/absl/container/internal/hashtablez_sampler_test.cc index 102b2375..36f5ccdd 100644 --- a/absl/container/internal/hashtablez_sampler_test.cc +++ b/absl/container/internal/hashtablez_sampler_test.cc @@ -169,7 +169,7 @@ TEST(HashtablezInfoTest, RecordRehash) { EXPECT_EQ(info.num_erases.load(), 0); } -#if ABSL_PER_THREAD_TLS == 1 +#if defined(ABSL_HASHTABLEZ_SAMPLE) TEST(HashtablezSamplerTest, SmallSampleParameter) { SetHashtablezEnabled(true); SetHashtablezSampleParameter(100); diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc index 38e5e0e8..a96ae68a 100644 --- a/absl/container/internal/raw_hash_set_test.cc +++ b/absl/container/internal/raw_hash_set_test.cc @@ -418,53 +418,6 @@ TEST(Table, Empty) { EXPECT_TRUE(t.empty()); } -#ifdef __GNUC__ -template -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) { IntTable t; auto it = t.find(0); @@ -1842,7 +1795,7 @@ TEST(TableDeathTest, EraseOfEndAsserts) { EXPECT_DEATH_IF_SUPPORTED(t.erase(t.end()), kDeathMsg); } -#if ABSL_PER_THREAD_TLS == 1 +#if defined(ABSL_HASHTABLEZ_SAMPLE) TEST(RawHashSamplerTest, Sample) { // Enable the feature even if the prod default is off. SetHashtablezEnabled(true); @@ -1863,7 +1816,7 @@ TEST(RawHashSamplerTest, Sample) { EXPECT_NEAR((end_size - start_size) / static_cast(tables.size()), 0.01, 0.005); } -#endif +#endif // ABSL_HASHTABLEZ_SAMPLER TEST(RawHashSamplerTest, DoNotSampleCustomAllocators) { // Enable the feature even if the prod default is off. diff --git a/absl/copts/AbseilConfigureCopts.cmake b/absl/copts/AbseilConfigureCopts.cmake index 7543928a..77d4ace8 100644 --- a/absl/copts/AbseilConfigureCopts.cmake +++ b/absl/copts/AbseilConfigureCopts.cmake @@ -5,6 +5,13 @@ set(ABSL_LSAN_LINKOPTS "") set(ABSL_HAVE_LSAN OFF) 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 (MSVC) set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_MSVC_X64_FLAGS}") diff --git a/absl/debugging/symbolize_test.cc b/absl/debugging/symbolize_test.cc index 0bac60b9..a1d03aab 100644 --- a/absl/debugging/symbolize_test.cc +++ b/absl/debugging/symbolize_test.cc @@ -473,6 +473,7 @@ void ABSL_ATTRIBUTE_NOINLINE TestWithReturnAddress() { } #elif defined(_WIN32) +#if !defined(ABSL_CONSUME_DLL) TEST(Symbolize, Basics) { EXPECT_STREQ("nonstatic_func", TrySymbolize((void *)(&nonstatic_func))); @@ -511,6 +512,7 @@ TEST(Symbolize, SymbolizeWithDemangling) { EXPECT_TRUE(strstr(result, "Foo::func") != nullptr) << result; } +#endif // !defined(ABSL_CONSUME_DLL) #else // Symbolizer unimplemented TEST(Symbolize, Unimplemented) { diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel index 6c7b2b6e..cbdbae52 100644 --- a/absl/flags/BUILD.bazel +++ b/absl/flags/BUILD.bazel @@ -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( name = "marshalling_test", size = "small", diff --git a/absl/flags/flag.cc b/absl/flags/flag.cc index 9af80079..e67f7304 100644 --- a/absl/flags/flag.cc +++ b/absl/flags/flag.cc @@ -22,7 +22,14 @@ namespace absl { 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& 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. #if defined(_MSC_VER) && !defined(__clang__) diff --git a/absl/flags/flag.h b/absl/flags/flag.h index cc22cdb9..bd61668f 100644 --- a/absl/flags/flag.h +++ b/absl/flags/flag.h @@ -186,25 +186,29 @@ class Flag { // // // FLAGS_firstname is a Flag of type `std::string` // std::string first_name = absl::GetFlag(FLAGS_firstname); -template ::value, int>::type = 0> -ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag& flag) { - return flag.Get(); -} - +#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. -#ifndef NDEBUG +template +ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag& flag) { + return flag.Get(); +} +// We currently need an external linkage for built-in types because shared +// libraries have different addresses of flags_internal::FlagOps 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& flag); +ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(ABSL_FLAGS_INTERNAL_BUILT_IN_EXPORT) +#undef ABSL_FLAGS_INTERNAL_BUILT_IN_EXPORT +#else template ::value, int>::type = 0> + !flags_internal::IsAtomicFlagTypeTrait::value, int>::type = 0> ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag& flag) { return flag.Get(); } -#else // Overload for `GetFlag()` for types that support lock-free reads. template ; +using AbslDuration = absl::Duration; + +// We do not want to take over marshalling for the types absl::optional, +// absl::optional which we do not own. Instead we introduce unique +// "aliases" to these types, which we do. +using AbslOptionalInt = absl::optional; +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; +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 diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h index 8639181f..ae7a60cd 100644 --- a/absl/hash/internal/hash.h +++ b/absl/hash/internal/hash.h @@ -708,7 +708,8 @@ struct is_hashable : std::integral_constant::value> {}; // CityHashState -class CityHashState : public HashStateBase { +class ABSL_DLL CityHashState + : public HashStateBase { // absl::uint128 is not an alias or a thin wrapper around the intrinsic. // We use the intrinsic when available to improve performance. #ifdef ABSL_HAVE_INTRINSIC_INT128 diff --git a/absl/numeric/int128.cc b/absl/numeric/int128.cc index a20a77e7..b605a870 100644 --- a/absl/numeric/int128.cc +++ b/absl/numeric/int128.cc @@ -25,8 +25,8 @@ namespace absl { ABSL_NAMESPACE_BEGIN -const uint128 kuint128max = MakeUint128(std::numeric_limits::max(), - std::numeric_limits::max()); +ABSL_DLL const uint128 kuint128max = MakeUint128( + std::numeric_limits::max(), std::numeric_limits::max()); namespace { diff --git a/absl/numeric/int128.h b/absl/numeric/int128.h index 718f70b1..636e3a5b 100644 --- a/absl/numeric/int128.h +++ b/absl/numeric/int128.h @@ -234,7 +234,7 @@ class // Prefer to use the constexpr `Uint128Max()`. // // 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 std::ostream& operator<<(std::ostream& os, uint128 v); diff --git a/absl/random/BUILD.bazel b/absl/random/BUILD.bazel index 2585b397..f78fbc7e 100644 --- a/absl/random/BUILD.bazel +++ b/absl/random/BUILD.bazel @@ -67,6 +67,7 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ "//absl/base:base_internal", + "//absl/base:config", "//absl/base:core_headers", "//absl/meta:type_traits", "//absl/random/internal:distributions", @@ -183,6 +184,7 @@ cc_test( timeout = "eternal", # Android can take a very long time srcs = ["beta_distribution_test.cc"], copts = ABSL_TEST_COPTS, + flaky = 1, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":distributions", diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt index 46dbc3ef..efa55d8f 100644 --- a/absl/random/CMakeLists.txt +++ b/absl/random/CMakeLists.txt @@ -183,6 +183,7 @@ absl_cc_library( ${ABSL_DEFAULT_LINKOPTS} DEPS absl::base_internal + absl::config absl::core_headers absl::random_internal_generate_real absl::random_internal_distributions diff --git a/absl/random/gaussian_distribution.h b/absl/random/gaussian_distribution.h index c1427b06..4b07a5c0 100644 --- a/absl/random/gaussian_distribution.h +++ b/absl/random/gaussian_distribution.h @@ -28,6 +28,7 @@ #include #include +#include "absl/base/config.h" #include "absl/random/internal/fast_uniform_bits.h" #include "absl/random/internal/generate_real.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 // 2005 paper, "An Improved Ziggurat Method to Generate Normal Random Samples", // Jurgen A Doornik. (https://www.doornik.com/research/ziggurat.pdf) -class gaussian_distribution_base { +class ABSL_DLL gaussian_distribution_base { public: template inline double zignor(URBG& g); // NOLINT(runtime/references) diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel index dc7e1bfd..d5a362d0 100644 --- a/absl/strings/BUILD.bazel +++ b/absl/strings/BUILD.bazel @@ -37,7 +37,6 @@ cc_library( "internal/charconv_bigint.h", "internal/charconv_parse.cc", "internal/charconv_parse.h", - "internal/escaping.cc", "internal/memutil.cc", "internal/memutil.h", "internal/stl_type_traits.h", @@ -55,7 +54,6 @@ cc_library( "ascii.h", "charconv.h", "escaping.h", - "internal/escaping.h", "match.h", "numbers.h", "str_cat.h", @@ -85,11 +83,13 @@ cc_library( cc_library( name = "internal", srcs = [ + "internal/escaping.cc", "internal/ostringstream.cc", "internal/utf8.cc", ], hdrs = [ "internal/char_map.h", + "internal/escaping.h", "internal/ostringstream.h", "internal/resize_uninitialized.h", "internal/utf8.h", @@ -99,6 +99,7 @@ cc_library( "//absl/base:config", "//absl/base:core_headers", "//absl/base:endian", + "//absl/base:raw_logging_internal", "//absl/meta:type_traits", ], ) diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt index 36702f71..3feb5e94 100644 --- a/absl/strings/CMakeLists.txt +++ b/absl/strings/CMakeLists.txt @@ -38,8 +38,6 @@ absl_cc_library( "internal/charconv_bigint.h" "internal/charconv_parse.cc" "internal/charconv_parse.h" - "internal/escaping.cc" - "internal/escaping.h" "internal/memutil.cc" "internal/memutil.h" "internal/stl_type_traits.h" @@ -74,6 +72,8 @@ absl_cc_library( strings_internal HDRS "internal/char_map.h" + "internal/escaping.cc" + "internal/escaping.h" "internal/ostringstream.h" "internal/resize_uninitialized.h" "internal/utf8.h" @@ -86,6 +86,7 @@ absl_cc_library( absl::config absl::core_headers absl::endian + absl::raw_logging_internal absl::type_traits ) diff --git a/absl/strings/ascii.cc b/absl/strings/ascii.cc index abea3e4f..93bb03e9 100644 --- a/absl/strings/ascii.cc +++ b/absl/strings/ascii.cc @@ -57,7 +57,7 @@ namespace ascii_internal { // 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 // zero-initialized. -const unsigned char kPropertyBits[256] = { +ABSL_DLL const unsigned char kPropertyBits[256] = { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x00 0x40, 0x68, 0x48, 0x48, 0x48, 0x48, 0x40, 0x40, 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' // through 'Z', return the lower-case character; otherwise, return the // identity of the passed character. -const char kToLower[256] = { +ABSL_DLL const char kToLower[256] = { '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', '\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' // through 'z', return the upper-case character; otherwise, return the // identity of the passed character. -const char kToUpper[256] = { +ABSL_DLL const char kToUpper[256] = { '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', diff --git a/absl/strings/ascii.h b/absl/strings/ascii.h index 792aabe5..b46bc71f 100644 --- a/absl/strings/ascii.h +++ b/absl/strings/ascii.h @@ -56,6 +56,7 @@ #include #include "absl/base/attributes.h" +#include "absl/base/config.h" #include "absl/strings/string_view.h" namespace absl { @@ -63,13 +64,13 @@ ABSL_NAMESPACE_BEGIN namespace ascii_internal { // 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. -extern const char kToUpper[256]; +ABSL_DLL extern const char kToUpper[256]; // 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 diff --git a/absl/strings/internal/charconv_bigint.cc b/absl/strings/internal/charconv_bigint.cc index 860c27b2..66f33e72 100644 --- a/absl/strings/internal/charconv_bigint.cc +++ b/absl/strings/internal/charconv_bigint.cc @@ -158,12 +158,12 @@ const uint32_t* LargePowerOfFiveData(int i) { int LargePowerOfFiveSize(int i) { return 2 * i; } } // namespace -const uint32_t kFiveToNth[14] = { +ABSL_DLL const uint32_t kFiveToNth[14] = { 1, 5, 25, 125, 625, 3125, 15625, 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, }; diff --git a/absl/strings/internal/charconv_bigint.h b/absl/strings/internal/charconv_bigint.h index 108e1eb2..999e9ae3 100644 --- a/absl/strings/internal/charconv_bigint.h +++ b/absl/strings/internal/charconv_bigint.h @@ -20,6 +20,7 @@ #include #include +#include "absl/base/config.h" #include "absl/strings/ascii.h" #include "absl/strings/internal/charconv_parse.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. constexpr int kMaxSmallPowerOfTen = 9; -extern const uint32_t kFiveToNth[kMaxSmallPowerOfFive + 1]; -extern const uint32_t kTenToNth[kMaxSmallPowerOfTen + 1]; +ABSL_DLL extern const uint32_t + kFiveToNth[kMaxSmallPowerOfFive + 1]; +ABSL_DLL extern const uint32_t kTenToNth[kMaxSmallPowerOfTen + 1]; // Large, fixed-width unsigned integer. // diff --git a/absl/strings/internal/str_format/bind.h b/absl/strings/internal/str_format/bind.h index 2bf0c085..cf41b197 100644 --- a/absl/strings/internal/str_format/bind.h +++ b/absl/strings/internal/str_format/bind.h @@ -122,8 +122,8 @@ class FormatSpecTemplate #endif // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER template (), + AllOf(sizeof...(C) == sizeof...(Args), + Contains(ArgumentToConv(), C)...)>::type> FormatSpecTemplate(const ExtendedParsedFormat& pc) // NOLINT : Base(&pc) {} diff --git a/absl/strings/internal/str_format/extension.h b/absl/strings/internal/str_format/extension.h index 51d7dd6f..0a764035 100644 --- a/absl/strings/internal/str_format/extension.h +++ b/absl/strings/internal/str_format/extension.h @@ -17,10 +17,12 @@ #define ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_ #include + #include #include #include +#include "absl/base/config.h" #include "absl/base/port.h" #include "absl/strings/internal/str_format/output.h" #include "absl/strings/string_view.h" @@ -134,7 +136,7 @@ struct Flags { } }; -struct LengthMod { +struct ABSL_DLL LengthMod { public: enum Id : uint8_t { h, hh, l, ll, L, j, z, t, q, none @@ -196,7 +198,7 @@ struct LengthMod { X_VAL(n) X_SEP X_VAL(p) // clang-format on -struct ConversionChar { +struct ABSL_DLL ConversionChar { public: enum Id : uint8_t { c, C, s, S, // text diff --git a/absl/strings/numbers.cc b/absl/strings/numbers.cc index a0e5a7fd..68c26dd6 100644 --- a/absl/strings/numbers.cc +++ b/absl/strings/numbers.cc @@ -900,9 +900,10 @@ inline bool safe_uint_internal(absl::string_view text, IntType* value_p, namespace numbers_internal { // 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" "101112131415161718191a1b1c1d1e1f" "202122232425262728292a2b2c2d2e2f" @@ -920,7 +921,7 @@ ABSL_CONST_INIT const char kHexTable[513] = "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" "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', '6'}, {'0', '7'}, {'0', '8'}, {'0', '9'}, {'1', '0'}, {'1', '1'}, {'1', '2'}, {'1', '3'}, {'1', '4'}, {'1', '5'}, {'1', '6'}, {'1', '7'}, diff --git a/absl/strings/numbers.h b/absl/strings/numbers.h index 61204683..d872cca5 100644 --- a/absl/strings/numbers.h +++ b/absl/strings/numbers.h @@ -36,6 +36,7 @@ #include #include +#include "absl/base/config.h" #include "absl/base/internal/bits.h" #ifdef __SSE4_2__ // TODO(jorg): Remove this when we figure out the right way @@ -106,9 +107,11 @@ ABSL_NAMESPACE_BEGIN namespace numbers_internal { // Digit conversion. -extern const char kHexChar[17]; // 0123456789abcdef -extern const char kHexTable[513]; // 000102030405060708090a0b0c0d0e0f1011... -extern const char two_ASCII_digits[100][2]; // 00, 01, 02, 03... +ABSL_DLL extern const char kHexChar[17]; // 0123456789abcdef +ABSL_DLL extern const char + 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 // range 0 <= i < 100, and buf must have space for two characters. Example: diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h index 4f7dd6b3..01965b0e 100644 --- a/absl/strings/string_view.h +++ b/absl/strings/string_view.h @@ -28,7 +28,19 @@ #define ABSL_STRINGS_STRING_VIEW_H_ #include +#include +#include +#include +#include +#include +#include +#include + #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 @@ -49,19 +61,6 @@ ABSL_NAMESPACE_END #define ABSL_INTERNAL_STRING_VIEW_MEMCMP memcmp #endif // ABSL_HAVE_BUILTIN(__builtin_memcmp) -#include -#include -#include -#include -#include -#include -#include - -#include "absl/base/internal/throw_delegate.h" -#include "absl/base/macros.h" -#include "absl/base/optimization.h" -#include "absl/base/port.h" - namespace absl { ABSL_NAMESPACE_BEGIN diff --git a/absl/time/format.cc b/absl/time/format.cc index 5997ef0c..ee088f33 100644 --- a/absl/time/format.cc +++ b/absl/time/format.cc @@ -24,11 +24,14 @@ namespace cctz = absl::time_internal::cctz; namespace absl { ABSL_NAMESPACE_BEGIN -extern const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez"; -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"; -extern const char RFC1123_no_wday[] = "%d %b %E4Y %H:%M:%S %z"; +ABSL_DLL extern const char RFC3339_full[] = + "%Y-%m-%dT%H:%M:%E*S%Ez"; +ABSL_DLL extern const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez"; + +ABSL_DLL extern const char RFC1123_full[] = + "%a, %d %b %E4Y %H:%M:%S %z"; +ABSL_DLL extern const char RFC1123_no_wday[] = + "%d %b %E4Y %H:%M:%S %z"; namespace { diff --git a/absl/time/internal/cctz/src/time_zone_fixed.cc b/absl/time/internal/cctz/src/time_zone_fixed.cc index a342e37d..303c0244 100644 --- a/absl/time/internal/cctz/src/time_zone_fixed.cc +++ b/absl/time/internal/cctz/src/time_zone_fixed.cc @@ -89,29 +89,29 @@ std::string FixedOffsetToName(const seconds& offset) { // offsets and to (somewhat) limit the total number of zones. return "UTC"; } - int seconds = static_cast(offset.count()); - const char sign = (seconds < 0 ? '-' : '+'); - int minutes = seconds / 60; - seconds %= 60; + int offset_seconds = static_cast(offset.count()); + const char sign = (offset_seconds < 0 ? '-' : '+'); + int offset_minutes = offset_seconds / 60; + offset_seconds %= 60; if (sign == '-') { - if (seconds > 0) { - seconds -= 60; - minutes += 1; + if (offset_seconds > 0) { + offset_seconds -= 60; + offset_minutes += 1; } - seconds = -seconds; - minutes = -minutes; + offset_seconds = -offset_seconds; + offset_minutes = -offset_minutes; } - int hours = minutes / 60; - minutes %= 60; + int offset_hours = offset_minutes / 60; + offset_minutes %= 60; const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1; char buf[prefix_len + sizeof("-24:00:00")]; char* ep = std::copy(kFixedZonePrefix, kFixedZonePrefix + prefix_len, buf); *ep++ = sign; - ep = Format02d(ep, hours); + ep = Format02d(ep, offset_hours); *ep++ = ':'; - ep = Format02d(ep, minutes); + ep = Format02d(ep, offset_minutes); *ep++ = ':'; - ep = Format02d(ep, seconds); + ep = Format02d(ep, offset_seconds); *ep++ = '\0'; assert(ep == buf + sizeof(buf)); return buf; diff --git a/absl/time/internal/cctz/src/time_zone_format_test.cc b/absl/time/internal/cctz/src/time_zone_format_test.cc index de75629a..caebcc4d 100644 --- a/absl/time/internal/cctz/src/time_zone_format_test.cc +++ b/absl/time/internal/cctz/src/time_zone_format_test.cc @@ -1252,9 +1252,9 @@ TEST(Parse, ExtendedSubecondsScan) { const auto expected = chrono::system_clock::from_time_t(0) + chrono::nanoseconds(micros * 1000 + ns); for (int ps = 0; ps < 1000; ps += 250) { - std::ostringstream oss; + std::ostringstream ps_oss; 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_EQ(expected + chrono::nanoseconds(ps) / 1000, tp) << input; } diff --git a/absl/time/internal/cctz/src/time_zone_info.cc b/absl/time/internal/cctz/src/time_zone_info.cc index 971542d0..f1697cdf 100644 --- a/absl/time/internal/cctz/src/time_zone_info.cc +++ b/absl/time/internal/cctz/src/time_zone_info.cc @@ -641,9 +641,9 @@ std::unique_ptr FileZoneInfoSource::Open( if (fp == nullptr) return nullptr; std::size_t length = 0; if (fseek(fp, 0, SEEK_END) == 0) { - long pos = ftell(fp); - if (pos >= 0) { - length = static_cast(pos); + long offset = ftell(fp); + if (offset >= 0) { + length = static_cast(offset); } rewind(fp); } diff --git a/absl/time/internal/cctz/src/time_zone_lookup_test.cc b/absl/time/internal/cctz/src/time_zone_lookup_test.cc index 227b1278..99137a08 100644 --- a/absl/time/internal/cctz/src/time_zone_lookup_test.cc +++ b/absl/time/internal/cctz/src/time_zone_lookup_test.cc @@ -1028,16 +1028,17 @@ TEST(MakeTime, LocalTimeLibC) { ASSERT_EQ(0, setenv("TZ", *np, 1)); // change what "localtime" means const auto zi = local_time_zone(); const auto lc = LoadZone("libc:localtime"); - time_zone::civil_transition trans; + time_zone::civil_transition transition; for (auto tp = zi.lookup(civil_second()).trans; - zi.next_transition(tp, &trans); tp = zi.lookup(trans.to).trans) { - const auto fcl = zi.lookup(trans.from); - const auto tcl = zi.lookup(trans.to); + zi.next_transition(tp, &transition); + tp = zi.lookup(transition.to).trans) { + const auto fcl = zi.lookup(transition.from); + const auto tcl = zi.lookup(transition.to); civil_second cs; // compare cs in zi and lc if (fcl.kind == time_zone::civil_lookup::UNIQUE) { if (tcl.kind == time_zone::civil_lookup::UNIQUE) { // 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 tal = zi.lookup(trans); const auto tprev = trans - absl::time_internal::cctz::seconds(1); @@ -1048,11 +1049,11 @@ TEST(MakeTime, LocalTimeLibC) { continue; } ASSERT_EQ(time_zone::civil_lookup::REPEATED, tcl.kind); - cs = trans.to; + cs = transition.to; } else { ASSERT_EQ(time_zone::civil_lookup::UNIQUE, tcl.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) const auto cl_zi = zi.lookup(cs); diff --git a/absl/time/time.h b/absl/time/time.h index 1be5727c..33a4a630 100644 --- a/absl/time/time.h +++ b/absl/time/time.h @@ -527,59 +527,30 @@ std::chrono::seconds ToChronoSeconds(Duration d); std::chrono::minutes ToChronoMinutes(Duration d); std::chrono::hours ToChronoHours(Duration d); - // FormatDuration() // -// Returns a string represention of the duration in a format consisting of a -// possibly-signed prefix and a sequence of decimal numbers, each with an -// 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()` +// Returns a string representing the duration in the form "72h3m0.5s". +// Returns "inf" or "-inf" for +/- `InfiniteDuration()`. std::string FormatDuration(Duration d); +// Output stream operator. +inline std::ostream& operator<<(std::ostream& os, Duration d) { + return os << FormatDuration(d); +} + // ParseDuration() // -// 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. +// 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); -// 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()` +// 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); - -// 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) { - return os << FormatDuration(d); -} - ABSL_DEPRECATED("Use AbslParseFlag() instead.") bool ParseFlag(const std::string& text, Duration* dst, std::string* error); 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); std::chrono::system_clock::time_point ToChronoTime(Time); -// AbslParseFlag() -// -// 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: +// Support for flag values of type Time. Time flags must be specified in a +// format that matches absl::RFC3339_full. For example: // // --start_time=2016-01-02T03:04:05.678+08:00 // // Note: A UTC offset (or 'Z' indicating a zero-offset from UTC) is required. // // Additionally, if you'd like to specify a time as a count of -// seconds/milliseconds/etc from the Unix epoch, use an `absl::Duration` flag -// and add that duration to `absl::UnixEpoch()` to get an `absl::Time`. +// seconds/milliseconds/etc from the Unix epoch, use an absl::Duration flag +// and add that duration to absl::UnixEpoch() to get an absl::Time. bool AbslParseFlag(absl::string_view text, Time* t, std::string* error); - -// AbslUnparseFlag() -// -// Unparses an `absl::Time` into a command-line string format as noted above. std::string AbslUnparseFlag(Time t); - ABSL_DEPRECATED("Use AbslParseFlag() instead.") bool ParseFlag(const std::string& text, Time* t, std::string* error); ABSL_DEPRECATED("Use AbslUnparseFlag() instead.") @@ -1243,15 +1203,18 @@ struct tm ToTM(Time t, TimeZone tz); // time with UTC offset. Also note the use of "%Y": RFC3339 mandates that // years have exactly four digits, but we allow them to take their natural // width. -extern const char RFC3339_full[]; // %Y-%m-%dT%H:%M:%E*S%Ez -extern const char RFC3339_sec[]; // %Y-%m-%dT%H:%M:%S%Ez +ABSL_DLL extern const char + 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_no_wday // // FormatTime()/ParseTime() format specifiers for RFC1123 date/time strings. -extern const char RFC1123_full[]; // %a, %d %b %E4Y %H:%M:%S %z -extern const char RFC1123_no_wday[]; // %d %b %E4Y %H:%M:%S %z +ABSL_DLL extern const char + RFC1123_full[]; // %a, %d %b %E4Y %H:%M:%S %z +ABSL_DLL extern const char + RFC1123_no_wday[]; // %d %b %E4Y %H:%M:%S %z // FormatTime() // -- cgit v1.2.3 From 79e0dc11514df035a8d07a356f9ee1800fb2160c Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 26 Mar 2020 08:48:01 -0700 Subject: Export of internal Abseil changes -- 990253454819ce26ff1dda9ab4bbc145b61d01e4 by Xiaoyi Zhang : Import github PR https://github.com/abseil/abseil-cpp/pull/645 PiperOrigin-RevId: 303119797 -- 5ac845cb7929b7d1eaf59a309afd811db5001175 by Abseil Team : Fix internal exception spec compatibility error PiperOrigin-RevId: 303104081 -- 3290595dd866eecab3c7044e2e3ca0adb74f1bf5 by Gennadiy Rozental : Use FlagValue to represent the value of a flag. Place it directly after FlagImpl and use a computed offset refer to it. The offset is computed based on the assumption that the `value_` data member is placed directly after the impl_ data member in Flag. This change will allow us to migrate to `T`-specific storage in the generic case. This change decreases the overhead for int flags by 32 bytes. PiperOrigin-RevId: 303038099 -- f2b37722cd7a6d3a60ef9713f0d2bbff56f3ddbf by Derek Mauro : Minor correctness fix for an ABSL_HAVE_BUILTIN conditional PiperOrigin-RevId: 302980666 -- 39c079a6141ae1c5728af8bf33a39c8aff9deb9f by Abseil Team : Use ABSL_HARDENING_ASSERT in b-tree and SwissTable iterators. PiperOrigin-RevId: 302970075 -- 9668a044e080c789df32bcaa1ffb5100831cd9fa by Benjamin Barenblat : Correct `add_subdirectory` line in CMake googletest support Commit bcefbdcdf6ad85046ccacee0aeffba5404d3e528 added support for building with CMake against a local googletest checkout, but I missed a line when constructing the diff. Change the `add_subdirectory` line to reference the correct directories. PiperOrigin-RevId: 302947488 -- 0a3c10fabf80a43ca69ab8b1570030e55f2be741 by Andy Soffer : Remove unused distribution format traits. PiperOrigin-RevId: 302896176 -- 0478f2f6270e5ed64c0e28ec09556ca90b2d46a9 by Samuel Benzaquen : Fix for CWG:2310. PiperOrigin-RevId: 302734089 -- 3cb978dda5cae5905affdc0914dcc2d27671ed11 by Samuel Benzaquen : Fix the Allocate/Deallocate functions to use the same underlying allocator type. PiperOrigin-RevId: 302721804 -- ae38d3984fb68b4e3ddc165fa8d5c24d5936be52 by Matthew Brown : Internal Change PiperOrigin-RevId: 302717314 -- 7357cf7abd03cc60b6e82b5f28a8e34935c3b4dc by Andy Getzendanner : Fix typo: s/ABSL_HARDENED_ASSERT/ABSL_HARDENING_ASSERT/ PiperOrigin-RevId: 302532164 GitOrigin-RevId: 990253454819ce26ff1dda9ab4bbc145b61d01e4 Change-Id: Ie595a221c16e1e7e1255ad42e029b646c5f3e11d --- CMake/Googletest/DownloadGTest.cmake | 4 +- absl/base/macros.h | 7 +- absl/container/internal/btree.h | 11 +- absl/container/internal/common.h | 3 +- absl/container/internal/container_memory.h | 7 +- absl/container/internal/container_memory_test.cc | 38 +++ absl/container/internal/raw_hash_set.h | 5 +- absl/flags/flag_test.cc | 24 +- absl/flags/internal/flag.cc | 82 +++--- absl/flags/internal/flag.h | 259 ++++++++++++------- absl/random/BUILD.bazel | 5 - absl/random/CMakeLists.txt | 3 - absl/random/bit_gen_ref.h | 5 +- absl/random/distribution_format_traits.h | 278 --------------------- absl/random/distributions.h | 37 +-- absl/random/internal/distribution_caller.h | 15 +- absl/random/internal/mocking_bit_gen_base.h | 39 +-- absl/random/mocking_bit_gen.cc | 30 --- absl/random/mocking_bit_gen.h | 8 +- absl/strings/BUILD.bazel | 1 + absl/strings/CMakeLists.txt | 1 + absl/strings/internal/str_format/arg.cc | 52 ++-- absl/strings/internal/str_format/arg.h | 16 +- absl/strings/internal/str_format/bind.cc | 2 +- absl/strings/internal/str_format/checker_test.cc | 10 +- .../internal/str_format/float_conversion.cc | 41 +-- absl/strings/internal/str_format/parser_test.cc | 2 +- absl/strings/numbers_test.cc | 1 + absl/strings/str_format_test.cc | 8 +- 29 files changed, 387 insertions(+), 607 deletions(-) delete mode 100644 absl/random/distribution_format_traits.h delete mode 100644 absl/random/mocking_bit_gen.cc (limited to 'absl/random/CMakeLists.txt') diff --git a/CMake/Googletest/DownloadGTest.cmake b/CMake/Googletest/DownloadGTest.cmake index 6552e1da..9d071c91 100644 --- a/CMake/Googletest/DownloadGTest.cmake +++ b/CMake/Googletest/DownloadGTest.cmake @@ -38,6 +38,4 @@ set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) # Add googletest directly to our build. This defines the gtest and gtest_main # targets. -add_subdirectory(${CMAKE_BINARY_DIR}/googletest-src - ${CMAKE_BINARY_DIR}/googletest-build - EXCLUDE_FROM_ALL) +add_subdirectory(${absl_gtest_src_dir} ${absl_gtest_build_dir} EXCLUDE_FROM_ALL) diff --git a/absl/base/macros.h b/absl/base/macros.h index 2f6089f4..2c4e3570 100644 --- a/absl/base/macros.h +++ b/absl/base/macros.h @@ -212,7 +212,8 @@ ABSL_NAMESPACE_END // aborts the program in release mode (when NDEBUG is defined). The // implementation should abort the program as quickly as possible and ideally it // should not be possible to ignore the abort request. -#if ABSL_HAVE_BUILTIN(__builtin_trap) || \ +#if (ABSL_HAVE_BUILTIN(__builtin_trap) && \ + ABSL_HAVE_BUILTIN(__builtin_unreachable)) || \ (defined(__GNUC__) && !defined(__clang__)) #define ABSL_INTERNAL_HARDENING_ABORT() \ do { \ @@ -225,11 +226,11 @@ ABSL_NAMESPACE_END // ABSL_HARDENING_ASSERT() // -// `ABSL_HARDENED_ASSERT()` is like `ABSL_ASSERT()`, but used to implement +// `ABSL_HARDENING_ASSERT()` is like `ABSL_ASSERT()`, but used to implement // runtime assertions that should be enabled in hardened builds even when // `NDEBUG` is defined. // -// When `NDEBUG` is not defined, `ABSL_HARDENED_ASSERT()` is identical to +// When `NDEBUG` is not defined, `ABSL_HARDENING_ASSERT()` is identical to // `ABSL_ASSERT()`. // // See `ABSL_OPTION_HARDENED` in `absl/base/options.h` for more information on diff --git a/absl/container/internal/btree.h b/absl/container/internal/btree.h index adf49f81..4504e9ce 100644 --- a/absl/container/internal/btree.h +++ b/absl/container/internal/btree.h @@ -937,8 +937,13 @@ struct btree_iterator { } // Accessors for the key/value the iterator is pointing at. - reference operator*() const { return node->value(position); } - pointer operator->() const { return &node->value(position); } + reference operator*() const { + ABSL_HARDENING_ASSERT(node != nullptr); + ABSL_HARDENING_ASSERT(node->start() <= position); + ABSL_HARDENING_ASSERT(node->finish() > position); + return node->value(position); + } + pointer operator->() const { return &operator*(); } btree_iterator &operator++() { increment(); @@ -1769,6 +1774,7 @@ void btree_iterator::increment_slow() { position = node->position(); node = node->parent(); } + // TODO(ezb): assert we aren't incrementing end() instead of handling. if (position == node->finish()) { *this = save; } @@ -1792,6 +1798,7 @@ void btree_iterator::decrement_slow() { position = node->position() - 1; node = node->parent(); } + // TODO(ezb): assert we aren't decrementing begin() instead of handling. if (position < node->start()) { *this = save; } diff --git a/absl/container/internal/common.h b/absl/container/internal/common.h index 5037d803..8990f294 100644 --- a/absl/container/internal/common.h +++ b/absl/container/internal/common.h @@ -138,6 +138,7 @@ class node_handle> : public node_handle_base { using Base = node_handle_base; + using slot_type = typename PolicyTraits::slot_type; public: using key_type = typename Policy::key_type; @@ -145,7 +146,7 @@ class node_handle decltype(PolicyTraits::key(this->slot())) { + auto key() const -> decltype(PolicyTraits::key(std::declval())) { return PolicyTraits::key(this->slot()); } diff --git a/absl/container/internal/container_memory.h b/absl/container/internal/container_memory.h index d24b0f84..55b59c7f 100644 --- a/absl/container/internal/container_memory.h +++ b/absl/container/internal/container_memory.h @@ -37,6 +37,9 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace container_internal { +template +struct alignas(Alignment) AlignedType {}; + // Allocates at least n bytes aligned to the specified alignment. // Alignment must be a power of 2. It must be positive. // @@ -48,7 +51,7 @@ template void* Allocate(Alloc* alloc, size_t n) { static_assert(Alignment > 0, ""); assert(n && "n must be positive"); - struct alignas(Alignment) M {}; + using M = AlignedType; using A = typename absl::allocator_traits::template rebind_alloc; using AT = typename absl::allocator_traits::template rebind_traits; A mem_alloc(*alloc); @@ -64,7 +67,7 @@ template void Deallocate(Alloc* alloc, void* p, size_t n) { static_assert(Alignment > 0, ""); assert(n && "n must be positive"); - struct alignas(Alignment) M {}; + using M = AlignedType; using A = typename absl::allocator_traits::template rebind_alloc; using AT = typename absl::allocator_traits::template rebind_traits; A mem_alloc(*alloc); diff --git a/absl/container/internal/container_memory_test.cc b/absl/container/internal/container_memory_test.cc index 7942c7be..e3262e3c 100644 --- a/absl/container/internal/container_memory_test.cc +++ b/absl/container/internal/container_memory_test.cc @@ -16,6 +16,8 @@ #include #include +#include +#include #include #include "gmock/gmock.h" @@ -27,6 +29,9 @@ ABSL_NAMESPACE_BEGIN namespace container_internal { namespace { +using ::testing::Gt; +using ::testing::_; +using ::testing::ElementsAre; using ::testing::Pair; TEST(Memory, AlignmentLargerThanBase) { @@ -45,6 +50,39 @@ TEST(Memory, AlignmentSmallerThanBase) { Deallocate<2>(&alloc, mem, 3); } +std::map& AllocationMap() { + static auto* map = new std::map; + return *map; +} + +template +struct TypeCountingAllocator { + TypeCountingAllocator() = default; + template + TypeCountingAllocator(const TypeCountingAllocator&) {} // NOLINT + + using value_type = T; + + T* allocate(size_t n, const void* = nullptr) { + AllocationMap()[typeid(T)] += n; + return std::allocator().allocate(n); + } + void deallocate(T* p, std::size_t n) { + AllocationMap()[typeid(T)] -= n; + return std::allocator().deallocate(p, n); + } +}; + +TEST(Memory, AllocateDeallocateMatchType) { + TypeCountingAllocator alloc; + void* mem = Allocate<1>(&alloc, 1); + // Verify that it was allocated + EXPECT_THAT(AllocationMap(), ElementsAre(Pair(_, Gt(0)))); + Deallocate<1>(&alloc, mem, 1); + // Verify that the deallocation matched. + EXPECT_THAT(AllocationMap(), ElementsAre(Pair(_, 0))); +} + class Fixture : public ::testing::Test { using Alloc = std::allocator; diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index fb47f62f..e47e1fed 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -104,6 +104,7 @@ #include "absl/base/internal/bits.h" #include "absl/base/internal/endian.h" +#include "absl/base/macros.h" #include "absl/base/port.h" #include "absl/container/internal/common.h" #include "absl/container/internal/compressed_tuple.h" @@ -651,9 +652,9 @@ class raw_hash_set { iterator(ctrl_t* ctrl) : ctrl_(ctrl) {} // for end() iterator(ctrl_t* ctrl, slot_type* slot) : ctrl_(ctrl), slot_(slot) {} - void assert_is_full() const { assert(IsFull(*ctrl_)); } + void assert_is_full() const { ABSL_HARDENING_ASSERT(IsFull(*ctrl_)); } void assert_is_valid() const { - assert(!ctrl_ || IsFull(*ctrl_) || *ctrl_ == kSentinel); + ABSL_HARDENING_ASSERT(!ctrl_ || IsFull(*ctrl_) || *ctrl_ == kSentinel); } void skip_empty_or_deleted() { diff --git a/absl/flags/flag_test.cc b/absl/flags/flag_test.cc index 3a025576..377e3b2b 100644 --- a/absl/flags/flag_test.cc +++ b/absl/flags/flag_test.cc @@ -91,30 +91,30 @@ struct S2 { }; TEST_F(FlagTest, Traits) { - EXPECT_EQ(flags::FlagValue::Kind(), + EXPECT_EQ(flags::StorageKind(), flags::FlagValueStorageKind::kOneWordAtomic); - EXPECT_EQ(flags::FlagValue::Kind(), + EXPECT_EQ(flags::StorageKind(), flags::FlagValueStorageKind::kOneWordAtomic); - EXPECT_EQ(flags::FlagValue::Kind(), + EXPECT_EQ(flags::StorageKind(), flags::FlagValueStorageKind::kOneWordAtomic); - EXPECT_EQ(flags::FlagValue::Kind(), + EXPECT_EQ(flags::StorageKind(), flags::FlagValueStorageKind::kOneWordAtomic); #if defined(ABSL_FLAGS_INTERNAL_ATOMIC_DOUBLE_WORD) - EXPECT_EQ(flags::FlagValue::Kind(), + EXPECT_EQ(flags::StorageKind(), flags::FlagValueStorageKind::kTwoWordsAtomic); - EXPECT_EQ(flags::FlagValue::Kind(), + EXPECT_EQ(flags::StorageKind(), flags::FlagValueStorageKind::kTwoWordsAtomic); #else - EXPECT_EQ(flags::FlagValue::Kind(), + EXPECT_EQ(flags::StorageKind(), flags::FlagValueStorageKind::kHeapAllocated); - EXPECT_EQ(flags::FlagValue::Kind(), + EXPECT_EQ(flags::StorageKind(), flags::FlagValueStorageKind::kHeapAllocated); #endif - EXPECT_EQ(flags::FlagValue::Kind(), + EXPECT_EQ(flags::StorageKind(), flags::FlagValueStorageKind::kHeapAllocated); - EXPECT_EQ(flags::FlagValue::Kind>(), + EXPECT_EQ(flags::StorageKind>(), flags::FlagValueStorageKind::kHeapAllocated); } @@ -624,10 +624,10 @@ TEST_F(FlagTest, TestNonDefaultConstructibleType) { EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag2).value, 25); } -// -------------------------------------------------------------------- - } // namespace +// -------------------------------------------------------------------- + ABSL_RETIRED_FLAG(bool, old_bool_flag, true, "old descr"); ABSL_RETIRED_FLAG(int, old_int_flag, (int)std::sqrt(10), "old descr"); ABSL_RETIRED_FLAG(std::string, old_str_flag, "", absl::StrCat("old ", "descr")); diff --git a/absl/flags/internal/flag.cc b/absl/flags/internal/flag.cc index 56a5ed2b..5b4499ab 100644 --- a/absl/flags/internal/flag.cc +++ b/absl/flags/internal/flag.cc @@ -25,6 +25,7 @@ #include #include "absl/base/attributes.h" +#include "absl/base/casts.h" #include "absl/base/config.h" #include "absl/base/const_init.h" #include "absl/base/optimization.h" @@ -135,18 +136,18 @@ void FlagImpl::Init() { (*default_value_.gen_func)(), DynValueDeleter{op_}); switch (ValueStorageKind()) { case FlagValueStorageKind::kHeapAllocated: - value_.dynamic = init_value.release(); + HeapAllocatedValue() = init_value.release(); break; case FlagValueStorageKind::kOneWordAtomic: { int64_t atomic_value; - std::memcpy(&atomic_value, init_value.get(), flags_internal::Sizeof(op_)); - value_.one_word_atomic.store(atomic_value, std::memory_order_release); + std::memcpy(&atomic_value, init_value.get(), Sizeof(op_)); + OneWordValue().store(atomic_value, std::memory_order_release); break; } case FlagValueStorageKind::kTwoWordsAtomic: { AlignedTwoWords atomic_value{0, 0}; - std::memcpy(&atomic_value, init_value.get(), flags_internal::Sizeof(op_)); - value_.two_words_atomic.store(atomic_value, std::memory_order_release); + std::memcpy(&atomic_value, init_value.get(), Sizeof(op_)); + TwoWordsValue().store(atomic_value, std::memory_order_release); break; } } @@ -198,18 +199,18 @@ std::unique_ptr FlagImpl::MakeInitValue() const { void FlagImpl::StoreValue(const void* src) { switch (ValueStorageKind()) { case FlagValueStorageKind::kHeapAllocated: - flags_internal::Copy(op_, src, value_.dynamic); + Copy(op_, src, HeapAllocatedValue()); break; case FlagValueStorageKind::kOneWordAtomic: { - int64_t one_word_val; - std::memcpy(&one_word_val, src, flags_internal::Sizeof(op_)); - value_.one_word_atomic.store(one_word_val, std::memory_order_release); + int64_t one_word_val = 0; + std::memcpy(&one_word_val, src, Sizeof(op_)); + OneWordValue().store(one_word_val, std::memory_order_release); break; } case FlagValueStorageKind::kTwoWordsAtomic: { AlignedTwoWords two_words_val{0, 0}; - std::memcpy(&two_words_val, src, flags_internal::Sizeof(op_)); - value_.two_words_atomic.store(two_words_val, std::memory_order_release); + std::memcpy(&two_words_val, src, Sizeof(op_)); + TwoWordsValue().store(two_words_val, std::memory_order_release); break; } } @@ -258,17 +259,19 @@ std::string FlagImpl::CurrentValue() const { switch (ValueStorageKind()) { case FlagValueStorageKind::kHeapAllocated: { absl::MutexLock l(guard); - return flags_internal::Unparse(op_, value_.dynamic); + return flags_internal::Unparse(op_, HeapAllocatedValue()); } case FlagValueStorageKind::kOneWordAtomic: { const auto one_word_val = - value_.one_word_atomic.load(std::memory_order_acquire); - return flags_internal::Unparse(op_, &one_word_val); + absl::bit_cast>( + OneWordValue().load(std::memory_order_acquire)); + return flags_internal::Unparse(op_, one_word_val.data()); } case FlagValueStorageKind::kTwoWordsAtomic: { const auto two_words_val = - value_.two_words_atomic.load(std::memory_order_acquire); - return flags_internal::Unparse(op_, &two_words_val); + absl::bit_cast>( + TwoWordsValue().load(std::memory_order_acquire)); + return flags_internal::Unparse(op_, two_words_val.data()); } } @@ -317,18 +320,18 @@ std::unique_ptr FlagImpl::SaveState() { switch (ValueStorageKind()) { case FlagValueStorageKind::kHeapAllocated: { return absl::make_unique( - this, flags_internal::Clone(op_, value_.dynamic), modified, + this, flags_internal::Clone(op_, HeapAllocatedValue()), modified, on_command_line, counter_); } case FlagValueStorageKind::kOneWordAtomic: { return absl::make_unique( - this, value_.one_word_atomic.load(std::memory_order_acquire), - modified, on_command_line, counter_); + this, OneWordValue().load(std::memory_order_acquire), modified, + on_command_line, counter_); } case FlagValueStorageKind::kTwoWordsAtomic: { return absl::make_unique( - this, value_.two_words_atomic.load(std::memory_order_acquire), - modified, on_command_line, counter_); + this, TwoWordsValue().load(std::memory_order_acquire), modified, + on_command_line, counter_); } } return nullptr; @@ -359,6 +362,28 @@ bool FlagImpl::RestoreState(const FlagState& flag_state) { return true; } +template +typename StorageT::value_type& FlagImpl::OffsetValue() const { + char* p = reinterpret_cast(const_cast(this)); + // The offset is deduced via Flag value type specific op_. + size_t offset = flags_internal::ValueOffset(op_); + + return reinterpret_cast(p + offset)->value; +} + +void*& FlagImpl::HeapAllocatedValue() const { + assert(ValueStorageKind() == FlagValueStorageKind::kHeapAllocated); + return OffsetValue(); +} +std::atomic& FlagImpl::OneWordValue() const { + assert(ValueStorageKind() == FlagValueStorageKind::kOneWordAtomic); + return OffsetValue(); +} +std::atomic& FlagImpl::TwoWordsValue() const { + assert(ValueStorageKind() == FlagValueStorageKind::kTwoWordsAtomic); + return OffsetValue(); +} + // Attempts to parse supplied `value` string using parsing routine in the `flag` // argument. If parsing successful, this function replaces the dst with newly // parsed value. In case if any error is encountered in either step, the error @@ -383,20 +408,19 @@ void FlagImpl::Read(void* dst) const { switch (ValueStorageKind()) { case FlagValueStorageKind::kHeapAllocated: { absl::MutexLock l(guard); - - flags_internal::CopyConstruct(op_, value_.dynamic, dst); + flags_internal::CopyConstruct(op_, HeapAllocatedValue(), dst); break; } case FlagValueStorageKind::kOneWordAtomic: { - const auto one_word_val = - value_.one_word_atomic.load(std::memory_order_acquire); - std::memcpy(dst, &one_word_val, flags_internal::Sizeof(op_)); + const int64_t one_word_val = + OneWordValue().load(std::memory_order_acquire); + std::memcpy(dst, &one_word_val, Sizeof(op_)); break; } case FlagValueStorageKind::kTwoWordsAtomic: { - const auto two_words_val = - value_.two_words_atomic.load(std::memory_order_acquire); - std::memcpy(dst, &two_words_val, flags_internal::Sizeof(op_)); + const AlignedTwoWords two_words_val = + TwoWordsValue().load(std::memory_order_acquire); + std::memcpy(dst, &two_words_val, Sizeof(op_)); break; } } diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h index f27e558b..19119bbb 100644 --- a/absl/flags/internal/flag.h +++ b/absl/flags/internal/flag.h @@ -53,56 +53,13 @@ enum class FlagOp { kStaticTypeId, kParse, kUnparse, + kValueOffset, }; using FlagOpFn = void* (*)(FlagOp, const void*, void*, void*); -// Flag value specific operations routine. +// Forward declaration for Flag value specific operations. template -void* FlagOps(FlagOp op, const void* v1, void* v2, void* v3) { - switch (op) { - case FlagOp::kDelete: - delete static_cast(v1); - return nullptr; - case FlagOp::kClone: - return new T(*static_cast(v1)); - case FlagOp::kCopy: - *static_cast(v2) = *static_cast(v1); - return nullptr; - case FlagOp::kCopyConstruct: - new (v2) T(*static_cast(v1)); - return nullptr; - case FlagOp::kSizeof: - return reinterpret_cast(sizeof(T)); - case FlagOp::kStaticTypeId: { - auto* static_id = &FlagStaticTypeIdGen; - - // Cast from function pointer to void* is not portable. - // We don't have an easy way to work around this, but it works fine - // on all the platforms we test and as long as size of pointers match - // we should be fine to do reinterpret cast. - static_assert(sizeof(void*) == sizeof(static_id), - "Flag's static type id does not work on this platform"); - return reinterpret_cast(static_id); - } - case FlagOp::kParse: { - // Initialize the temporary instance of type T based on current value in - // destination (which is going to be flag's default value). - T temp(*static_cast(v2)); - if (!absl::ParseFlag(*static_cast(v1), &temp, - static_cast(v3))) { - return nullptr; - } - *static_cast(v2) = std::move(temp); - return v2; - } - case FlagOp::kUnparse: - *static_cast(v2) = - absl::UnparseFlag(*static_cast(v1)); - return nullptr; - default: - return nullptr; - } -} +void* FlagOps(FlagOp op, const void* v1, void* v2, void* v3); // Deletes memory interpreting obj as flag value type pointer. inline void Delete(FlagOpFn op, const void* obj) { @@ -144,6 +101,16 @@ inline FlagStaticTypeId StaticTypeId(FlagOpFn op) { return reinterpret_cast( op(FlagOp::kStaticTypeId, nullptr, nullptr, nullptr)); } +// Returns offset of the field value_ from the field impl_ inside of +// absl::Flag data. Given FlagImpl pointer p you can get the +// location of the corresponding value as: +// reinterpret_cast(p) + ValueOffset(). +inline ptrdiff_t ValueOffset(FlagOpFn op) { + // This sequence of casts reverses the sequence from + // `flags_internal::FlagOps()` + return static_cast(reinterpret_cast( + op(FlagOp::kValueOffset, nullptr, nullptr, nullptr))); +} /////////////////////////////////////////////////////////////////////////////// // Flag help auxiliary structs. @@ -239,6 +206,10 @@ using FlagUseOneWordStorage = std::integral_constant< struct alignas(16) AlignedTwoWords { int64_t first; int64_t second; + + bool IsInitialized() const { + return first != flags_internal::UninitializedFlagValue(); + } }; template @@ -248,8 +219,14 @@ using FlagUseTwoWordsStorage = std::integral_constant< #else // This is actually unused and only here to avoid ifdefs in other palces. struct AlignedTwoWords { - constexpr AlignedTwoWords() = default; - constexpr AlignedTwoWords(int64_t, int64_t) {} + constexpr AlignedTwoWords() noexcept : dummy() {} + constexpr AlignedTwoWords(int64_t, int64_t) noexcept : dummy() {} + char dummy; + + bool IsInitialized() const { + std::abort(); + return true; + } }; // This trait should be type dependent, otherwise SFINAE below will fail @@ -269,23 +246,70 @@ enum class FlagValueStorageKind : uint8_t { kTwoWordsAtomic = 2 }; -union FlagValue { - constexpr explicit FlagValue(int64_t v) : one_word_atomic(v) {} +template +static constexpr FlagValueStorageKind StorageKind() { + return FlagUseHeapStorage::value + ? FlagValueStorageKind::kHeapAllocated + : FlagUseOneWordStorage::value + ? FlagValueStorageKind::kOneWordAtomic + : FlagUseTwoWordsStorage::value + ? FlagValueStorageKind::kTwoWordsAtomic + : FlagValueStorageKind::kHeapAllocated; +} + +struct FlagHeapAllocatedValue { + using value_type = void*; + + value_type value; +}; + +struct FlagOneWordValue { + using value_type = std::atomic; + constexpr FlagOneWordValue() : value(UninitializedFlagValue()) {} - template - static constexpr FlagValueStorageKind Kind() { - return FlagUseHeapStorage::value - ? FlagValueStorageKind::kHeapAllocated - : FlagUseOneWordStorage::value - ? FlagValueStorageKind::kOneWordAtomic - : FlagUseTwoWordsStorage::value - ? FlagValueStorageKind::kTwoWordsAtomic - : FlagValueStorageKind::kHeapAllocated; + value_type value; +}; + +struct FlagTwoWordsValue { + using value_type = std::atomic; + constexpr FlagTwoWordsValue() + : value(AlignedTwoWords{UninitializedFlagValue(), 0}) {} + + value_type value; +}; + +template ()> +struct FlagValue; + +template +struct FlagValue + : FlagHeapAllocatedValue { + bool Get(T*) const { return false; } +}; + +template +struct FlagValue : FlagOneWordValue { + bool Get(T* dst) const { + int64_t one_word_val = value.load(std::memory_order_acquire); + if (ABSL_PREDICT_FALSE(one_word_val == UninitializedFlagValue())) { + return false; + } + std::memcpy(dst, static_cast(&one_word_val), sizeof(T)); + return true; } +}; - void* dynamic; - std::atomic one_word_atomic; - std::atomic two_words_atomic; +template +struct FlagValue : FlagTwoWordsValue { + bool Get(T* dst) const { + AlignedTwoWords two_words_val = value.load(std::memory_order_acquire); + if (ABSL_PREDICT_FALSE(!two_words_val.IsInitialized())) { + return false; + } + std::memcpy(dst, static_cast(&two_words_val), sizeof(T)); + return true; + } }; /////////////////////////////////////////////////////////////////////////////// @@ -333,35 +357,10 @@ class FlagImpl final : public flags_internal::CommandLineFlag { counter_(0), callback_(nullptr), default_value_(default_value_gen), - value_(flags_internal::UninitializedFlagValue()), data_guard_{} {} // Constant access methods void Read(void* dst) const override ABSL_LOCKS_EXCLUDED(*DataGuard()); - template ::value, - int>::type = 0> - void Get(T* dst) const { - Read(dst); - } - template ::value, - int>::type = 0> - void Get(T* dst) const { - int64_t one_word_val = - value_.one_word_atomic.load(std::memory_order_acquire); - if (ABSL_PREDICT_FALSE(one_word_val == UninitializedFlagValue())) { - DataGuard(); // Make sure flag initialized - one_word_val = value_.one_word_atomic.load(std::memory_order_acquire); - } - std::memcpy(dst, static_cast(&one_word_val), sizeof(T)); - } - template ::value, int>::type = 0> - void Get(T* dst) const { - DataGuard(); // Make sure flag initialized - const auto two_words_val = - value_.two_words_atomic.load(std::memory_order_acquire); - std::memcpy(dst, &two_words_val, sizeof(T)); - } // Mutating access methods void Write(const void* src) ABSL_LOCKS_EXCLUDED(*DataGuard()); @@ -391,6 +390,25 @@ class FlagImpl final : public flags_internal::CommandLineFlag { ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); // Flag initialization called via absl::call_once. void Init(); + + // Offset value access methods. One per storage kind. These methods to not + // respect const correctness, so be very carefull using them. + + // This is a shared helper routine which encapsulates most of the magic. Since + // it is only used inside the three routines below, which are defined in + // flag.cc, we can define it in that file as well. + template + typename StorageT::value_type& OffsetValue() const; + // This is an accessor for a value stored in heap allocated storage. + // Returns a mutable reference to a pointer to allow vlaue mutation. + void*& HeapAllocatedValue() const; + // This is an accessor for a value stored as one word atomic. Returns a + // mutable reference to an atomic value. + std::atomic& OneWordValue() const; + // This is an accessor for a value stored as two words atomic. Returns a + // mutable reference to an atomic value. + std::atomic& TwoWordsValue() const; + // Attempts to parse supplied `value` string. If parsing is successful, // returns new value. Otherwise returns nullptr. std::unique_ptr TryParse(absl::string_view value, @@ -488,13 +506,6 @@ class FlagImpl final : public flags_internal::CommandLineFlag { // these two cases. FlagDefaultSrc default_value_; - // Atomically mutable flag's state - - // Flag's value. This can be either the atomically stored small value or - // pointer to the heap allocated dynamic value. value_storage_kind_ is used - // to distinguish these cases. - FlagValue value_; - // This is reserved space for an absl::Mutex to guard flag data. It will be // initialized in FlagImpl::Init via placement new. // We can't use "absl::Mutex data_guard_", since this class is not literal. @@ -514,8 +525,9 @@ class Flag { public: constexpr Flag(const char* name, const char* filename, const FlagHelpArg help, const FlagDfltGenFunc default_value_gen) - : impl_(name, filename, &FlagOps, help, FlagValue::Kind(), - default_value_gen) {} + : impl_(name, filename, &FlagOps, help, + flags_internal::StorageKind(), default_value_gen), + value_() {} T Get() const { // See implementation notes in CommandLineFlag::Get(). @@ -530,7 +542,7 @@ class Flag { impl_.AssertValidType(&flags_internal::FlagStaticTypeIdGen); #endif - impl_.Get(&u.value); + if (!value_.Get(&u.value)) impl_.Read(&u.value); return std::move(u.value); } void Set(const T& v) { @@ -556,10 +568,63 @@ class Flag { private: template friend class FlagRegistrar; + // Flag's data + // The implementation depends on value_ field to be placed exactly after the + // impl_ field, so that impl_ can figure out the offset to the value and + // access it. FlagImpl impl_; + FlagValue value_; }; +/////////////////////////////////////////////////////////////////////////////// +// Implementation of Flag value specific operations routine. +template +void* FlagOps(FlagOp op, const void* v1, void* v2, void* v3) { + switch (op) { + case FlagOp::kDelete: + delete static_cast(v1); + return nullptr; + case FlagOp::kClone: + return new T(*static_cast(v1)); + case FlagOp::kCopy: + *static_cast(v2) = *static_cast(v1); + return nullptr; + case FlagOp::kCopyConstruct: + new (v2) T(*static_cast(v1)); + return nullptr; + case FlagOp::kSizeof: + return reinterpret_cast(static_cast(sizeof(T))); + case FlagOp::kStaticTypeId: + return reinterpret_cast(&FlagStaticTypeIdGen); + case FlagOp::kParse: { + // Initialize the temporary instance of type T based on current value in + // destination (which is going to be flag's default value). + T temp(*static_cast(v2)); + if (!absl::ParseFlag(*static_cast(v1), &temp, + static_cast(v3))) { + return nullptr; + } + *static_cast(v2) = std::move(temp); + return v2; + } + case FlagOp::kUnparse: + *static_cast(v2) = + absl::UnparseFlag(*static_cast(v1)); + return nullptr; + case FlagOp::kValueOffset: { + // Round sizeof(FlagImp) to a multiple of alignof(FlagValue) to get the + // offset of the data. + ptrdiff_t round_to = alignof(FlagValue); + ptrdiff_t offset = + (sizeof(FlagImpl) + round_to - 1) / round_to * round_to; + return reinterpret_cast(offset); + } + } + return nullptr; +} + +/////////////////////////////////////////////////////////////////////////////// // This class facilitates Flag object registration and tail expression-based // flag definition, for example: // ABSL_FLAG(int, foo, 42, "Foo help").OnUpdate(NotifyFooWatcher); diff --git a/absl/random/BUILD.bazel b/absl/random/BUILD.bazel index f78fbc7e..4d94e1ba 100644 --- a/absl/random/BUILD.bazel +++ b/absl/random/BUILD.bazel @@ -53,7 +53,6 @@ cc_library( "bernoulli_distribution.h", "beta_distribution.h", "discrete_distribution.h", - "distribution_format_traits.h", "distributions.h", "exponential_distribution.h", "gaussian_distribution.h", @@ -141,16 +140,12 @@ cc_library( cc_library( name = "mocking_bit_gen", testonly = 1, - srcs = [ - "mocking_bit_gen.cc", - ], hdrs = [ "mocking_bit_gen.h", ], linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":distributions", - "//absl/base:raw_logging_internal", "//absl/container:flat_hash_map", "//absl/meta:type_traits", "//absl/random/internal:distribution_caller", diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt index efa55d8f..69bedbd6 100644 --- a/absl/random/CMakeLists.txt +++ b/absl/random/CMakeLists.txt @@ -102,8 +102,6 @@ absl_cc_library( HDRS "mock_distributions.h" "mocking_bit_gen.h" - SRCS - "mocking_bit_gen.cc" COPTS ${ABSL_DEFAULT_COPTS} LINKOPTS @@ -168,7 +166,6 @@ absl_cc_library( "bernoulli_distribution.h" "beta_distribution.h" "discrete_distribution.h" - "distribution_format_traits.h" "distributions.h" "exponential_distribution.h" "gaussian_distribution.h" diff --git a/absl/random/bit_gen_ref.h b/absl/random/bit_gen_ref.h index e8771162..59591a47 100644 --- a/absl/random/bit_gen_ref.h +++ b/absl/random/bit_gen_ref.h @@ -132,7 +132,7 @@ namespace random_internal { template <> struct DistributionCaller { - template + template static typename DistrT::result_type Call(absl::BitGenRef* gen_ref, Args&&... args) { auto* mock_ptr = gen_ref->mocked_gen_ptr_; @@ -140,8 +140,7 @@ struct DistributionCaller { DistrT dist(std::forward(args)...); return dist(*gen_ref); } else { - return mock_ptr->template Call( - std::forward(args)...); + return mock_ptr->template Call(std::forward(args)...); } } }; diff --git a/absl/random/distribution_format_traits.h b/absl/random/distribution_format_traits.h deleted file mode 100644 index 22b358cc..00000000 --- a/absl/random/distribution_format_traits.h +++ /dev/null @@ -1,278 +0,0 @@ -// -// Copyright 2018 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef ABSL_RANDOM_DISTRIBUTION_FORMAT_TRAITS_H_ -#define ABSL_RANDOM_DISTRIBUTION_FORMAT_TRAITS_H_ - -#include -#include -#include - -#include "absl/meta/type_traits.h" -#include "absl/random/bernoulli_distribution.h" -#include "absl/random/beta_distribution.h" -#include "absl/random/exponential_distribution.h" -#include "absl/random/gaussian_distribution.h" -#include "absl/random/log_uniform_int_distribution.h" -#include "absl/random/poisson_distribution.h" -#include "absl/random/uniform_int_distribution.h" -#include "absl/random/uniform_real_distribution.h" -#include "absl/random/zipf_distribution.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/str_join.h" -#include "absl/strings/string_view.h" -#include "absl/types/span.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -struct IntervalClosedClosedTag; -struct IntervalClosedOpenTag; -struct IntervalOpenClosedTag; -struct IntervalOpenOpenTag; - -namespace random_internal { - -// ScalarTypeName defines a preferred hierarchy of preferred type names for -// scalars, and is evaluated at compile time for the specific type -// specialization. -template -constexpr const char* ScalarTypeName() { - static_assert(std::is_integral() || std::is_floating_point(), ""); - // clang-format off - return - std::is_same::value ? "float" : - std::is_same::value ? "double" : - std::is_same::value ? "long double" : - std::is_same::value ? "bool" : - std::is_signed::value && sizeof(T) == 1 ? "int8_t" : - std::is_signed::value && sizeof(T) == 2 ? "int16_t" : - std::is_signed::value && sizeof(T) == 4 ? "int32_t" : - std::is_signed::value && sizeof(T) == 8 ? "int64_t" : - std::is_unsigned::value && sizeof(T) == 1 ? "uint8_t" : - std::is_unsigned::value && sizeof(T) == 2 ? "uint16_t" : - std::is_unsigned::value && sizeof(T) == 4 ? "uint32_t" : - std::is_unsigned::value && sizeof(T) == 8 ? "uint64_t" : - "undefined"; - // clang-format on - - // NOTE: It would be nice to use typeid(T).name(), but that's an - // implementation-defined attribute which does not necessarily - // correspond to a name. We could potentially demangle it - // using, e.g. abi::__cxa_demangle. -} - -// Distribution traits used by DistributionCaller and internal implementation -// details of the mocking framework. -/* -struct DistributionFormatTraits { - // Returns the parameterized name of the distribution function. - static constexpr const char* FunctionName() - // Format DistrT parameters. - static std::string FormatArgs(DistrT& dist); - // Format DistrT::result_type results. - static std::string FormatResults(DistrT& dist); -}; -*/ -template -struct DistributionFormatTraits; - -template -struct DistributionFormatTraits> { - using distribution_t = absl::uniform_int_distribution; - using result_t = typename distribution_t::result_type; - - static constexpr const char* Name() { return "Uniform"; } - - static std::string FunctionName() { - return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); - } - static std::string FormatArgs(const distribution_t& d) { - return absl::StrCat("absl::IntervalClosedClosed, ", (d.min)(), ", ", - (d.max)()); - } - static std::string FormatResults(absl::Span results) { - return absl::StrJoin(results, ", "); - } -}; - -template -struct DistributionFormatTraits> { - using distribution_t = absl::uniform_real_distribution; - using result_t = typename distribution_t::result_type; - - static constexpr const char* Name() { return "Uniform"; } - - static std::string FunctionName() { - return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); - } - static std::string FormatArgs(const distribution_t& d) { - return absl::StrCat((d.min)(), ", ", (d.max)()); - } - static std::string FormatResults(absl::Span results) { - return absl::StrJoin(results, ", "); - } -}; - -template -struct DistributionFormatTraits> { - using distribution_t = absl::exponential_distribution; - using result_t = typename distribution_t::result_type; - - static constexpr const char* Name() { return "Exponential"; } - - static std::string FunctionName() { - return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); - } - static std::string FormatArgs(const distribution_t& d) { - return absl::StrCat(d.lambda()); - } - static std::string FormatResults(absl::Span results) { - return absl::StrJoin(results, ", "); - } -}; - -template -struct DistributionFormatTraits> { - using distribution_t = absl::poisson_distribution; - using result_t = typename distribution_t::result_type; - - static constexpr const char* Name() { return "Poisson"; } - - static std::string FunctionName() { - return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); - } - static std::string FormatArgs(const distribution_t& d) { - return absl::StrCat(d.mean()); - } - static std::string FormatResults(absl::Span results) { - return absl::StrJoin(results, ", "); - } -}; - -template <> -struct DistributionFormatTraits { - using distribution_t = absl::bernoulli_distribution; - using result_t = typename distribution_t::result_type; - - static constexpr const char* Name() { return "Bernoulli"; } - - static constexpr const char* FunctionName() { return Name(); } - static std::string FormatArgs(const distribution_t& d) { - return absl::StrCat(d.p()); - } - static std::string FormatResults(absl::Span results) { - return absl::StrJoin(results, ", "); - } -}; - -template -struct DistributionFormatTraits> { - using distribution_t = absl::beta_distribution; - using result_t = typename distribution_t::result_type; - - static constexpr const char* Name() { return "Beta"; } - - static std::string FunctionName() { - return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); - } - static std::string FormatArgs(const distribution_t& d) { - return absl::StrCat(d.alpha(), ", ", d.beta()); - } - static std::string FormatResults(absl::Span results) { - return absl::StrJoin(results, ", "); - } -}; - -template -struct DistributionFormatTraits> { - using distribution_t = absl::zipf_distribution; - using result_t = typename distribution_t::result_type; - - static constexpr const char* Name() { return "Zipf"; } - - static std::string FunctionName() { - return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); - } - static std::string FormatArgs(const distribution_t& d) { - return absl::StrCat(d.k(), ", ", d.v(), ", ", d.q()); - } - static std::string FormatResults(absl::Span results) { - return absl::StrJoin(results, ", "); - } -}; - -template -struct DistributionFormatTraits> { - using distribution_t = absl::gaussian_distribution; - using result_t = typename distribution_t::result_type; - - static constexpr const char* Name() { return "Gaussian"; } - - static std::string FunctionName() { - return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); - } - static std::string FormatArgs(const distribution_t& d) { - return absl::StrJoin(std::make_tuple(d.mean(), d.stddev()), ", "); - } - static std::string FormatResults(absl::Span results) { - return absl::StrJoin(results, ", "); - } -}; - -template -struct DistributionFormatTraits> { - using distribution_t = absl::log_uniform_int_distribution; - using result_t = typename distribution_t::result_type; - - static constexpr const char* Name() { return "LogUniform"; } - - static std::string FunctionName() { - return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); - } - static std::string FormatArgs(const distribution_t& d) { - return absl::StrJoin(std::make_tuple((d.min)(), (d.max)(), d.base()), ", "); - } - static std::string FormatResults(absl::Span results) { - return absl::StrJoin(results, ", "); - } -}; - -template -struct UniformDistributionWrapper; - -template -struct DistributionFormatTraits> { - using distribution_t = UniformDistributionWrapper; - using result_t = NumType; - - static constexpr const char* Name() { return "Uniform"; } - - static std::string FunctionName() { - return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); - } - static std::string FormatArgs(const distribution_t& d) { - return absl::StrCat((d.min)(), ", ", (d.max)()); - } - static std::string FormatResults(absl::Span results) { - return absl::StrJoin(results, ", "); - } -}; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_DISTRIBUTION_FORMAT_TRAITS_H_ diff --git a/absl/random/distributions.h b/absl/random/distributions.h index d026d92b..8680f6a6 100644 --- a/absl/random/distributions.h +++ b/absl/random/distributions.h @@ -55,7 +55,6 @@ #include "absl/base/internal/inline_variable.h" #include "absl/random/bernoulli_distribution.h" #include "absl/random/beta_distribution.h" -#include "absl/random/distribution_format_traits.h" #include "absl/random/exponential_distribution.h" #include "absl/random/gaussian_distribution.h" #include "absl/random/internal/distributions.h" // IWYU pragma: export @@ -126,14 +125,13 @@ Uniform(TagType tag, R lo, R hi) { using gen_t = absl::decay_t; using distribution_t = random_internal::UniformDistributionWrapper; - using format_t = random_internal::DistributionFormatTraits; auto a = random_internal::uniform_lower_bound(tag, lo, hi); auto b = random_internal::uniform_upper_bound(tag, lo, hi); if (a > b) return a; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, tag, lo, hi); + distribution_t>(&urbg, tag, lo, hi); } // absl::Uniform(bitgen, lo, hi) @@ -146,7 +144,6 @@ Uniform(URBG&& urbg, // NOLINT(runtime/references) R lo, R hi) { using gen_t = absl::decay_t; using distribution_t = random_internal::UniformDistributionWrapper; - using format_t = random_internal::DistributionFormatTraits; constexpr auto tag = absl::IntervalClosedOpen; auto a = random_internal::uniform_lower_bound(tag, lo, hi); @@ -154,7 +151,7 @@ Uniform(URBG&& urbg, // NOLINT(runtime/references) if (a > b) return a; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, lo, hi); + distribution_t>(&urbg, lo, hi); } // absl::Uniform(tag, bitgen, lo, hi) @@ -172,14 +169,13 @@ Uniform(TagType tag, using gen_t = absl::decay_t; using return_t = typename random_internal::uniform_inferred_return_t; using distribution_t = random_internal::UniformDistributionWrapper; - using format_t = random_internal::DistributionFormatTraits; auto a = random_internal::uniform_lower_bound(tag, lo, hi); auto b = random_internal::uniform_upper_bound(tag, lo, hi); if (a > b) return a; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, tag, static_cast(lo), + distribution_t>(&urbg, tag, static_cast(lo), static_cast(hi)); } @@ -196,7 +192,6 @@ Uniform(URBG&& urbg, // NOLINT(runtime/references) using gen_t = absl::decay_t; using return_t = typename random_internal::uniform_inferred_return_t; using distribution_t = random_internal::UniformDistributionWrapper; - using format_t = random_internal::DistributionFormatTraits; constexpr auto tag = absl::IntervalClosedOpen; auto a = random_internal::uniform_lower_bound(tag, lo, hi); @@ -204,7 +199,7 @@ Uniform(URBG&& urbg, // NOLINT(runtime/references) if (a > b) return a; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, static_cast(lo), + distribution_t>(&urbg, static_cast(lo), static_cast(hi)); } @@ -217,10 +212,9 @@ typename absl::enable_if_t::value, R> // Uniform(URBG&& urbg) { // NOLINT(runtime/references) using gen_t = absl::decay_t; using distribution_t = random_internal::UniformDistributionWrapper; - using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg); + distribution_t>(&urbg); } // ----------------------------------------------------------------------------- @@ -248,10 +242,9 @@ bool Bernoulli(URBG&& urbg, // NOLINT(runtime/references) double p) { using gen_t = absl::decay_t; using distribution_t = absl::bernoulli_distribution; - using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, p); + distribution_t>(&urbg, p); } // ----------------------------------------------------------------------------- @@ -281,10 +274,9 @@ RealType Beta(URBG&& urbg, // NOLINT(runtime/references) using gen_t = absl::decay_t; using distribution_t = typename absl::beta_distribution; - using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, alpha, beta); + distribution_t>(&urbg, alpha, beta); } // ----------------------------------------------------------------------------- @@ -314,10 +306,9 @@ RealType Exponential(URBG&& urbg, // NOLINT(runtime/references) using gen_t = absl::decay_t; using distribution_t = typename absl::exponential_distribution; - using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, lambda); + distribution_t>(&urbg, lambda); } // ----------------------------------------------------------------------------- @@ -346,10 +337,9 @@ RealType Gaussian(URBG&& urbg, // NOLINT(runtime/references) using gen_t = absl::decay_t; using distribution_t = typename absl::gaussian_distribution; - using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, mean, stddev); + distribution_t>(&urbg, mean, stddev); } // ----------------------------------------------------------------------------- @@ -389,10 +379,9 @@ IntType LogUniform(URBG&& urbg, // NOLINT(runtime/references) using gen_t = absl::decay_t; using distribution_t = typename absl::log_uniform_int_distribution; - using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, lo, hi, base); + distribution_t>(&urbg, lo, hi, base); } // ----------------------------------------------------------------------------- @@ -420,10 +409,9 @@ IntType Poisson(URBG&& urbg, // NOLINT(runtime/references) using gen_t = absl::decay_t; using distribution_t = typename absl::poisson_distribution; - using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, mean); + distribution_t>(&urbg, mean); } // ----------------------------------------------------------------------------- @@ -453,10 +441,9 @@ IntType Zipf(URBG&& urbg, // NOLINT(runtime/references) using gen_t = absl::decay_t; using distribution_t = typename absl::zipf_distribution; - using format_t = random_internal::DistributionFormatTraits; return random_internal::DistributionCaller::template Call< - distribution_t, format_t>(&urbg, hi, q, v); + distribution_t>(&urbg, hi, q, v); } ABSL_NAMESPACE_END diff --git a/absl/random/internal/distribution_caller.h b/absl/random/internal/distribution_caller.h index 02603cf8..4e072444 100644 --- a/absl/random/internal/distribution_caller.h +++ b/absl/random/internal/distribution_caller.h @@ -33,20 +33,7 @@ struct DistributionCaller { // Call the provided distribution type. The parameters are expected // to be explicitly specified. // DistrT is the distribution type. - // FormatT is the formatter type: - // - // struct FormatT { - // using result_type = distribution_t::result_type; - // static std::string FormatCall( - // const distribution_t& distr, - // absl::Span); - // - // static std::string FormatExpectation( - // absl::string_view match_args, - // absl::Span results); - // } - // - template + template static typename DistrT::result_type Call(URBG* urbg, Args&&... args) { DistrT dist(std::forward(args)...); return dist(*urbg); diff --git a/absl/random/internal/mocking_bit_gen_base.h b/absl/random/internal/mocking_bit_gen_base.h index eeeae9d2..23ecaf6c 100644 --- a/absl/random/internal/mocking_bit_gen_base.h +++ b/absl/random/internal/mocking_bit_gen_base.h @@ -16,8 +16,6 @@ #ifndef ABSL_RANDOM_INTERNAL_MOCKING_BIT_GEN_BASE_H_ #define ABSL_RANDOM_INTERNAL_MOCKING_BIT_GEN_BASE_H_ -#include -#include #include #include @@ -28,27 +26,6 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace random_internal { -// MockingBitGenExpectationFormatter is invoked to format unsatisfied mocks -// and remaining results into a description string. -template -struct MockingBitGenExpectationFormatter { - std::string operator()(absl::string_view args) { - return absl::StrCat(FormatT::FunctionName(), "(", args, ")"); - } -}; - -// MockingBitGenCallFormatter is invoked to format each distribution call -// into a description string for the mock log. -template -struct MockingBitGenCallFormatter { - std::string operator()(const DistrT& dist, - const typename DistrT::result_type& result) { - return absl::StrCat( - FormatT::FunctionName(), "(", FormatT::FormatArgs(dist), ") => {", - FormatT::FormatResults(absl::MakeSpan(&result, 1)), "}"); - } -}; - class MockingBitGenBase { template friend struct DistributionCaller; @@ -61,14 +38,9 @@ class MockingBitGenBase { static constexpr result_type(max)() { return (generator_type::max)(); } result_type operator()() { return gen_(); } - MockingBitGenBase() : gen_(), observed_call_log_() {} virtual ~MockingBitGenBase() = default; protected: - const std::deque& observed_call_log() { - return observed_call_log_; - } - // CallImpl is the type-erased virtual dispatch. // The type of dist is always distribution, // The type of result is always distribution::result_type. @@ -81,10 +53,9 @@ class MockingBitGenBase { } // Call the generating distribution function. - // Invoked by DistributionCaller<>::Call. + // Invoked by DistributionCaller<>::Call. // DistT is the distribution type. - // FormatT is the distribution formatter traits type. - template + template typename DistrT::result_type Call(Args&&... args) { using distr_result_type = typename DistrT::result_type; using ArgTupleT = std::tuple...>; @@ -100,17 +71,11 @@ class MockingBitGenBase { result = dist(gen_); } - // TODO(asoffer): Forwarding the args through means we no longer need to - // extract them from the from the distribution in formatter traits. We can - // just StrJoin them. - observed_call_log_.push_back( - MockingBitGenCallFormatter{}(dist, result)); return result; } private: generator_type gen_; - std::deque observed_call_log_; }; // namespace random_internal } // namespace random_internal diff --git a/absl/random/mocking_bit_gen.cc b/absl/random/mocking_bit_gen.cc deleted file mode 100644 index 6bb1e414..00000000 --- a/absl/random/mocking_bit_gen.cc +++ /dev/null @@ -1,30 +0,0 @@ -// -// Copyright 2018 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#include "absl/random/mocking_bit_gen.h" - -#include - -namespace absl { -ABSL_NAMESPACE_BEGIN -MockingBitGen::~MockingBitGen() { - - for (const auto& del : deleters_) { - del(); - } -} - -ABSL_NAMESPACE_END -} // namespace absl diff --git a/absl/random/mocking_bit_gen.h b/absl/random/mocking_bit_gen.h index 36cef911..3d8a979e 100644 --- a/absl/random/mocking_bit_gen.h +++ b/absl/random/mocking_bit_gen.h @@ -100,7 +100,9 @@ class MockingBitGen : public absl::random_internal::MockingBitGenBase { public: MockingBitGen() {} - ~MockingBitGen() override; + ~MockingBitGen() override { + for (const auto& del : deleters_) del(); + } private: template @@ -182,10 +184,10 @@ namespace random_internal { template <> struct DistributionCaller { - template + template static typename DistrT::result_type Call(absl::MockingBitGen* gen, Args&&... args) { - return gen->template Call(std::forward(args)...); + return gen->template Call(std::forward(args)...); } }; diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel index e72db82c..64f55fb4 100644 --- a/absl/strings/BUILD.bazel +++ b/absl/strings/BUILD.bazel @@ -485,6 +485,7 @@ cc_test( copts = ABSL_TEST_COPTS, visibility = ["//visibility:private"], deps = [ + ":internal", ":pow10_helper", ":strings", "//absl/base:config", diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt index 668d722b..c7874ecf 100644 --- a/absl/strings/CMakeLists.txt +++ b/absl/strings/CMakeLists.txt @@ -284,6 +284,7 @@ absl_cc_test( absl::raw_logging_internal absl::random_random absl::random_distributions + absl::strings_internal gmock_main ) diff --git a/absl/strings/internal/str_format/arg.cc b/absl/strings/internal/str_format/arg.cc index 4d0604e0..3aa0296b 100644 --- a/absl/strings/internal/str_format/arg.cc +++ b/absl/strings/internal/str_format/arg.cc @@ -120,24 +120,25 @@ class ConvertedIntInfo { // the '#' flag is specified to modify the precision for 'o' conversions. string_view BaseIndicator(const ConvertedIntInfo &info, const ConversionSpec conv) { - bool alt = conv.flags().alt; - int radix = FormatConversionCharRadix(conv.conv()); - if (conv.conv() == ConversionChar::p) alt = true; // always show 0x for %p. + bool alt = conv.has_alt_flag(); + int radix = FormatConversionCharRadix(conv.conversion_char()); + if (conv.conversion_char() == ConversionChar::p) + alt = true; // always show 0x for %p. // From the POSIX description of '#' flag: // "For x or X conversion specifiers, a non-zero result shall have // 0x (or 0X) prefixed to it." if (alt && radix == 16 && !info.digits().empty()) { - if (FormatConversionCharIsUpper(conv.conv())) return "0X"; + if (FormatConversionCharIsUpper(conv.conversion_char())) return "0X"; return "0x"; } return {}; } string_view SignColumn(bool neg, const ConversionSpec conv) { - if (FormatConversionCharIsSigned(conv.conv())) { + if (FormatConversionCharIsSigned(conv.conversion_char())) { if (neg) return "-"; - if (conv.flags().show_pos) return "+"; - if (conv.flags().sign_col) return " "; + if (conv.has_show_pos_flag()) return "+"; + if (conv.has_sign_col_flag()) return " "; } return {}; } @@ -147,9 +148,9 @@ bool ConvertCharImpl(unsigned char v, const ConversionSpec conv, size_t fill = 0; if (conv.width() >= 0) fill = conv.width(); ReducePadding(1, &fill); - if (!conv.flags().left) sink->Append(fill, ' '); + if (!conv.has_left_flag()) sink->Append(fill, ' '); sink->Append(1, v); - if (conv.flags().left) sink->Append(fill, ' '); + if (conv.has_left_flag()) sink->Append(fill, ' '); return true; } @@ -174,7 +175,7 @@ bool ConvertIntImplInner(const ConvertedIntInfo &info, if (!precision_specified) precision = 1; - if (conv.flags().alt && conv.conv() == ConversionChar::o) { + if (conv.has_alt_flag() && conv.conversion_char() == ConversionChar::o) { // From POSIX description of the '#' (alt) flag: // "For o conversion, it increases the precision (if necessary) to // force the first digit of the result to be zero." @@ -187,13 +188,13 @@ bool ConvertIntImplInner(const ConvertedIntInfo &info, size_t num_zeroes = Excess(formatted.size(), precision); ReducePadding(num_zeroes, &fill); - size_t num_left_spaces = !conv.flags().left ? fill : 0; - size_t num_right_spaces = conv.flags().left ? fill : 0; + size_t num_left_spaces = !conv.has_left_flag() ? fill : 0; + size_t num_right_spaces = conv.has_left_flag() ? fill : 0; // From POSIX description of the '0' (zero) flag: // "For d, i, o, u, x, and X conversion specifiers, if a precision // is specified, the '0' flag is ignored." - if (!precision_specified && conv.flags().zero) { + if (!precision_specified && conv.has_zero_flag()) { num_zeroes += num_left_spaces; num_left_spaces = 0; } @@ -209,8 +210,8 @@ bool ConvertIntImplInner(const ConvertedIntInfo &info, template bool ConvertIntImplInner(T v, const ConversionSpec conv, FormatSinkImpl *sink) { - ConvertedIntInfo info(v, conv.conv()); - if (conv.flags().basic && (conv.conv() != ConversionChar::p)) { + ConvertedIntInfo info(v, conv.conversion_char()); + if (conv.is_basic() && (conv.conversion_char() != ConversionChar::p)) { if (info.is_neg()) sink->Append(1, '-'); if (info.digits().empty()) { sink->Append(1, '0'); @@ -224,13 +225,14 @@ bool ConvertIntImplInner(T v, const ConversionSpec conv, FormatSinkImpl *sink) { template bool ConvertIntArg(T v, const ConversionSpec conv, FormatSinkImpl *sink) { - if (FormatConversionCharIsFloat(conv.conv())) { + if (FormatConversionCharIsFloat(conv.conversion_char())) { return FormatConvertImpl(static_cast(v), conv, sink).value; } - if (conv.conv() == ConversionChar::c) + if (conv.conversion_char() == ConversionChar::c) return ConvertCharImpl(static_cast(v), conv, sink); - if (!FormatConversionCharIsIntegral(conv.conv())) return false; - if (!FormatConversionCharIsSigned(conv.conv()) && IsSigned::value) { + if (!FormatConversionCharIsIntegral(conv.conversion_char())) return false; + if (!FormatConversionCharIsSigned(conv.conversion_char()) && + IsSigned::value) { using U = typename MakeUnsigned::type; return FormatConvertImpl(static_cast(v), conv, sink).value; } @@ -239,19 +241,19 @@ bool ConvertIntArg(T v, const ConversionSpec conv, FormatSinkImpl *sink) { template bool ConvertFloatArg(T v, const ConversionSpec conv, FormatSinkImpl *sink) { - return FormatConversionCharIsFloat(conv.conv()) && + return FormatConversionCharIsFloat(conv.conversion_char()) && ConvertFloatImpl(v, conv, sink); } inline bool ConvertStringArg(string_view v, const ConversionSpec conv, FormatSinkImpl *sink) { - if (conv.conv() != ConversionChar::s) return false; - if (conv.flags().basic) { + if (conv.conversion_char() != ConversionChar::s) return false; + if (conv.is_basic()) { sink->Append(v); return true; } return sink->PutPaddedString(v, conv.width(), conv.precision(), - conv.flags().left); + conv.has_left_flag()); } } // namespace @@ -272,7 +274,7 @@ ConvertResult FormatConvertImpl(string_view v, ConvertResult FormatConvertImpl(const char *v, const ConversionSpec conv, FormatSinkImpl *sink) { - if (conv.conv() == ConversionChar::p) + if (conv.conversion_char() == ConversionChar::p) return {FormatConvertImpl(VoidPtr(v), conv, sink).value}; size_t len; if (v == nullptr) { @@ -289,7 +291,7 @@ ConvertResult FormatConvertImpl(const char *v, // ==================== Raw pointers ==================== ConvertResult FormatConvertImpl(VoidPtr v, const ConversionSpec conv, FormatSinkImpl *sink) { - if (conv.conv() != ConversionChar::p) return {false}; + if (conv.conversion_char() != ConversionChar::p) return {false}; if (!v.value) { sink->Append("(nil)"); return {true}; diff --git a/absl/strings/internal/str_format/arg.h b/absl/strings/internal/str_format/arg.h index 7a937563..1c36e309 100644 --- a/absl/strings/internal/str_format/arg.h +++ b/absl/strings/internal/str_format/arg.h @@ -70,9 +70,11 @@ template FormatConvertImpl(const AbslCord& value, ConversionSpec conv, FormatSinkImpl* sink) { - if (conv.conv() != ConversionChar::s) return {false}; + if (conv.conversion_char() != ConversionChar::s) { + return {false}; + } - bool is_left = conv.flags().left; + bool is_left = conv.has_left_flag(); size_t space_remaining = 0; int width = conv.width(); @@ -106,8 +108,8 @@ ConvertResult FormatConvertImpl(const AbslCord& value, } using IntegralConvertResult = - ConvertResult; -using FloatingConvertResult = ConvertResult; + ConvertResult; +using FloatingConvertResult = ConvertResult; // Floats. FloatingConvertResult FormatConvertImpl(float v, ConversionSpec conv, @@ -185,7 +187,9 @@ struct FormatCountCaptureHelper { FormatSinkImpl* sink) { const absl::enable_if_t& v2 = v; - if (conv.conv() != str_format_internal::ConversionChar::n) return {false}; + if (conv.conversion_char() != str_format_internal::ConversionChar::n) { + return {false}; + } *v2.p_ = static_cast(sink->size()); return {true}; } @@ -377,7 +381,7 @@ class FormatArgImpl { template static bool Dispatch(Data arg, ConversionSpec spec, void* out) { // A `none` conv indicates that we want the `int` conversion. - if (ABSL_PREDICT_FALSE(spec.conv() == ConversionChar::none)) { + if (ABSL_PREDICT_FALSE(spec.conversion_char() == ConversionChar::kNone)) { return ToInt(arg, static_cast(out), std::is_integral(), std::is_enum()); } diff --git a/absl/strings/internal/str_format/bind.cc b/absl/strings/internal/str_format/bind.cc index 27522fdb..6980ed1d 100644 --- a/absl/strings/internal/str_format/bind.cc +++ b/absl/strings/internal/str_format/bind.cc @@ -147,7 +147,7 @@ class SummarizingConverter { << FormatConversionSpecImplFriend::FlagsToString(bound); if (bound.width() >= 0) ss << bound.width(); if (bound.precision() >= 0) ss << "." << bound.precision(); - ss << bound.conv() << "}"; + ss << bound.conversion_char() << "}"; Append(ss.str()); return true; } diff --git a/absl/strings/internal/str_format/checker_test.cc b/absl/strings/internal/str_format/checker_test.cc index ea2a7681..49a24b40 100644 --- a/absl/strings/internal/str_format/checker_test.cc +++ b/absl/strings/internal/str_format/checker_test.cc @@ -9,13 +9,17 @@ ABSL_NAMESPACE_BEGIN namespace str_format_internal { namespace { -std::string ConvToString(Conv conv) { +std::string ConvToString(FormatConversionCharSet conv) { std::string out; #define CONV_SET_CASE(c) \ - if (Contains(conv, Conv::c)) out += #c; + if (Contains(conv, FormatConversionCharSet::c)) { \ + out += #c; \ + } ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(CONV_SET_CASE, ) #undef CONV_SET_CASE - if (Contains(conv, Conv::star)) out += "*"; + if (Contains(conv, FormatConversionCharSet::kStar)) { + out += "*"; + } return out; } diff --git a/absl/strings/internal/str_format/float_conversion.cc b/absl/strings/internal/str_format/float_conversion.cc index d4c647c3..d5a1ee40 100644 --- a/absl/strings/internal/str_format/float_conversion.cc +++ b/absl/strings/internal/str_format/float_conversion.cc @@ -33,7 +33,7 @@ bool FallbackToSnprintf(const Float v, const ConversionSpec &conv, if (std::is_same()) { *fp++ = 'L'; } - *fp++ = FormatConversionCharToChar(conv.conv()); + *fp++ = FormatConversionCharToChar(conv.conversion_char()); *fp = 0; assert(fp < fmt + sizeof(fmt)); } @@ -100,17 +100,19 @@ bool ConvertNonNumericFloats(char sign_char, Float v, char text[4], *ptr = text; if (sign_char) *ptr++ = sign_char; if (std::isnan(v)) { - ptr = std::copy_n(FormatConversionCharIsUpper(conv.conv()) ? "NAN" : "nan", - 3, ptr); + ptr = std::copy_n( + FormatConversionCharIsUpper(conv.conversion_char()) ? "NAN" : "nan", 3, + ptr); } else if (std::isinf(v)) { - ptr = std::copy_n(FormatConversionCharIsUpper(conv.conv()) ? "INF" : "inf", - 3, ptr); + ptr = std::copy_n( + FormatConversionCharIsUpper(conv.conversion_char()) ? "INF" : "inf", 3, + ptr); } else { return false; } return sink->PutPaddedString(string_view(text, ptr - text), conv.width(), -1, - conv.flags().left); + conv.has_left_flag()); } // Round up the last digit of the value. @@ -358,9 +360,9 @@ void WriteBufferToSink(char sign_char, string_view str, static_cast(sign_char != 0), 0) : 0; - if (conv.flags().left) { + if (conv.has_left_flag()) { right_spaces = missing_chars; - } else if (conv.flags().zero) { + } else if (conv.has_zero_flag()) { zeros = missing_chars; } else { left_spaces = missing_chars; @@ -382,9 +384,9 @@ bool FloatToSink(const Float v, const ConversionSpec &conv, if (std::signbit(abs_v)) { sign_char = '-'; abs_v = -abs_v; - } else if (conv.flags().show_pos) { + } else if (conv.has_show_pos_flag()) { sign_char = '+'; - } else if (conv.flags().sign_col) { + } else if (conv.has_sign_col_flag()) { sign_char = ' '; } @@ -401,14 +403,14 @@ bool FloatToSink(const Float v, const ConversionSpec &conv, Buffer buffer; - switch (conv.conv()) { + switch (conv.conversion_char()) { case ConversionChar::f: case ConversionChar::F: if (!FloatToBuffer(decomposed, precision, &buffer, nullptr)) { return FallbackToSnprintf(v, conv, sink); } - if (!conv.flags().alt && buffer.back() == '.') buffer.pop_back(); + if (!conv.has_alt_flag() && buffer.back() == '.') buffer.pop_back(); break; case ConversionChar::e: @@ -417,9 +419,10 @@ bool FloatToSink(const Float v, const ConversionSpec &conv, &exp)) { return FallbackToSnprintf(v, conv, sink); } - if (!conv.flags().alt && buffer.back() == '.') buffer.pop_back(); - PrintExponent(exp, FormatConversionCharIsUpper(conv.conv()) ? 'E' : 'e', - &buffer); + if (!conv.has_alt_flag() && buffer.back() == '.') buffer.pop_back(); + PrintExponent( + exp, FormatConversionCharIsUpper(conv.conversion_char()) ? 'E' : 'e', + &buffer); break; case ConversionChar::g: @@ -446,13 +449,15 @@ bool FloatToSink(const Float v, const ConversionSpec &conv, } exp = 0; } - if (!conv.flags().alt) { + if (!conv.has_alt_flag()) { while (buffer.back() == '0') buffer.pop_back(); if (buffer.back() == '.') buffer.pop_back(); } if (exp) { - PrintExponent(exp, FormatConversionCharIsUpper(conv.conv()) ? 'E' : 'e', - &buffer); + PrintExponent( + exp, + FormatConversionCharIsUpper(conv.conversion_char()) ? 'E' : 'e', + &buffer); } break; diff --git a/absl/strings/internal/str_format/parser_test.cc b/absl/strings/internal/str_format/parser_test.cc index 1b1ee030..51eb53f5 100644 --- a/absl/strings/internal/str_format/parser_test.cc +++ b/absl/strings/internal/str_format/parser_test.cc @@ -52,7 +52,7 @@ TEST(ConversionCharTest, Names) { X(f), X(F), X(e), X(E), X(g), X(G), X(a), X(A), // float X(n), X(p), // misc #undef X - {ConversionChar::none, '\0'}, + {ConversionChar::kNone, '\0'}, }; // clang-format on for (auto e : kExpect) { diff --git a/absl/strings/numbers_test.cc b/absl/strings/numbers_test.cc index bd4e1162..7db85e75 100644 --- a/absl/strings/numbers_test.cc +++ b/absl/strings/numbers_test.cc @@ -40,6 +40,7 @@ #include "absl/random/distributions.h" #include "absl/random/random.h" #include "absl/strings/internal/numbers_test_common.h" +#include "absl/strings/internal/ostringstream.h" #include "absl/strings/internal/pow10_helper.h" #include "absl/strings/str_cat.h" diff --git a/absl/strings/str_format_test.cc b/absl/strings/str_format_test.cc index 554dca72..f0d1f0ad 100644 --- a/absl/strings/str_format_test.cc +++ b/absl/strings/str_format_test.cc @@ -540,19 +540,19 @@ TEST_F(ParsedFormatTest, UncheckedCorrect) { EXPECT_EQ("[ABC]{d:1$d}[DEF]", SummarizeParsedFormat(*f)); std::string format = "%sFFF%dZZZ%f"; - auto f2 = - ExtendedParsedFormat::New(format); + auto f2 = ExtendedParsedFormat::New( + format); ASSERT_TRUE(f2); EXPECT_EQ("{s:1$s}[FFF]{d:2$d}[ZZZ]{f:3$f}", SummarizeParsedFormat(*f2)); - f2 = ExtendedParsedFormat::New( + f2 = ExtendedParsedFormat::New( "%s %d %f"); ASSERT_TRUE(f2); EXPECT_EQ("{s:1$s}[ ]{d:2$d}[ ]{f:3$f}", SummarizeParsedFormat(*f2)); - auto star = ExtendedParsedFormat::New("%*d"); + auto star = ExtendedParsedFormat::New("%*d"); ASSERT_TRUE(star); EXPECT_EQ("{*d:2$1$*d}", SummarizeParsedFormat(*star)); -- cgit v1.2.3 From 768eb2ca2857342673fcd462792ce04b8bac3fa3 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 18 May 2020 17:53:14 -0700 Subject: Export of internal Abseil changes -- f012012ef78234a6a4585321b67d7b7c92ebc266 by Laramie Leavitt : Slight restructuring of absl/random/internal randen implementation. Convert round-keys.inc into randen_round_keys.cc file. Consistently use a 128-bit pointer type for internal method parameters. This allows simpler pointer arithmetic in C++ & permits removal of some constants and casts. Remove some redundancy in comments & constexpr variables. Specifically, all references to Randen algorithm parameters use RandenTraits; duplication in RandenSlow removed. PiperOrigin-RevId: 312190313 -- dc8b42e054046741e9ed65335bfdface997c6063 by Abseil Team : Internal change. PiperOrigin-RevId: 312167304 -- f13d248fafaf206492c1362c3574031aea3abaf7 by Matthew Brown : Cleanup StrFormat extensions a little. PiperOrigin-RevId: 312166336 -- 9d9117589667afe2332bb7ad42bc967ca7c54502 by Derek Mauro : Internal change PiperOrigin-RevId: 312105213 -- 9a12b9b3aa0e59b8ee6cf9408ed0029045543a9b by Abseil Team : Complete IGNORE_TYPE macro renaming. PiperOrigin-RevId: 311999699 -- 64756f20d61021d999bd0d4c15e9ad3857382f57 by Gennadiy Rozental : Switch to fixed bytes specific default value. This fixes the Abseil Flags for big endian platforms. PiperOrigin-RevId: 311844448 -- bdbe6b5b29791dbc3816ada1828458b3010ff1e9 by Laramie Leavitt : Change many distribution tests to use pcg_engine as a deterministic source of entropy. It's reasonable to test that the BitGen itself has good entropy, however when testing the cross product of all random distributions x all the architecture variations x all submitted changes results in a large number of tests. In order to account for these failures while still using good entropy requires that our allowed sigma need to account for all of these independent tests. Our current sigma values are too restrictive, and we see a lot of failures, so we have to either relax the sigma values or convert some of the statistical tests to use deterministic values. This changelist does the latter. PiperOrigin-RevId: 311840096 GitOrigin-RevId: f012012ef78234a6a4585321b67d7b7c92ebc266 Change-Id: Ic84886f38ff30d7d72c126e9b63c9a61eb729a1a --- CMake/AbseilDll.cmake | 1 + absl/flags/config.h | 20 + absl/flags/flag_test.cc | 4 +- absl/flags/internal/commandlineflag.h | 17 - absl/flags/internal/flag.cc | 36 +- absl/flags/internal/flag.h | 37 +- absl/flags/parse.cc | 6 +- absl/random/BUILD.bazel | 10 +- absl/random/CMakeLists.txt | 13 +- absl/random/bernoulli_distribution_test.cc | 6 +- absl/random/beta_distribution_test.cc | 17 +- absl/random/discrete_distribution_test.cc | 6 +- absl/random/exponential_distribution_test.cc | 6 +- absl/random/gaussian_distribution_test.cc | 5 +- absl/random/internal/BUILD.bazel | 5 +- absl/random/internal/randen-keys.inc | 207 ---------- absl/random/internal/randen_hwaes.cc | 398 ++++++++----------- absl/random/internal/randen_hwaes_test.cc | 12 +- absl/random/internal/randen_round_keys.cc | 462 +++++++++++++++++++++++ absl/random/internal/randen_slow.cc | 197 ++++------ absl/random/internal/randen_slow.h | 7 - absl/random/internal/randen_slow_test.cc | 8 +- absl/random/internal/randen_traits.h | 31 +- absl/random/log_uniform_int_distribution_test.cc | 7 +- absl/random/poisson_distribution_test.cc | 12 +- absl/random/uniform_int_distribution_test.cc | 13 +- absl/random/uniform_real_distribution_test.cc | 13 +- absl/random/zipf_distribution_test.cc | 6 +- absl/strings/internal/str_format/arg.cc | 36 +- absl/strings/internal/str_format/arg.h | 2 + absl/strings/internal/str_format/arg_test.cc | 4 +- absl/strings/internal/str_format/checker_test.cc | 8 +- absl/strings/internal/str_format/extension.cc | 15 +- absl/strings/internal/str_format/extension.h | 80 +--- absl/strings/str_format.h | 4 - absl/strings/str_format_test.cc | 97 ++--- 36 files changed, 974 insertions(+), 834 deletions(-) delete mode 100644 absl/random/internal/randen-keys.inc create mode 100644 absl/random/internal/randen_round_keys.cc (limited to 'absl/random/CMakeLists.txt') diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake index d342959b..a5c9bc0d 100644 --- a/CMake/AbseilDll.cmake +++ b/CMake/AbseilDll.cmake @@ -147,6 +147,7 @@ set(ABSL_INTERNAL_DLL_FILES "random/internal/platform.h" "random/internal/pool_urbg.cc" "random/internal/pool_urbg.h" + "random/internal/randen_round_keys.cc" "random/internal/randen.cc" "random/internal/randen.h" "random/internal/randen_detect.cc" diff --git a/absl/flags/config.h b/absl/flags/config.h index 001f8fea..813a9257 100644 --- a/absl/flags/config.h +++ b/absl/flags/config.h @@ -64,4 +64,24 @@ #define ABSL_FLAGS_INTERNAL_HAS_RTTI 1 #endif // !defined(__GNUC__) || defined(__GXX_RTTI) +// These macros represent the "source of truth" for the list of supported +// built-in types. +#define ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(A) \ + A(bool, bool) \ + A(short, short) \ + A(unsigned short, unsigned_short) \ + A(int, int) \ + A(unsigned int, unsigned_int) \ + A(long, long) \ + A(unsigned long, unsigned_long) \ + A(long long, long_long) \ + A(unsigned long long, unsigned_long_long) \ + A(double, double) \ + A(float, float) + +#define ABSL_FLAGS_INTERNAL_SUPPORTED_TYPES(A) \ + ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(A) \ + A(std::string, std_string) \ + A(std::vector, std_vector_of_string) + #endif // ABSL_FLAGS_CONFIG_H_ diff --git a/absl/flags/flag_test.cc b/absl/flags/flag_test.cc index 015b1fc9..416a31e5 100644 --- a/absl/flags/flag_test.cc +++ b/absl/flags/flag_test.cc @@ -145,8 +145,8 @@ DEFINE_CONSTRUCTED_FLAG(int32_t, 3, kOneWord); DEFINE_CONSTRUCTED_FLAG(uint32_t, 4, kOneWord); DEFINE_CONSTRUCTED_FLAG(int64_t, 5, kOneWord); DEFINE_CONSTRUCTED_FLAG(uint64_t, 6, kOneWord); -DEFINE_CONSTRUCTED_FLAG(float, 7.8, kFloat); -DEFINE_CONSTRUCTED_FLAG(double, 9.10, kDouble); +DEFINE_CONSTRUCTED_FLAG(float, 7.8, kOneWord); +DEFINE_CONSTRUCTED_FLAG(double, 9.10, kOneWord); DEFINE_CONSTRUCTED_FLAG(String, &TestMakeDflt, kGenFunc); DEFINE_CONSTRUCTED_FLAG(UDT, &TestMakeDflt, kGenFunc); diff --git a/absl/flags/internal/commandlineflag.h b/absl/flags/internal/commandlineflag.h index 0a7197b7..fa050209 100644 --- a/absl/flags/internal/commandlineflag.h +++ b/absl/flags/internal/commandlineflag.h @@ -178,23 +178,6 @@ class CommandLineFlag { virtual void CheckDefaultValueParsingRoundtrip() const = 0; }; -// This macro is the "source of truth" for the list of supported flag built-in -// types. -#define ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(A) \ - A(bool) \ - A(short) \ - A(unsigned short) \ - A(int) \ - A(unsigned int) \ - A(long) \ - A(unsigned long) \ - A(long long) \ - A(unsigned long long) \ - A(double) \ - A(float) \ - A(std::string) \ - A(std::vector) - } // namespace flags_internal ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/flags/internal/flag.cc b/absl/flags/internal/flag.cc index 8f0777fa..96c026dc 100644 --- a/absl/flags/internal/flag.cc +++ b/absl/flags/internal/flag.cc @@ -49,9 +49,9 @@ namespace { // Currently we only validate flag values for user-defined flag types. bool ShouldValidateFlagValue(FlagFastTypeId flag_type_id) { -#define DONT_VALIDATE(T) \ +#define DONT_VALIDATE(T, _) \ if (flag_type_id == base_internal::FastTypeId()) return false; - ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(DONT_VALIDATE) + ABSL_FLAGS_INTERNAL_SUPPORTED_TYPES(DONT_VALIDATE) #undef DONT_VALIDATE return true; @@ -150,23 +150,11 @@ void FlagImpl::Init() { break; case FlagValueStorageKind::kOneWordAtomic: { alignas(int64_t) std::array buf{}; - switch (def_kind) { - case FlagDefaultKind::kOneWord: - std::memcpy(buf.data(), &default_value_.one_word, - sizeof(default_value_.one_word)); - break; - case FlagDefaultKind::kFloat: - std::memcpy(buf.data(), &default_value_.float_value, - sizeof(default_value_.float_value)); - break; - case FlagDefaultKind::kDouble: - std::memcpy(buf.data(), &default_value_.double_value, - sizeof(default_value_.double_value)); - break; - default: - assert(def_kind == FlagDefaultKind::kGenFunc); - (*default_value_.gen_func)(buf.data()); - break; + if (def_kind == FlagDefaultKind::kGenFunc) { + (*default_value_.gen_func)(buf.data()); + } else { + assert(def_kind != FlagDefaultKind::kDynamicValue); + std::memcpy(buf.data(), &default_value_, Sizeof(op_)); } OneWordValue().store(absl::bit_cast(buf), std::memory_order_release); @@ -228,14 +216,8 @@ std::unique_ptr FlagImpl::MakeInitValue() const { res = flags_internal::Alloc(op_); (*default_value_.gen_func)(res); break; - case FlagDefaultKind::kOneWord: - res = flags_internal::Clone(op_, &default_value_.one_word); - break; - case FlagDefaultKind::kFloat: - res = flags_internal::Clone(op_, &default_value_.float_value); - break; - case FlagDefaultKind::kDouble: - res = flags_internal::Clone(op_, &default_value_.double_value); + default: + res = flags_internal::Clone(op_, &default_value_); break; } return {res, DynValueDeleter{op_}}; diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h index 146c3efc..e374ecde 100644 --- a/absl/flags/internal/flag.h +++ b/absl/flags/internal/flag.h @@ -231,25 +231,21 @@ using FlagDfltGenFunc = void (*)(void*); union FlagDefaultSrc { constexpr explicit FlagDefaultSrc(FlagDfltGenFunc gen_func_arg) : gen_func(gen_func_arg) {} - template - constexpr explicit FlagDefaultSrc(T one_word_value) - : one_word(static_cast(one_word_value)) {} - constexpr explicit FlagDefaultSrc(float f) : float_value(f) {} - constexpr explicit FlagDefaultSrc(double d) : double_value(d) {} + +#define ABSL_FLAGS_INTERNAL_DFLT_FOR_TYPE(T, name) \ + T name##_value; \ + constexpr explicit FlagDefaultSrc(T value) : name##_value(value) {} // NOLINT + ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(ABSL_FLAGS_INTERNAL_DFLT_FOR_TYPE) +#undef ABSL_FLAGS_INTERNAL_DFLT_FOR_TYPE void* dynamic_value; FlagDfltGenFunc gen_func; - int64_t one_word; - float float_value; - double double_value; }; enum class FlagDefaultKind : uint8_t { kDynamicValue = 0, kGenFunc = 1, - kOneWord = 2, - kFloat = 3, - kDouble = 4 + kOneWord = 2 // for default values UP to one word in size }; struct FlagDefaultArg { @@ -279,20 +275,6 @@ constexpr FlagDefaultArg DefaultArg(int) { return {FlagDefaultSrc(GenT{}.value), FlagDefaultKind::kOneWord}; } -template ::value, - int>::type = (GenT{}, 0)> -constexpr FlagDefaultArg DefaultArg(int) { - return {FlagDefaultSrc(GenT{}.value), FlagDefaultKind::kFloat}; -} - -template ::value, - int>::type = (GenT{}, 0)> -constexpr FlagDefaultArg DefaultArg(int) { - return {FlagDefaultSrc(GenT{}.value), FlagDefaultKind::kDouble}; -} - template constexpr FlagDefaultArg DefaultArg(char) { return {FlagDefaultSrc(&GenT::Gen), FlagDefaultKind::kGenFunc}; @@ -576,9 +558,8 @@ class FlagImpl final : public flags_internal::CommandLineFlag { // Mutable flag's state (guarded by `data_guard_`). // def_kind_ is not guard by DataGuard() since it is accessed in Init without - // locks. If necessary we can decrease number of bits used to 2 by folding - // one_word storage cases. - uint8_t def_kind_ : 3; + // locks. + uint8_t def_kind_ : 2; // Has this flag's value been modified? bool modified_ : 1 ABSL_GUARDED_BY(*DataGuard()); // Has this flag been specified on command line. diff --git a/absl/flags/parse.cc b/absl/flags/parse.cc index 2e8f03b4..fbf42675 100644 --- a/absl/flags/parse.cc +++ b/absl/flags/parse.cc @@ -309,11 +309,11 @@ void CheckDefaultValuesParsingRoundtrip() { flags_internal::ForEachFlag([&](CommandLineFlag* flag) { if (flag->IsRetired()) return; -#define IGNORE_TYPE(T) \ +#define ABSL_FLAGS_INTERNAL_IGNORE_TYPE(T, _) \ if (flag->IsOfType()) return; - ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(IGNORE_TYPE) -#undef IGNORE_TYPE + ABSL_FLAGS_INTERNAL_SUPPORTED_TYPES(ABSL_FLAGS_INTERNAL_IGNORE_TYPE) +#undef ABSL_FLAGS_INTERNAL_IGNORE_TYPE flags_internal::PrivateHandleAccessor::CheckDefaultValueParsingRoundtrip( *flag); diff --git a/absl/random/BUILD.bazel b/absl/random/BUILD.bazel index e61d31b5..9ba75b52 100644 --- a/absl/random/BUILD.bazel +++ b/absl/random/BUILD.bazel @@ -168,6 +168,7 @@ cc_test( deps = [ ":distributions", ":random", + "//absl/random/internal:pcg_engine", "//absl/random/internal:sequence_urbg", "@com_google_googletest//:gtest_main", ], @@ -186,6 +187,7 @@ cc_test( ":random", "//absl/base:raw_logging_internal", "//absl/random/internal:distribution_test_util", + "//absl/random/internal:pcg_engine", "//absl/random/internal:sequence_urbg", "//absl/strings", "//absl/strings:str_format", @@ -233,9 +235,9 @@ cc_test( deps = [ ":distributions", ":random", - "//absl/base:core_headers", "//absl/base:raw_logging_internal", "//absl/random/internal:distribution_test_util", + "//absl/random/internal:pcg_engine", "//absl/random/internal:sequence_urbg", "//absl/strings", "//absl/strings:str_format", @@ -256,6 +258,7 @@ cc_test( ":random", "//absl/base:raw_logging_internal", "//absl/random/internal:distribution_test_util", + "//absl/random/internal:pcg_engine", "//absl/random/internal:sequence_urbg", "//absl/strings", "@com_google_googletest//:gtest_main", @@ -283,6 +286,7 @@ cc_test( "//absl/base:raw_logging_internal", "//absl/container:flat_hash_map", "//absl/random/internal:distribution_test_util", + "//absl/random/internal:pcg_engine", "//absl/random/internal:sequence_urbg", "//absl/strings", "//absl/strings:str_format", @@ -302,6 +306,7 @@ cc_test( "//absl/base:core_headers", "//absl/base:raw_logging_internal", "//absl/random/internal:distribution_test_util", + "//absl/random/internal:pcg_engine", "//absl/random/internal:sequence_urbg", "//absl/strings", "//absl/strings:str_format", @@ -345,6 +350,7 @@ cc_test( ":random", "//absl/base:raw_logging_internal", "//absl/random/internal:distribution_test_util", + "//absl/random/internal:pcg_engine", "//absl/random/internal:sequence_urbg", "//absl/strings", "@com_google_googletest//:gtest_main", @@ -369,6 +375,7 @@ cc_test( ":random", "//absl/base:raw_logging_internal", "//absl/random/internal:distribution_test_util", + "//absl/random/internal:pcg_engine", "//absl/random/internal:sequence_urbg", "//absl/strings", "@com_google_googletest//:gtest_main", @@ -388,6 +395,7 @@ cc_test( ":random", "//absl/base:raw_logging_internal", "//absl/random/internal:distribution_test_util", + "//absl/random/internal:pcg_engine", "//absl/random/internal:sequence_urbg", "//absl/strings", "@com_google_googletest//:gtest_main", diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt index 69bedbd6..ec616dd9 100644 --- a/absl/random/CMakeLists.txt +++ b/absl/random/CMakeLists.txt @@ -244,6 +244,7 @@ absl_cc_test( absl::random_distributions absl::random_random absl::random_internal_sequence_urbg + absl::random_internal_pcg_engine gmock gtest_main ) @@ -262,6 +263,7 @@ absl_cc_test( absl::random_random absl::random_internal_distribution_test_util absl::random_internal_sequence_urbg + absl::random_internal_pcg_engine absl::raw_logging_internal absl::strings absl::str_format @@ -311,9 +313,9 @@ absl_cc_test( ${ABSL_TEST_COPTS} LINKOPTS ${ABSL_DEFAULT_LINKOPTS} - absl::core_headers absl::random_distributions absl::random_internal_distribution_test_util + absl::random_internal_pcg_engine absl::random_internal_sequence_urbg absl::random_random absl::raw_logging_internal @@ -335,6 +337,7 @@ absl_cc_test( DEPS absl::random_distributions absl::random_internal_distribution_test_util + absl::random_internal_pcg_engine absl::random_internal_sequence_urbg absl::random_random absl::raw_logging_internal @@ -358,6 +361,7 @@ absl_cc_test( absl::core_headers absl::flat_hash_map absl::random_internal_distribution_test_util + absl::random_internal_pcg_engine absl::random_internal_sequence_urbg absl::raw_logging_internal absl::strings @@ -379,6 +383,7 @@ absl_cc_test( absl::core_headers absl::random_distributions absl::random_internal_distribution_test_util + absl::random_internal_pcg_engine absl::random_internal_sequence_urbg absl::random_random absl::raw_logging_internal @@ -422,6 +427,7 @@ absl_cc_test( DEPS absl::random_distributions absl::random_internal_distribution_test_util + absl::random_internal_pcg_engine absl::random_internal_sequence_urbg absl::random_random absl::raw_logging_internal @@ -442,6 +448,7 @@ absl_cc_test( DEPS absl::random_distributions absl::random_internal_distribution_test_util + absl::random_internal_pcg_engine absl::random_internal_sequence_urbg absl::random_random absl::strings @@ -461,6 +468,7 @@ absl_cc_test( DEPS absl::random_distributions absl::random_internal_distribution_test_util + absl::random_internal_pcg_engine absl::random_internal_sequence_urbg absl::random_random absl::raw_logging_internal @@ -782,8 +790,9 @@ absl_cc_library( random_internal_platform HDRS "internal/randen_traits.h" - "internal/randen-keys.inc" "internal/platform.h" + SRCS + "internal/randen_round_keys.cc" COPTS ${ABSL_DEFAULT_COPTS} LINKOPTS diff --git a/absl/random/bernoulli_distribution_test.cc b/absl/random/bernoulli_distribution_test.cc index 5581af50..b250f878 100644 --- a/absl/random/bernoulli_distribution_test.cc +++ b/absl/random/bernoulli_distribution_test.cc @@ -21,6 +21,7 @@ #include #include "gtest/gtest.h" +#include "absl/random/internal/pcg_engine.h" #include "absl/random/internal/sequence_urbg.h" #include "absl/random/random.h" @@ -63,7 +64,10 @@ TEST_P(BernoulliTest, Accuracy) { size_t trials = para.second; double p = para.first; - absl::InsecureBitGen rng; + // We use a fixed bit generator for distribution accuracy tests. This allows + // these tests to be deterministic, while still testing the qualify of the + // implementation. + absl::random_internal::pcg64_2018_engine rng(0x2B7E151628AED2A6); size_t yes = 0; absl::bernoulli_distribution dist(p); diff --git a/absl/random/beta_distribution_test.cc b/absl/random/beta_distribution_test.cc index d0111b3e..277e4dc6 100644 --- a/absl/random/beta_distribution_test.cc +++ b/absl/random/beta_distribution_test.cc @@ -29,6 +29,7 @@ #include "absl/base/internal/raw_logging.h" #include "absl/random/internal/chi_square.h" #include "absl/random/internal/distribution_test_util.h" +#include "absl/random/internal/pcg_engine.h" #include "absl/random/internal/sequence_urbg.h" #include "absl/random/random.h" #include "absl/strings/str_cat.h" @@ -159,8 +160,12 @@ TYPED_TEST(BetaDistributionInterfaceTest, SerializeTest) { } TYPED_TEST(BetaDistributionInterfaceTest, DegenerateCases) { + // We use a fixed bit generator for distribution accuracy tests. This allows + // these tests to be deterministic, while still testing the qualify of the + // implementation. + absl::random_internal::pcg64_2018_engine rng(0x2B7E151628AED2A6); + // Extreme cases when the params are abnormal. - absl::InsecureBitGen gen; constexpr int kCount = 1000; const TypeParam kSmallValues[] = { std::numeric_limits::min(), @@ -186,7 +191,7 @@ TYPED_TEST(BetaDistributionInterfaceTest, DegenerateCases) { int ones = 0; absl::beta_distribution d(alpha, beta); for (int i = 0; i < kCount; ++i) { - TypeParam x = d(gen); + TypeParam x = d(rng); if (x == 0.0) { zeros++; } else if (x == 1.0) { @@ -212,7 +217,7 @@ TYPED_TEST(BetaDistributionInterfaceTest, DegenerateCases) { for (TypeParam beta : kLargeValues) { absl::beta_distribution d(alpha, beta); for (int i = 0; i < kCount; ++i) { - EXPECT_EQ(d(gen), 0.0); + EXPECT_EQ(d(rng), 0.0); } } } @@ -227,7 +232,7 @@ TYPED_TEST(BetaDistributionInterfaceTest, DegenerateCases) { for (TypeParam beta : kSmallValues) { absl::beta_distribution d(alpha, beta); for (int i = 0; i < kCount; ++i) { - EXPECT_EQ(d(gen), 1.0); + EXPECT_EQ(d(rng), 1.0); } } } @@ -237,7 +242,7 @@ TYPED_TEST(BetaDistributionInterfaceTest, DegenerateCases) { absl::beta_distribution d(std::numeric_limits::max(), std::numeric_limits::max()); for (int i = 0; i < kCount; ++i) { - EXPECT_EQ(d(gen), 0.5); + EXPECT_EQ(d(rng), 0.5); } } { @@ -246,7 +251,7 @@ TYPED_TEST(BetaDistributionInterfaceTest, DegenerateCases) { std::numeric_limits::max(), std::numeric_limits::max() * 0.9999); for (int i = 0; i < kCount; ++i) { - TypeParam x = d(gen); + TypeParam x = d(rng); EXPECT_NE(x, 0.5f); EXPECT_FLOAT_EQ(x, 0.500025f); } diff --git a/absl/random/discrete_distribution_test.cc b/absl/random/discrete_distribution_test.cc index 7296f0ac..6d007006 100644 --- a/absl/random/discrete_distribution_test.cc +++ b/absl/random/discrete_distribution_test.cc @@ -29,6 +29,7 @@ #include "absl/base/internal/raw_logging.h" #include "absl/random/internal/chi_square.h" #include "absl/random/internal/distribution_test_util.h" +#include "absl/random/internal/pcg_engine.h" #include "absl/random/internal/sequence_urbg.h" #include "absl/random/random.h" #include "absl/strings/str_cat.h" @@ -156,7 +157,10 @@ TEST(DiscreteDistributionTest, ChiSquaredTest50) { std::iota(std::begin(weights), std::end(weights), 1); absl::discrete_distribution dist(std::begin(weights), std::end(weights)); - absl::InsecureBitGen rng; + // We use a fixed bit generator for distribution accuracy tests. This allows + // these tests to be deterministic, while still testing the qualify of the + // implementation. + absl::random_internal::pcg64_2018_engine rng(0x2B7E151628AED2A6); std::vector counts(kBuckets, 0); for (size_t i = 0; i < kTrials; i++) { diff --git a/absl/random/exponential_distribution_test.cc b/absl/random/exponential_distribution_test.cc index f3cfd764..8e9e69b6 100644 --- a/absl/random/exponential_distribution_test.cc +++ b/absl/random/exponential_distribution_test.cc @@ -32,6 +32,7 @@ #include "absl/base/macros.h" #include "absl/random/internal/chi_square.h" #include "absl/random/internal/distribution_test_util.h" +#include "absl/random/internal/pcg_engine.h" #include "absl/random/internal/sequence_urbg.h" #include "absl/random/random.h" #include "absl/strings/str_cat.h" @@ -205,7 +206,10 @@ class ExponentialDistributionTests : public testing::TestWithParam, template double SingleChiSquaredTest(); - absl::InsecureBitGen rng_; + // We use a fixed bit generator for distribution accuracy tests. This allows + // these tests to be deterministic, while still testing the qualify of the + // implementation. + absl::random_internal::pcg64_2018_engine rng_{0x2B7E151628AED2A6}; }; template diff --git a/absl/random/gaussian_distribution_test.cc b/absl/random/gaussian_distribution_test.cc index 398f0131..02ac578a 100644 --- a/absl/random/gaussian_distribution_test.cc +++ b/absl/random/gaussian_distribution_test.cc @@ -216,7 +216,10 @@ class GaussianDistributionTests : public testing::TestWithParam, template double SingleChiSquaredTest(); - absl::InsecureBitGen rng_; + // We use a fixed bit generator for distribution accuracy tests. This allows + // these tests to be deterministic, while still testing the qualify of the + // implementation. + absl::random_internal::pcg64_2018_engine rng_{0x2B7E151628AED2A6}; }; template diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel index dc452816..85d1fb81 100644 --- a/absl/random/internal/BUILD.bazel +++ b/absl/random/internal/BUILD.bazel @@ -255,13 +255,15 @@ cc_library( cc_library( name = "platform", + srcs = [ + "randen_round_keys.cc", + ], hdrs = [ "randen_traits.h", ], copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, textual_hdrs = [ - "randen-keys.inc", "platform.h", ], deps = ["//absl/base:config"], @@ -613,6 +615,7 @@ cc_test( copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ + ":platform", ":randen_slow", "@com_google_googletest//:gtest_main", ], diff --git a/absl/random/internal/randen-keys.inc b/absl/random/internal/randen-keys.inc deleted file mode 100644 index fa4b1668..00000000 --- a/absl/random/internal/randen-keys.inc +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_RANDEN_KEYS_INC_ -#define ABSL_RANDOM_INTERNAL_RANDEN_KEYS_INC_ - -// Textual header to include the randen_keys where necessary. -// REQUIRES: struct u64x2{} -// -// PROVIDES: kKeys -// PROVIDES: round_keys[] - -// "Nothing up my sleeve" numbers from the first hex digits of Pi, obtained -// from http://hexpi.sourceforge.net/. The array was generated by following -// Python script: -/* -python << EOF -"""Generates Randen round keys array from pi-hex.62500.txt file.""" -import binascii - -KEYS = 136 - -def chunks(l, n): - """Yield successive n-sized chunks from l.""" - for i in range(0, len(l), n): - yield l[i:i + n] - -def pairwise(t): - """Transforms sequence into sequence of pairs.""" - it = iter(t) - return zip(it,it) - -def digits_from_pi(): - """Reads digits from hexpi.sourceforge.net file.""" - with open("pi-hex.62500.txt") as file: - return file.read() - -def digits_from_urandom(): - """Reads digits from /dev/urandom.""" - with open("/dev/urandom") as file: - return binascii.hexlify(file.read(KEYS * 16)) - -digits = digits_from_pi() -print("static constexpr const size_t kRoundKeys = {0};\n".format(KEYS)) -print("alignas(16) constexpr const u64x2 round_keys[kRoundKeys] = {") - -for i, (hi, lo) in zip(range(KEYS), pairwise(chunks(digits, 16))): - hi = "0x{0}ull".format(hi) - lo = "0x{0}ull".format(lo) - print(" u64x2({0}, {1}){2}".format(hi, lo, ',' if i+1 < KEYS else '')) - -print("};") -EOF -*/ - -static constexpr const size_t kRoundKeys = 136; - -alignas(16) constexpr u64x2 round_keys[kRoundKeys] = { - u64x2(0x243F6A8885A308D3ull, 0x13198A2E03707344ull), - u64x2(0xA4093822299F31D0ull, 0x082EFA98EC4E6C89ull), - u64x2(0x452821E638D01377ull, 0xBE5466CF34E90C6Cull), - u64x2(0xC0AC29B7C97C50DDull, 0x3F84D5B5B5470917ull), - u64x2(0x9216D5D98979FB1Bull, 0xD1310BA698DFB5ACull), - u64x2(0x2FFD72DBD01ADFB7ull, 0xB8E1AFED6A267E96ull), - u64x2(0xBA7C9045F12C7F99ull, 0x24A19947B3916CF7ull), - u64x2(0x0801F2E2858EFC16ull, 0x636920D871574E69ull), - u64x2(0xA458FEA3F4933D7Eull, 0x0D95748F728EB658ull), - u64x2(0x718BCD5882154AEEull, 0x7B54A41DC25A59B5ull), - u64x2(0x9C30D5392AF26013ull, 0xC5D1B023286085F0ull), - u64x2(0xCA417918B8DB38EFull, 0x8E79DCB0603A180Eull), - u64x2(0x6C9E0E8BB01E8A3Eull, 0xD71577C1BD314B27ull), - u64x2(0x78AF2FDA55605C60ull, 0xE65525F3AA55AB94ull), - u64x2(0x5748986263E81440ull, 0x55CA396A2AAB10B6ull), - u64x2(0xB4CC5C341141E8CEull, 0xA15486AF7C72E993ull), - u64x2(0xB3EE1411636FBC2Aull, 0x2BA9C55D741831F6ull), - u64x2(0xCE5C3E169B87931Eull, 0xAFD6BA336C24CF5Cull), - u64x2(0x7A32538128958677ull, 0x3B8F48986B4BB9AFull), - u64x2(0xC4BFE81B66282193ull, 0x61D809CCFB21A991ull), - u64x2(0x487CAC605DEC8032ull, 0xEF845D5DE98575B1ull), - u64x2(0xDC262302EB651B88ull, 0x23893E81D396ACC5ull), - u64x2(0x0F6D6FF383F44239ull, 0x2E0B4482A4842004ull), - u64x2(0x69C8F04A9E1F9B5Eull, 0x21C66842F6E96C9Aull), - u64x2(0x670C9C61ABD388F0ull, 0x6A51A0D2D8542F68ull), - u64x2(0x960FA728AB5133A3ull, 0x6EEF0B6C137A3BE4ull), - u64x2(0xBA3BF0507EFB2A98ull, 0xA1F1651D39AF0176ull), - u64x2(0x66CA593E82430E88ull, 0x8CEE8619456F9FB4ull), - u64x2(0x7D84A5C33B8B5EBEull, 0xE06F75D885C12073ull), - u64x2(0x401A449F56C16AA6ull, 0x4ED3AA62363F7706ull), - u64x2(0x1BFEDF72429B023Dull, 0x37D0D724D00A1248ull), - u64x2(0xDB0FEAD349F1C09Bull, 0x075372C980991B7Bull), - u64x2(0x25D479D8F6E8DEF7ull, 0xE3FE501AB6794C3Bull), - u64x2(0x976CE0BD04C006BAull, 0xC1A94FB6409F60C4ull), - u64x2(0x5E5C9EC2196A2463ull, 0x68FB6FAF3E6C53B5ull), - u64x2(0x1339B2EB3B52EC6Full, 0x6DFC511F9B30952Cull), - u64x2(0xCC814544AF5EBD09ull, 0xBEE3D004DE334AFDull), - u64x2(0x660F2807192E4BB3ull, 0xC0CBA85745C8740Full), - u64x2(0xD20B5F39B9D3FBDBull, 0x5579C0BD1A60320Aull), - u64x2(0xD6A100C6402C7279ull, 0x679F25FEFB1FA3CCull), - u64x2(0x8EA5E9F8DB3222F8ull, 0x3C7516DFFD616B15ull), - u64x2(0x2F501EC8AD0552ABull, 0x323DB5FAFD238760ull), - u64x2(0x53317B483E00DF82ull, 0x9E5C57BBCA6F8CA0ull), - u64x2(0x1A87562EDF1769DBull, 0xD542A8F6287EFFC3ull), - u64x2(0xAC6732C68C4F5573ull, 0x695B27B0BBCA58C8ull), - u64x2(0xE1FFA35DB8F011A0ull, 0x10FA3D98FD2183B8ull), - u64x2(0x4AFCB56C2DD1D35Bull, 0x9A53E479B6F84565ull), - u64x2(0xD28E49BC4BFB9790ull, 0xE1DDF2DAA4CB7E33ull), - u64x2(0x62FB1341CEE4C6E8ull, 0xEF20CADA36774C01ull), - u64x2(0xD07E9EFE2BF11FB4ull, 0x95DBDA4DAE909198ull), - u64x2(0xEAAD8E716B93D5A0ull, 0xD08ED1D0AFC725E0ull), - u64x2(0x8E3C5B2F8E7594B7ull, 0x8FF6E2FBF2122B64ull), - u64x2(0x8888B812900DF01Cull, 0x4FAD5EA0688FC31Cull), - u64x2(0xD1CFF191B3A8C1ADull, 0x2F2F2218BE0E1777ull), - u64x2(0xEA752DFE8B021FA1ull, 0xE5A0CC0FB56F74E8ull), - u64x2(0x18ACF3D6CE89E299ull, 0xB4A84FE0FD13E0B7ull), - u64x2(0x7CC43B81D2ADA8D9ull, 0x165FA26680957705ull), - u64x2(0x93CC7314211A1477ull, 0xE6AD206577B5FA86ull), - u64x2(0xC75442F5FB9D35CFull, 0xEBCDAF0C7B3E89A0ull), - u64x2(0xD6411BD3AE1E7E49ull, 0x00250E2D2071B35Eull), - u64x2(0x226800BB57B8E0AFull, 0x2464369BF009B91Eull), - u64x2(0x5563911D59DFA6AAull, 0x78C14389D95A537Full), - u64x2(0x207D5BA202E5B9C5ull, 0x832603766295CFA9ull), - u64x2(0x11C819684E734A41ull, 0xB3472DCA7B14A94Aull), - u64x2(0x1B5100529A532915ull, 0xD60F573FBC9BC6E4ull), - u64x2(0x2B60A47681E67400ull, 0x08BA6FB5571BE91Full), - u64x2(0xF296EC6B2A0DD915ull, 0xB6636521E7B9F9B6ull), - u64x2(0xFF34052EC5855664ull, 0x53B02D5DA99F8FA1ull), - u64x2(0x08BA47996E85076Aull, 0x4B7A70E9B5B32944ull), - u64x2(0xDB75092EC4192623ull, 0xAD6EA6B049A7DF7Dull), - u64x2(0x9CEE60B88FEDB266ull, 0xECAA8C71699A18FFull), - u64x2(0x5664526CC2B19EE1ull, 0x193602A575094C29ull), - u64x2(0xA0591340E4183A3Eull, 0x3F54989A5B429D65ull), - u64x2(0x6B8FE4D699F73FD6ull, 0xA1D29C07EFE830F5ull), - u64x2(0x4D2D38E6F0255DC1ull, 0x4CDD20868470EB26ull), - u64x2(0x6382E9C6021ECC5Eull, 0x09686B3F3EBAEFC9ull), - u64x2(0x3C9718146B6A70A1ull, 0x687F358452A0E286ull), - u64x2(0xB79C5305AA500737ull, 0x3E07841C7FDEAE5Cull), - u64x2(0x8E7D44EC5716F2B8ull, 0xB03ADA37F0500C0Dull), - u64x2(0xF01C1F040200B3FFull, 0xAE0CF51A3CB574B2ull), - u64x2(0x25837A58DC0921BDull, 0xD19113F97CA92FF6ull), - u64x2(0x9432477322F54701ull, 0x3AE5E58137C2DADCull), - u64x2(0xC8B576349AF3DDA7ull, 0xA94461460FD0030Eull), - u64x2(0xECC8C73EA4751E41ull, 0xE238CD993BEA0E2Full), - u64x2(0x3280BBA1183EB331ull, 0x4E548B384F6DB908ull), - u64x2(0x6F420D03F60A04BFull, 0x2CB8129024977C79ull), - u64x2(0x5679B072BCAF89AFull, 0xDE9A771FD9930810ull), - u64x2(0xB38BAE12DCCF3F2Eull, 0x5512721F2E6B7124ull), - u64x2(0x501ADDE69F84CD87ull, 0x7A5847187408DA17ull), - u64x2(0xBC9F9ABCE94B7D8Cull, 0xEC7AEC3ADB851DFAull), - u64x2(0x63094366C464C3D2ull, 0xEF1C18473215D808ull), - u64x2(0xDD433B3724C2BA16ull, 0x12A14D432A65C451ull), - u64x2(0x50940002133AE4DDull, 0x71DFF89E10314E55ull), - u64x2(0x81AC77D65F11199Bull, 0x043556F1D7A3C76Bull), - u64x2(0x3C11183B5924A509ull, 0xF28FE6ED97F1FBFAull), - u64x2(0x9EBABF2C1E153C6Eull, 0x86E34570EAE96FB1ull), - u64x2(0x860E5E0A5A3E2AB3ull, 0x771FE71C4E3D06FAull), - u64x2(0x2965DCB999E71D0Full, 0x803E89D65266C825ull), - u64x2(0x2E4CC9789C10B36Aull, 0xC6150EBA94E2EA78ull), - u64x2(0xA6FC3C531E0A2DF4ull, 0xF2F74EA7361D2B3Dull), - u64x2(0x1939260F19C27960ull, 0x5223A708F71312B6ull), - u64x2(0xEBADFE6EEAC31F66ull, 0xE3BC4595A67BC883ull), - u64x2(0xB17F37D1018CFF28ull, 0xC332DDEFBE6C5AA5ull), - u64x2(0x6558218568AB9702ull, 0xEECEA50FDB2F953Bull), - u64x2(0x2AEF7DAD5B6E2F84ull, 0x1521B62829076170ull), - u64x2(0xECDD4775619F1510ull, 0x13CCA830EB61BD96ull), - u64x2(0x0334FE1EAA0363CFull, 0xB5735C904C70A239ull), - u64x2(0xD59E9E0BCBAADE14ull, 0xEECC86BC60622CA7ull), - u64x2(0x9CAB5CABB2F3846Eull, 0x648B1EAF19BDF0CAull), - u64x2(0xA02369B9655ABB50ull, 0x40685A323C2AB4B3ull), - u64x2(0x319EE9D5C021B8F7ull, 0x9B540B19875FA099ull), - u64x2(0x95F7997E623D7DA8ull, 0xF837889A97E32D77ull), - u64x2(0x11ED935F16681281ull, 0x0E358829C7E61FD6ull), - u64x2(0x96DEDFA17858BA99ull, 0x57F584A51B227263ull), - u64x2(0x9B83C3FF1AC24696ull, 0xCDB30AEB532E3054ull), - u64x2(0x8FD948E46DBC3128ull, 0x58EBF2EF34C6FFEAull), - u64x2(0xFE28ED61EE7C3C73ull, 0x5D4A14D9E864B7E3ull), - u64x2(0x42105D14203E13E0ull, 0x45EEE2B6A3AAABEAull), - u64x2(0xDB6C4F15FACB4FD0ull, 0xC742F442EF6ABBB5ull), - u64x2(0x654F3B1D41CD2105ull, 0xD81E799E86854DC7ull), - u64x2(0xE44B476A3D816250ull, 0xCF62A1F25B8D2646ull), - u64x2(0xFC8883A0C1C7B6A3ull, 0x7F1524C369CB7492ull), - u64x2(0x47848A0B5692B285ull, 0x095BBF00AD19489Dull), - u64x2(0x1462B17423820D00ull, 0x58428D2A0C55F5EAull), - u64x2(0x1DADF43E233F7061ull, 0x3372F0928D937E41ull), - u64x2(0xD65FECF16C223BDBull, 0x7CDE3759CBEE7460ull), - u64x2(0x4085F2A7CE77326Eull, 0xA607808419F8509Eull), - u64x2(0xE8EFD85561D99735ull, 0xA969A7AAC50C06C2ull), - u64x2(0x5A04ABFC800BCADCull, 0x9E447A2EC3453484ull), - u64x2(0xFDD567050E1E9EC9ull, 0xDB73DBD3105588CDull), - u64x2(0x675FDA79E3674340ull, 0xC5C43465713E38D8ull), - u64x2(0x3D28F89EF16DFF20ull, 0x153E21E78FB03D4Aull), - u64x2(0xE6E39F2BDB83ADF7ull, 0xE93D5A68948140F7ull), - u64x2(0xF64C261C94692934ull, 0x411520F77602D4F7ull), - u64x2(0xBCF46B2ED4A10068ull, 0xD40824713320F46Aull), - u64x2(0x43B7D4B7500061AFull, 0x1E39F62E97244546ull)}; - -#endif // ABSL_RANDOM_INTERNAL_RANDEN_KEYS_INC_ diff --git a/absl/random/internal/randen_hwaes.cc b/absl/random/internal/randen_hwaes.cc index e23844f1..9966486f 100644 --- a/absl/random/internal/randen_hwaes.cc +++ b/absl/random/internal/randen_hwaes.cc @@ -24,6 +24,7 @@ #include "absl/base/attributes.h" #include "absl/random/internal/platform.h" +#include "absl/random/internal/randen_traits.h" // ABSL_RANDEN_HWAES_IMPL indicates whether this file will contain // a hardware accelerated implementation of randen, or whether it @@ -115,8 +116,16 @@ ABSL_NAMESPACE_END // Accelerated implementations are supported. // We need the per-architecture includes and defines. // +namespace { -#include "absl/random/internal/randen_traits.h" +using absl::random_internal::RandenTraits; + +// Randen operates on 128-bit vectors. +struct alignas(16) u64x2 { + uint64_t data[2]; +}; + +} // namespace // TARGET_CRYPTO defines a crypto attribute for each architecture. // @@ -150,7 +159,6 @@ ABSL_NAMESPACE_END using Vector128 = __vector unsigned long long; // NOLINT(runtime/int) namespace { - inline ABSL_TARGET_CRYPTO Vector128 ReverseBytes(const Vector128& v) { // Reverses the bytes of the vector. const __vector unsigned char perm = {15, 14, 13, 12, 11, 10, 9, 8, @@ -177,14 +185,9 @@ inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state, } // Enables native loads in the round loop by pre-swapping. -inline ABSL_TARGET_CRYPTO void SwapEndian(uint64_t* state) { - using absl::random_internal::RandenTraits; - constexpr size_t kLanes = 2; - constexpr size_t kFeistelBlocks = RandenTraits::kFeistelBlocks; - - for (uint32_t branch = 0; branch < kFeistelBlocks; ++branch) { - const Vector128 v = ReverseBytes(Vector128Load(state + kLanes * branch)); - Vector128Store(v, state + kLanes * branch); +inline ABSL_TARGET_CRYPTO void SwapEndian(u64x2* state) { + for (uint32_t block = 0; block < RandenTraits::kFeistelBlocks; ++block) { + Vector128Store(ReverseBytes(Vector128Load(state + block)), state + block); } } @@ -251,7 +254,7 @@ inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state, return vaesmcq_u8(vaeseq_u8(state, uint8x16_t{})) ^ round_key; } -inline ABSL_TARGET_CRYPTO void SwapEndian(uint64_t*) {} +inline ABSL_TARGET_CRYPTO void SwapEndian(void*) {} } // namespace @@ -297,39 +300,12 @@ inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state, return Vector128(_mm_aesenc_si128(state.data(), round_key.data())); } -inline ABSL_TARGET_CRYPTO void SwapEndian(uint64_t*) {} +inline ABSL_TARGET_CRYPTO void SwapEndian(void*) {} } // namespace #endif -namespace { - -// u64x2 is a 128-bit, (2 x uint64_t lanes) struct used to store -// the randen_keys. -struct alignas(16) u64x2 { - constexpr u64x2(uint64_t hi, uint64_t lo) -#if defined(ABSL_ARCH_PPC) - // This has been tested with PPC running in little-endian mode; - // We byte-swap the u64x2 structure from little-endian to big-endian - // because altivec always runs in big-endian mode. - : v{__builtin_bswap64(hi), __builtin_bswap64(lo)} { -#else - : v{lo, hi} { -#endif - } - - constexpr bool operator==(const u64x2& other) const { - return v[0] == other.v[0] && v[1] == other.v[1]; - } - - constexpr bool operator!=(const u64x2& other) const { - return !(*this == other); - } - - uint64_t v[2]; -}; // namespace - #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunknown-pragmas" @@ -338,7 +314,6 @@ struct alignas(16) u64x2 { // At this point, all of the platform-specific features have been defined / // implemented. // -// REQUIRES: using u64x2 = ... // REQUIRES: using Vector128 = ... // REQUIRES: Vector128 Vector128Load(void*) {...} // REQUIRES: void Vector128Store(Vector128, void*) {...} @@ -347,94 +322,50 @@ struct alignas(16) u64x2 { // // PROVIDES: absl::random_internal::RandenHwAes::Absorb // PROVIDES: absl::random_internal::RandenHwAes::Generate - -// RANDen = RANDom generator or beetroots in Swiss German. -// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random -// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32. -// -// High-level summary: -// 1) Reverie (see "A Robust and Sponge-Like PRNG with Improved Efficiency") is -// a sponge-like random generator that requires a cryptographic permutation. -// It improves upon "Provably Robust Sponge-Based PRNGs and KDFs" by -// achieving backtracking resistance with only one Permute() per buffer. -// -// 2) "Simpira v2: A Family of Efficient Permutations Using the AES Round -// Function" constructs up to 1024-bit permutations using an improved -// Generalized Feistel network with 2-round AES-128 functions. This Feistel -// block shuffle achieves diffusion faster and is less vulnerable to -// sliced-biclique attacks than the Type-2 cyclic shuffle. -// -// 3) "Improving the Generalized Feistel" and "New criterion for diffusion -// property" extends the same kind of improved Feistel block shuffle to 16 -// branches, which enables a 2048-bit permutation. -// -// We combine these three ideas and also change Simpira's subround keys from -// structured/low-entropy counters to digits of Pi. - -// Randen constants. -using absl::random_internal::RandenTraits; -constexpr size_t kStateBytes = RandenTraits::kStateBytes; -constexpr size_t kCapacityBytes = RandenTraits::kCapacityBytes; -constexpr size_t kFeistelBlocks = RandenTraits::kFeistelBlocks; -constexpr size_t kFeistelRounds = RandenTraits::kFeistelRounds; -constexpr size_t kFeistelFunctions = RandenTraits::kFeistelFunctions; - -// Independent keys (272 = 2.1 KiB) for the first AES subround of each function. -constexpr size_t kKeys = kFeistelRounds * kFeistelFunctions; - -// INCLUDE keys. -#include "absl/random/internal/randen-keys.inc" - -static_assert(kKeys == kRoundKeys, "kKeys and kRoundKeys must be equal"); -static_assert(round_keys[kKeys - 1] != u64x2(0, 0), - "Too few round_keys initializers"); - -// Number of uint64_t lanes per 128-bit vector; -constexpr size_t kLanes = 2; +namespace { // Block shuffles applies a shuffle to the entire state between AES rounds. // Improved odd-even shuffle from "New criterion for diffusion property". -inline ABSL_TARGET_CRYPTO void BlockShuffle(uint64_t* state) { - static_assert(kFeistelBlocks == 16, "Expecting 16 FeistelBlocks."); - - constexpr size_t shuffle[kFeistelBlocks] = {7, 2, 13, 4, 11, 8, 3, 6, - 15, 0, 9, 10, 1, 14, 5, 12}; - - // The fully unrolled loop without the memcpy improves the speed by about - // 30% over the equivalent loop. - const Vector128 v0 = Vector128Load(state + kLanes * shuffle[0]); - const Vector128 v1 = Vector128Load(state + kLanes * shuffle[1]); - const Vector128 v2 = Vector128Load(state + kLanes * shuffle[2]); - const Vector128 v3 = Vector128Load(state + kLanes * shuffle[3]); - const Vector128 v4 = Vector128Load(state + kLanes * shuffle[4]); - const Vector128 v5 = Vector128Load(state + kLanes * shuffle[5]); - const Vector128 v6 = Vector128Load(state + kLanes * shuffle[6]); - const Vector128 v7 = Vector128Load(state + kLanes * shuffle[7]); - const Vector128 w0 = Vector128Load(state + kLanes * shuffle[8]); - const Vector128 w1 = Vector128Load(state + kLanes * shuffle[9]); - const Vector128 w2 = Vector128Load(state + kLanes * shuffle[10]); - const Vector128 w3 = Vector128Load(state + kLanes * shuffle[11]); - const Vector128 w4 = Vector128Load(state + kLanes * shuffle[12]); - const Vector128 w5 = Vector128Load(state + kLanes * shuffle[13]); - const Vector128 w6 = Vector128Load(state + kLanes * shuffle[14]); - const Vector128 w7 = Vector128Load(state + kLanes * shuffle[15]); - - Vector128Store(v0, state + kLanes * 0); - Vector128Store(v1, state + kLanes * 1); - Vector128Store(v2, state + kLanes * 2); - Vector128Store(v3, state + kLanes * 3); - Vector128Store(v4, state + kLanes * 4); - Vector128Store(v5, state + kLanes * 5); - Vector128Store(v6, state + kLanes * 6); - Vector128Store(v7, state + kLanes * 7); - Vector128Store(w0, state + kLanes * 8); - Vector128Store(w1, state + kLanes * 9); - Vector128Store(w2, state + kLanes * 10); - Vector128Store(w3, state + kLanes * 11); - Vector128Store(w4, state + kLanes * 12); - Vector128Store(w5, state + kLanes * 13); - Vector128Store(w6, state + kLanes * 14); - Vector128Store(w7, state + kLanes * 15); +inline ABSL_TARGET_CRYPTO void BlockShuffle(u64x2* state) { + static_assert(RandenTraits::kFeistelBlocks == 16, + "Expecting 16 FeistelBlocks."); + + constexpr size_t shuffle[RandenTraits::kFeistelBlocks] = { + 7, 2, 13, 4, 11, 8, 3, 6, 15, 0, 9, 10, 1, 14, 5, 12}; + + const Vector128 v0 = Vector128Load(state + shuffle[0]); + const Vector128 v1 = Vector128Load(state + shuffle[1]); + const Vector128 v2 = Vector128Load(state + shuffle[2]); + const Vector128 v3 = Vector128Load(state + shuffle[3]); + const Vector128 v4 = Vector128Load(state + shuffle[4]); + const Vector128 v5 = Vector128Load(state + shuffle[5]); + const Vector128 v6 = Vector128Load(state + shuffle[6]); + const Vector128 v7 = Vector128Load(state + shuffle[7]); + const Vector128 w0 = Vector128Load(state + shuffle[8]); + const Vector128 w1 = Vector128Load(state + shuffle[9]); + const Vector128 w2 = Vector128Load(state + shuffle[10]); + const Vector128 w3 = Vector128Load(state + shuffle[11]); + const Vector128 w4 = Vector128Load(state + shuffle[12]); + const Vector128 w5 = Vector128Load(state + shuffle[13]); + const Vector128 w6 = Vector128Load(state + shuffle[14]); + const Vector128 w7 = Vector128Load(state + shuffle[15]); + + Vector128Store(v0, state + 0); + Vector128Store(v1, state + 1); + Vector128Store(v2, state + 2); + Vector128Store(v3, state + 3); + Vector128Store(v4, state + 4); + Vector128Store(v5, state + 5); + Vector128Store(v6, state + 6); + Vector128Store(v7, state + 7); + Vector128Store(w0, state + 8); + Vector128Store(w1, state + 9); + Vector128Store(w2, state + 10); + Vector128Store(w3, state + 11); + Vector128Store(w4, state + 12); + Vector128Store(w5, state + 13); + Vector128Store(w6, state + 14); + Vector128Store(w7, state + 15); } // Feistel round function using two AES subrounds. Very similar to F() @@ -443,27 +374,28 @@ inline ABSL_TARGET_CRYPTO void BlockShuffle(uint64_t* state) { // parallel hides the 7-cycle AESNI latency on HSW. Note that the Feistel // XORs are 'free' (included in the second AES instruction). inline ABSL_TARGET_CRYPTO const u64x2* FeistelRound( - uint64_t* state, const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys) { - static_assert(kFeistelBlocks == 16, "Expecting 16 FeistelBlocks."); + u64x2* state, const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys) { + static_assert(RandenTraits::kFeistelBlocks == 16, + "Expecting 16 FeistelBlocks."); // MSVC does a horrible job at unrolling loops. // So we unroll the loop by hand to improve the performance. - const Vector128 s0 = Vector128Load(state + kLanes * 0); - const Vector128 s1 = Vector128Load(state + kLanes * 1); - const Vector128 s2 = Vector128Load(state + kLanes * 2); - const Vector128 s3 = Vector128Load(state + kLanes * 3); - const Vector128 s4 = Vector128Load(state + kLanes * 4); - const Vector128 s5 = Vector128Load(state + kLanes * 5); - const Vector128 s6 = Vector128Load(state + kLanes * 6); - const Vector128 s7 = Vector128Load(state + kLanes * 7); - const Vector128 s8 = Vector128Load(state + kLanes * 8); - const Vector128 s9 = Vector128Load(state + kLanes * 9); - const Vector128 s10 = Vector128Load(state + kLanes * 10); - const Vector128 s11 = Vector128Load(state + kLanes * 11); - const Vector128 s12 = Vector128Load(state + kLanes * 12); - const Vector128 s13 = Vector128Load(state + kLanes * 13); - const Vector128 s14 = Vector128Load(state + kLanes * 14); - const Vector128 s15 = Vector128Load(state + kLanes * 15); + const Vector128 s0 = Vector128Load(state + 0); + const Vector128 s1 = Vector128Load(state + 1); + const Vector128 s2 = Vector128Load(state + 2); + const Vector128 s3 = Vector128Load(state + 3); + const Vector128 s4 = Vector128Load(state + 4); + const Vector128 s5 = Vector128Load(state + 5); + const Vector128 s6 = Vector128Load(state + 6); + const Vector128 s7 = Vector128Load(state + 7); + const Vector128 s8 = Vector128Load(state + 8); + const Vector128 s9 = Vector128Load(state + 9); + const Vector128 s10 = Vector128Load(state + 10); + const Vector128 s11 = Vector128Load(state + 11); + const Vector128 s12 = Vector128Load(state + 12); + const Vector128 s13 = Vector128Load(state + 13); + const Vector128 s14 = Vector128Load(state + 14); + const Vector128 s15 = Vector128Load(state + 15); // Encode even blocks with keys. const Vector128 e0 = AesRound(s0, Vector128Load(keys + 0)); @@ -486,14 +418,14 @@ inline ABSL_TARGET_CRYPTO const u64x2* FeistelRound( const Vector128 o15 = AesRound(e14, s15); // Store odd blocks. (These will be shuffled later). - Vector128Store(o1, state + kLanes * 1); - Vector128Store(o3, state + kLanes * 3); - Vector128Store(o5, state + kLanes * 5); - Vector128Store(o7, state + kLanes * 7); - Vector128Store(o9, state + kLanes * 9); - Vector128Store(o11, state + kLanes * 11); - Vector128Store(o13, state + kLanes * 13); - Vector128Store(o15, state + kLanes * 15); + Vector128Store(o1, state + 1); + Vector128Store(o3, state + 3); + Vector128Store(o5, state + 5); + Vector128Store(o7, state + 7); + Vector128Store(o9, state + 9); + Vector128Store(o11, state + 11); + Vector128Store(o13, state + 13); + Vector128Store(o15, state + 15); return keys + 8; } @@ -503,16 +435,13 @@ inline ABSL_TARGET_CRYPTO const u64x2* FeistelRound( // 2^64 queries if the round function is a PRF. This is similar to the b=8 case // of Simpira v2, but more efficient than its generic construction for b=16. inline ABSL_TARGET_CRYPTO void Permute( - const void* ABSL_RANDOM_INTERNAL_RESTRICT keys, uint64_t* state) { - const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys128 = - static_cast(keys); - + u64x2* state, const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys) { // (Successfully unrolled; the first iteration jumps into the second half) #ifdef __clang__ #pragma clang loop unroll_count(2) #endif - for (size_t round = 0; round < kFeistelRounds; ++round) { - keys128 = FeistelRound(state, keys128); + for (size_t round = 0; round < RandenTraits::kFeistelRounds; ++round) { + keys = FeistelRound(state, keys); BlockShuffle(state); } } @@ -528,96 +457,101 @@ bool HasRandenHwAesImplementation() { return true; } const void* ABSL_TARGET_CRYPTO RandenHwAes::GetKeys() { // Round keys for one AES per Feistel round and branch. // The canonical implementation uses first digits of Pi. - return round_keys; +#if defined(ABSL_ARCH_PPC) + return kRandenRoundKeysBE; +#else + return kRandenRoundKeys; +#endif } // NOLINTNEXTLINE void ABSL_TARGET_CRYPTO RandenHwAes::Absorb(const void* seed_void, void* state_void) { - auto* state = static_cast(state_void); - const auto* seed = static_cast(seed_void); - - constexpr size_t kCapacityBlocks = kCapacityBytes / sizeof(Vector128); - constexpr size_t kStateBlocks = kStateBytes / sizeof(Vector128); - - static_assert(kCapacityBlocks * sizeof(Vector128) == kCapacityBytes, - "Not i*V"); - static_assert(kCapacityBlocks == 1, "Unexpected Randen kCapacityBlocks"); - static_assert(kStateBlocks == 16, "Unexpected Randen kStateBlocks"); - - Vector128 b1 = Vector128Load(state + kLanes * 1); - b1 ^= Vector128Load(seed + kLanes * 0); - Vector128Store(b1, state + kLanes * 1); - - Vector128 b2 = Vector128Load(state + kLanes * 2); - b2 ^= Vector128Load(seed + kLanes * 1); - Vector128Store(b2, state + kLanes * 2); - - Vector128 b3 = Vector128Load(state + kLanes * 3); - b3 ^= Vector128Load(seed + kLanes * 2); - Vector128Store(b3, state + kLanes * 3); - - Vector128 b4 = Vector128Load(state + kLanes * 4); - b4 ^= Vector128Load(seed + kLanes * 3); - Vector128Store(b4, state + kLanes * 4); - - Vector128 b5 = Vector128Load(state + kLanes * 5); - b5 ^= Vector128Load(seed + kLanes * 4); - Vector128Store(b5, state + kLanes * 5); - - Vector128 b6 = Vector128Load(state + kLanes * 6); - b6 ^= Vector128Load(seed + kLanes * 5); - Vector128Store(b6, state + kLanes * 6); - - Vector128 b7 = Vector128Load(state + kLanes * 7); - b7 ^= Vector128Load(seed + kLanes * 6); - Vector128Store(b7, state + kLanes * 7); - - Vector128 b8 = Vector128Load(state + kLanes * 8); - b8 ^= Vector128Load(seed + kLanes * 7); - Vector128Store(b8, state + kLanes * 8); - - Vector128 b9 = Vector128Load(state + kLanes * 9); - b9 ^= Vector128Load(seed + kLanes * 8); - Vector128Store(b9, state + kLanes * 9); - - Vector128 b10 = Vector128Load(state + kLanes * 10); - b10 ^= Vector128Load(seed + kLanes * 9); - Vector128Store(b10, state + kLanes * 10); - - Vector128 b11 = Vector128Load(state + kLanes * 11); - b11 ^= Vector128Load(seed + kLanes * 10); - Vector128Store(b11, state + kLanes * 11); - - Vector128 b12 = Vector128Load(state + kLanes * 12); - b12 ^= Vector128Load(seed + kLanes * 11); - Vector128Store(b12, state + kLanes * 12); - - Vector128 b13 = Vector128Load(state + kLanes * 13); - b13 ^= Vector128Load(seed + kLanes * 12); - Vector128Store(b13, state + kLanes * 13); - - Vector128 b14 = Vector128Load(state + kLanes * 14); - b14 ^= Vector128Load(seed + kLanes * 13); - Vector128Store(b14, state + kLanes * 14); - - Vector128 b15 = Vector128Load(state + kLanes * 15); - b15 ^= Vector128Load(seed + kLanes * 14); - Vector128Store(b15, state + kLanes * 15); + static_assert(RandenTraits::kCapacityBytes / sizeof(Vector128) == 1, + "Unexpected Randen kCapacityBlocks"); + static_assert(RandenTraits::kStateBytes / sizeof(Vector128) == 16, + "Unexpected Randen kStateBlocks"); + + auto* state = + reinterpret_cast(state_void); + const auto* seed = + reinterpret_cast(seed_void); + + Vector128 b1 = Vector128Load(state + 1); + b1 ^= Vector128Load(seed + 0); + Vector128Store(b1, state + 1); + + Vector128 b2 = Vector128Load(state + 2); + b2 ^= Vector128Load(seed + 1); + Vector128Store(b2, state + 2); + + Vector128 b3 = Vector128Load(state + 3); + b3 ^= Vector128Load(seed + 2); + Vector128Store(b3, state + 3); + + Vector128 b4 = Vector128Load(state + 4); + b4 ^= Vector128Load(seed + 3); + Vector128Store(b4, state + 4); + + Vector128 b5 = Vector128Load(state + 5); + b5 ^= Vector128Load(seed + 4); + Vector128Store(b5, state + 5); + + Vector128 b6 = Vector128Load(state + 6); + b6 ^= Vector128Load(seed + 5); + Vector128Store(b6, state + 6); + + Vector128 b7 = Vector128Load(state + 7); + b7 ^= Vector128Load(seed + 6); + Vector128Store(b7, state + 7); + + Vector128 b8 = Vector128Load(state + 8); + b8 ^= Vector128Load(seed + 7); + Vector128Store(b8, state + 8); + + Vector128 b9 = Vector128Load(state + 9); + b9 ^= Vector128Load(seed + 8); + Vector128Store(b9, state + 9); + + Vector128 b10 = Vector128Load(state + 10); + b10 ^= Vector128Load(seed + 9); + Vector128Store(b10, state + 10); + + Vector128 b11 = Vector128Load(state + 11); + b11 ^= Vector128Load(seed + 10); + Vector128Store(b11, state + 11); + + Vector128 b12 = Vector128Load(state + 12); + b12 ^= Vector128Load(seed + 11); + Vector128Store(b12, state + 12); + + Vector128 b13 = Vector128Load(state + 13); + b13 ^= Vector128Load(seed + 12); + Vector128Store(b13, state + 13); + + Vector128 b14 = Vector128Load(state + 14); + b14 ^= Vector128Load(seed + 13); + Vector128Store(b14, state + 14); + + Vector128 b15 = Vector128Load(state + 15); + b15 ^= Vector128Load(seed + 14); + Vector128Store(b15, state + 15); } // NOLINTNEXTLINE -void ABSL_TARGET_CRYPTO RandenHwAes::Generate(const void* keys, +void ABSL_TARGET_CRYPTO RandenHwAes::Generate(const void* keys_void, void* state_void) { - static_assert(kCapacityBytes == sizeof(Vector128), "Capacity mismatch"); + static_assert(RandenTraits::kCapacityBytes == sizeof(Vector128), + "Capacity mismatch"); - auto* state = static_cast(state_void); + auto* state = reinterpret_cast(state_void); + const auto* keys = reinterpret_cast(keys_void); const Vector128 prev_inner = Vector128Load(state); SwapEndian(state); - Permute(keys, state); + Permute(state, keys); SwapEndian(state); diff --git a/absl/random/internal/randen_hwaes_test.cc b/absl/random/internal/randen_hwaes_test.cc index a7cbd46b..66ddb43f 100644 --- a/absl/random/internal/randen_hwaes_test.cc +++ b/absl/random/internal/randen_hwaes_test.cc @@ -27,12 +27,14 @@ namespace { using absl::random_internal::RandenHwAes; using absl::random_internal::RandenTraits; -struct randen { - static constexpr size_t kStateSizeT = - RandenTraits::kStateBytes / sizeof(uint64_t); +// Local state parameters. +constexpr size_t kSeedBytes = + RandenTraits::kStateBytes - RandenTraits::kCapacityBytes; +constexpr size_t kStateSizeT = RandenTraits::kStateBytes / sizeof(uint64_t); +constexpr size_t kSeedSizeT = kSeedBytes / sizeof(uint32_t); + +struct alignas(16) randen { uint64_t state[kStateSizeT]; - static constexpr size_t kSeedSizeT = - RandenTraits::kSeedBytes / sizeof(uint32_t); uint32_t seed[kSeedSizeT]; }; diff --git a/absl/random/internal/randen_round_keys.cc b/absl/random/internal/randen_round_keys.cc new file mode 100644 index 00000000..5fb3ca55 --- /dev/null +++ b/absl/random/internal/randen_round_keys.cc @@ -0,0 +1,462 @@ +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/random/internal/randen_traits.h" + +// This file contains only the round keys for randen. +// +// "Nothing up my sleeve" numbers from the first hex digits of Pi, obtained +// from http://hexpi.sourceforge.net/. The array was generated by following +// Python script: + +/* +python >tmp.cc << EOF +"""Generates Randen round keys array from pi-hex.62500.txt file.""" +import binascii + +KEYS = 17 * 8 + +def chunks(l, n): + """Yield successive n-sized chunks from l.""" + for i in range(0, len(l), n): + yield l[i:i + n] + +def pairwise(t): + """Transforms sequence into sequence of pairs.""" + it = iter(t) + return zip(it,it) + +def digits_from_pi(): + """Reads digits from hexpi.sourceforge.net file.""" + with open("pi-hex.62500.txt") as file: + return file.read() + +def digits_from_urandom(): + """Reads digits from /dev/urandom.""" + with open("/dev/urandom") as file: + return binascii.hexlify(file.read(KEYS * 16)) + +def print_row(b) + print(" 0x{0}, 0x{1}, 0x{2}, 0x{3}, 0x{4}, 0x{5}, 0x{6}, 0x{7}, 0x{8}, 0x{9}, +0x{10}, 0x{11}, 0x{12}, 0x{13}, 0x{14}, 0x{15},".format(*b)) + + +digits = digits_from_pi() +#digits = digits_from_urandom() + +print("namespace {") +print("static constexpr size_t kKeyBytes = {0};\n".format(KEYS * 16)) +print("}") + +print("alignas(16) const unsigned char kRandenRoundKeysBE[kKeyBytes] = {") + +for i, u16 in zip(range(KEYS), chunks(digits, 32)): + b = list(chunks(u16, 2)) + print_row(b) + +print("};") + +print("alignas(16) const unsigned char kRandenRoundKeys[kKeyBytes] = {") + +for i, u16 in zip(range(KEYS), chunks(digits, 32)): + b = list(chunks(u16, 2)) + b.reverse() + print_row(b) + +print("};") + +EOF + +*/ + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace random_internal { +namespace { +static constexpr size_t kKeyBytes = 2176; +} + +alignas(16) const unsigned char kRandenRoundKeysBE[kKeyBytes] = { + 0x24, 0x3F, 0x6A, 0x88, 0x85, 0xA3, 0x08, 0xD3, 0x13, 0x19, 0x8A, 0x2E, + 0x03, 0x70, 0x73, 0x44, 0xA4, 0x09, 0x38, 0x22, 0x29, 0x9F, 0x31, 0xD0, + 0x08, 0x2E, 0xFA, 0x98, 0xEC, 0x4E, 0x6C, 0x89, 0x45, 0x28, 0x21, 0xE6, + 0x38, 0xD0, 0x13, 0x77, 0xBE, 0x54, 0x66, 0xCF, 0x34, 0xE9, 0x0C, 0x6C, + 0xC0, 0xAC, 0x29, 0xB7, 0xC9, 0x7C, 0x50, 0xDD, 0x3F, 0x84, 0xD5, 0xB5, + 0xB5, 0x47, 0x09, 0x17, 0x92, 0x16, 0xD5, 0xD9, 0x89, 0x79, 0xFB, 0x1B, + 0xD1, 0x31, 0x0B, 0xA6, 0x98, 0xDF, 0xB5, 0xAC, 0x2F, 0xFD, 0x72, 0xDB, + 0xD0, 0x1A, 0xDF, 0xB7, 0xB8, 0xE1, 0xAF, 0xED, 0x6A, 0x26, 0x7E, 0x96, + 0xBA, 0x7C, 0x90, 0x45, 0xF1, 0x2C, 0x7F, 0x99, 0x24, 0xA1, 0x99, 0x47, + 0xB3, 0x91, 0x6C, 0xF7, 0x08, 0x01, 0xF2, 0xE2, 0x85, 0x8E, 0xFC, 0x16, + 0x63, 0x69, 0x20, 0xD8, 0x71, 0x57, 0x4E, 0x69, 0xA4, 0x58, 0xFE, 0xA3, + 0xF4, 0x93, 0x3D, 0x7E, 0x0D, 0x95, 0x74, 0x8F, 0x72, 0x8E, 0xB6, 0x58, + 0x71, 0x8B, 0xCD, 0x58, 0x82, 0x15, 0x4A, 0xEE, 0x7B, 0x54, 0xA4, 0x1D, + 0xC2, 0x5A, 0x59, 0xB5, 0x9C, 0x30, 0xD5, 0x39, 0x2A, 0xF2, 0x60, 0x13, + 0xC5, 0xD1, 0xB0, 0x23, 0x28, 0x60, 0x85, 0xF0, 0xCA, 0x41, 0x79, 0x18, + 0xB8, 0xDB, 0x38, 0xEF, 0x8E, 0x79, 0xDC, 0xB0, 0x60, 0x3A, 0x18, 0x0E, + 0x6C, 0x9E, 0x0E, 0x8B, 0xB0, 0x1E, 0x8A, 0x3E, 0xD7, 0x15, 0x77, 0xC1, + 0xBD, 0x31, 0x4B, 0x27, 0x78, 0xAF, 0x2F, 0xDA, 0x55, 0x60, 0x5C, 0x60, + 0xE6, 0x55, 0x25, 0xF3, 0xAA, 0x55, 0xAB, 0x94, 0x57, 0x48, 0x98, 0x62, + 0x63, 0xE8, 0x14, 0x40, 0x55, 0xCA, 0x39, 0x6A, 0x2A, 0xAB, 0x10, 0xB6, + 0xB4, 0xCC, 0x5C, 0x34, 0x11, 0x41, 0xE8, 0xCE, 0xA1, 0x54, 0x86, 0xAF, + 0x7C, 0x72, 0xE9, 0x93, 0xB3, 0xEE, 0x14, 0x11, 0x63, 0x6F, 0xBC, 0x2A, + 0x2B, 0xA9, 0xC5, 0x5D, 0x74, 0x18, 0x31, 0xF6, 0xCE, 0x5C, 0x3E, 0x16, + 0x9B, 0x87, 0x93, 0x1E, 0xAF, 0xD6, 0xBA, 0x33, 0x6C, 0x24, 0xCF, 0x5C, + 0x7A, 0x32, 0x53, 0x81, 0x28, 0x95, 0x86, 0x77, 0x3B, 0x8F, 0x48, 0x98, + 0x6B, 0x4B, 0xB9, 0xAF, 0xC4, 0xBF, 0xE8, 0x1B, 0x66, 0x28, 0x21, 0x93, + 0x61, 0xD8, 0x09, 0xCC, 0xFB, 0x21, 0xA9, 0x91, 0x48, 0x7C, 0xAC, 0x60, + 0x5D, 0xEC, 0x80, 0x32, 0xEF, 0x84, 0x5D, 0x5D, 0xE9, 0x85, 0x75, 0xB1, + 0xDC, 0x26, 0x23, 0x02, 0xEB, 0x65, 0x1B, 0x88, 0x23, 0x89, 0x3E, 0x81, + 0xD3, 0x96, 0xAC, 0xC5, 0x0F, 0x6D, 0x6F, 0xF3, 0x83, 0xF4, 0x42, 0x39, + 0x2E, 0x0B, 0x44, 0x82, 0xA4, 0x84, 0x20, 0x04, 0x69, 0xC8, 0xF0, 0x4A, + 0x9E, 0x1F, 0x9B, 0x5E, 0x21, 0xC6, 0x68, 0x42, 0xF6, 0xE9, 0x6C, 0x9A, + 0x67, 0x0C, 0x9C, 0x61, 0xAB, 0xD3, 0x88, 0xF0, 0x6A, 0x51, 0xA0, 0xD2, + 0xD8, 0x54, 0x2F, 0x68, 0x96, 0x0F, 0xA7, 0x28, 0xAB, 0x51, 0x33, 0xA3, + 0x6E, 0xEF, 0x0B, 0x6C, 0x13, 0x7A, 0x3B, 0xE4, 0xBA, 0x3B, 0xF0, 0x50, + 0x7E, 0xFB, 0x2A, 0x98, 0xA1, 0xF1, 0x65, 0x1D, 0x39, 0xAF, 0x01, 0x76, + 0x66, 0xCA, 0x59, 0x3E, 0x82, 0x43, 0x0E, 0x88, 0x8C, 0xEE, 0x86, 0x19, + 0x45, 0x6F, 0x9F, 0xB4, 0x7D, 0x84, 0xA5, 0xC3, 0x3B, 0x8B, 0x5E, 0xBE, + 0xE0, 0x6F, 0x75, 0xD8, 0x85, 0xC1, 0x20, 0x73, 0x40, 0x1A, 0x44, 0x9F, + 0x56, 0xC1, 0x6A, 0xA6, 0x4E, 0xD3, 0xAA, 0x62, 0x36, 0x3F, 0x77, 0x06, + 0x1B, 0xFE, 0xDF, 0x72, 0x42, 0x9B, 0x02, 0x3D, 0x37, 0xD0, 0xD7, 0x24, + 0xD0, 0x0A, 0x12, 0x48, 0xDB, 0x0F, 0xEA, 0xD3, 0x49, 0xF1, 0xC0, 0x9B, + 0x07, 0x53, 0x72, 0xC9, 0x80, 0x99, 0x1B, 0x7B, 0x25, 0xD4, 0x79, 0xD8, + 0xF6, 0xE8, 0xDE, 0xF7, 0xE3, 0xFE, 0x50, 0x1A, 0xB6, 0x79, 0x4C, 0x3B, + 0x97, 0x6C, 0xE0, 0xBD, 0x04, 0xC0, 0x06, 0xBA, 0xC1, 0xA9, 0x4F, 0xB6, + 0x40, 0x9F, 0x60, 0xC4, 0x5E, 0x5C, 0x9E, 0xC2, 0x19, 0x6A, 0x24, 0x63, + 0x68, 0xFB, 0x6F, 0xAF, 0x3E, 0x6C, 0x53, 0xB5, 0x13, 0x39, 0xB2, 0xEB, + 0x3B, 0x52, 0xEC, 0x6F, 0x6D, 0xFC, 0x51, 0x1F, 0x9B, 0x30, 0x95, 0x2C, + 0xCC, 0x81, 0x45, 0x44, 0xAF, 0x5E, 0xBD, 0x09, 0xBE, 0xE3, 0xD0, 0x04, + 0xDE, 0x33, 0x4A, 0xFD, 0x66, 0x0F, 0x28, 0x07, 0x19, 0x2E, 0x4B, 0xB3, + 0xC0, 0xCB, 0xA8, 0x57, 0x45, 0xC8, 0x74, 0x0F, 0xD2, 0x0B, 0x5F, 0x39, + 0xB9, 0xD3, 0xFB, 0xDB, 0x55, 0x79, 0xC0, 0xBD, 0x1A, 0x60, 0x32, 0x0A, + 0xD6, 0xA1, 0x00, 0xC6, 0x40, 0x2C, 0x72, 0x79, 0x67, 0x9F, 0x25, 0xFE, + 0xFB, 0x1F, 0xA3, 0xCC, 0x8E, 0xA5, 0xE9, 0xF8, 0xDB, 0x32, 0x22, 0xF8, + 0x3C, 0x75, 0x16, 0xDF, 0xFD, 0x61, 0x6B, 0x15, 0x2F, 0x50, 0x1E, 0xC8, + 0xAD, 0x05, 0x52, 0xAB, 0x32, 0x3D, 0xB5, 0xFA, 0xFD, 0x23, 0x87, 0x60, + 0x53, 0x31, 0x7B, 0x48, 0x3E, 0x00, 0xDF, 0x82, 0x9E, 0x5C, 0x57, 0xBB, + 0xCA, 0x6F, 0x8C, 0xA0, 0x1A, 0x87, 0x56, 0x2E, 0xDF, 0x17, 0x69, 0xDB, + 0xD5, 0x42, 0xA8, 0xF6, 0x28, 0x7E, 0xFF, 0xC3, 0xAC, 0x67, 0x32, 0xC6, + 0x8C, 0x4F, 0x55, 0x73, 0x69, 0x5B, 0x27, 0xB0, 0xBB, 0xCA, 0x58, 0xC8, + 0xE1, 0xFF, 0xA3, 0x5D, 0xB8, 0xF0, 0x11, 0xA0, 0x10, 0xFA, 0x3D, 0x98, + 0xFD, 0x21, 0x83, 0xB8, 0x4A, 0xFC, 0xB5, 0x6C, 0x2D, 0xD1, 0xD3, 0x5B, + 0x9A, 0x53, 0xE4, 0x79, 0xB6, 0xF8, 0x45, 0x65, 0xD2, 0x8E, 0x49, 0xBC, + 0x4B, 0xFB, 0x97, 0x90, 0xE1, 0xDD, 0xF2, 0xDA, 0xA4, 0xCB, 0x7E, 0x33, + 0x62, 0xFB, 0x13, 0x41, 0xCE, 0xE4, 0xC6, 0xE8, 0xEF, 0x20, 0xCA, 0xDA, + 0x36, 0x77, 0x4C, 0x01, 0xD0, 0x7E, 0x9E, 0xFE, 0x2B, 0xF1, 0x1F, 0xB4, + 0x95, 0xDB, 0xDA, 0x4D, 0xAE, 0x90, 0x91, 0x98, 0xEA, 0xAD, 0x8E, 0x71, + 0x6B, 0x93, 0xD5, 0xA0, 0xD0, 0x8E, 0xD1, 0xD0, 0xAF, 0xC7, 0x25, 0xE0, + 0x8E, 0x3C, 0x5B, 0x2F, 0x8E, 0x75, 0x94, 0xB7, 0x8F, 0xF6, 0xE2, 0xFB, + 0xF2, 0x12, 0x2B, 0x64, 0x88, 0x88, 0xB8, 0x12, 0x90, 0x0D, 0xF0, 0x1C, + 0x4F, 0xAD, 0x5E, 0xA0, 0x68, 0x8F, 0xC3, 0x1C, 0xD1, 0xCF, 0xF1, 0x91, + 0xB3, 0xA8, 0xC1, 0xAD, 0x2F, 0x2F, 0x22, 0x18, 0xBE, 0x0E, 0x17, 0x77, + 0xEA, 0x75, 0x2D, 0xFE, 0x8B, 0x02, 0x1F, 0xA1, 0xE5, 0xA0, 0xCC, 0x0F, + 0xB5, 0x6F, 0x74, 0xE8, 0x18, 0xAC, 0xF3, 0xD6, 0xCE, 0x89, 0xE2, 0x99, + 0xB4, 0xA8, 0x4F, 0xE0, 0xFD, 0x13, 0xE0, 0xB7, 0x7C, 0xC4, 0x3B, 0x81, + 0xD2, 0xAD, 0xA8, 0xD9, 0x16, 0x5F, 0xA2, 0x66, 0x80, 0x95, 0x77, 0x05, + 0x93, 0xCC, 0x73, 0x14, 0x21, 0x1A, 0x14, 0x77, 0xE6, 0xAD, 0x20, 0x65, + 0x77, 0xB5, 0xFA, 0x86, 0xC7, 0x54, 0x42, 0xF5, 0xFB, 0x9D, 0x35, 0xCF, + 0xEB, 0xCD, 0xAF, 0x0C, 0x7B, 0x3E, 0x89, 0xA0, 0xD6, 0x41, 0x1B, 0xD3, + 0xAE, 0x1E, 0x7E, 0x49, 0x00, 0x25, 0x0E, 0x2D, 0x20, 0x71, 0xB3, 0x5E, + 0x22, 0x68, 0x00, 0xBB, 0x57, 0xB8, 0xE0, 0xAF, 0x24, 0x64, 0x36, 0x9B, + 0xF0, 0x09, 0xB9, 0x1E, 0x55, 0x63, 0x91, 0x1D, 0x59, 0xDF, 0xA6, 0xAA, + 0x78, 0xC1, 0x43, 0x89, 0xD9, 0x5A, 0x53, 0x7F, 0x20, 0x7D, 0x5B, 0xA2, + 0x02, 0xE5, 0xB9, 0xC5, 0x83, 0x26, 0x03, 0x76, 0x62, 0x95, 0xCF, 0xA9, + 0x11, 0xC8, 0x19, 0x68, 0x4E, 0x73, 0x4A, 0x41, 0xB3, 0x47, 0x2D, 0xCA, + 0x7B, 0x14, 0xA9, 0x4A, 0x1B, 0x51, 0x00, 0x52, 0x9A, 0x53, 0x29, 0x15, + 0xD6, 0x0F, 0x57, 0x3F, 0xBC, 0x9B, 0xC6, 0xE4, 0x2B, 0x60, 0xA4, 0x76, + 0x81, 0xE6, 0x74, 0x00, 0x08, 0xBA, 0x6F, 0xB5, 0x57, 0x1B, 0xE9, 0x1F, + 0xF2, 0x96, 0xEC, 0x6B, 0x2A, 0x0D, 0xD9, 0x15, 0xB6, 0x63, 0x65, 0x21, + 0xE7, 0xB9, 0xF9, 0xB6, 0xFF, 0x34, 0x05, 0x2E, 0xC5, 0x85, 0x56, 0x64, + 0x53, 0xB0, 0x2D, 0x5D, 0xA9, 0x9F, 0x8F, 0xA1, 0x08, 0xBA, 0x47, 0x99, + 0x6E, 0x85, 0x07, 0x6A, 0x4B, 0x7A, 0x70, 0xE9, 0xB5, 0xB3, 0x29, 0x44, + 0xDB, 0x75, 0x09, 0x2E, 0xC4, 0x19, 0x26, 0x23, 0xAD, 0x6E, 0xA6, 0xB0, + 0x49, 0xA7, 0xDF, 0x7D, 0x9C, 0xEE, 0x60, 0xB8, 0x8F, 0xED, 0xB2, 0x66, + 0xEC, 0xAA, 0x8C, 0x71, 0x69, 0x9A, 0x18, 0xFF, 0x56, 0x64, 0x52, 0x6C, + 0xC2, 0xB1, 0x9E, 0xE1, 0x19, 0x36, 0x02, 0xA5, 0x75, 0x09, 0x4C, 0x29, + 0xA0, 0x59, 0x13, 0x40, 0xE4, 0x18, 0x3A, 0x3E, 0x3F, 0x54, 0x98, 0x9A, + 0x5B, 0x42, 0x9D, 0x65, 0x6B, 0x8F, 0xE4, 0xD6, 0x99, 0xF7, 0x3F, 0xD6, + 0xA1, 0xD2, 0x9C, 0x07, 0xEF, 0xE8, 0x30, 0xF5, 0x4D, 0x2D, 0x38, 0xE6, + 0xF0, 0x25, 0x5D, 0xC1, 0x4C, 0xDD, 0x20, 0x86, 0x84, 0x70, 0xEB, 0x26, + 0x63, 0x82, 0xE9, 0xC6, 0x02, 0x1E, 0xCC, 0x5E, 0x09, 0x68, 0x6B, 0x3F, + 0x3E, 0xBA, 0xEF, 0xC9, 0x3C, 0x97, 0x18, 0x14, 0x6B, 0x6A, 0x70, 0xA1, + 0x68, 0x7F, 0x35, 0x84, 0x52, 0xA0, 0xE2, 0x86, 0xB7, 0x9C, 0x53, 0x05, + 0xAA, 0x50, 0x07, 0x37, 0x3E, 0x07, 0x84, 0x1C, 0x7F, 0xDE, 0xAE, 0x5C, + 0x8E, 0x7D, 0x44, 0xEC, 0x57, 0x16, 0xF2, 0xB8, 0xB0, 0x3A, 0xDA, 0x37, + 0xF0, 0x50, 0x0C, 0x0D, 0xF0, 0x1C, 0x1F, 0x04, 0x02, 0x00, 0xB3, 0xFF, + 0xAE, 0x0C, 0xF5, 0x1A, 0x3C, 0xB5, 0x74, 0xB2, 0x25, 0x83, 0x7A, 0x58, + 0xDC, 0x09, 0x21, 0xBD, 0xD1, 0x91, 0x13, 0xF9, 0x7C, 0xA9, 0x2F, 0xF6, + 0x94, 0x32, 0x47, 0x73, 0x22, 0xF5, 0x47, 0x01, 0x3A, 0xE5, 0xE5, 0x81, + 0x37, 0xC2, 0xDA, 0xDC, 0xC8, 0xB5, 0x76, 0x34, 0x9A, 0xF3, 0xDD, 0xA7, + 0xA9, 0x44, 0x61, 0x46, 0x0F, 0xD0, 0x03, 0x0E, 0xEC, 0xC8, 0xC7, 0x3E, + 0xA4, 0x75, 0x1E, 0x41, 0xE2, 0x38, 0xCD, 0x99, 0x3B, 0xEA, 0x0E, 0x2F, + 0x32, 0x80, 0xBB, 0xA1, 0x18, 0x3E, 0xB3, 0x31, 0x4E, 0x54, 0x8B, 0x38, + 0x4F, 0x6D, 0xB9, 0x08, 0x6F, 0x42, 0x0D, 0x03, 0xF6, 0x0A, 0x04, 0xBF, + 0x2C, 0xB8, 0x12, 0x90, 0x24, 0x97, 0x7C, 0x79, 0x56, 0x79, 0xB0, 0x72, + 0xBC, 0xAF, 0x89, 0xAF, 0xDE, 0x9A, 0x77, 0x1F, 0xD9, 0x93, 0x08, 0x10, + 0xB3, 0x8B, 0xAE, 0x12, 0xDC, 0xCF, 0x3F, 0x2E, 0x55, 0x12, 0x72, 0x1F, + 0x2E, 0x6B, 0x71, 0x24, 0x50, 0x1A, 0xDD, 0xE6, 0x9F, 0x84, 0xCD, 0x87, + 0x7A, 0x58, 0x47, 0x18, 0x74, 0x08, 0xDA, 0x17, 0xBC, 0x9F, 0x9A, 0xBC, + 0xE9, 0x4B, 0x7D, 0x8C, 0xEC, 0x7A, 0xEC, 0x3A, 0xDB, 0x85, 0x1D, 0xFA, + 0x63, 0x09, 0x43, 0x66, 0xC4, 0x64, 0xC3, 0xD2, 0xEF, 0x1C, 0x18, 0x47, + 0x32, 0x15, 0xD8, 0x08, 0xDD, 0x43, 0x3B, 0x37, 0x24, 0xC2, 0xBA, 0x16, + 0x12, 0xA1, 0x4D, 0x43, 0x2A, 0x65, 0xC4, 0x51, 0x50, 0x94, 0x00, 0x02, + 0x13, 0x3A, 0xE4, 0xDD, 0x71, 0xDF, 0xF8, 0x9E, 0x10, 0x31, 0x4E, 0x55, + 0x81, 0xAC, 0x77, 0xD6, 0x5F, 0x11, 0x19, 0x9B, 0x04, 0x35, 0x56, 0xF1, + 0xD7, 0xA3, 0xC7, 0x6B, 0x3C, 0x11, 0x18, 0x3B, 0x59, 0x24, 0xA5, 0x09, + 0xF2, 0x8F, 0xE6, 0xED, 0x97, 0xF1, 0xFB, 0xFA, 0x9E, 0xBA, 0xBF, 0x2C, + 0x1E, 0x15, 0x3C, 0x6E, 0x86, 0xE3, 0x45, 0x70, 0xEA, 0xE9, 0x6F, 0xB1, + 0x86, 0x0E, 0x5E, 0x0A, 0x5A, 0x3E, 0x2A, 0xB3, 0x77, 0x1F, 0xE7, 0x1C, + 0x4E, 0x3D, 0x06, 0xFA, 0x29, 0x65, 0xDC, 0xB9, 0x99, 0xE7, 0x1D, 0x0F, + 0x80, 0x3E, 0x89, 0xD6, 0x52, 0x66, 0xC8, 0x25, 0x2E, 0x4C, 0xC9, 0x78, + 0x9C, 0x10, 0xB3, 0x6A, 0xC6, 0x15, 0x0E, 0xBA, 0x94, 0xE2, 0xEA, 0x78, + 0xA6, 0xFC, 0x3C, 0x53, 0x1E, 0x0A, 0x2D, 0xF4, 0xF2, 0xF7, 0x4E, 0xA7, + 0x36, 0x1D, 0x2B, 0x3D, 0x19, 0x39, 0x26, 0x0F, 0x19, 0xC2, 0x79, 0x60, + 0x52, 0x23, 0xA7, 0x08, 0xF7, 0x13, 0x12, 0xB6, 0xEB, 0xAD, 0xFE, 0x6E, + 0xEA, 0xC3, 0x1F, 0x66, 0xE3, 0xBC, 0x45, 0x95, 0xA6, 0x7B, 0xC8, 0x83, + 0xB1, 0x7F, 0x37, 0xD1, 0x01, 0x8C, 0xFF, 0x28, 0xC3, 0x32, 0xDD, 0xEF, + 0xBE, 0x6C, 0x5A, 0xA5, 0x65, 0x58, 0x21, 0x85, 0x68, 0xAB, 0x97, 0x02, + 0xEE, 0xCE, 0xA5, 0x0F, 0xDB, 0x2F, 0x95, 0x3B, 0x2A, 0xEF, 0x7D, 0xAD, + 0x5B, 0x6E, 0x2F, 0x84, 0x15, 0x21, 0xB6, 0x28, 0x29, 0x07, 0x61, 0x70, + 0xEC, 0xDD, 0x47, 0x75, 0x61, 0x9F, 0x15, 0x10, 0x13, 0xCC, 0xA8, 0x30, + 0xEB, 0x61, 0xBD, 0x96, 0x03, 0x34, 0xFE, 0x1E, 0xAA, 0x03, 0x63, 0xCF, + 0xB5, 0x73, 0x5C, 0x90, 0x4C, 0x70, 0xA2, 0x39, 0xD5, 0x9E, 0x9E, 0x0B, + 0xCB, 0xAA, 0xDE, 0x14, 0xEE, 0xCC, 0x86, 0xBC, 0x60, 0x62, 0x2C, 0xA7, + 0x9C, 0xAB, 0x5C, 0xAB, 0xB2, 0xF3, 0x84, 0x6E, 0x64, 0x8B, 0x1E, 0xAF, + 0x19, 0xBD, 0xF0, 0xCA, 0xA0, 0x23, 0x69, 0xB9, 0x65, 0x5A, 0xBB, 0x50, + 0x40, 0x68, 0x5A, 0x32, 0x3C, 0x2A, 0xB4, 0xB3, 0x31, 0x9E, 0xE9, 0xD5, + 0xC0, 0x21, 0xB8, 0xF7, 0x9B, 0x54, 0x0B, 0x19, 0x87, 0x5F, 0xA0, 0x99, + 0x95, 0xF7, 0x99, 0x7E, 0x62, 0x3D, 0x7D, 0xA8, 0xF8, 0x37, 0x88, 0x9A, + 0x97, 0xE3, 0x2D, 0x77, 0x11, 0xED, 0x93, 0x5F, 0x16, 0x68, 0x12, 0x81, + 0x0E, 0x35, 0x88, 0x29, 0xC7, 0xE6, 0x1F, 0xD6, 0x96, 0xDE, 0xDF, 0xA1, + 0x78, 0x58, 0xBA, 0x99, 0x57, 0xF5, 0x84, 0xA5, 0x1B, 0x22, 0x72, 0x63, + 0x9B, 0x83, 0xC3, 0xFF, 0x1A, 0xC2, 0x46, 0x96, 0xCD, 0xB3, 0x0A, 0xEB, + 0x53, 0x2E, 0x30, 0x54, 0x8F, 0xD9, 0x48, 0xE4, 0x6D, 0xBC, 0x31, 0x28, + 0x58, 0xEB, 0xF2, 0xEF, 0x34, 0xC6, 0xFF, 0xEA, 0xFE, 0x28, 0xED, 0x61, + 0xEE, 0x7C, 0x3C, 0x73, 0x5D, 0x4A, 0x14, 0xD9, 0xE8, 0x64, 0xB7, 0xE3, + 0x42, 0x10, 0x5D, 0x14, 0x20, 0x3E, 0x13, 0xE0, 0x45, 0xEE, 0xE2, 0xB6, + 0xA3, 0xAA, 0xAB, 0xEA, 0xDB, 0x6C, 0x4F, 0x15, 0xFA, 0xCB, 0x4F, 0xD0, + 0xC7, 0x42, 0xF4, 0x42, 0xEF, 0x6A, 0xBB, 0xB5, 0x65, 0x4F, 0x3B, 0x1D, + 0x41, 0xCD, 0x21, 0x05, 0xD8, 0x1E, 0x79, 0x9E, 0x86, 0x85, 0x4D, 0xC7, + 0xE4, 0x4B, 0x47, 0x6A, 0x3D, 0x81, 0x62, 0x50, 0xCF, 0x62, 0xA1, 0xF2, + 0x5B, 0x8D, 0x26, 0x46, 0xFC, 0x88, 0x83, 0xA0, 0xC1, 0xC7, 0xB6, 0xA3, + 0x7F, 0x15, 0x24, 0xC3, 0x69, 0xCB, 0x74, 0x92, 0x47, 0x84, 0x8A, 0x0B, + 0x56, 0x92, 0xB2, 0x85, 0x09, 0x5B, 0xBF, 0x00, 0xAD, 0x19, 0x48, 0x9D, + 0x14, 0x62, 0xB1, 0x74, 0x23, 0x82, 0x0D, 0x00, 0x58, 0x42, 0x8D, 0x2A, + 0x0C, 0x55, 0xF5, 0xEA, 0x1D, 0xAD, 0xF4, 0x3E, 0x23, 0x3F, 0x70, 0x61, + 0x33, 0x72, 0xF0, 0x92, 0x8D, 0x93, 0x7E, 0x41, 0xD6, 0x5F, 0xEC, 0xF1, + 0x6C, 0x22, 0x3B, 0xDB, 0x7C, 0xDE, 0x37, 0x59, 0xCB, 0xEE, 0x74, 0x60, + 0x40, 0x85, 0xF2, 0xA7, 0xCE, 0x77, 0x32, 0x6E, 0xA6, 0x07, 0x80, 0x84, + 0x19, 0xF8, 0x50, 0x9E, 0xE8, 0xEF, 0xD8, 0x55, 0x61, 0xD9, 0x97, 0x35, + 0xA9, 0x69, 0xA7, 0xAA, 0xC5, 0x0C, 0x06, 0xC2, 0x5A, 0x04, 0xAB, 0xFC, + 0x80, 0x0B, 0xCA, 0xDC, 0x9E, 0x44, 0x7A, 0x2E, 0xC3, 0x45, 0x34, 0x84, + 0xFD, 0xD5, 0x67, 0x05, 0x0E, 0x1E, 0x9E, 0xC9, 0xDB, 0x73, 0xDB, 0xD3, + 0x10, 0x55, 0x88, 0xCD, 0x67, 0x5F, 0xDA, 0x79, 0xE3, 0x67, 0x43, 0x40, + 0xC5, 0xC4, 0x34, 0x65, 0x71, 0x3E, 0x38, 0xD8, 0x3D, 0x28, 0xF8, 0x9E, + 0xF1, 0x6D, 0xFF, 0x20, 0x15, 0x3E, 0x21, 0xE7, 0x8F, 0xB0, 0x3D, 0x4A, + 0xE6, 0xE3, 0x9F, 0x2B, 0xDB, 0x83, 0xAD, 0xF7, 0xE9, 0x3D, 0x5A, 0x68, + 0x94, 0x81, 0x40, 0xF7, 0xF6, 0x4C, 0x26, 0x1C, 0x94, 0x69, 0x29, 0x34, + 0x41, 0x15, 0x20, 0xF7, 0x76, 0x02, 0xD4, 0xF7, 0xBC, 0xF4, 0x6B, 0x2E, + 0xD4, 0xA1, 0x00, 0x68, 0xD4, 0x08, 0x24, 0x71, 0x33, 0x20, 0xF4, 0x6A, + 0x43, 0xB7, 0xD4, 0xB7, 0x50, 0x00, 0x61, 0xAF, 0x1E, 0x39, 0xF6, 0x2E, + 0x97, 0x24, 0x45, 0x46, +}; + +alignas(16) const unsigned char kRandenRoundKeys[kKeyBytes] = { + 0x44, 0x73, 0x70, 0x03, 0x2E, 0x8A, 0x19, 0x13, 0xD3, 0x08, 0xA3, 0x85, + 0x88, 0x6A, 0x3F, 0x24, 0x89, 0x6C, 0x4E, 0xEC, 0x98, 0xFA, 0x2E, 0x08, + 0xD0, 0x31, 0x9F, 0x29, 0x22, 0x38, 0x09, 0xA4, 0x6C, 0x0C, 0xE9, 0x34, + 0xCF, 0x66, 0x54, 0xBE, 0x77, 0x13, 0xD0, 0x38, 0xE6, 0x21, 0x28, 0x45, + 0x17, 0x09, 0x47, 0xB5, 0xB5, 0xD5, 0x84, 0x3F, 0xDD, 0x50, 0x7C, 0xC9, + 0xB7, 0x29, 0xAC, 0xC0, 0xAC, 0xB5, 0xDF, 0x98, 0xA6, 0x0B, 0x31, 0xD1, + 0x1B, 0xFB, 0x79, 0x89, 0xD9, 0xD5, 0x16, 0x92, 0x96, 0x7E, 0x26, 0x6A, + 0xED, 0xAF, 0xE1, 0xB8, 0xB7, 0xDF, 0x1A, 0xD0, 0xDB, 0x72, 0xFD, 0x2F, + 0xF7, 0x6C, 0x91, 0xB3, 0x47, 0x99, 0xA1, 0x24, 0x99, 0x7F, 0x2C, 0xF1, + 0x45, 0x90, 0x7C, 0xBA, 0x69, 0x4E, 0x57, 0x71, 0xD8, 0x20, 0x69, 0x63, + 0x16, 0xFC, 0x8E, 0x85, 0xE2, 0xF2, 0x01, 0x08, 0x58, 0xB6, 0x8E, 0x72, + 0x8F, 0x74, 0x95, 0x0D, 0x7E, 0x3D, 0x93, 0xF4, 0xA3, 0xFE, 0x58, 0xA4, + 0xB5, 0x59, 0x5A, 0xC2, 0x1D, 0xA4, 0x54, 0x7B, 0xEE, 0x4A, 0x15, 0x82, + 0x58, 0xCD, 0x8B, 0x71, 0xF0, 0x85, 0x60, 0x28, 0x23, 0xB0, 0xD1, 0xC5, + 0x13, 0x60, 0xF2, 0x2A, 0x39, 0xD5, 0x30, 0x9C, 0x0E, 0x18, 0x3A, 0x60, + 0xB0, 0xDC, 0x79, 0x8E, 0xEF, 0x38, 0xDB, 0xB8, 0x18, 0x79, 0x41, 0xCA, + 0x27, 0x4B, 0x31, 0xBD, 0xC1, 0x77, 0x15, 0xD7, 0x3E, 0x8A, 0x1E, 0xB0, + 0x8B, 0x0E, 0x9E, 0x6C, 0x94, 0xAB, 0x55, 0xAA, 0xF3, 0x25, 0x55, 0xE6, + 0x60, 0x5C, 0x60, 0x55, 0xDA, 0x2F, 0xAF, 0x78, 0xB6, 0x10, 0xAB, 0x2A, + 0x6A, 0x39, 0xCA, 0x55, 0x40, 0x14, 0xE8, 0x63, 0x62, 0x98, 0x48, 0x57, + 0x93, 0xE9, 0x72, 0x7C, 0xAF, 0x86, 0x54, 0xA1, 0xCE, 0xE8, 0x41, 0x11, + 0x34, 0x5C, 0xCC, 0xB4, 0xF6, 0x31, 0x18, 0x74, 0x5D, 0xC5, 0xA9, 0x2B, + 0x2A, 0xBC, 0x6F, 0x63, 0x11, 0x14, 0xEE, 0xB3, 0x5C, 0xCF, 0x24, 0x6C, + 0x33, 0xBA, 0xD6, 0xAF, 0x1E, 0x93, 0x87, 0x9B, 0x16, 0x3E, 0x5C, 0xCE, + 0xAF, 0xB9, 0x4B, 0x6B, 0x98, 0x48, 0x8F, 0x3B, 0x77, 0x86, 0x95, 0x28, + 0x81, 0x53, 0x32, 0x7A, 0x91, 0xA9, 0x21, 0xFB, 0xCC, 0x09, 0xD8, 0x61, + 0x93, 0x21, 0x28, 0x66, 0x1B, 0xE8, 0xBF, 0xC4, 0xB1, 0x75, 0x85, 0xE9, + 0x5D, 0x5D, 0x84, 0xEF, 0x32, 0x80, 0xEC, 0x5D, 0x60, 0xAC, 0x7C, 0x48, + 0xC5, 0xAC, 0x96, 0xD3, 0x81, 0x3E, 0x89, 0x23, 0x88, 0x1B, 0x65, 0xEB, + 0x02, 0x23, 0x26, 0xDC, 0x04, 0x20, 0x84, 0xA4, 0x82, 0x44, 0x0B, 0x2E, + 0x39, 0x42, 0xF4, 0x83, 0xF3, 0x6F, 0x6D, 0x0F, 0x9A, 0x6C, 0xE9, 0xF6, + 0x42, 0x68, 0xC6, 0x21, 0x5E, 0x9B, 0x1F, 0x9E, 0x4A, 0xF0, 0xC8, 0x69, + 0x68, 0x2F, 0x54, 0xD8, 0xD2, 0xA0, 0x51, 0x6A, 0xF0, 0x88, 0xD3, 0xAB, + 0x61, 0x9C, 0x0C, 0x67, 0xE4, 0x3B, 0x7A, 0x13, 0x6C, 0x0B, 0xEF, 0x6E, + 0xA3, 0x33, 0x51, 0xAB, 0x28, 0xA7, 0x0F, 0x96, 0x76, 0x01, 0xAF, 0x39, + 0x1D, 0x65, 0xF1, 0xA1, 0x98, 0x2A, 0xFB, 0x7E, 0x50, 0xF0, 0x3B, 0xBA, + 0xB4, 0x9F, 0x6F, 0x45, 0x19, 0x86, 0xEE, 0x8C, 0x88, 0x0E, 0x43, 0x82, + 0x3E, 0x59, 0xCA, 0x66, 0x73, 0x20, 0xC1, 0x85, 0xD8, 0x75, 0x6F, 0xE0, + 0xBE, 0x5E, 0x8B, 0x3B, 0xC3, 0xA5, 0x84, 0x7D, 0x06, 0x77, 0x3F, 0x36, + 0x62, 0xAA, 0xD3, 0x4E, 0xA6, 0x6A, 0xC1, 0x56, 0x9F, 0x44, 0x1A, 0x40, + 0x48, 0x12, 0x0A, 0xD0, 0x24, 0xD7, 0xD0, 0x37, 0x3D, 0x02, 0x9B, 0x42, + 0x72, 0xDF, 0xFE, 0x1B, 0x7B, 0x1B, 0x99, 0x80, 0xC9, 0x72, 0x53, 0x07, + 0x9B, 0xC0, 0xF1, 0x49, 0xD3, 0xEA, 0x0F, 0xDB, 0x3B, 0x4C, 0x79, 0xB6, + 0x1A, 0x50, 0xFE, 0xE3, 0xF7, 0xDE, 0xE8, 0xF6, 0xD8, 0x79, 0xD4, 0x25, + 0xC4, 0x60, 0x9F, 0x40, 0xB6, 0x4F, 0xA9, 0xC1, 0xBA, 0x06, 0xC0, 0x04, + 0xBD, 0xE0, 0x6C, 0x97, 0xB5, 0x53, 0x6C, 0x3E, 0xAF, 0x6F, 0xFB, 0x68, + 0x63, 0x24, 0x6A, 0x19, 0xC2, 0x9E, 0x5C, 0x5E, 0x2C, 0x95, 0x30, 0x9B, + 0x1F, 0x51, 0xFC, 0x6D, 0x6F, 0xEC, 0x52, 0x3B, 0xEB, 0xB2, 0x39, 0x13, + 0xFD, 0x4A, 0x33, 0xDE, 0x04, 0xD0, 0xE3, 0xBE, 0x09, 0xBD, 0x5E, 0xAF, + 0x44, 0x45, 0x81, 0xCC, 0x0F, 0x74, 0xC8, 0x45, 0x57, 0xA8, 0xCB, 0xC0, + 0xB3, 0x4B, 0x2E, 0x19, 0x07, 0x28, 0x0F, 0x66, 0x0A, 0x32, 0x60, 0x1A, + 0xBD, 0xC0, 0x79, 0x55, 0xDB, 0xFB, 0xD3, 0xB9, 0x39, 0x5F, 0x0B, 0xD2, + 0xCC, 0xA3, 0x1F, 0xFB, 0xFE, 0x25, 0x9F, 0x67, 0x79, 0x72, 0x2C, 0x40, + 0xC6, 0x00, 0xA1, 0xD6, 0x15, 0x6B, 0x61, 0xFD, 0xDF, 0x16, 0x75, 0x3C, + 0xF8, 0x22, 0x32, 0xDB, 0xF8, 0xE9, 0xA5, 0x8E, 0x60, 0x87, 0x23, 0xFD, + 0xFA, 0xB5, 0x3D, 0x32, 0xAB, 0x52, 0x05, 0xAD, 0xC8, 0x1E, 0x50, 0x2F, + 0xA0, 0x8C, 0x6F, 0xCA, 0xBB, 0x57, 0x5C, 0x9E, 0x82, 0xDF, 0x00, 0x3E, + 0x48, 0x7B, 0x31, 0x53, 0xC3, 0xFF, 0x7E, 0x28, 0xF6, 0xA8, 0x42, 0xD5, + 0xDB, 0x69, 0x17, 0xDF, 0x2E, 0x56, 0x87, 0x1A, 0xC8, 0x58, 0xCA, 0xBB, + 0xB0, 0x27, 0x5B, 0x69, 0x73, 0x55, 0x4F, 0x8C, 0xC6, 0x32, 0x67, 0xAC, + 0xB8, 0x83, 0x21, 0xFD, 0x98, 0x3D, 0xFA, 0x10, 0xA0, 0x11, 0xF0, 0xB8, + 0x5D, 0xA3, 0xFF, 0xE1, 0x65, 0x45, 0xF8, 0xB6, 0x79, 0xE4, 0x53, 0x9A, + 0x5B, 0xD3, 0xD1, 0x2D, 0x6C, 0xB5, 0xFC, 0x4A, 0x33, 0x7E, 0xCB, 0xA4, + 0xDA, 0xF2, 0xDD, 0xE1, 0x90, 0x97, 0xFB, 0x4B, 0xBC, 0x49, 0x8E, 0xD2, + 0x01, 0x4C, 0x77, 0x36, 0xDA, 0xCA, 0x20, 0xEF, 0xE8, 0xC6, 0xE4, 0xCE, + 0x41, 0x13, 0xFB, 0x62, 0x98, 0x91, 0x90, 0xAE, 0x4D, 0xDA, 0xDB, 0x95, + 0xB4, 0x1F, 0xF1, 0x2B, 0xFE, 0x9E, 0x7E, 0xD0, 0xE0, 0x25, 0xC7, 0xAF, + 0xD0, 0xD1, 0x8E, 0xD0, 0xA0, 0xD5, 0x93, 0x6B, 0x71, 0x8E, 0xAD, 0xEA, + 0x64, 0x2B, 0x12, 0xF2, 0xFB, 0xE2, 0xF6, 0x8F, 0xB7, 0x94, 0x75, 0x8E, + 0x2F, 0x5B, 0x3C, 0x8E, 0x1C, 0xC3, 0x8F, 0x68, 0xA0, 0x5E, 0xAD, 0x4F, + 0x1C, 0xF0, 0x0D, 0x90, 0x12, 0xB8, 0x88, 0x88, 0x77, 0x17, 0x0E, 0xBE, + 0x18, 0x22, 0x2F, 0x2F, 0xAD, 0xC1, 0xA8, 0xB3, 0x91, 0xF1, 0xCF, 0xD1, + 0xE8, 0x74, 0x6F, 0xB5, 0x0F, 0xCC, 0xA0, 0xE5, 0xA1, 0x1F, 0x02, 0x8B, + 0xFE, 0x2D, 0x75, 0xEA, 0xB7, 0xE0, 0x13, 0xFD, 0xE0, 0x4F, 0xA8, 0xB4, + 0x99, 0xE2, 0x89, 0xCE, 0xD6, 0xF3, 0xAC, 0x18, 0x05, 0x77, 0x95, 0x80, + 0x66, 0xA2, 0x5F, 0x16, 0xD9, 0xA8, 0xAD, 0xD2, 0x81, 0x3B, 0xC4, 0x7C, + 0x86, 0xFA, 0xB5, 0x77, 0x65, 0x20, 0xAD, 0xE6, 0x77, 0x14, 0x1A, 0x21, + 0x14, 0x73, 0xCC, 0x93, 0xA0, 0x89, 0x3E, 0x7B, 0x0C, 0xAF, 0xCD, 0xEB, + 0xCF, 0x35, 0x9D, 0xFB, 0xF5, 0x42, 0x54, 0xC7, 0x5E, 0xB3, 0x71, 0x20, + 0x2D, 0x0E, 0x25, 0x00, 0x49, 0x7E, 0x1E, 0xAE, 0xD3, 0x1B, 0x41, 0xD6, + 0x1E, 0xB9, 0x09, 0xF0, 0x9B, 0x36, 0x64, 0x24, 0xAF, 0xE0, 0xB8, 0x57, + 0xBB, 0x00, 0x68, 0x22, 0x7F, 0x53, 0x5A, 0xD9, 0x89, 0x43, 0xC1, 0x78, + 0xAA, 0xA6, 0xDF, 0x59, 0x1D, 0x91, 0x63, 0x55, 0xA9, 0xCF, 0x95, 0x62, + 0x76, 0x03, 0x26, 0x83, 0xC5, 0xB9, 0xE5, 0x02, 0xA2, 0x5B, 0x7D, 0x20, + 0x4A, 0xA9, 0x14, 0x7B, 0xCA, 0x2D, 0x47, 0xB3, 0x41, 0x4A, 0x73, 0x4E, + 0x68, 0x19, 0xC8, 0x11, 0xE4, 0xC6, 0x9B, 0xBC, 0x3F, 0x57, 0x0F, 0xD6, + 0x15, 0x29, 0x53, 0x9A, 0x52, 0x00, 0x51, 0x1B, 0x1F, 0xE9, 0x1B, 0x57, + 0xB5, 0x6F, 0xBA, 0x08, 0x00, 0x74, 0xE6, 0x81, 0x76, 0xA4, 0x60, 0x2B, + 0xB6, 0xF9, 0xB9, 0xE7, 0x21, 0x65, 0x63, 0xB6, 0x15, 0xD9, 0x0D, 0x2A, + 0x6B, 0xEC, 0x96, 0xF2, 0xA1, 0x8F, 0x9F, 0xA9, 0x5D, 0x2D, 0xB0, 0x53, + 0x64, 0x56, 0x85, 0xC5, 0x2E, 0x05, 0x34, 0xFF, 0x44, 0x29, 0xB3, 0xB5, + 0xE9, 0x70, 0x7A, 0x4B, 0x6A, 0x07, 0x85, 0x6E, 0x99, 0x47, 0xBA, 0x08, + 0x7D, 0xDF, 0xA7, 0x49, 0xB0, 0xA6, 0x6E, 0xAD, 0x23, 0x26, 0x19, 0xC4, + 0x2E, 0x09, 0x75, 0xDB, 0xFF, 0x18, 0x9A, 0x69, 0x71, 0x8C, 0xAA, 0xEC, + 0x66, 0xB2, 0xED, 0x8F, 0xB8, 0x60, 0xEE, 0x9C, 0x29, 0x4C, 0x09, 0x75, + 0xA5, 0x02, 0x36, 0x19, 0xE1, 0x9E, 0xB1, 0xC2, 0x6C, 0x52, 0x64, 0x56, + 0x65, 0x9D, 0x42, 0x5B, 0x9A, 0x98, 0x54, 0x3F, 0x3E, 0x3A, 0x18, 0xE4, + 0x40, 0x13, 0x59, 0xA0, 0xF5, 0x30, 0xE8, 0xEF, 0x07, 0x9C, 0xD2, 0xA1, + 0xD6, 0x3F, 0xF7, 0x99, 0xD6, 0xE4, 0x8F, 0x6B, 0x26, 0xEB, 0x70, 0x84, + 0x86, 0x20, 0xDD, 0x4C, 0xC1, 0x5D, 0x25, 0xF0, 0xE6, 0x38, 0x2D, 0x4D, + 0xC9, 0xEF, 0xBA, 0x3E, 0x3F, 0x6B, 0x68, 0x09, 0x5E, 0xCC, 0x1E, 0x02, + 0xC6, 0xE9, 0x82, 0x63, 0x86, 0xE2, 0xA0, 0x52, 0x84, 0x35, 0x7F, 0x68, + 0xA1, 0x70, 0x6A, 0x6B, 0x14, 0x18, 0x97, 0x3C, 0x5C, 0xAE, 0xDE, 0x7F, + 0x1C, 0x84, 0x07, 0x3E, 0x37, 0x07, 0x50, 0xAA, 0x05, 0x53, 0x9C, 0xB7, + 0x0D, 0x0C, 0x50, 0xF0, 0x37, 0xDA, 0x3A, 0xB0, 0xB8, 0xF2, 0x16, 0x57, + 0xEC, 0x44, 0x7D, 0x8E, 0xB2, 0x74, 0xB5, 0x3C, 0x1A, 0xF5, 0x0C, 0xAE, + 0xFF, 0xB3, 0x00, 0x02, 0x04, 0x1F, 0x1C, 0xF0, 0xF6, 0x2F, 0xA9, 0x7C, + 0xF9, 0x13, 0x91, 0xD1, 0xBD, 0x21, 0x09, 0xDC, 0x58, 0x7A, 0x83, 0x25, + 0xDC, 0xDA, 0xC2, 0x37, 0x81, 0xE5, 0xE5, 0x3A, 0x01, 0x47, 0xF5, 0x22, + 0x73, 0x47, 0x32, 0x94, 0x0E, 0x03, 0xD0, 0x0F, 0x46, 0x61, 0x44, 0xA9, + 0xA7, 0xDD, 0xF3, 0x9A, 0x34, 0x76, 0xB5, 0xC8, 0x2F, 0x0E, 0xEA, 0x3B, + 0x99, 0xCD, 0x38, 0xE2, 0x41, 0x1E, 0x75, 0xA4, 0x3E, 0xC7, 0xC8, 0xEC, + 0x08, 0xB9, 0x6D, 0x4F, 0x38, 0x8B, 0x54, 0x4E, 0x31, 0xB3, 0x3E, 0x18, + 0xA1, 0xBB, 0x80, 0x32, 0x79, 0x7C, 0x97, 0x24, 0x90, 0x12, 0xB8, 0x2C, + 0xBF, 0x04, 0x0A, 0xF6, 0x03, 0x0D, 0x42, 0x6F, 0x10, 0x08, 0x93, 0xD9, + 0x1F, 0x77, 0x9A, 0xDE, 0xAF, 0x89, 0xAF, 0xBC, 0x72, 0xB0, 0x79, 0x56, + 0x24, 0x71, 0x6B, 0x2E, 0x1F, 0x72, 0x12, 0x55, 0x2E, 0x3F, 0xCF, 0xDC, + 0x12, 0xAE, 0x8B, 0xB3, 0x17, 0xDA, 0x08, 0x74, 0x18, 0x47, 0x58, 0x7A, + 0x87, 0xCD, 0x84, 0x9F, 0xE6, 0xDD, 0x1A, 0x50, 0xFA, 0x1D, 0x85, 0xDB, + 0x3A, 0xEC, 0x7A, 0xEC, 0x8C, 0x7D, 0x4B, 0xE9, 0xBC, 0x9A, 0x9F, 0xBC, + 0x08, 0xD8, 0x15, 0x32, 0x47, 0x18, 0x1C, 0xEF, 0xD2, 0xC3, 0x64, 0xC4, + 0x66, 0x43, 0x09, 0x63, 0x51, 0xC4, 0x65, 0x2A, 0x43, 0x4D, 0xA1, 0x12, + 0x16, 0xBA, 0xC2, 0x24, 0x37, 0x3B, 0x43, 0xDD, 0x55, 0x4E, 0x31, 0x10, + 0x9E, 0xF8, 0xDF, 0x71, 0xDD, 0xE4, 0x3A, 0x13, 0x02, 0x00, 0x94, 0x50, + 0x6B, 0xC7, 0xA3, 0xD7, 0xF1, 0x56, 0x35, 0x04, 0x9B, 0x19, 0x11, 0x5F, + 0xD6, 0x77, 0xAC, 0x81, 0xFA, 0xFB, 0xF1, 0x97, 0xED, 0xE6, 0x8F, 0xF2, + 0x09, 0xA5, 0x24, 0x59, 0x3B, 0x18, 0x11, 0x3C, 0xB1, 0x6F, 0xE9, 0xEA, + 0x70, 0x45, 0xE3, 0x86, 0x6E, 0x3C, 0x15, 0x1E, 0x2C, 0xBF, 0xBA, 0x9E, + 0xFA, 0x06, 0x3D, 0x4E, 0x1C, 0xE7, 0x1F, 0x77, 0xB3, 0x2A, 0x3E, 0x5A, + 0x0A, 0x5E, 0x0E, 0x86, 0x25, 0xC8, 0x66, 0x52, 0xD6, 0x89, 0x3E, 0x80, + 0x0F, 0x1D, 0xE7, 0x99, 0xB9, 0xDC, 0x65, 0x29, 0x78, 0xEA, 0xE2, 0x94, + 0xBA, 0x0E, 0x15, 0xC6, 0x6A, 0xB3, 0x10, 0x9C, 0x78, 0xC9, 0x4C, 0x2E, + 0x3D, 0x2B, 0x1D, 0x36, 0xA7, 0x4E, 0xF7, 0xF2, 0xF4, 0x2D, 0x0A, 0x1E, + 0x53, 0x3C, 0xFC, 0xA6, 0xB6, 0x12, 0x13, 0xF7, 0x08, 0xA7, 0x23, 0x52, + 0x60, 0x79, 0xC2, 0x19, 0x0F, 0x26, 0x39, 0x19, 0x83, 0xC8, 0x7B, 0xA6, + 0x95, 0x45, 0xBC, 0xE3, 0x66, 0x1F, 0xC3, 0xEA, 0x6E, 0xFE, 0xAD, 0xEB, + 0xA5, 0x5A, 0x6C, 0xBE, 0xEF, 0xDD, 0x32, 0xC3, 0x28, 0xFF, 0x8C, 0x01, + 0xD1, 0x37, 0x7F, 0xB1, 0x3B, 0x95, 0x2F, 0xDB, 0x0F, 0xA5, 0xCE, 0xEE, + 0x02, 0x97, 0xAB, 0x68, 0x85, 0x21, 0x58, 0x65, 0x70, 0x61, 0x07, 0x29, + 0x28, 0xB6, 0x21, 0x15, 0x84, 0x2F, 0x6E, 0x5B, 0xAD, 0x7D, 0xEF, 0x2A, + 0x96, 0xBD, 0x61, 0xEB, 0x30, 0xA8, 0xCC, 0x13, 0x10, 0x15, 0x9F, 0x61, + 0x75, 0x47, 0xDD, 0xEC, 0x39, 0xA2, 0x70, 0x4C, 0x90, 0x5C, 0x73, 0xB5, + 0xCF, 0x63, 0x03, 0xAA, 0x1E, 0xFE, 0x34, 0x03, 0xA7, 0x2C, 0x62, 0x60, + 0xBC, 0x86, 0xCC, 0xEE, 0x14, 0xDE, 0xAA, 0xCB, 0x0B, 0x9E, 0x9E, 0xD5, + 0xCA, 0xF0, 0xBD, 0x19, 0xAF, 0x1E, 0x8B, 0x64, 0x6E, 0x84, 0xF3, 0xB2, + 0xAB, 0x5C, 0xAB, 0x9C, 0xB3, 0xB4, 0x2A, 0x3C, 0x32, 0x5A, 0x68, 0x40, + 0x50, 0xBB, 0x5A, 0x65, 0xB9, 0x69, 0x23, 0xA0, 0x99, 0xA0, 0x5F, 0x87, + 0x19, 0x0B, 0x54, 0x9B, 0xF7, 0xB8, 0x21, 0xC0, 0xD5, 0xE9, 0x9E, 0x31, + 0x77, 0x2D, 0xE3, 0x97, 0x9A, 0x88, 0x37, 0xF8, 0xA8, 0x7D, 0x3D, 0x62, + 0x7E, 0x99, 0xF7, 0x95, 0xD6, 0x1F, 0xE6, 0xC7, 0x29, 0x88, 0x35, 0x0E, + 0x81, 0x12, 0x68, 0x16, 0x5F, 0x93, 0xED, 0x11, 0x63, 0x72, 0x22, 0x1B, + 0xA5, 0x84, 0xF5, 0x57, 0x99, 0xBA, 0x58, 0x78, 0xA1, 0xDF, 0xDE, 0x96, + 0x54, 0x30, 0x2E, 0x53, 0xEB, 0x0A, 0xB3, 0xCD, 0x96, 0x46, 0xC2, 0x1A, + 0xFF, 0xC3, 0x83, 0x9B, 0xEA, 0xFF, 0xC6, 0x34, 0xEF, 0xF2, 0xEB, 0x58, + 0x28, 0x31, 0xBC, 0x6D, 0xE4, 0x48, 0xD9, 0x8F, 0xE3, 0xB7, 0x64, 0xE8, + 0xD9, 0x14, 0x4A, 0x5D, 0x73, 0x3C, 0x7C, 0xEE, 0x61, 0xED, 0x28, 0xFE, + 0xEA, 0xAB, 0xAA, 0xA3, 0xB6, 0xE2, 0xEE, 0x45, 0xE0, 0x13, 0x3E, 0x20, + 0x14, 0x5D, 0x10, 0x42, 0xB5, 0xBB, 0x6A, 0xEF, 0x42, 0xF4, 0x42, 0xC7, + 0xD0, 0x4F, 0xCB, 0xFA, 0x15, 0x4F, 0x6C, 0xDB, 0xC7, 0x4D, 0x85, 0x86, + 0x9E, 0x79, 0x1E, 0xD8, 0x05, 0x21, 0xCD, 0x41, 0x1D, 0x3B, 0x4F, 0x65, + 0x46, 0x26, 0x8D, 0x5B, 0xF2, 0xA1, 0x62, 0xCF, 0x50, 0x62, 0x81, 0x3D, + 0x6A, 0x47, 0x4B, 0xE4, 0x92, 0x74, 0xCB, 0x69, 0xC3, 0x24, 0x15, 0x7F, + 0xA3, 0xB6, 0xC7, 0xC1, 0xA0, 0x83, 0x88, 0xFC, 0x9D, 0x48, 0x19, 0xAD, + 0x00, 0xBF, 0x5B, 0x09, 0x85, 0xB2, 0x92, 0x56, 0x0B, 0x8A, 0x84, 0x47, + 0xEA, 0xF5, 0x55, 0x0C, 0x2A, 0x8D, 0x42, 0x58, 0x00, 0x0D, 0x82, 0x23, + 0x74, 0xB1, 0x62, 0x14, 0x41, 0x7E, 0x93, 0x8D, 0x92, 0xF0, 0x72, 0x33, + 0x61, 0x70, 0x3F, 0x23, 0x3E, 0xF4, 0xAD, 0x1D, 0x60, 0x74, 0xEE, 0xCB, + 0x59, 0x37, 0xDE, 0x7C, 0xDB, 0x3B, 0x22, 0x6C, 0xF1, 0xEC, 0x5F, 0xD6, + 0x9E, 0x50, 0xF8, 0x19, 0x84, 0x80, 0x07, 0xA6, 0x6E, 0x32, 0x77, 0xCE, + 0xA7, 0xF2, 0x85, 0x40, 0xC2, 0x06, 0x0C, 0xC5, 0xAA, 0xA7, 0x69, 0xA9, + 0x35, 0x97, 0xD9, 0x61, 0x55, 0xD8, 0xEF, 0xE8, 0x84, 0x34, 0x45, 0xC3, + 0x2E, 0x7A, 0x44, 0x9E, 0xDC, 0xCA, 0x0B, 0x80, 0xFC, 0xAB, 0x04, 0x5A, + 0xCD, 0x88, 0x55, 0x10, 0xD3, 0xDB, 0x73, 0xDB, 0xC9, 0x9E, 0x1E, 0x0E, + 0x05, 0x67, 0xD5, 0xFD, 0xD8, 0x38, 0x3E, 0x71, 0x65, 0x34, 0xC4, 0xC5, + 0x40, 0x43, 0x67, 0xE3, 0x79, 0xDA, 0x5F, 0x67, 0x4A, 0x3D, 0xB0, 0x8F, + 0xE7, 0x21, 0x3E, 0x15, 0x20, 0xFF, 0x6D, 0xF1, 0x9E, 0xF8, 0x28, 0x3D, + 0xF7, 0x40, 0x81, 0x94, 0x68, 0x5A, 0x3D, 0xE9, 0xF7, 0xAD, 0x83, 0xDB, + 0x2B, 0x9F, 0xE3, 0xE6, 0xF7, 0xD4, 0x02, 0x76, 0xF7, 0x20, 0x15, 0x41, + 0x34, 0x29, 0x69, 0x94, 0x1C, 0x26, 0x4C, 0xF6, 0x6A, 0xF4, 0x20, 0x33, + 0x71, 0x24, 0x08, 0xD4, 0x68, 0x00, 0xA1, 0xD4, 0x2E, 0x6B, 0xF4, 0xBC, + 0x46, 0x45, 0x24, 0x97, 0x2E, 0xF6, 0x39, 0x1E, 0xAF, 0x61, 0x00, 0x50, + 0xB7, 0xD4, 0xB7, 0x43, +}; + +} // namespace random_internal +ABSL_NAMESPACE_END +} // namespace absl diff --git a/absl/random/internal/randen_slow.cc b/absl/random/internal/randen_slow.cc index 8d074582..4e5f3dc1 100644 --- a/absl/random/internal/randen_slow.cc +++ b/absl/random/internal/randen_slow.cc @@ -20,6 +20,7 @@ #include "absl/base/attributes.h" #include "absl/random/internal/platform.h" +#include "absl/random/internal/randen_traits.h" #if ABSL_HAVE_ATTRIBUTE(always_inline) || \ (defined(__GNUC__) && !defined(__clang__)) @@ -225,35 +226,16 @@ constexpr uint32_t te3[256] = { 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c, }; -struct alignas(16) u64x2 { - constexpr u64x2() : v{0, 0} {}; - constexpr u64x2(uint64_t hi, uint64_t lo) : v{lo, hi} {} - - uint64_t v[2]; -}; - // Software implementation of the Vector128 class, using uint32_t // as an underlying vector register. -// -struct Vector128 { - inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128& operator^=( - const Vector128& other) { - s[0] ^= other.s[0]; - s[1] ^= other.s[1]; - s[2] ^= other.s[2]; - s[3] ^= other.s[3]; - return *this; - } - +struct alignas(16) Vector128 { uint32_t s[4]; }; inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128 -Vector128Load(const void* ABSL_RANDOM_INTERNAL_RESTRICT from) { +Vector128Load(const void* from) { Vector128 result; - const uint8_t* ABSL_RANDOM_INTERNAL_RESTRICT src = - reinterpret_cast(from); - + const uint8_t* src = reinterpret_cast(from); result.s[0] = static_cast(src[0]) << 24 | static_cast(src[1]) << 16 | static_cast(src[2]) << 8 | @@ -274,7 +256,7 @@ Vector128Load(const void* ABSL_RANDOM_INTERNAL_RESTRICT from) { } inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void Vector128Store( - const Vector128& v, void* ABSL_RANDOM_INTERNAL_RESTRICT to) { + const Vector128& v, void* to) { uint8_t* dst = reinterpret_cast(to); dst[0] = static_cast(v.s[0] >> 24); dst[1] = static_cast(v.s[0] >> 16); @@ -298,91 +280,57 @@ inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void Vector128Store( // symmetry of AES (ensures previously equal columns differ afterwards). inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128 AesRound(const Vector128& state, const Vector128& round_key) { - // clang-format off Vector128 result; - result.s[0] = round_key.s[0] ^ - te0[uint8_t(state.s[0] >> 24)] ^ - te1[uint8_t(state.s[1] >> 16)] ^ - te2[uint8_t(state.s[2] >> 8)] ^ + result.s[0] = round_key.s[0] ^ // + te0[uint8_t(state.s[0] >> 24)] ^ // + te1[uint8_t(state.s[1] >> 16)] ^ // + te2[uint8_t(state.s[2] >> 8)] ^ // te3[uint8_t(state.s[3])]; - result.s[1] = round_key.s[1] ^ - te0[uint8_t(state.s[1] >> 24)] ^ - te1[uint8_t(state.s[2] >> 16)] ^ - te2[uint8_t(state.s[3] >> 8)] ^ + result.s[1] = round_key.s[1] ^ // + te0[uint8_t(state.s[1] >> 24)] ^ // + te1[uint8_t(state.s[2] >> 16)] ^ // + te2[uint8_t(state.s[3] >> 8)] ^ // te3[uint8_t(state.s[0])]; - result.s[2] = round_key.s[2] ^ - te0[uint8_t(state.s[2] >> 24)] ^ - te1[uint8_t(state.s[3] >> 16)] ^ - te2[uint8_t(state.s[0] >> 8)] ^ + result.s[2] = round_key.s[2] ^ // + te0[uint8_t(state.s[2] >> 24)] ^ // + te1[uint8_t(state.s[3] >> 16)] ^ // + te2[uint8_t(state.s[0] >> 8)] ^ // te3[uint8_t(state.s[1])]; - result.s[3] = round_key.s[3] ^ - te0[uint8_t(state.s[3] >> 24)] ^ - te1[uint8_t(state.s[0] >> 16)] ^ - te2[uint8_t(state.s[1] >> 8)] ^ + result.s[3] = round_key.s[3] ^ // + te0[uint8_t(state.s[3] >> 24)] ^ // + te1[uint8_t(state.s[0] >> 16)] ^ // + te2[uint8_t(state.s[1] >> 8)] ^ // te3[uint8_t(state.s[2])]; return result; - // clang-format on } -// RANDen = RANDom generator or beetroots in Swiss German. -// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random -// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32. -// -// High-level summary: -// 1) Reverie (see "A Robust and Sponge-Like PRNG with Improved Efficiency") is -// a sponge-like random generator that requires a cryptographic permutation. -// It improves upon "Provably Robust Sponge-Based PRNGs and KDFs" by -// achieving backtracking resistance with only one Permute() per buffer. -// -// 2) "Simpira v2: A Family of Efficient Permutations Using the AES Round -// Function" constructs up to 1024-bit permutations using an improved -// Generalized Feistel network with 2-round AES-128 functions. This Feistel -// block shuffle achieves diffusion faster and is less vulnerable to -// sliced-biclique attacks than the Type-2 cyclic shuffle. -// -// 3) "Improving the Generalized Feistel" and "New criterion for diffusion -// property" extends the same kind of improved Feistel block shuffle to 16 -// branches, which enables a 2048-bit permutation. -// -// Combine these three ideas and also change Simpira's subround keys from -// structured/low-entropy counters to digits of Pi. - -// Randen constants. -constexpr size_t kFeistelBlocks = 16; -constexpr size_t kFeistelFunctions = kFeistelBlocks / 2; // = 8 -constexpr size_t kFeistelRounds = 16 + 1; // > 4 * log2(kFeistelBlocks) -constexpr size_t kKeys = kFeistelRounds * kFeistelFunctions; - -// INCLUDE keys. -#include "absl/random/internal/randen-keys.inc" - -static_assert(kKeys == kRoundKeys, "kKeys and kRoundKeys must be equal"); +using ::absl::random_internal::RandenTraits; -// 2 uint64_t lanes per Vector128 -static constexpr size_t kLanes = 2; +// Randen operates on 128-bit vectors. +struct alignas(16) u64x2 { + uint64_t data[2]; +}; // The improved Feistel block shuffle function for 16 blocks. inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void BlockShuffle( - uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state_u64) { - static_assert(kFeistelBlocks == 16, + u64x2* state) { + static_assert(RandenTraits::kFeistelBlocks == 16, "Feistel block shuffle only works for 16 blocks."); - constexpr size_t shuffle[kFeistelBlocks] = {7, 2, 13, 4, 11, 8, 3, 6, - 15, 0, 9, 10, 1, 14, 5, 12}; - - u64x2* ABSL_RANDOM_INTERNAL_RESTRICT state = - reinterpret_cast(state_u64); + constexpr size_t shuffle[RandenTraits::kFeistelBlocks] = { + 7, 2, 13, 4, 11, 8, 3, 6, 15, 0, 9, 10, 1, 14, 5, 12}; // The fully unrolled loop without the memcpy improves the speed by about - // 30% over the equivalent (leaving code here as a comment): - if (false) { - u64x2 source[kFeistelBlocks]; - std::memcpy(source, state, sizeof(source)); - for (size_t i = 0; i < kFeistelBlocks; i++) { - const u64x2 v0 = source[shuffle[i]]; - state[i] = v0; - } + // 30% over the equivalent: +#if 0 + u64x2 source[RandenTraits::kFeistelBlocks]; + std::memcpy(source, state, sizeof(source)); + for (size_t i = 0; i < RandenTraits::kFeistelBlocks; i++) { + const u64x2 v0 = source[shuffle[i]]; + state[i] = v0; } + return; +#endif const u64x2 v0 = state[shuffle[0]]; const u64x2 v1 = state[shuffle[1]]; @@ -424,23 +372,23 @@ inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void BlockShuffle( // parallel hides the 7-cycle AESNI latency on HSW. Note that the Feistel // XORs are 'free' (included in the second AES instruction). inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE const u64x2* FeistelRound( - uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state, + u64x2* ABSL_RANDOM_INTERNAL_RESTRICT state, const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys) { - for (size_t branch = 0; branch < kFeistelBlocks; branch += 4) { - const Vector128 s0 = Vector128Load(state + kLanes * branch); - const Vector128 s1 = Vector128Load(state + kLanes * (branch + 1)); + for (size_t branch = 0; branch < RandenTraits::kFeistelBlocks; branch += 4) { + const Vector128 s0 = Vector128Load(state + branch); + const Vector128 s1 = Vector128Load(state + branch + 1); const Vector128 f0 = AesRound(s0, Vector128Load(keys)); keys++; const Vector128 o1 = AesRound(f0, s1); - Vector128Store(o1, state + kLanes * (branch + 1)); + Vector128Store(o1, state + branch + 1); // Manually unroll this loop once. about 10% better than not unrolled. - const Vector128 s2 = Vector128Load(state + kLanes * (branch + 2)); - const Vector128 s3 = Vector128Load(state + kLanes * (branch + 3)); + const Vector128 s2 = Vector128Load(state + branch + 2); + const Vector128 s3 = Vector128Load(state + branch + 3); const Vector128 f2 = AesRound(s2, Vector128Load(keys)); keys++; const Vector128 o3 = AesRound(f2, s3); - Vector128Store(o3, state + kLanes * (branch + 3)); + Vector128Store(o3, state + branch + 3); } return keys; } @@ -450,11 +398,9 @@ inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE const u64x2* FeistelRound( // 2^64 queries if the round function is a PRF. This is similar to the b=8 case // of Simpira v2, but more efficient than its generic construction for b=16. inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void Permute( - const void* keys, uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state) { - const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys128 = - static_cast(keys); - for (size_t round = 0; round < kFeistelRounds; ++round) { - keys128 = FeistelRound(state, keys128); + u64x2* state, const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys) { + for (size_t round = 0; round < RandenTraits::kFeistelRounds; ++round) { + keys = FeistelRound(state, keys); BlockShuffle(state); } } @@ -468,37 +414,42 @@ namespace random_internal { const void* RandenSlow::GetKeys() { // Round keys for one AES per Feistel round and branch. // The canonical implementation uses first digits of Pi. - return round_keys; + return kRandenRoundKeys; } void RandenSlow::Absorb(const void* seed_void, void* state_void) { - uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state = - reinterpret_cast(state_void); - const uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT seed = - reinterpret_cast(seed_void); - - constexpr size_t kCapacityBlocks = kCapacityBytes / sizeof(uint64_t); - static_assert(kCapacityBlocks * sizeof(uint64_t) == kCapacityBytes, - "Not i*V"); - for (size_t i = kCapacityBlocks; i < kStateBytes / sizeof(uint64_t); ++i) { + auto* state = + reinterpret_cast(state_void); + const auto* seed = + reinterpret_cast( + seed_void); + + constexpr size_t kCapacityBlocks = + RandenTraits::kCapacityBytes / sizeof(uint64_t); + static_assert( + kCapacityBlocks * sizeof(uint64_t) == RandenTraits::kCapacityBytes, + "Not i*V"); + + for (size_t i = kCapacityBlocks; + i < RandenTraits::kStateBytes / sizeof(uint64_t); ++i) { state[i] ^= seed[i - kCapacityBlocks]; } } -void RandenSlow::Generate(const void* keys, void* state_void) { - static_assert(kCapacityBytes == sizeof(Vector128), "Capacity mismatch"); +void RandenSlow::Generate(const void* keys_void, void* state_void) { + static_assert(RandenTraits::kCapacityBytes == sizeof(u64x2), + "Capacity mismatch"); - uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state = - reinterpret_cast(state_void); + auto* state = reinterpret_cast(state_void); + const auto* keys = reinterpret_cast(keys_void); - const Vector128 prev_inner = Vector128Load(state); + const u64x2 prev_inner = state[0]; - Permute(keys, state); + Permute(state, keys); // Ensure backtracking resistance. - Vector128 inner = Vector128Load(state); - inner ^= prev_inner; - Vector128Store(inner, state); + state[0].data[0] ^= prev_inner.data[0]; + state[0].data[1] ^= prev_inner.data[1]; } } // namespace random_internal diff --git a/absl/random/internal/randen_slow.h b/absl/random/internal/randen_slow.h index 72f92b54..b6f137eb 100644 --- a/absl/random/internal/randen_slow.h +++ b/absl/random/internal/randen_slow.h @@ -28,13 +28,6 @@ namespace random_internal { // architectures lacking AES hardware acceleration intrinsics. class RandenSlow { public: - // Size of the entire sponge / state for the randen PRNG. - static constexpr size_t kStateBytes = 256; // 2048-bit - - // Size of the 'inner' (inaccessible) part of the sponge. Larger values would - // require more frequent calls to RandenGenerate. - static constexpr size_t kCapacityBytes = 16; // 128-bit - static void Generate(const void* keys, void* state_void); static void Absorb(const void* seed_void, void* state_void); static const void* GetKeys(); diff --git a/absl/random/internal/randen_slow_test.cc b/absl/random/internal/randen_slow_test.cc index c07155d8..4a535837 100644 --- a/absl/random/internal/randen_slow_test.cc +++ b/absl/random/internal/randen_slow_test.cc @@ -17,18 +17,20 @@ #include #include "gtest/gtest.h" +#include "absl/random/internal/randen_traits.h" namespace { using absl::random_internal::RandenSlow; +using absl::random_internal::RandenTraits; // Local state parameters. constexpr size_t kSeedBytes = - RandenSlow::kStateBytes - RandenSlow::kCapacityBytes; -constexpr size_t kStateSizeT = RandenSlow::kStateBytes / sizeof(uint64_t); + RandenTraits::kStateBytes - RandenTraits::kCapacityBytes; +constexpr size_t kStateSizeT = RandenTraits::kStateBytes / sizeof(uint64_t); constexpr size_t kSeedSizeT = kSeedBytes / sizeof(uint32_t); -struct randen { +struct alignas(16) randen { uint64_t state[kStateSizeT]; uint32_t seed[kSeedSizeT]; }; diff --git a/absl/random/internal/randen_traits.h b/absl/random/internal/randen_traits.h index 2b8bbe73..53caa936 100644 --- a/absl/random/internal/randen_traits.h +++ b/absl/random/internal/randen_traits.h @@ -32,6 +32,25 @@ namespace random_internal { // 'Strong' (well-distributed, unpredictable, backtracking-resistant) random // generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32. // +// High-level summary: +// 1) Reverie (see "A Robust and Sponge-Like PRNG with Improved Efficiency") is +// a sponge-like random generator that requires a cryptographic permutation. +// It improves upon "Provably Robust Sponge-Based PRNGs and KDFs" by +// achieving backtracking resistance with only one Permute() per buffer. +// +// 2) "Simpira v2: A Family of Efficient Permutations Using the AES Round +// Function" constructs up to 1024-bit permutations using an improved +// Generalized Feistel network with 2-round AES-128 functions. This Feistel +// block shuffle achieves diffusion faster and is less vulnerable to +// sliced-biclique attacks than the Type-2 cyclic shuffle. +// +// 3) "Improving the Generalized Feistel" and "New criterion for diffusion +// property" extends the same kind of improved Feistel block shuffle to 16 +// branches, which enables a 2048-bit permutation. +// +// Combine these three ideas and also change Simpira's subround keys from +// structured/low-entropy counters to digits of Pi (or other random source). + // RandenTraits contains the basic algorithm traits, such as the size of the // state, seed, sponge, etc. struct RandenTraits { @@ -45,17 +64,23 @@ struct RandenTraits { // Size of the default seed consumed by the sponge. static constexpr size_t kSeedBytes = kStateBytes - kCapacityBytes; + // Assuming 128-bit blocks, the number of blocks in the state. // Largest size for which security proofs are known. static constexpr size_t kFeistelBlocks = 16; - // Type-2 generalized Feistel => one round function for every two blocks. - static constexpr size_t kFeistelFunctions = kFeistelBlocks / 2; // = 8 - // Ensures SPRP security and two full subblock diffusions. // Must be > 4 * log2(kFeistelBlocks). static constexpr size_t kFeistelRounds = 16 + 1; + + // Size of the key. A 128-bit key block is used for every-other + // feistel block (Type-2 generalized Feistel network) in each round. + static constexpr size_t kKeyBytes = 16 * kFeistelRounds * kFeistelBlocks / 2; }; +// Randen key arrays. In randen_round_keys.cc +extern const unsigned char kRandenRoundKeys[RandenTraits::kKeyBytes]; +extern const unsigned char kRandenRoundKeysBE[RandenTraits::kKeyBytes]; + } // namespace random_internal ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/random/log_uniform_int_distribution_test.cc b/absl/random/log_uniform_int_distribution_test.cc index 5270531d..5e780d96 100644 --- a/absl/random/log_uniform_int_distribution_test.cc +++ b/absl/random/log_uniform_int_distribution_test.cc @@ -27,6 +27,7 @@ #include "absl/base/internal/raw_logging.h" #include "absl/random/internal/chi_square.h" #include "absl/random/internal/distribution_test_util.h" +#include "absl/random/internal/pcg_engine.h" #include "absl/random/internal/sequence_urbg.h" #include "absl/random/random.h" #include "absl/strings/str_cat.h" @@ -121,7 +122,10 @@ class LogUniformIntChiSquaredTest // data generated by the log-uniform-int distribution. double ChiSquaredTestImpl(); - absl::InsecureBitGen rng_; + // We use a fixed bit generator for distribution accuracy tests. This allows + // these tests to be deterministic, while still testing the qualify of the + // implementation. + absl::random_internal::pcg64_2018_engine rng_{0x2B7E151628AED2A6}; }; double LogUniformIntChiSquaredTest::ChiSquaredTestImpl() { @@ -194,7 +198,6 @@ double LogUniformIntChiSquaredTest::ChiSquaredTestImpl() { TEST_P(LogUniformIntChiSquaredTest, MultiTest) { const int kTrials = 5; - int failures = 0; for (int i = 0; i < kTrials; i++) { double p_value = ChiSquaredTestImpl(); diff --git a/absl/random/poisson_distribution_test.cc b/absl/random/poisson_distribution_test.cc index 9d215fbc..8baabd11 100644 --- a/absl/random/poisson_distribution_test.cc +++ b/absl/random/poisson_distribution_test.cc @@ -30,6 +30,7 @@ #include "absl/container/flat_hash_map.h" #include "absl/random/internal/chi_square.h" #include "absl/random/internal/distribution_test_util.h" +#include "absl/random/internal/pcg_engine.h" #include "absl/random/internal/sequence_urbg.h" #include "absl/random/random.h" #include "absl/strings/str_cat.h" @@ -257,7 +258,10 @@ class PoissonDistributionZTest : public testing::TestWithParam, template bool SingleZTest(const double p, const size_t samples); - absl::InsecureBitGen rng_; + // We use a fixed bit generator for distribution accuracy tests. This allows + // these tests to be deterministic, while still testing the qualify of the + // implementation. + absl::random_internal::pcg64_2018_engine rng_{0x2B7E151628AED2A6}; }; template @@ -357,9 +361,13 @@ class PoissonDistributionChiSquaredTest : public testing::TestWithParam, private: void InitChiSquaredTest(const double buckets); - absl::InsecureBitGen rng_; std::vector cutoffs_; std::vector expected_; + + // We use a fixed bit generator for distribution accuracy tests. This allows + // these tests to be deterministic, while still testing the qualify of the + // implementation. + absl::random_internal::pcg64_2018_engine rng_{0x2B7E151628AED2A6}; }; void PoissonDistributionChiSquaredTest::InitChiSquaredTest( diff --git a/absl/random/uniform_int_distribution_test.cc b/absl/random/uniform_int_distribution_test.cc index 69537603..276d72ad 100644 --- a/absl/random/uniform_int_distribution_test.cc +++ b/absl/random/uniform_int_distribution_test.cc @@ -26,6 +26,7 @@ #include "absl/base/internal/raw_logging.h" #include "absl/random/internal/chi_square.h" #include "absl/random/internal/distribution_test_util.h" +#include "absl/random/internal/pcg_engine.h" #include "absl/random/internal/sequence_urbg.h" #include "absl/random/random.h" #include "absl/strings/str_cat.h" @@ -134,7 +135,11 @@ TYPED_TEST(UniformIntDistributionTest, TestMoments) { using param_type = typename absl::uniform_int_distribution::param_type; - absl::InsecureBitGen rng; + // We use a fixed bit generator for distribution accuracy tests. This allows + // these tests to be deterministic, while still testing the qualify of the + // implementation. + absl::random_internal::pcg64_2018_engine rng{0x2B7E151628AED2A6}; + std::vector values(kSize); for (const auto& param : {param_type(0, Limits::max()), param_type(13, 127)}) { @@ -178,7 +183,11 @@ TYPED_TEST(UniformIntDistributionTest, ChiSquaredTest50) { const TypeParam min = std::is_unsigned::value ? 37 : -37; const TypeParam max = min + kBuckets; - absl::InsecureBitGen rng; + // We use a fixed bit generator for distribution accuracy tests. This allows + // these tests to be deterministic, while still testing the qualify of the + // implementation. + absl::random_internal::pcg64_2018_engine rng{0x2B7E151628AED2A6}; + absl::uniform_int_distribution dist(min, max); std::vector counts(kBuckets + 1, 0); diff --git a/absl/random/uniform_real_distribution_test.cc b/absl/random/uniform_real_distribution_test.cc index a56374a6..be107cdd 100644 --- a/absl/random/uniform_real_distribution_test.cc +++ b/absl/random/uniform_real_distribution_test.cc @@ -27,6 +27,7 @@ #include "absl/base/internal/raw_logging.h" #include "absl/random/internal/chi_square.h" #include "absl/random/internal/distribution_test_util.h" +#include "absl/random/internal/pcg_engine.h" #include "absl/random/internal/sequence_urbg.h" #include "absl/random/random.h" #include "absl/strings/str_cat.h" @@ -207,7 +208,11 @@ TYPED_TEST(UniformRealDistributionTest, TestMoments) { constexpr int kSize = 1000000; std::vector values(kSize); - absl::InsecureBitGen rng; + // We use a fixed bit generator for distribution accuracy tests. This allows + // these tests to be deterministic, while still testing the qualify of the + // implementation. + absl::random_internal::pcg64_2018_engine rng{0x2B7E151628AED2A6}; + absl::uniform_real_distribution dist; for (int i = 0; i < kSize; i++) { values[i] = dist(rng); @@ -237,7 +242,11 @@ TYPED_TEST(UniformRealDistributionTest, ChiSquaredTest50) { const int kThreshold = absl::random_internal::ChiSquareValue(kBuckets - 1, 0.999999); - absl::InsecureBitGen rng; + // We use a fixed bit generator for distribution accuracy tests. This allows + // these tests to be deterministic, while still testing the qualify of the + // implementation. + absl::random_internal::pcg64_2018_engine rng{0x2B7E151628AED2A6}; + for (const auto& param : {param_type(0, 1), param_type(5, 12), param_type(-5, 13), param_type(-5, -2)}) { const double min_val = param.a(); diff --git a/absl/random/zipf_distribution_test.cc b/absl/random/zipf_distribution_test.cc index 4d4a0fcf..f8cf70e0 100644 --- a/absl/random/zipf_distribution_test.cc +++ b/absl/random/zipf_distribution_test.cc @@ -27,6 +27,7 @@ #include "gtest/gtest.h" #include "absl/base/internal/raw_logging.h" #include "absl/random/internal/chi_square.h" +#include "absl/random/internal/pcg_engine.h" #include "absl/random/internal/sequence_urbg.h" #include "absl/random/random.h" #include "absl/strings/str_cat.h" @@ -213,7 +214,10 @@ class ZipfTest : public testing::TestWithParam, public: ZipfTest() : ZipfModel(GetParam().k(), GetParam().q(), GetParam().v()) {} - absl::InsecureBitGen rng_; + // We use a fixed bit generator for distribution accuracy tests. This allows + // these tests to be deterministic, while still testing the qualify of the + // implementation. + absl::random_internal::pcg64_2018_engine rng_{0x2B7E151628AED2A6}; }; TEST_P(ZipfTest, ChiSquaredTest) { diff --git a/absl/strings/internal/str_format/arg.cc b/absl/strings/internal/str_format/arg.cc index 02646add..9feb2248 100644 --- a/absl/strings/internal/str_format/arg.cc +++ b/absl/strings/internal/str_format/arg.cc @@ -267,38 +267,42 @@ bool ConvertIntArg(T v, const FormatConversionSpecImpl conv, using U = typename MakeUnsigned::type; IntDigits as_digits; - switch (conv.conversion_char()) { - case FormatConversionCharInternal::c: + // This odd casting is due to a bug in -Wswitch behavior in gcc49 which causes + // it to complain about a switch/case type mismatch, even though both are + // FormatConverionChar. Likely this is because at this point + // FormatConversionChar is declared, but not defined. + switch (static_cast(conv.conversion_char())) { + case static_cast(FormatConversionCharInternal::c): return ConvertCharImpl(static_cast(v), conv, sink); - case FormatConversionCharInternal::o: + case static_cast(FormatConversionCharInternal::o): as_digits.PrintAsOct(static_cast(v)); break; - case FormatConversionCharInternal::x: + case static_cast(FormatConversionCharInternal::x): as_digits.PrintAsHexLower(static_cast(v)); break; - case FormatConversionCharInternal::X: + case static_cast(FormatConversionCharInternal::X): as_digits.PrintAsHexUpper(static_cast(v)); break; - case FormatConversionCharInternal::u: + case static_cast(FormatConversionCharInternal::u): as_digits.PrintAsDec(static_cast(v)); break; - case FormatConversionCharInternal::d: - case FormatConversionCharInternal::i: + case static_cast(FormatConversionCharInternal::d): + case static_cast(FormatConversionCharInternal::i): as_digits.PrintAsDec(v); break; - case FormatConversionCharInternal::a: - case FormatConversionCharInternal::e: - case FormatConversionCharInternal::f: - case FormatConversionCharInternal::g: - case FormatConversionCharInternal::A: - case FormatConversionCharInternal::E: - case FormatConversionCharInternal::F: - case FormatConversionCharInternal::G: + case static_cast(FormatConversionCharInternal::a): + case static_cast(FormatConversionCharInternal::e): + case static_cast(FormatConversionCharInternal::f): + case static_cast(FormatConversionCharInternal::g): + case static_cast(FormatConversionCharInternal::A): + case static_cast(FormatConversionCharInternal::E): + case static_cast(FormatConversionCharInternal::F): + case static_cast(FormatConversionCharInternal::G): return ConvertFloatImpl(static_cast(v), conv, sink); default: diff --git a/absl/strings/internal/str_format/arg.h b/absl/strings/internal/str_format/arg.h index 8f79948b..d441e87f 100644 --- a/absl/strings/internal/str_format/arg.h +++ b/absl/strings/internal/str_format/arg.h @@ -27,6 +27,8 @@ class FormatSink; namespace str_format_internal { +class FormatConversionSpec; + template struct HasUserDefinedConvert : std::false_type {}; diff --git a/absl/strings/internal/str_format/arg_test.cc b/absl/strings/internal/str_format/arg_test.cc index 37e5b754..bf3d7e8e 100644 --- a/absl/strings/internal/str_format/arg_test.cc +++ b/absl/strings/internal/str_format/arg_test.cc @@ -96,8 +96,8 @@ TEST_F(FormatArgImplTest, WorksWithCharArraysOfUnknownSize) { std::string s; FormatSinkImpl sink(&s); FormatConversionSpecImpl conv; - FormatConversionSpecImplFriend::SetConversionChar(FormatConversionChar::s, - &conv); + FormatConversionSpecImplFriend::SetConversionChar( + FormatConversionCharInternal::s, &conv); FormatConversionSpecImplFriend::SetFlags(Flags(), &conv); FormatConversionSpecImplFriend::SetWidth(-1, &conv); FormatConversionSpecImplFriend::SetPrecision(-1, &conv); diff --git a/absl/strings/internal/str_format/checker_test.cc b/absl/strings/internal/str_format/checker_test.cc index 23348174..a76d70b0 100644 --- a/absl/strings/internal/str_format/checker_test.cc +++ b/absl/strings/internal/str_format/checker_test.cc @@ -11,13 +11,13 @@ namespace { std::string ConvToString(FormatConversionCharSet conv) { std::string out; -#define CONV_SET_CASE(c) \ - if (Contains(conv, FormatConversionCharSet::c)) { \ - out += #c; \ +#define CONV_SET_CASE(c) \ + if (Contains(conv, FormatConversionCharSetInternal::c)) { \ + out += #c; \ } ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(CONV_SET_CASE, ) #undef CONV_SET_CASE - if (Contains(conv, FormatConversionCharSet::kStar)) { + if (Contains(conv, FormatConversionCharSetInternal::kStar)) { out += "*"; } return out; diff --git a/absl/strings/internal/str_format/extension.cc b/absl/strings/internal/str_format/extension.cc index 2e5bc2ce..94f2b9c2 100644 --- a/absl/strings/internal/str_format/extension.cc +++ b/absl/strings/internal/str_format/extension.cc @@ -33,16 +33,17 @@ std::string Flags::ToString() const { return s; } -bool FormatSinkImpl::PutPaddedString(string_view v, int w, int p, bool l) { +bool FormatSinkImpl::PutPaddedString(string_view value, int width, + int precision, bool left) { size_t space_remaining = 0; - if (w >= 0) space_remaining = w; - size_t n = v.size(); - if (p >= 0) n = std::min(n, static_cast(p)); - string_view shown(v.data(), n); + if (width >= 0) space_remaining = width; + size_t n = value.size(); + if (precision >= 0) n = std::min(n, static_cast(precision)); + string_view shown(value.data(), n); space_remaining = Excess(shown.size(), space_remaining); - if (!l) Append(space_remaining, ' '); + if (!left) Append(space_remaining, ' '); Append(shown); - if (l) Append(space_remaining, ' '); + if (left) Append(space_remaining, ' '); return true; } diff --git a/absl/strings/internal/str_format/extension.h b/absl/strings/internal/str_format/extension.h index 36e70646..6c60c6c3 100644 --- a/absl/strings/internal/str_format/extension.h +++ b/absl/strings/internal/str_format/extension.h @@ -32,8 +32,9 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace str_format_internal { -enum class FormatConversionCharSet : uint64_t; + enum class FormatConversionChar : uint8_t; +enum class FormatConversionCharSet : uint64_t; class FormatRawSinkImpl { public: @@ -106,7 +107,7 @@ class FormatSinkImpl { size_t size() const { return size_; } // Put 'v' to 'sink' with specified width, precision, and left flag. - bool PutPaddedString(string_view v, int w, int p, bool l); + bool PutPaddedString(string_view v, int width, int precision, bool left); template T Wrap() { @@ -420,81 +421,6 @@ inline size_t Excess(size_t used, size_t capacity) { return used < capacity ? capacity - used : 0; } -class FormatConversionSpec { - public: - // Width and precison are not specified, no flags are set. - bool is_basic() const { return impl_.is_basic(); } - bool has_left_flag() const { return impl_.has_left_flag(); } - bool has_show_pos_flag() const { return impl_.has_show_pos_flag(); } - bool has_sign_col_flag() const { return impl_.has_sign_col_flag(); } - bool has_alt_flag() const { return impl_.has_alt_flag(); } - bool has_zero_flag() const { return impl_.has_zero_flag(); } - - FormatConversionChar conversion_char() const { - return impl_.conversion_char(); - } - - // Returns the specified width. If width is unspecfied, it returns a negative - // value. - int width() const { return impl_.width(); } - // Returns the specified precision. If precision is unspecfied, it returns a - // negative value. - int precision() const { return impl_.precision(); } - - private: - explicit FormatConversionSpec( - str_format_internal::FormatConversionSpecImpl impl) - : impl_(impl) {} - - friend str_format_internal::FormatConversionSpecImpl; - - absl::str_format_internal::FormatConversionSpecImpl impl_; -}; - -// clang-format off -enum class FormatConversionChar : uint8_t { - c, s, // text - d, i, o, u, x, X, // int - f, F, e, E, g, G, a, A, // float - n, p // misc -}; -// clang-format on - -enum class FormatConversionCharSet : uint64_t { - // text - c = str_format_internal::FormatConversionCharToConvInt('c'), - s = str_format_internal::FormatConversionCharToConvInt('s'), - // integer - d = str_format_internal::FormatConversionCharToConvInt('d'), - i = str_format_internal::FormatConversionCharToConvInt('i'), - o = str_format_internal::FormatConversionCharToConvInt('o'), - u = str_format_internal::FormatConversionCharToConvInt('u'), - x = str_format_internal::FormatConversionCharToConvInt('x'), - X = str_format_internal::FormatConversionCharToConvInt('X'), - // Float - f = str_format_internal::FormatConversionCharToConvInt('f'), - F = str_format_internal::FormatConversionCharToConvInt('F'), - e = str_format_internal::FormatConversionCharToConvInt('e'), - E = str_format_internal::FormatConversionCharToConvInt('E'), - g = str_format_internal::FormatConversionCharToConvInt('g'), - G = str_format_internal::FormatConversionCharToConvInt('G'), - a = str_format_internal::FormatConversionCharToConvInt('a'), - A = str_format_internal::FormatConversionCharToConvInt('A'), - // misc - n = str_format_internal::FormatConversionCharToConvInt('n'), - p = str_format_internal::FormatConversionCharToConvInt('p'), - - // Used for width/precision '*' specification. - kStar = str_format_internal::FormatConversionCharToConvInt('*'), - - // Some predefined values: - kIntegral = d | i | u | o | x | X, - kFloating = a | e | f | g | A | E | F | G, - kNumeric = kIntegral | kFloating, - kString = s, - kPointer = p, -}; - } // namespace str_format_internal ABSL_NAMESPACE_END diff --git a/absl/strings/str_format.h b/absl/strings/str_format.h index f48510b4..f833a80a 100644 --- a/absl/strings/str_format.h +++ b/absl/strings/str_format.h @@ -63,10 +63,6 @@ // loosely typed. `FormatUntyped()` is not a template and does not perform // any compile-time checking of the format string; instead, it returns a // boolean from a runtime check. -// -// In addition, the `str_format` library provides extension points for -// augmenting formatting to new types. These extensions are fully documented -// within the `str_format_extension.h` header file. #ifndef ABSL_STRINGS_STR_FORMAT_H_ #define ABSL_STRINGS_STR_FORMAT_H_ diff --git a/absl/strings/str_format_test.cc b/absl/strings/str_format_test.cc index 3f14dba3..49a68849 100644 --- a/absl/strings/str_format_test.cc +++ b/absl/strings/str_format_test.cc @@ -1,4 +1,6 @@ +#include "absl/strings/str_format.h" + #include #include #include @@ -6,13 +8,14 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "absl/strings/str_format.h" +#include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" namespace absl { ABSL_NAMESPACE_BEGIN namespace { using str_format_internal::FormatArgImpl; +using str_format_internal::FormatConversionCharSetInternal; using FormatEntryPointTest = ::testing::Test; @@ -535,100 +538,106 @@ TEST_F(ParsedFormatTest, SimpleUncheckedIncorrect) { using absl::str_format_internal::FormatConversionCharSet; TEST_F(ParsedFormatTest, UncheckedCorrect) { - auto f = ExtendedParsedFormat::New("ABC%dDEF"); + auto f = + ExtendedParsedFormat::New("ABC%dDEF"); ASSERT_TRUE(f); EXPECT_EQ("[ABC]{d:1$d}[DEF]", SummarizeParsedFormat(*f)); std::string format = "%sFFF%dZZZ%f"; - auto f2 = - ExtendedParsedFormat::New(format); + auto f2 = ExtendedParsedFormat< + FormatConversionCharSetInternal::kString, + FormatConversionCharSetInternal::d, + FormatConversionCharSetInternal::kFloating>::New(format); ASSERT_TRUE(f2); EXPECT_EQ("{s:1$s}[FFF]{d:2$d}[ZZZ]{f:3$f}", SummarizeParsedFormat(*f2)); - f2 = - ExtendedParsedFormat::New("%s %d %f"); + f2 = ExtendedParsedFormat< + FormatConversionCharSetInternal::kString, + FormatConversionCharSetInternal::d, + FormatConversionCharSetInternal::kFloating>::New("%s %d %f"); ASSERT_TRUE(f2); EXPECT_EQ("{s:1$s}[ ]{d:2$d}[ ]{f:3$f}", SummarizeParsedFormat(*f2)); - auto star = ExtendedParsedFormat::New("%*d"); + auto star = + ExtendedParsedFormat::New("%*d"); ASSERT_TRUE(star); EXPECT_EQ("{*d:2$1$*d}", SummarizeParsedFormat(*star)); - auto dollar = - ExtendedParsedFormat::New("%2$s %1$d"); + auto dollar = ExtendedParsedFormat< + FormatConversionCharSetInternal::d, + FormatConversionCharSetInternal::s>::New("%2$s %1$d"); ASSERT_TRUE(dollar); EXPECT_EQ("{2$s:2$s}[ ]{1$d:1$d}", SummarizeParsedFormat(*dollar)); // with reuse - dollar = - ExtendedParsedFormat::New("%2$s %1$d %1$d"); + dollar = ExtendedParsedFormat< + FormatConversionCharSetInternal::d, + FormatConversionCharSetInternal::s>::New("%2$s %1$d %1$d"); ASSERT_TRUE(dollar); EXPECT_EQ("{2$s:2$s}[ ]{1$d:1$d}[ ]{1$d:1$d}", SummarizeParsedFormat(*dollar)); } TEST_F(ParsedFormatTest, UncheckedIgnoredArgs) { - EXPECT_FALSE((ExtendedParsedFormat::New("ABC"))); EXPECT_FALSE( - (ExtendedParsedFormat::New("%dABC"))); + (ExtendedParsedFormat::New("ABC"))); EXPECT_FALSE( - (ExtendedParsedFormat::New("ABC%2$s"))); - auto f = - ExtendedParsedFormat::NewAllowIgnored("ABC"); + (ExtendedParsedFormat::New("%dABC"))); + EXPECT_FALSE((ExtendedParsedFormat< + FormatConversionCharSetInternal::d, + FormatConversionCharSetInternal::s>::New("ABC%2$s"))); + auto f = ExtendedParsedFormat< + FormatConversionCharSetInternal::d, + FormatConversionCharSetInternal::s>::NewAllowIgnored("ABC"); ASSERT_TRUE(f); EXPECT_EQ("[ABC]", SummarizeParsedFormat(*f)); f = ExtendedParsedFormat< - FormatConversionCharSet::d, - FormatConversionCharSet::s>::NewAllowIgnored("%dABC"); + FormatConversionCharSetInternal::d, + FormatConversionCharSetInternal::s>::NewAllowIgnored("%dABC"); ASSERT_TRUE(f); EXPECT_EQ("{d:1$d}[ABC]", SummarizeParsedFormat(*f)); f = ExtendedParsedFormat< - FormatConversionCharSet::d, - FormatConversionCharSet::s>::NewAllowIgnored("ABC%2$s"); + FormatConversionCharSetInternal::d, + FormatConversionCharSetInternal::s>::NewAllowIgnored("ABC%2$s"); ASSERT_TRUE(f); EXPECT_EQ("[ABC]{2$s:2$s}", SummarizeParsedFormat(*f)); } TEST_F(ParsedFormatTest, UncheckedMultipleTypes) { - auto dx = ExtendedParsedFormat::New("%1$d %1$x"); + auto dx = ExtendedParsedFormat< + FormatConversionCharSetInternal::d | + FormatConversionCharSetInternal::x>::New("%1$d %1$x"); EXPECT_TRUE(dx); EXPECT_EQ("{1$d:1$d}[ ]{1$x:1$x}", SummarizeParsedFormat(*dx)); - dx = ExtendedParsedFormat::New("%1$d"); + dx = ExtendedParsedFormat::New("%1$d"); EXPECT_TRUE(dx); EXPECT_EQ("{1$d:1$d}", SummarizeParsedFormat(*dx)); } TEST_F(ParsedFormatTest, UncheckedIncorrect) { - EXPECT_FALSE(ExtendedParsedFormat::New("")); - EXPECT_FALSE( - ExtendedParsedFormat::New("ABC%dDEF%d")); + ExtendedParsedFormat::New("")); + + EXPECT_FALSE(ExtendedParsedFormat::New( + "ABC%dDEF%d")); std::string format = "%sFFF%dZZZ%f"; - EXPECT_FALSE((ExtendedParsedFormat::New(format))); + EXPECT_FALSE( + (ExtendedParsedFormat::New(format))); } TEST_F(ParsedFormatTest, RegressionMixPositional) { - EXPECT_FALSE( - (ExtendedParsedFormat::New("%1$d %o"))); + EXPECT_FALSE((ExtendedParsedFormat< + FormatConversionCharSetInternal::d, + FormatConversionCharSetInternal::o>::New("%1$d %o"))); } using FormatWrapperTest = ::testing::Test; -- cgit v1.2.3 From 33caf1097ecce4fe892567462fa8821d477854b4 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 26 May 2020 10:57:33 -0700 Subject: Export of internal Abseil changes -- 7d0468a6610ed85586d5c87fd65de8dac5118923 by Derek Mauro : Import of CCTZ from GitHub. PiperOrigin-RevId: 313226473 -- 1131ef6d116f5ce7d46537a82f300ea06dcaaa53 by Gennadiy Rozental : Migrate internal interface to use mutable references. PiperOrigin-RevId: 312931131 -- 96225212a9f5fbd0b38c71fe65539164992c7c3b by Laramie Leavitt : Remove random/internal/distributions.h This file was something of an historical artifact. All of the related code has either been removed or migraged, and so the only remaining type belongs with uniform_helper.h, as it is used to infer the return type of the absl::Uniform method in a few cases. PiperOrigin-RevId: 312878173 -- 6dcbd5be58ad425e08740ff64088373ee7fe4a72 by Mark Barolak : Release the StrFormat test case for Cords to open source. PiperOrigin-RevId: 312707974 -- 34484d18dfb63a0a7ad6e2aaeb570e33592968be by Abseil Team : Let Cord::Cord(string&&), Cord::operator=(string&&), Cord::Append(string&&), and Cord::Prepend(string&&) steal string data and embed it into the Cord as a single external chunk, instead of copying it into flat chunks (at most 4083-byte each). Stealing string data is faster, but it creates a long chunk, which leads to a higher more memory usage if its subcords are created and outlive the whole Cord. These functions revert to copying the data if any of the following conditions holds: - string size is at most kMaxBytesToCopy (511), to avoid the overhead of an external chunk for short strings; - less than half of string capacity is used, to avoid pinning to much unused memory. PiperOrigin-RevId: 312683785 GitOrigin-RevId: 7d0468a6610ed85586d5c87fd65de8dac5118923 Change-Id: If79b5a1dfe6d53a8ddddbc7da84338f11fc4cfa3 --- CMake/AbseilDll.cmake | 1 - absl/flags/commandlineflag.cc | 2 +- absl/flags/commandlineflag.h | 2 +- absl/flags/commandlineflag_test.cc | 50 ++++++------ absl/flags/flag.h | 32 ++++---- absl/flags/flag_test.cc | 10 +-- absl/flags/internal/flag.cc | 38 ++++----- absl/flags/internal/flag.h | 24 +++--- absl/flags/internal/private_handle_accessor.cc | 10 +-- absl/flags/internal/private_handle_accessor.h | 6 +- absl/flags/internal/registry.cc | 95 +++++++++++----------- absl/flags/internal/registry.h | 6 +- absl/flags/internal/type_erased.cc | 2 +- absl/flags/internal/usage.cc | 25 +++--- absl/flags/marshalling.cc | 21 ++--- absl/flags/parse.cc | 38 ++++----- absl/flags/parse_test.cc | 26 +++--- absl/random/BUILD.bazel | 3 +- absl/random/CMakeLists.txt | 29 +------ absl/random/distributions.h | 2 +- absl/random/internal/BUILD.bazel | 18 +--- absl/random/internal/distributions.h | 52 ------------ absl/random/internal/uniform_helper.h | 30 +++++++ absl/strings/cord.cc | 65 +++++++++++++++ absl/strings/cord.h | 27 ++---- absl/strings/str_format_test.cc | 2 + absl/time/internal/cctz/include/cctz/time_zone.h | 3 +- absl/time/internal/cctz/src/cctz_benchmark.cc | 16 ++-- absl/time/internal/cctz/src/time_zone_format.cc | 23 +++++- .../internal/cctz/src/time_zone_format_test.cc | 18 +++- .../internal/cctz/src/time_zone_lookup_test.cc | 2 +- 31 files changed, 345 insertions(+), 333 deletions(-) delete mode 100644 absl/random/internal/distributions.h (limited to 'absl/random/CMakeLists.txt') diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake index a5c9bc0d..ccd409f3 100644 --- a/CMake/AbseilDll.cmake +++ b/CMake/AbseilDll.cmake @@ -135,7 +135,6 @@ set(ABSL_INTERNAL_DLL_FILES "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" diff --git a/absl/flags/commandlineflag.cc b/absl/flags/commandlineflag.cc index 83d14c1b..cea57234 100644 --- a/absl/flags/commandlineflag.cc +++ b/absl/flags/commandlineflag.cc @@ -21,7 +21,7 @@ ABSL_NAMESPACE_BEGIN bool CommandLineFlag::IsRetired() const { return false; } bool CommandLineFlag::ParseFrom(absl::string_view value, std::string* error) { return ParseFrom(value, flags_internal::SET_FLAGS_VALUE, - flags_internal::kProgrammaticChange, error); + flags_internal::kProgrammaticChange, *error); } namespace flags_internal { diff --git a/absl/flags/commandlineflag.h b/absl/flags/commandlineflag.h index f09f1f70..43055d04 100644 --- a/absl/flags/commandlineflag.h +++ b/absl/flags/commandlineflag.h @@ -159,7 +159,7 @@ class CommandLineFlag { virtual bool ParseFrom(absl::string_view value, flags_internal::FlagSettingMode set_mode, flags_internal::ValueSource source, - std::string* error) = 0; + std::string& error) = 0; // Returns id of the flag's value type. virtual flags_internal::FlagFastTypeId TypeId() const = 0; diff --git a/absl/flags/commandlineflag_test.cc b/absl/flags/commandlineflag_test.cc index 352edccf..4b9718e9 100644 --- a/absl/flags/commandlineflag_test.cc +++ b/absl/flags/commandlineflag_test.cc @@ -129,57 +129,57 @@ TEST_F(CommandLineFlagTest, TestParseFromCurrentValue) { flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01)); EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( - flag_01, "11", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err)); + *flag_01, "11", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, err)); EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 11); EXPECT_FALSE( flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01)); EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( - flag_01, "-123", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, - &err)); + *flag_01, "-123", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, + err)); EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), -123); EXPECT_FALSE( flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01)); EXPECT_TRUE(!flags::PrivateHandleAccessor::ParseFrom( - flag_01, "xyz", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, - &err)); + *flag_01, "xyz", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, + err)); EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), -123); EXPECT_EQ(err, "Illegal value 'xyz' specified for flag 'int_flag'"); EXPECT_FALSE( flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01)); EXPECT_TRUE(!flags::PrivateHandleAccessor::ParseFrom( - flag_01, "A1", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err)); + *flag_01, "A1", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, err)); EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), -123); EXPECT_EQ(err, "Illegal value 'A1' specified for flag 'int_flag'"); EXPECT_FALSE( flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01)); EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( - flag_01, "0x10", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, - &err)); + *flag_01, "0x10", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, + err)); EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 16); EXPECT_FALSE( flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01)); EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( - flag_01, "011", flags::SET_FLAGS_VALUE, flags::kCommandLine, &err)); + *flag_01, "011", flags::SET_FLAGS_VALUE, flags::kCommandLine, err)); EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 11); EXPECT_TRUE(flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01)); EXPECT_TRUE(!flags::PrivateHandleAccessor::ParseFrom( - flag_01, "", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err)); + *flag_01, "", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, err)); EXPECT_EQ(err, "Illegal value '' specified for flag 'int_flag'"); auto* flag_02 = flags::FindCommandLineFlag("string_flag"); EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( - flag_02, "xyz", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, - &err)); + *flag_02, "xyz", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, + err)); EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "xyz"); EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( - flag_02, "", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err)); + *flag_02, "", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, err)); EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), ""); } @@ -191,15 +191,15 @@ TEST_F(CommandLineFlagTest, TestParseFromDefaultValue) { auto* flag_01 = flags::FindCommandLineFlag("int_flag"); EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( - flag_01, "111", flags::SET_FLAGS_DEFAULT, flags::kProgrammaticChange, - &err)); + *flag_01, "111", flags::SET_FLAGS_DEFAULT, flags::kProgrammaticChange, + err)); EXPECT_EQ(flag_01->DefaultValue(), "111"); auto* flag_02 = flags::FindCommandLineFlag("string_flag"); EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( - flag_02, "abc", flags::SET_FLAGS_DEFAULT, flags::kProgrammaticChange, - &err)); + *flag_02, "abc", flags::SET_FLAGS_DEFAULT, flags::kProgrammaticChange, + err)); EXPECT_EQ(flag_02->DefaultValue(), "abc"); } @@ -211,25 +211,25 @@ TEST_F(CommandLineFlagTest, TestParseFromIfDefault) { auto* flag_01 = flags::FindCommandLineFlag("int_flag"); EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( - flag_01, "22", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange, - &err)) + *flag_01, "22", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange, + err)) << err; EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 22); EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( - flag_01, "33", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange, - &err)); + *flag_01, "33", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange, + err)); EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 22); // EXPECT_EQ(err, "ERROR: int_flag is already set to 22"); // Reset back to default value EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( - flag_01, "201", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, - &err)); + *flag_01, "201", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, + err)); EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( - flag_01, "33", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange, - &err)); + *flag_01, "33", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange, + err)); EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 201); // EXPECT_EQ(err, "ERROR: int_flag is already set to 201"); } diff --git a/absl/flags/flag.h b/absl/flags/flag.h index f84853ea..dd36e6c7 100644 --- a/absl/flags/flag.h +++ b/absl/flags/flag.h @@ -110,12 +110,12 @@ class Flag { impl_(nullptr) {} #endif - flags_internal::Flag* GetImpl() const { + flags_internal::Flag& GetImpl() const { if (!inited_.load(std::memory_order_acquire)) { absl::MutexLock l(flags_internal::GetGlobalConstructionGuard()); if (inited_.load(std::memory_order_acquire)) { - return impl_; + return *impl_; } impl_ = new flags_internal::Flag( @@ -127,28 +127,28 @@ class Flag { inited_.store(true, std::memory_order_release); } - return impl_; + return *impl_; } // Public methods of `absl::Flag` are NOT part of the Abseil Flags API. // See https://abseil.io/docs/cpp/guides/flags - bool IsRetired() const { return GetImpl()->IsRetired(); } - absl::string_view Name() const { return GetImpl()->Name(); } - std::string Help() const { return GetImpl()->Help(); } - bool IsModified() const { return GetImpl()->IsModified(); } + bool IsRetired() const { return GetImpl().IsRetired(); } + absl::string_view Name() const { return GetImpl().Name(); } + std::string Help() const { return GetImpl().Help(); } + bool IsModified() const { return GetImpl().IsModified(); } bool IsSpecifiedOnCommandLine() const { - return GetImpl()->IsSpecifiedOnCommandLine(); + return GetImpl().IsSpecifiedOnCommandLine(); } - std::string Filename() const { return GetImpl()->Filename(); } - std::string DefaultValue() const { return GetImpl()->DefaultValue(); } - std::string CurrentValue() const { return GetImpl()->CurrentValue(); } + std::string Filename() const { return GetImpl().Filename(); } + std::string DefaultValue() const { return GetImpl().DefaultValue(); } + std::string CurrentValue() const { return GetImpl().CurrentValue(); } template inline bool IsOfType() const { - return GetImpl()->template IsOfType(); + return GetImpl().template IsOfType(); } - T Get() const { return GetImpl()->Get(); } - void Set(const T& v) { GetImpl()->Set(v); } - void InvokeCallback() { GetImpl()->InvokeCallback(); } + T Get() const { return GetImpl().Get(); } + void Set(const T& v) { GetImpl().Set(v); } + void InvokeCallback() { GetImpl().InvokeCallback(); } // The data members are logically private, but they need to be public for // this to be an aggregate type. @@ -265,7 +265,7 @@ ABSL_NAMESPACE_END // ABSL_FLAG_IMPL macro definition conditional on ABSL_FLAGS_STRIP_NAMES #if !defined(_MSC_VER) || defined(__clang__) -#define ABSL_FLAG_IMPL_FLAG_PTR(flag) &flag +#define ABSL_FLAG_IMPL_FLAG_PTR(flag) flag #define ABSL_FLAG_IMPL_HELP_ARG(name) \ absl::flags_internal::HelpArg( \ FLAGS_help_storage_##name) diff --git a/absl/flags/flag_test.cc b/absl/flags/flag_test.cc index 8d53ecd6..58a07999 100644 --- a/absl/flags/flag_test.cc +++ b/absl/flags/flag_test.cc @@ -150,21 +150,21 @@ DEFINE_CONSTRUCTED_FLAG(String, &TestMakeDflt, kGenFunc); DEFINE_CONSTRUCTED_FLAG(UDT, &TestMakeDflt, kGenFunc); template -bool TestConstructionFor(const flags::Flag& f1, flags::Flag* f2) { +bool TestConstructionFor(const flags::Flag& f1, flags::Flag& f2) { EXPECT_EQ(f1.Name(), "f1"); EXPECT_EQ(f1.Help(), "literal help"); EXPECT_EQ(f1.Filename(), "file"); flags::FlagRegistrar(f2).OnUpdate(TestCallback); - EXPECT_EQ(f2->Name(), "f2"); - EXPECT_EQ(f2->Help(), "dynamic help"); - EXPECT_EQ(f2->Filename(), "file"); + EXPECT_EQ(f2.Name(), "f2"); + EXPECT_EQ(f2.Help(), "dynamic help"); + EXPECT_EQ(f2.Filename(), "file"); return true; } -#define TEST_CONSTRUCTED_FLAG(T) TestConstructionFor(f1##T, &f2##T); +#define TEST_CONSTRUCTED_FLAG(T) TestConstructionFor(f1##T, f2##T); TEST_F(FlagTest, TestConstruction) { TEST_CONSTRUCTED_FLAG(bool); diff --git a/absl/flags/internal/flag.cc b/absl/flags/internal/flag.cc index 35ae55fb..ee974244 100644 --- a/absl/flags/internal/flag.cc +++ b/absl/flags/internal/flag.cc @@ -62,14 +62,14 @@ bool ShouldValidateFlagValue(FlagFastTypeId flag_type_id) { // need to acquire these locks themselves. class MutexRelock { public: - explicit MutexRelock(absl::Mutex* mu) : mu_(mu) { mu_->Unlock(); } - ~MutexRelock() { mu_->Lock(); } + explicit MutexRelock(absl::Mutex& mu) : mu_(mu) { mu_.Unlock(); } + ~MutexRelock() { mu_.Lock(); } MutexRelock(const MutexRelock&) = delete; MutexRelock& operator=(const MutexRelock&) = delete; private: - absl::Mutex* mu_; + absl::Mutex& mu_; }; } // namespace @@ -82,7 +82,7 @@ class FlagImpl; class FlagState : public flags_internal::FlagStateInterface { public: template - FlagState(FlagImpl* flag_impl, const V& v, bool modified, + FlagState(FlagImpl& flag_impl, const V& v, bool modified, bool on_command_line, int64_t counter) : flag_impl_(flag_impl), value_(v), @@ -91,9 +91,9 @@ class FlagState : public flags_internal::FlagStateInterface { counter_(counter) {} ~FlagState() override { - if (flag_impl_->ValueStorageKind() != FlagValueStorageKind::kAlignedBuffer) + if (flag_impl_.ValueStorageKind() != FlagValueStorageKind::kAlignedBuffer) return; - flags_internal::Delete(flag_impl_->op_, value_.heap_allocated); + flags_internal::Delete(flag_impl_.op_, value_.heap_allocated); } private: @@ -101,15 +101,15 @@ class FlagState : public flags_internal::FlagStateInterface { // Restores the flag to the saved state. void Restore() const override { - if (!flag_impl_->RestoreState(*this)) return; + if (!flag_impl_.RestoreState(*this)) return; - ABSL_INTERNAL_LOG( - INFO, absl::StrCat("Restore saved value of ", flag_impl_->Name(), - " to: ", flag_impl_->CurrentValue())); + ABSL_INTERNAL_LOG(INFO, + absl::StrCat("Restore saved value of ", flag_impl_.Name(), + " to: ", flag_impl_.CurrentValue())); } // Flag and saved flag data. - FlagImpl* flag_impl_; + FlagImpl& flag_impl_; union SavedValue { explicit SavedValue(void* v) : heap_allocated(v) {} explicit SavedValue(int64_t v) : one_word(v) {} @@ -326,7 +326,7 @@ void FlagImpl::InvokeCallback() const { // and it also can be different by the time the callback invocation is // completed. Requires that *primary_lock be held in exclusive mode; it may be // released and reacquired by the implementation. - MutexRelock relock(DataGuard()); + MutexRelock relock(*DataGuard()); absl::MutexLock lock(&callback_->guard); cb(); } @@ -339,17 +339,17 @@ std::unique_ptr FlagImpl::SaveState() { switch (ValueStorageKind()) { case FlagValueStorageKind::kAlignedBuffer: { return absl::make_unique( - this, flags_internal::Clone(op_, AlignedBufferValue()), modified, + *this, flags_internal::Clone(op_, AlignedBufferValue()), modified, on_command_line, counter_); } case FlagValueStorageKind::kOneWordAtomic: { return absl::make_unique( - this, OneWordValue().load(std::memory_order_acquire), modified, + *this, OneWordValue().load(std::memory_order_acquire), modified, on_command_line, counter_); } case FlagValueStorageKind::kTwoWordsAtomic: { return absl::make_unique( - this, TwoWordsValue().load(std::memory_order_acquire), modified, + *this, TwoWordsValue().load(std::memory_order_acquire), modified, on_command_line, counter_); } } @@ -410,14 +410,14 @@ std::atomic& FlagImpl::TwoWordsValue() const { // parsed value. In case if any error is encountered in either step, the error // message is stored in 'err' std::unique_ptr FlagImpl::TryParse( - absl::string_view value, std::string* err) const { + absl::string_view value, std::string& err) const { std::unique_ptr tentative_value = MakeInitValue(); std::string parse_err; if (!flags_internal::Parse(op_, value, tentative_value.get(), &parse_err)) { absl::string_view err_sep = parse_err.empty() ? "" : "; "; - *err = absl::StrCat("Illegal value '", value, "' specified for flag '", - Name(), "'", err_sep, parse_err); + err = absl::StrCat("Illegal value '", value, "' specified for flag '", + Name(), "'", err_sep, parse_err); return nullptr; } @@ -473,7 +473,7 @@ void FlagImpl::Write(const void* src) { // * Update the current flag value if it was never set before // The mode is selected based on 'set_mode' parameter. bool FlagImpl::ParseFrom(absl::string_view value, FlagSettingMode set_mode, - ValueSource source, std::string* err) { + ValueSource source, std::string& err) { absl::MutexLock l(DataGuard()); switch (set_mode) { diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h index 97ddb5f9..e1885809 100644 --- a/absl/flags/internal/flag.h +++ b/absl/flags/internal/flag.h @@ -374,31 +374,31 @@ struct FlagValue; template struct FlagValue { - bool Get(T*) const { return false; } + bool Get(T&) const { return false; } alignas(T) char value[sizeof(T)]; }; template struct FlagValue : FlagOneWordValue { - bool Get(T* dst) const { + bool Get(T& dst) const { int64_t one_word_val = value.load(std::memory_order_acquire); if (ABSL_PREDICT_FALSE(one_word_val == UninitializedFlagValue())) { return false; } - std::memcpy(dst, static_cast(&one_word_val), sizeof(T)); + std::memcpy(&dst, static_cast(&one_word_val), sizeof(T)); return true; } }; template struct FlagValue : FlagTwoWordsValue { - bool Get(T* dst) const { + bool Get(T& dst) const { AlignedTwoWords two_words_val = value.load(std::memory_order_acquire); if (ABSL_PREDICT_FALSE(!two_words_val.IsInitialized())) { return false; } - std::memcpy(dst, static_cast(&two_words_val), sizeof(T)); + std::memcpy(&dst, static_cast(&two_words_val), sizeof(T)); return true; } }; @@ -502,7 +502,7 @@ class FlagImpl final : public CommandLineFlag { // Attempts to parse supplied `value` string. If parsing is successful, // returns new value. Otherwise returns nullptr. std::unique_ptr TryParse(absl::string_view value, - std::string* err) const + std::string& err) const ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); // Stores the flag value based on the pointer to the source. void StoreValue(const void* src) ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); @@ -544,7 +544,7 @@ class FlagImpl final : public CommandLineFlag { ABSL_LOCKS_EXCLUDED(*DataGuard()); bool ParseFrom(absl::string_view value, FlagSettingMode set_mode, - ValueSource source, std::string* error) override + ValueSource source, std::string& error) override ABSL_LOCKS_EXCLUDED(*DataGuard()); // Immutable flag's state. @@ -651,7 +651,7 @@ class Flag { impl_.AssertValidType(base_internal::FastTypeId(), &GenRuntimeTypeId); #endif - if (!value_.Get(&u.value)) impl_.Read(&u.value); + if (!value_.Get(u.value)) impl_.Read(&u.value); return std::move(u.value); } void Set(const T& v) { @@ -730,12 +730,12 @@ struct FlagRegistrarEmpty {}; template class FlagRegistrar { public: - explicit FlagRegistrar(Flag* flag) : flag_(flag) { - if (do_register) flags_internal::RegisterCommandLineFlag(&flag_->impl_); + explicit FlagRegistrar(Flag& flag) : flag_(flag) { + if (do_register) flags_internal::RegisterCommandLineFlag(flag_.impl_); } FlagRegistrar OnUpdate(FlagCallbackFunc cb) && { - flag_->impl_.SetCallback(cb); + flag_.impl_.SetCallback(cb); return *this; } @@ -745,7 +745,7 @@ class FlagRegistrar { operator FlagRegistrarEmpty() const { return {}; } // NOLINT private: - Flag* flag_; // Flag being registered (not owned). + Flag& flag_; // Flag being registered (not owned). }; } // namespace flags_internal diff --git a/absl/flags/internal/private_handle_accessor.cc b/absl/flags/internal/private_handle_accessor.cc index 64fe3166..24b49136 100644 --- a/absl/flags/internal/private_handle_accessor.cc +++ b/absl/flags/internal/private_handle_accessor.cc @@ -24,8 +24,8 @@ FlagFastTypeId PrivateHandleAccessor::TypeId(const CommandLineFlag& flag) { } std::unique_ptr PrivateHandleAccessor::SaveState( - CommandLineFlag* flag) { - return flag->SaveState(); + CommandLineFlag& flag) { + return flag.SaveState(); } bool PrivateHandleAccessor::IsSpecifiedOnCommandLine( @@ -43,12 +43,12 @@ void PrivateHandleAccessor::CheckDefaultValueParsingRoundtrip( flag.CheckDefaultValueParsingRoundtrip(); } -bool PrivateHandleAccessor::ParseFrom(CommandLineFlag* flag, +bool PrivateHandleAccessor::ParseFrom(CommandLineFlag& flag, absl::string_view value, flags_internal::FlagSettingMode set_mode, flags_internal::ValueSource source, - std::string* error) { - return flag->ParseFrom(value, set_mode, source, error); + std::string& error) { + return flag.ParseFrom(value, set_mode, source, error); } } // namespace flags_internal diff --git a/absl/flags/internal/private_handle_accessor.h b/absl/flags/internal/private_handle_accessor.h index 07838600..9a327a07 100644 --- a/absl/flags/internal/private_handle_accessor.h +++ b/absl/flags/internal/private_handle_accessor.h @@ -31,7 +31,7 @@ class PrivateHandleAccessor { static FlagFastTypeId TypeId(const CommandLineFlag& flag); // Access to CommandLineFlag::SaveState. - static std::unique_ptr SaveState(CommandLineFlag* flag); + static std::unique_ptr SaveState(CommandLineFlag& flag); // Access to CommandLineFlag::IsSpecifiedOnCommandLine. static bool IsSpecifiedOnCommandLine(const CommandLineFlag& flag); @@ -43,9 +43,9 @@ class PrivateHandleAccessor { // Access to CommandLineFlag::CheckDefaultValueParsingRoundtrip. static void CheckDefaultValueParsingRoundtrip(const CommandLineFlag& flag); - static bool ParseFrom(CommandLineFlag* flag, absl::string_view value, + static bool ParseFrom(CommandLineFlag& flag, absl::string_view value, flags_internal::FlagSettingMode set_mode, - flags_internal::ValueSource source, std::string* error); + flags_internal::ValueSource source, std::string& error); }; } // namespace flags_internal diff --git a/absl/flags/internal/registry.cc b/absl/flags/internal/registry.cc index 70d76557..4bcebfa9 100644 --- a/absl/flags/internal/registry.cc +++ b/absl/flags/internal/registry.cc @@ -60,8 +60,8 @@ class FlagRegistry { FlagRegistry() = default; ~FlagRegistry() = default; - // Store a flag in this registry. Takes ownership of *flag. - void RegisterFlag(CommandLineFlag* flag); + // Store a flag in this registry. Takes ownership of *flag. + void RegisterFlag(CommandLineFlag& flag); void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION(lock_) { lock_.Lock(); } void Unlock() ABSL_UNLOCK_FUNCTION(lock_) { lock_.Unlock(); } @@ -74,12 +74,12 @@ class FlagRegistry { // found or not retired. Does not emit a warning. CommandLineFlag* FindRetiredFlagLocked(absl::string_view name); - static FlagRegistry* GlobalRegistry(); // returns a singleton registry + static FlagRegistry& GlobalRegistry(); // returns a singleton registry private: friend class FlagSaverImpl; // reads all the flags in order to copy them friend void ForEachFlagUnlocked( - std::function visitor); + std::function visitor); // The map from name to flag, for FindFlagLocked(). using FlagMap = std::map; @@ -94,65 +94,62 @@ class FlagRegistry { FlagRegistry& operator=(const FlagRegistry&); }; -FlagRegistry* FlagRegistry::GlobalRegistry() { +FlagRegistry& FlagRegistry::GlobalRegistry() { static FlagRegistry* global_registry = new FlagRegistry; - return global_registry; + return *global_registry; } namespace { class FlagRegistryLock { public: - explicit FlagRegistryLock(FlagRegistry* fr) : fr_(fr) { fr_->Lock(); } - ~FlagRegistryLock() { fr_->Unlock(); } + explicit FlagRegistryLock(FlagRegistry& fr) : fr_(fr) { fr_.Lock(); } + ~FlagRegistryLock() { fr_.Unlock(); } private: - FlagRegistry* const fr_; + FlagRegistry& fr_; }; -void DestroyRetiredFlag(CommandLineFlag* flag); +void DestroyRetiredFlag(CommandLineFlag& flag); } // namespace -void FlagRegistry::RegisterFlag(CommandLineFlag* flag) { - FlagRegistryLock registry_lock(this); +void FlagRegistry::RegisterFlag(CommandLineFlag& flag) { + FlagRegistryLock registry_lock(*this); std::pair ins = - flags_.insert(FlagMap::value_type(flag->Name(), flag)); + flags_.insert(FlagMap::value_type(flag.Name(), &flag)); if (ins.second == false) { // means the name was already in the map - CommandLineFlag* old_flag = ins.first->second; - if (flag->IsRetired() != old_flag->IsRetired()) { + CommandLineFlag& old_flag = *ins.first->second; + if (flag.IsRetired() != old_flag.IsRetired()) { // All registrations must agree on the 'retired' flag. flags_internal::ReportUsageError( absl::StrCat( - "Retired flag '", flag->Name(), - "' was defined normally in file '", - (flag->IsRetired() ? old_flag->Filename() : flag->Filename()), - "'."), + "Retired flag '", flag.Name(), "' was defined normally in file '", + (flag.IsRetired() ? old_flag.Filename() : flag.Filename()), "'."), true); - } else if (flags_internal::PrivateHandleAccessor::TypeId(*flag) != - flags_internal::PrivateHandleAccessor::TypeId(*old_flag)) { + } else if (flags_internal::PrivateHandleAccessor::TypeId(flag) != + flags_internal::PrivateHandleAccessor::TypeId(old_flag)) { flags_internal::ReportUsageError( - absl::StrCat("Flag '", flag->Name(), + absl::StrCat("Flag '", flag.Name(), "' was defined more than once but with " "differing types. Defined in files '", - old_flag->Filename(), "' and '", flag->Filename(), "'."), + old_flag.Filename(), "' and '", flag.Filename(), "'."), true); - } else if (old_flag->IsRetired()) { + } else if (old_flag.IsRetired()) { // Retired flag can just be deleted. DestroyRetiredFlag(flag); return; - } else if (old_flag->Filename() != flag->Filename()) { + } else if (old_flag.Filename() != flag.Filename()) { flags_internal::ReportUsageError( - absl::StrCat("Flag '", flag->Name(), + absl::StrCat("Flag '", flag.Name(), "' was defined more than once (in files '", - old_flag->Filename(), "' and '", flag->Filename(), - "')."), + old_flag.Filename(), "' and '", flag.Filename(), "')."), true); } else { flags_internal::ReportUsageError( absl::StrCat( - "Something wrong with flag '", flag->Name(), "' in file '", - flag->Filename(), "'. One possibility: file '", flag->Filename(), + "Something wrong with flag '", flag.Name(), "' in file '", + flag.Filename(), "'. One possibility: file '", flag.Filename(), "' is being linked both statically and dynamically into this " "executable. e.g. some files listed as srcs to a test and also " "listed as srcs of some shared lib deps of the same test."), @@ -206,7 +203,7 @@ class FlagSaverImpl { // It's an error to call this more than once. void SaveFromRegistry() { assert(backup_registry_.empty()); // call only once! - flags_internal::ForEachFlag([&](CommandLineFlag* flag) { + flags_internal::ForEachFlag([&](CommandLineFlag& flag) { if (auto flag_state = flags_internal::PrivateHandleAccessor::SaveState(flag)) { backup_registry_.emplace_back(std::move(flag_state)); @@ -244,39 +241,39 @@ FlagSaver::~FlagSaver() { CommandLineFlag* FindCommandLineFlag(absl::string_view name) { if (name.empty()) return nullptr; - FlagRegistry* const registry = FlagRegistry::GlobalRegistry(); + FlagRegistry& registry = FlagRegistry::GlobalRegistry(); FlagRegistryLock frl(registry); - return registry->FindFlagLocked(name); + return registry.FindFlagLocked(name); } CommandLineFlag* FindRetiredFlag(absl::string_view name) { - FlagRegistry* const registry = FlagRegistry::GlobalRegistry(); + FlagRegistry& registry = FlagRegistry::GlobalRegistry(); FlagRegistryLock frl(registry); - return registry->FindRetiredFlagLocked(name); + return registry.FindRetiredFlagLocked(name); } // -------------------------------------------------------------------- -void ForEachFlagUnlocked(std::function visitor) { - FlagRegistry* const registry = FlagRegistry::GlobalRegistry(); - for (FlagRegistry::FlagConstIterator i = registry->flags_.begin(); - i != registry->flags_.end(); ++i) { - visitor(i->second); +void ForEachFlagUnlocked(std::function visitor) { + FlagRegistry& registry = FlagRegistry::GlobalRegistry(); + for (FlagRegistry::FlagConstIterator i = registry.flags_.begin(); + i != registry.flags_.end(); ++i) { + visitor(*i->second); } } -void ForEachFlag(std::function visitor) { - FlagRegistry* const registry = FlagRegistry::GlobalRegistry(); +void ForEachFlag(std::function visitor) { + FlagRegistry& registry = FlagRegistry::GlobalRegistry(); FlagRegistryLock frl(registry); ForEachFlagUnlocked(visitor); } // -------------------------------------------------------------------- -bool RegisterCommandLineFlag(CommandLineFlag* flag) { - FlagRegistry::GlobalRegistry()->RegisterFlag(flag); +bool RegisterCommandLineFlag(CommandLineFlag& flag) { + FlagRegistry::GlobalRegistry().RegisterFlag(flag); return true; } @@ -307,7 +304,7 @@ class RetiredFlagObj final : public CommandLineFlag { } bool ParseFrom(absl::string_view, flags_internal::FlagSettingMode, - flags_internal::ValueSource, std::string*) override { + flags_internal::ValueSource, std::string&) override { return false; } @@ -320,16 +317,16 @@ class RetiredFlagObj final : public CommandLineFlag { const FlagFastTypeId type_id_; }; -void DestroyRetiredFlag(CommandLineFlag* flag) { - assert(flag->IsRetired()); - delete static_cast(flag); +void DestroyRetiredFlag(CommandLineFlag& flag) { + assert(flag.IsRetired()); + delete static_cast(&flag); } } // namespace bool Retire(const char* name, FlagFastTypeId type_id) { auto* flag = new flags_internal::RetiredFlagObj(name, type_id); - FlagRegistry::GlobalRegistry()->RegisterFlag(flag); + FlagRegistry::GlobalRegistry().RegisterFlag(*flag); return true; } diff --git a/absl/flags/internal/registry.h b/absl/flags/internal/registry.h index f722fd44..a118865a 100644 --- a/absl/flags/internal/registry.h +++ b/absl/flags/internal/registry.h @@ -39,14 +39,14 @@ CommandLineFlag* FindRetiredFlag(absl::string_view name); // Executes specified visitor for each non-retired flag in the registry. // Requires the caller hold the registry lock. -void ForEachFlagUnlocked(std::function visitor); +void ForEachFlagUnlocked(std::function visitor); // Executes specified visitor for each non-retired flag in the registry. While // callback are executed, the registry is locked and can't be changed. -void ForEachFlag(std::function visitor); +void ForEachFlag(std::function visitor); //----------------------------------------------------------------------------- -bool RegisterCommandLineFlag(CommandLineFlag*); +bool RegisterCommandLineFlag(CommandLineFlag&); //----------------------------------------------------------------------------- // Retired registrations: diff --git a/absl/flags/internal/type_erased.cc b/absl/flags/internal/type_erased.cc index 35b0d125..b2523b24 100644 --- a/absl/flags/internal/type_erased.cc +++ b/absl/flags/internal/type_erased.cc @@ -58,7 +58,7 @@ bool SetCommandLineOptionWithMode(absl::string_view name, std::string error; if (!flags_internal::PrivateHandleAccessor::ParseFrom( - flag, value, set_mode, kProgrammaticChange, &error)) { + *flag, value, set_mode, kProgrammaticChange, error)) { // Errors here are all of the form: the provided name was a recognized // flag, but the value was invalid (bad type, or validation failed). flags_internal::ReportUsageError(error, false); diff --git a/absl/flags/internal/usage.cc b/absl/flags/internal/usage.cc index 11664e10..2a2231a7 100644 --- a/absl/flags/internal/usage.cc +++ b/absl/flags/internal/usage.cc @@ -107,8 +107,8 @@ class FlagHelpPrettyPrinter { public: // Pretty printer holds on to the std::ostream& reference to direct an output // to that stream. - FlagHelpPrettyPrinter(int max_line_len, std::ostream* out) - : out_(*out), + FlagHelpPrettyPrinter(int max_line_len, std::ostream& out) + : out_(out), max_line_len_(max_line_len), line_len_(0), first_line_(true) {} @@ -182,7 +182,7 @@ class FlagHelpPrettyPrinter { bool first_line_; }; -void FlagHelpHumanReadable(const CommandLineFlag& flag, std::ostream* out) { +void FlagHelpHumanReadable(const CommandLineFlag& flag, std::ostream& out) { FlagHelpPrettyPrinter printer(80, out); // Max line length is 80. // Flag name. @@ -244,29 +244,28 @@ void FlagsHelpImpl(std::ostream& out, flags_internal::FlagKindFilter filter_cb, // This map is used to output matching flags grouped by package and file // name. std::map>> + std::map>> matching_flags; - flags_internal::ForEachFlag([&](CommandLineFlag* flag) { - std::string flag_filename = flag->Filename(); + flags_internal::ForEachFlag([&](absl::CommandLineFlag& flag) { + std::string flag_filename = flag.Filename(); // Ignore retired flags. - if (flag->IsRetired()) return; + if (flag.IsRetired()) return; // If the flag has been stripped, pretend that it doesn't exist. - if (flag->Help() == flags_internal::kStrippedFlagHelp) return; + if (flag.Help() == flags_internal::kStrippedFlagHelp) return; // Make sure flag satisfies the filter if (!filter_cb || !filter_cb(flag_filename)) return; matching_flags[std::string(flags_internal::Package(flag_filename))] [flag_filename] - .push_back(flag); + .push_back(&flag); }); - absl::string_view - package_separator; // controls blank lines between packages. - absl::string_view file_separator; // controls blank lines between files. + absl::string_view package_separator; // controls blank lines between packages + absl::string_view file_separator; // controls blank lines between files for (const auto& package : matching_flags) { if (format == HelpFormat::kHumanReadable) { out << package_separator; @@ -304,7 +303,7 @@ void FlagsHelpImpl(std::ostream& out, flags_internal::FlagKindFilter filter_cb, void FlagHelp(std::ostream& out, const CommandLineFlag& flag, HelpFormat format) { if (format == HelpFormat::kHumanReadable) - flags_internal::FlagHelpHumanReadable(flag, &out); + flags_internal::FlagHelpHumanReadable(flag, out); } // -------------------------------------------------------------------- diff --git a/absl/flags/marshalling.cc b/absl/flags/marshalling.cc index 09baae88..81f9cebd 100644 --- a/absl/flags/marshalling.cc +++ b/absl/flags/marshalling.cc @@ -74,15 +74,16 @@ static int NumericBase(absl::string_view text) { } template -inline bool ParseFlagImpl(absl::string_view text, IntType* dst) { +inline bool ParseFlagImpl(absl::string_view text, IntType& dst) { text = absl::StripAsciiWhitespace(text); - return absl::numbers_internal::safe_strtoi_base(text, dst, NumericBase(text)); + return absl::numbers_internal::safe_strtoi_base(text, &dst, + NumericBase(text)); } bool AbslParseFlag(absl::string_view text, short* dst, std::string*) { int val; - if (!ParseFlagImpl(text, &val)) return false; + if (!ParseFlagImpl(text, val)) return false; if (static_cast(val) != val) // worked, but number out of range return false; *dst = static_cast(val); @@ -91,7 +92,7 @@ bool AbslParseFlag(absl::string_view text, short* dst, std::string*) { bool AbslParseFlag(absl::string_view text, unsigned short* dst, std::string*) { unsigned int val; - if (!ParseFlagImpl(text, &val)) return false; + if (!ParseFlagImpl(text, val)) return false; if (static_cast(val) != val) // worked, but number out of range return false; @@ -100,28 +101,28 @@ bool AbslParseFlag(absl::string_view text, unsigned short* dst, std::string*) { } bool AbslParseFlag(absl::string_view text, int* dst, std::string*) { - return ParseFlagImpl(text, dst); + return ParseFlagImpl(text, *dst); } bool AbslParseFlag(absl::string_view text, unsigned int* dst, std::string*) { - return ParseFlagImpl(text, dst); + return ParseFlagImpl(text, *dst); } bool AbslParseFlag(absl::string_view text, long* dst, std::string*) { - return ParseFlagImpl(text, dst); + return ParseFlagImpl(text, *dst); } bool AbslParseFlag(absl::string_view text, unsigned long* dst, std::string*) { - return ParseFlagImpl(text, dst); + return ParseFlagImpl(text, *dst); } bool AbslParseFlag(absl::string_view text, long long* dst, std::string*) { - return ParseFlagImpl(text, dst); + return ParseFlagImpl(text, *dst); } bool AbslParseFlag(absl::string_view text, unsigned long long* dst, std::string*) { - return ParseFlagImpl(text, dst); + return ParseFlagImpl(text, *dst); } // -------------------------------------------------------------------- diff --git a/absl/flags/parse.cc b/absl/flags/parse.cc index 3f0a7a75..15300786 100644 --- a/absl/flags/parse.cc +++ b/absl/flags/parse.cc @@ -222,7 +222,7 @@ bool ArgsList::ReadFromFlagfile(const std::string& flag_file_name) { // Reads the environment variable with name `name` and stores results in // `value`. If variable is not present in environment returns false, otherwise // returns true. -bool GetEnvVar(const char* var_name, std::string* var_value) { +bool GetEnvVar(const char* var_name, std::string& var_value) { #ifdef _WIN32 char buf[1024]; auto get_res = GetEnvironmentVariableA(var_name, buf, sizeof(buf)); @@ -234,14 +234,14 @@ bool GetEnvVar(const char* var_name, std::string* var_value) { return false; } - *var_value = std::string(buf, get_res); + var_value = std::string(buf, get_res); #else const char* val = ::getenv(var_name); if (val == nullptr) { return false; } - *var_value = val; + var_value = val; #endif return true; @@ -306,17 +306,17 @@ std::tuple LocateFlag(absl::string_view flag_name) { // back. void CheckDefaultValuesParsingRoundtrip() { #ifndef NDEBUG - flags_internal::ForEachFlag([&](CommandLineFlag* flag) { - if (flag->IsRetired()) return; + flags_internal::ForEachFlag([&](CommandLineFlag& flag) { + if (flag.IsRetired()) return; #define ABSL_FLAGS_INTERNAL_IGNORE_TYPE(T, _) \ - if (flag->IsOfType()) return; + if (flag.IsOfType()) return; ABSL_FLAGS_INTERNAL_SUPPORTED_TYPES(ABSL_FLAGS_INTERNAL_IGNORE_TYPE) #undef ABSL_FLAGS_INTERNAL_IGNORE_TYPE flags_internal::PrivateHandleAccessor::CheckDefaultValueParsingRoundtrip( - *flag); + flag); }); #endif } @@ -329,13 +329,13 @@ void CheckDefaultValuesParsingRoundtrip() { // the first flagfile in the input list are processed before the second flagfile // etc. bool ReadFlagfiles(const std::vector& flagfiles, - std::vector* input_args) { + std::vector& input_args) { bool success = true; for (auto it = flagfiles.rbegin(); it != flagfiles.rend(); ++it) { ArgsList al; if (al.ReadFromFlagfile(*it)) { - input_args->push_back(al); + input_args.push_back(al); } else { success = false; } @@ -350,7 +350,7 @@ bool ReadFlagfiles(const std::vector& flagfiles, // `flag_name` is a string from the input flag_names list. If successful we // append a single ArgList at the end of the input_args. bool ReadFlagsFromEnv(const std::vector& flag_names, - std::vector* input_args, + std::vector& input_args, bool fail_on_absent_in_env) { bool success = true; std::vector args; @@ -371,7 +371,7 @@ bool ReadFlagsFromEnv(const std::vector& flag_names, const std::string envname = absl::StrCat("FLAGS_", flag_name); std::string envval; - if (!GetEnvVar(envname.c_str(), &envval)) { + if (!GetEnvVar(envname.c_str(), envval)) { if (fail_on_absent_in_env) { flags_internal::ReportUsageError( absl::StrCat(envname, " not found in environment"), true); @@ -386,7 +386,7 @@ bool ReadFlagsFromEnv(const std::vector& flag_names, } if (success) { - input_args->emplace_back(args); + input_args.emplace_back(args); } return success; @@ -396,8 +396,8 @@ bool ReadFlagsFromEnv(const std::vector& flag_names, // Returns success status, which is true if were able to handle all generator // flags (flagfile, fromenv, tryfromemv) successfully. -bool HandleGeneratorFlags(std::vector* input_args, - std::vector* flagfile_value) { +bool HandleGeneratorFlags(std::vector& input_args, + std::vector& flagfile_value) { bool success = true; absl::MutexLock l(&flags_internal::processing_checks_guard); @@ -422,9 +422,9 @@ bool HandleGeneratorFlags(std::vector* input_args, if (flags_internal::flagfile_needs_processing) { auto flagfiles = absl::GetFlag(FLAGS_flagfile); - if (input_args->size() == 1) { - flagfile_value->insert(flagfile_value->end(), flagfiles.begin(), - flagfiles.end()); + if (input_args.size() == 1) { + flagfile_value.insert(flagfile_value.end(), flagfiles.begin(), + flagfiles.end()); } success &= ReadFlagfiles(flagfiles, input_args); @@ -647,7 +647,7 @@ std::vector ParseCommandLineImpl(int argc, char* argv[], bool success = true; while (!input_args.empty()) { // 10. First we process the built-in generator flags. - success &= HandleGeneratorFlags(&input_args, &flagfile_value); + success &= HandleGeneratorFlags(input_args, flagfile_value); // 30. Select top-most (most recent) arguments list. If it is empty drop it // and re-try. @@ -733,7 +733,7 @@ std::vector ParseCommandLineImpl(int argc, char* argv[], std::string error; if (!flags_internal::PrivateHandleAccessor::ParseFrom( - flag, value, SET_FLAGS_VALUE, kCommandLine, &error)) { + *flag, value, SET_FLAGS_VALUE, kCommandLine, error)) { flags_internal::ReportUsageError(error, true); success = false; } else { diff --git a/absl/flags/parse_test.cc b/absl/flags/parse_test.cc index e6a53ae6..aea068ee 100644 --- a/absl/flags/parse_test.cc +++ b/absl/flags/parse_test.cc @@ -171,8 +171,8 @@ constexpr const char* const ff2_data[] = { // temporary directory location. This way we can test inclusion of one flagfile // from another flagfile. const char* GetFlagfileFlag(const std::vector& ffd, - std::string* flagfile_flag) { - *flagfile_flag = "--flagfile="; + std::string& flagfile_flag) { + flagfile_flag = "--flagfile="; absl::string_view separator; for (const auto& flagfile_data : ffd) { std::string flagfile_name = @@ -183,11 +183,11 @@ const char* GetFlagfileFlag(const std::vector& ffd, flagfile_out << absl::Substitute(line, GetTestTempDir()) << "\n"; } - absl::StrAppend(flagfile_flag, separator, flagfile_name); + absl::StrAppend(&flagfile_flag, separator, flagfile_name); separator = ","; } - return flagfile_flag->c_str(); + return flagfile_flag.c_str(); } } // namespace @@ -588,14 +588,14 @@ TEST_F(ParseTest, TestSimpleValidFlagfile) { const char* in_args1[] = { "testbin", GetFlagfileFlag({{"parse_test.ff1", absl::MakeConstSpan(ff1_data)}}, - &flagfile_flag), + flagfile_flag), }; TestParse(in_args1, -1, 0.1, "q2w2 ", true); const char* in_args2[] = { "testbin", GetFlagfileFlag({{"parse_test.ff2", absl::MakeConstSpan(ff2_data)}}, - &flagfile_flag), + flagfile_flag), }; TestParse(in_args2, 100, 0.1, "q2w2 ", false); } @@ -609,7 +609,7 @@ TEST_F(ParseTest, TestValidMultiFlagfile) { "testbin", GetFlagfileFlag({{"parse_test.ff2", absl::MakeConstSpan(ff2_data)}, {"parse_test.ff1", absl::MakeConstSpan(ff1_data)}}, - &flagfile_flag), + flagfile_flag), }; TestParse(in_args1, -1, 0.1, "q2w2 ", true); } @@ -622,7 +622,7 @@ TEST_F(ParseTest, TestFlagfileMixedWithRegularFlags) { const char* in_args1[] = { "testbin", "--int_flag=3", GetFlagfileFlag({{"parse_test.ff1", absl::MakeConstSpan(ff1_data)}}, - &flagfile_flag), + flagfile_flag), "-double_flag=0.2"}; TestParse(in_args1, -1, 0.2, "q2w2 ", true); } @@ -640,7 +640,7 @@ TEST_F(ParseTest, TestFlagfileInFlagfile) { const char* in_args1[] = { "testbin", GetFlagfileFlag({{"parse_test.ff3", absl::MakeConstSpan(ff3_data)}}, - &flagfile_flag), + flagfile_flag), }; TestParse(in_args1, 100, 0.1, "q2w2 ", false); } @@ -657,7 +657,7 @@ TEST_F(ParseDeathTest, TestInvalidFlagfiles) { const char* in_args1[] = { "testbin", GetFlagfileFlag({{"parse_test.ff4", - absl::MakeConstSpan(ff4_data)}}, &flagfile_flag), + absl::MakeConstSpan(ff4_data)}}, flagfile_flag), }; EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args1), "Unknown command line flag 'unknown_flag'"); @@ -669,7 +669,7 @@ TEST_F(ParseDeathTest, TestInvalidFlagfiles) { const char* in_args2[] = { "testbin", GetFlagfileFlag({{"parse_test.ff5", - absl::MakeConstSpan(ff5_data)}}, &flagfile_flag), + absl::MakeConstSpan(ff5_data)}}, flagfile_flag), }; EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args2), "Unknown command line flag 'int_flag 10'"); @@ -681,7 +681,7 @@ TEST_F(ParseDeathTest, TestInvalidFlagfiles) { const char* in_args3[] = { "testbin", GetFlagfileFlag({{"parse_test.ff6", absl::MakeConstSpan(ff6_data)}}, - &flagfile_flag), + flagfile_flag), }; EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args3), "Flagfile can't contain position arguments or --"); @@ -702,7 +702,7 @@ TEST_F(ParseDeathTest, TestInvalidFlagfiles) { const char* in_args5[] = { "testbin", GetFlagfileFlag({{"parse_test.ff7", absl::MakeConstSpan(ff7_data)}}, - &flagfile_flag), + flagfile_flag), }; EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args5), "Unexpected line in the flagfile .*: \\*bin\\*"); diff --git a/absl/random/BUILD.bazel b/absl/random/BUILD.bazel index 9ba75b52..4b804c86 100644 --- a/absl/random/BUILD.bazel +++ b/absl/random/BUILD.bazel @@ -69,7 +69,7 @@ cc_library( "//absl/base:config", "//absl/base:core_headers", "//absl/meta:type_traits", - "//absl/random/internal:distributions", + "//absl/random/internal:distribution_caller", "//absl/random/internal:fast_uniform_bits", "//absl/random/internal:fastmath", "//absl/random/internal:generate_real", @@ -78,7 +78,6 @@ cc_library( "//absl/random/internal:uniform_helper", "//absl/random/internal:wide_multiply", "//absl/strings", - "//absl/types:span", ], ) diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt index ec616dd9..85a2ea37 100644 --- a/absl/random/CMakeLists.txt +++ b/absl/random/CMakeLists.txt @@ -183,7 +183,7 @@ absl_cc_library( absl::config absl::core_headers absl::random_internal_generate_real - absl::random_internal_distributions + absl::random_internal_distribution_caller absl::random_internal_fast_uniform_bits absl::random_internal_fastmath absl::random_internal_iostream_state_saver @@ -191,7 +191,6 @@ absl_cc_library( absl::random_internal_uniform_helper absl::random_internal_wide_multiply absl::strings - absl::span absl::type_traits ) @@ -536,27 +535,6 @@ absl_cc_library( absl::config ) -# Internal-only target, do not depend on directly. -absl_cc_library( - NAME - random_internal_distributions - HDRS - "internal/distributions.h" - COPTS - ${ABSL_DEFAULT_COPTS} - LINKOPTS - ${ABSL_DEFAULT_LINKOPTS} - DEPS - absl::random_internal_distribution_caller - absl::random_internal_fast_uniform_bits - absl::random_internal_fastmath - absl::random_internal_traits - absl::random_internal_uniform_helper - absl::span - absl::strings - absl::type_traits -) - # Internal-only target, do not depend on directly. absl_cc_library( NAME @@ -745,7 +723,6 @@ absl_cc_library( absl::random_internal_salted_seed_seq absl::random_internal_seed_material absl::span - absl::strings absl::type_traits ) @@ -1174,9 +1151,7 @@ absl_cc_library( LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS - absl::core_headers - absl::random_internal_fast_uniform_bits - absl::random_internal_iostream_state_saver + absl::config absl::random_internal_traits absl::type_traits ) diff --git a/absl/random/distributions.h b/absl/random/distributions.h index 8680f6a6..6775c5d6 100644 --- a/absl/random/distributions.h +++ b/absl/random/distributions.h @@ -57,7 +57,7 @@ #include "absl/random/beta_distribution.h" #include "absl/random/exponential_distribution.h" #include "absl/random/gaussian_distribution.h" -#include "absl/random/internal/distributions.h" // IWYU pragma: export +#include "absl/random/internal/distribution_caller.h" // IWYU pragma: export #include "absl/random/internal/uniform_helper.h" // IWYU pragma: export #include "absl/random/log_uniform_int_distribution.h" #include "absl/random/poisson_distribution.h" diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel index 85d1fb81..813d926e 100644 --- a/absl/random/internal/BUILD.bazel +++ b/absl/random/internal/BUILD.bazel @@ -48,21 +48,6 @@ cc_library( deps = ["//absl/base:config"], ) -cc_library( - name = "distributions", - hdrs = ["distributions.h"], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":distribution_caller", - ":traits", - ":uniform_helper", - "//absl/base", - "//absl/meta:type_traits", - "//absl/strings", - ], -) - cc_library( name = "fast_uniform_bits", hdrs = [ @@ -221,7 +206,6 @@ cc_library( ":seed_material", "//absl/base:core_headers", "//absl/meta:type_traits", - "//absl/strings", "//absl/types:optional", "//absl/types:span", ], @@ -672,6 +656,8 @@ cc_library( copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ + ":traits", + "//absl/base:config", "//absl/meta:type_traits", ], ) diff --git a/absl/random/internal/distributions.h b/absl/random/internal/distributions.h deleted file mode 100644 index d7e3c016..00000000 --- a/absl/random/internal/distributions.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_DISTRIBUTIONS_H_ -#define ABSL_RANDOM_INTERNAL_DISTRIBUTIONS_H_ - -#include - -#include "absl/meta/type_traits.h" -#include "absl/random/internal/distribution_caller.h" -#include "absl/random/internal/traits.h" -#include "absl/random/internal/uniform_helper.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// In the absence of an explicitly provided return-type, the template -// "uniform_inferred_return_t" is used to derive a suitable type, based on -// the data-types of the endpoint-arguments {A lo, B hi}. -// -// Given endpoints {A lo, B hi}, one of {A, B} will be chosen as the -// return-type, if one type can be implicitly converted into the other, in a -// lossless way. The template "is_widening_convertible" implements the -// compile-time logic for deciding if such a conversion is possible. -// -// If no such conversion between {A, B} exists, then the overload for -// absl::Uniform() will be discarded, and the call will be ill-formed. -// Return-type for absl::Uniform() when the return-type is inferred. -template -using uniform_inferred_return_t = - absl::enable_if_t, - is_widening_convertible>::value, - typename std::conditional< - is_widening_convertible::value, B, A>::type>; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_DISTRIBUTIONS_H_ diff --git a/absl/random/internal/uniform_helper.h b/absl/random/internal/uniform_helper.h index 663107cb..5b2afecb 100644 --- a/absl/random/internal/uniform_helper.h +++ b/absl/random/internal/uniform_helper.h @@ -19,10 +19,13 @@ #include #include +#include "absl/base/config.h" #include "absl/meta/type_traits.h" +#include "absl/random/internal/traits.h" namespace absl { ABSL_NAMESPACE_BEGIN + template class uniform_int_distribution; @@ -58,6 +61,26 @@ struct IntervalOpenOpenTag : public random_internal::TagTypeCompare {}; namespace random_internal { + +// In the absence of an explicitly provided return-type, the template +// "uniform_inferred_return_t" is used to derive a suitable type, based on +// the data-types of the endpoint-arguments {A lo, B hi}. +// +// Given endpoints {A lo, B hi}, one of {A, B} will be chosen as the +// return-type, if one type can be implicitly converted into the other, in a +// lossless way. The template "is_widening_convertible" implements the +// compile-time logic for deciding if such a conversion is possible. +// +// If no such conversion between {A, B} exists, then the overload for +// absl::Uniform() will be discarded, and the call will be ill-formed. +// Return-type for absl::Uniform() when the return-type is inferred. +template +using uniform_inferred_return_t = + absl::enable_if_t, + is_widening_convertible>::value, + typename std::conditional< + is_widening_convertible::value, B, A>::type>; + // The functions // uniform_lower_bound(tag, a, b) // and @@ -149,12 +172,19 @@ uniform_upper_bound(Tag, FloatType, FloatType b) { return std::nextafter(b, (std::numeric_limits::max)()); } +// UniformDistribution selects either absl::uniform_int_distribution +// or absl::uniform_real_distribution depending on the NumType parameter. template using UniformDistribution = typename std::conditional::value, absl::uniform_int_distribution, absl::uniform_real_distribution>::type; +// UniformDistributionWrapper is used as the underlying distribution type +// by the absl::Uniform template function. It selects the proper Abseil +// uniform distribution and provides constructor overloads that match the +// expected parameter order as well as adjusting distribtuion bounds based +// on the tag. template struct UniformDistributionWrapper : public UniformDistribution { template diff --git a/absl/strings/cord.cc b/absl/strings/cord.cc index 1ddd6aec..68f53987 100644 --- a/absl/strings/cord.cc +++ b/absl/strings/cord.cc @@ -705,6 +705,37 @@ Cord::Cord(absl::string_view src) { } } +template > +Cord::Cord(T&& src) { + if ( + // String is short: copy data to avoid external block overhead. + src.size() <= kMaxBytesToCopy || + // String is wasteful: copy data to avoid pinning too much unused memory. + src.size() < src.capacity() / 2 + ) { + if (src.size() <= InlineRep::kMaxInline) { + contents_.set_data(src.data(), src.size(), false); + } else { + contents_.set_tree(NewTree(src.data(), src.size(), 0)); + } + } else { + struct StringReleaser { + void operator()(absl::string_view /* data */) {} + std::string data; + }; + const absl::string_view original_data = src; + CordRepExternal* rep = + static_cast(absl::cord_internal::NewExternalRep( + original_data, StringReleaser{std::move(src)})); + // Moving src may have invalidated its data pointer, so adjust it. + rep->base = + static_cast(GetExternalReleaser(rep))->data.data(); + contents_.set_tree(rep); + } +} + +template Cord::Cord(std::string&& src); + // The destruction code is separate so that the compiler can determine // that it does not need to call the destructor on a moved-from Cord. void Cord::DestroyCordSlow() { @@ -742,6 +773,18 @@ Cord& Cord::operator=(absl::string_view src) { return *this; } +template > +Cord& Cord::operator=(T&& src) { + if (src.size() <= kMaxBytesToCopy) { + *this = absl::string_view(src); + } else { + *this = Cord(std::move(src)); + } + return *this; +} + +template Cord& Cord::operator=(std::string&& src); + // TODO(sanjay): Move to Cord::InlineRep section of file. For now, // we keep it here to make diffs easier. void Cord::InlineRep::AppendArray(const char* src_data, size_t src_size) { @@ -853,6 +896,17 @@ void Cord::Append(const Cord& src) { AppendImpl(src); } void Cord::Append(Cord&& src) { AppendImpl(std::move(src)); } +template > +void Cord::Append(T&& src) { + if (src.size() <= kMaxBytesToCopy) { + Append(absl::string_view(src)); + } else { + Append(Cord(std::move(src))); + } +} + +template void Cord::Append(std::string&& src); + void Cord::Prepend(const Cord& src) { CordRep* src_tree = src.contents_.tree(); if (src_tree != nullptr) { @@ -882,6 +936,17 @@ void Cord::Prepend(absl::string_view src) { } } +template > +inline void Cord::Prepend(T&& src) { + if (src.size() <= kMaxBytesToCopy) { + Prepend(absl::string_view(src)); + } else { + Prepend(Cord(std::move(src))); + } +} + +template void Cord::Prepend(std::string&& src); + static CordRep* RemovePrefixFrom(CordRep* node, size_t n) { if (n >= node->length) return nullptr; if (n == 0) return Ref(node); diff --git a/absl/strings/cord.h b/absl/strings/cord.h index 3be8d7d8..dc987454 100644 --- a/absl/strings/cord.h +++ b/absl/strings/cord.h @@ -147,11 +147,8 @@ class Cord { // Creates a Cord from a `std::string&&` rvalue. These constructors are // templated to avoid ambiguities for types that are convertible to both // `absl::string_view` and `std::string`, such as `const char*`. - // - // Note that these functions reserve the right to use the `string&&`'s - // memory and that they will do so in the future. template = 0> - explicit Cord(T&& src) : Cord(absl::string_view(src)) {} + explicit Cord(T&& src); template = 0> Cord& operator=(T&& src); @@ -1048,11 +1045,8 @@ inline Cord& Cord::operator=(Cord&& x) noexcept { return *this; } -template > -inline Cord& Cord::operator=(T&& src) { - *this = absl::string_view(src); - return *this; -} +extern template Cord::Cord(std::string&& src); +extern template Cord& Cord::operator=(std::string&& src); inline size_t Cord::size() const { // Length is 1st field in str.rep_ @@ -1098,19 +1092,8 @@ inline void Cord::Append(absl::string_view src) { contents_.AppendArray(src.data(), src.size()); } -template > -inline void Cord::Append(T&& src) { - // Note that this function reserves the right to reuse the `string&&`'s - // memory and that it will do so in the future. - Append(absl::string_view(src)); -} - -template > -inline void Cord::Prepend(T&& src) { - // Note that this function reserves the right to reuse the `string&&`'s - // memory and that it will do so in the future. - Prepend(absl::string_view(src)); -} +extern template void Cord::Append(std::string&& src); +extern template void Cord::Prepend(std::string&& src); inline int Cord::Compare(const Cord& rhs) const { if (!contents_.is_tree() && !rhs.contents_.is_tree()) { diff --git a/absl/strings/str_format_test.cc b/absl/strings/str_format_test.cc index 49a68849..22cfef66 100644 --- a/absl/strings/str_format_test.cc +++ b/absl/strings/str_format_test.cc @@ -8,6 +8,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "absl/strings/cord.h" #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" @@ -353,6 +354,7 @@ TEST(StrFormat, BehavesAsDocumented) { EXPECT_EQ(StrFormat("%s", "C"), "C"); EXPECT_EQ(StrFormat("%s", std::string("C++")), "C++"); EXPECT_EQ(StrFormat("%s", string_view("view")), "view"); + EXPECT_EQ(StrFormat("%s", absl::Cord("cord")), "cord"); // Integral Conversion // These format integral types: char, int, long, uint64_t, etc. EXPECT_EQ(StrFormat("%d", char{10}), "10"); diff --git a/absl/time/internal/cctz/include/cctz/time_zone.h b/absl/time/internal/cctz/include/cctz/time_zone.h index d4ea90ef..b33e0c0a 100644 --- a/absl/time/internal/cctz/include/cctz/time_zone.h +++ b/absl/time/internal/cctz/include/cctz/time_zone.h @@ -292,6 +292,7 @@ bool parse(const std::string&, const std::string&, const time_zone&, // - %E#f - Fractional seconds with # digits of precision // - %E*f - Fractional seconds with full precision (a literal '*') // - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999) +// - %ET - The RFC3339 "date-time" separator "T" // // Note that %E0S behaves like %S, and %E0f produces no characters. In // contrast %E*f always produces at least one digit, which may be '0'. @@ -321,7 +322,7 @@ inline std::string format(const std::string& fmt, const time_point& tp, // returns the corresponding time_point. Uses strftime()-like formatting // options, with the same extensions as cctz::format(), but with the // exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f. %Ez -// and %E*z also accept the same inputs. +// and %E*z also accept the same inputs. %ET accepts either 'T' or 't'. // // %Y consumes as many numeric characters as it can, so the matching data // should always be terminated with a non-numeric. %E4Y always consumes diff --git a/absl/time/internal/cctz/src/cctz_benchmark.cc b/absl/time/internal/cctz/src/cctz_benchmark.cc index a402760d..4e39188f 100644 --- a/absl/time/internal/cctz/src/cctz_benchmark.cc +++ b/absl/time/internal/cctz/src/cctz_benchmark.cc @@ -97,8 +97,8 @@ void BM_PrevWeekday(benchmark::State& state) { } BENCHMARK(BM_PrevWeekday); -const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez"; -const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez"; +const char RFC3339_full[] = "%Y-%m-%d%ET%H:%M:%E*S%Ez"; +const char RFC3339_sec[] = "%Y-%m-%d%ET%H:%M:%S%Ez"; const char RFC1123_full[] = "%a, %d %b %Y %H:%M:%S %z"; const char RFC1123_no_wday[] = "%d %b %Y %H:%M:%S %z"; @@ -991,12 +991,12 @@ void BM_Time_FromCivilDay0_Libc(benchmark::State& state) { BENCHMARK(BM_Time_FromCivilDay0_Libc); const char* const kFormats[] = { - RFC1123_full, // 0 - RFC1123_no_wday, // 1 - RFC3339_full, // 2 - RFC3339_sec, // 3 - "%Y-%m-%dT%H:%M:%S", // 4 - "%Y-%m-%d", // 5 + RFC1123_full, // 0 + RFC1123_no_wday, // 1 + RFC3339_full, // 2 + RFC3339_sec, // 3 + "%Y-%m-%d%ET%H:%M:%S", // 4 + "%Y-%m-%d", // 5 }; const int kNumFormats = sizeof(kFormats) / sizeof(kFormats[0]); diff --git a/absl/time/internal/cctz/src/time_zone_format.cc b/absl/time/internal/cctz/src/time_zone_format.cc index 179975e0..a4428632 100644 --- a/absl/time/internal/cctz/src/time_zone_format.cc +++ b/absl/time/internal/cctz/src/time_zone_format.cc @@ -290,6 +290,7 @@ const std::int_fast64_t kExp10[kDigits10_64 + 1] = { // - %E#S - Seconds with # digits of fractional precision // - %E*S - Seconds with full fractional precision (a literal '*') // - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999) +// - %ET - The RFC3339 "date-time" separator "T" // // The standard specifiers from RFC3339_* (%Y, %m, %d, %H, %M, and %S) are // handled internally for performance reasons. strftime(3) is slow due to @@ -448,7 +449,14 @@ std::string format(const std::string& format, const time_point& tp, if (*cur != 'E' || ++cur == end) continue; // Format our extensions. - if (*cur == 'z') { + if (*cur == 'T') { + // Formats %ET. + if (cur - 2 != pending) { + FormatTM(&result, std::string(pending, cur - 2), tm); + } + result.append("T"); + pending = ++cur; + } else if (*cur == 'z') { // Formats %Ez. if (cur - 2 != pending) { FormatTM(&result, std::string(pending, cur - 2), tm); @@ -551,7 +559,7 @@ const char* ParseOffset(const char* dp, const char* mode, int* offset) { } else { dp = nullptr; } - } else if (first == 'Z') { // Zulu + } else if (first == 'Z' || first == 'z') { // Zulu *offset = 0; } else { dp = nullptr; @@ -607,7 +615,7 @@ const char* ParseTM(const char* dp, const char* fmt, std::tm* tm) { // Uses strptime(3) to parse the given input. Supports the same extended // format specifiers as format(), although %E#S and %E*S are treated // identically (and similarly for %E#f and %E*f). %Ez and %E*z also accept -// the same inputs. +// the same inputs. %ET accepts either 'T' or 't'. // // The standard specifiers from RFC3339_* (%Y, %m, %d, %H, %M, and %S) are // handled internally so that we can normally avoid strptime() altogether @@ -742,6 +750,15 @@ bool parse(const std::string& format, const std::string& input, data = (*data == '%' ? data + 1 : nullptr); continue; case 'E': + if (fmt[0] == 'T') { + if (*data == 'T' || *data == 't') { + ++data; + ++fmt; + } else { + data = nullptr; + } + continue; + } if (fmt[0] == 'z' || (fmt[0] == '*' && fmt[1] == 'z')) { data = ParseOffset(data, ":", &offset); if (data != nullptr) saw_offset = true; diff --git a/absl/time/internal/cctz/src/time_zone_format_test.cc b/absl/time/internal/cctz/src/time_zone_format_test.cc index 87382e15..13a4227e 100644 --- a/absl/time/internal/cctz/src/time_zone_format_test.cc +++ b/absl/time/internal/cctz/src/time_zone_format_test.cc @@ -48,8 +48,8 @@ namespace { EXPECT_STREQ(zone, al.abbr); \ } while (0) -const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez"; -const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez"; +const char RFC3339_full[] = "%Y-%m-%d%ET%H:%M:%E*S%Ez"; +const char RFC3339_sec[] = "%Y-%m-%d%ET%H:%M:%S%Ez"; const char RFC1123_full[] = "%a, %d %b %Y %H:%M:%S %z"; const char RFC1123_no_wday[] = "%d %b %Y %H:%M:%S %z"; @@ -1379,10 +1379,20 @@ TEST(Parse, RFC3339Format) { EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00+00:00", tz, &tp)); ExpectTime(tp, tz, 2014, 2, 12, 20, 21, 0, 0, false, "UTC"); - // Check that %Ez also accepts "Z" as a synonym for "+00:00". + // Check that %ET also accepts "t". time_point tp2; - EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00Z", tz, &tp2)); + EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12t20:21:00+00:00", tz, &tp2)); EXPECT_EQ(tp, tp2); + + // Check that %Ez also accepts "Z" as a synonym for "+00:00". + time_point tp3; + EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00Z", tz, &tp3)); + EXPECT_EQ(tp, tp3); + + // Check that %Ez also accepts "z" as a synonym for "+00:00". + time_point tp4; + EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00z", tz, &tp4)); + EXPECT_EQ(tp, tp4); } TEST(Parse, MaxRange) { diff --git a/absl/time/internal/cctz/src/time_zone_lookup_test.cc b/absl/time/internal/cctz/src/time_zone_lookup_test.cc index 0b0c1a3b..8f7ab154 100644 --- a/absl/time/internal/cctz/src/time_zone_lookup_test.cc +++ b/absl/time/internal/cctz/src/time_zone_lookup_test.cc @@ -933,7 +933,7 @@ TEST(MakeTime, Normalization) { // NOTE: Run this with -ftrapv to detect overflow problems. TEST(MakeTime, SysSecondsLimits) { - const char RFC3339[] = "%Y-%m-%dT%H:%M:%S%Ez"; + const char RFC3339[] = "%Y-%m-%d%ET%H:%M:%S%Ez"; const time_zone utc = utc_time_zone(); const time_zone east = fixed_time_zone(chrono::hours(14)); const time_zone west = fixed_time_zone(-chrono::hours(14)); -- cgit v1.2.3 From 1d31b5c365e975d3c8a8f90492c3d9de35ef024f Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 3 Jun 2020 14:03:13 -0700 Subject: Export of internal Abseil changes -- 9e8b4a286d70df9487bff080816bd07ae38af5f8 by Evan Brown : Add btree_node::transfer_n/transfer_n_backward and replace usage of uninitialized_move_n and value_destroy_n. PiperOrigin-RevId: 314600027 -- 6c452aa1ee7e46ab941ba7d1fa636da8ea3d7370 by Laramie Leavitt : Remove the MockingBitGenBase base class in favor of type-erasure in BitGenRef. In Abseil random, mocking was split across two different classes, MockingBitGenBase and MockingBitGen. This split existed because Google Mock is a test-only library that we don't link into production, so MockingBitGenBase provided a low-overhead scaffold used to lookup mocks when in test code, but which is unused in production code. That has been replaced by type-erasure which looks for a method named CallImpl with the correct signature. Weaken the coupling between MockingBitGen, DistributionCaller, and MockOverloadSet. Rename CallImpl to InvokeMock() Previously, the implementation of DistributionCaller was also split across different files using explicit instantiation of the DistributionCaller struct and some details in the Mocking classes. Now Distribution caller uses the presence of the InvokeMock() method to choose whether to use the mockable call path or the default call path. PiperOrigin-RevId: 314584095 -- 07853c47dc98698d67d65a3b9b662a65ab9def0a by Abseil Team : Add PC / backtrace / symbolization support for Apple platforms. Full backtrace support requires iOS 9+ PiperOrigin-RevId: 314415072 -- 43889f17a132b31f6558c6482721cbbc776128fd by Gennadiy Rozental : Consolidate all reflection interface in the new module 'reflection' and expose interface to locate reflection handle by name. PiperOrigin-RevId: 314390358 GitOrigin-RevId: 9e8b4a286d70df9487bff080816bd07ae38af5f8 Change-Id: I8e0910437740cf9ea9da5000adddfcef127e1158 --- CMake/AbseilDll.cmake | 2 +- absl/container/internal/btree.h | 151 +++++------- absl/debugging/BUILD.bazel | 2 + absl/debugging/CMakeLists.txt | 2 + absl/debugging/internal/examine_stack.cc | 30 +++ absl/debugging/internal/stacktrace_config.h | 21 ++ absl/debugging/internal/symbolize.h | 6 + absl/debugging/symbolize.cc | 2 + absl/debugging/symbolize_darwin.inc | 101 ++++++++ absl/debugging/symbolize_test.cc | 8 +- absl/flags/BUILD.bazel | 31 ++- absl/flags/CMakeLists.txt | 33 ++- absl/flags/commandlineflag_test.cc | 31 +-- absl/flags/flag_test.cc | 43 ++-- absl/flags/internal/registry.cc | 349 ---------------------------- absl/flags/internal/registry.h | 13 +- absl/flags/internal/type_erased.cc | 86 ------- absl/flags/internal/type_erased.h | 80 ------- absl/flags/internal/type_erased_test.cc | 156 ------------- absl/flags/internal/usage_test.cc | 12 +- absl/flags/parse.cc | 6 +- absl/flags/parse_test.cc | 2 +- absl/flags/reflection.cc | 319 +++++++++++++++++++++++++ absl/flags/reflection.h | 47 ++++ absl/flags/reflection_test.cc | 60 +++++ absl/random/BUILD.bazel | 7 +- absl/random/CMakeLists.txt | 22 +- absl/random/bit_gen_ref.h | 105 +++++---- absl/random/bit_gen_ref_test.cc | 25 +- absl/random/internal/BUILD.bazel | 17 +- absl/random/internal/distribution_caller.h | 51 +++- absl/random/internal/mock_overload_set.h | 33 ++- absl/random/internal/mocking_bit_gen_base.h | 85 ------- absl/random/mock_distributions.h | 5 + absl/random/mocking_bit_gen.h | 175 ++++++++------ 35 files changed, 1008 insertions(+), 1110 deletions(-) create mode 100644 absl/debugging/symbolize_darwin.inc delete mode 100644 absl/flags/internal/registry.cc delete mode 100644 absl/flags/internal/type_erased.cc delete mode 100644 absl/flags/internal/type_erased.h delete mode 100644 absl/flags/internal/type_erased_test.cc create mode 100644 absl/flags/reflection.cc create mode 100644 absl/flags/reflection.h create mode 100644 absl/flags/reflection_test.cc delete mode 100644 absl/random/internal/mocking_bit_gen_base.h (limited to 'absl/random/CMakeLists.txt') diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake index 8e93e794..07ae20fe 100644 --- a/CMake/AbseilDll.cmake +++ b/CMake/AbseilDll.cmake @@ -147,7 +147,6 @@ set(ABSL_INTERNAL_DLL_FILES "random/internal/platform.h" "random/internal/pool_urbg.cc" "random/internal/pool_urbg.h" - "random/internal/randen_round_keys.cc" "random/internal/randen.cc" "random/internal/randen.h" "random/internal/randen_detect.cc" @@ -155,6 +154,7 @@ set(ABSL_INTERNAL_DLL_FILES "random/internal/randen_engine.h" "random/internal/randen_hwaes.cc" "random/internal/randen_hwaes.h" + "random/internal/randen_round_keys.cc" "random/internal/randen_slow.cc" "random/internal/randen_slow.h" "random/internal/randen_traits.h" diff --git a/absl/container/internal/btree.h b/absl/container/internal/btree.h index b23138f0..f52fe235 100644 --- a/absl/container/internal/btree.h +++ b/absl/container/internal/btree.h @@ -817,33 +817,52 @@ class btree_node { absl::container_internal::SanitizerPoisonObject(slot(i)); } - // Transfers value from slot `src_i` in `src` to slot `dest_i` in `this`. - void transfer(const size_type dest_i, const size_type src_i, btree_node *src, - allocator_type *alloc) { + // Transfers value from slot `src_i` in `src_node` to slot `dest_i` in `this`. + void transfer(const size_type dest_i, const size_type src_i, + btree_node *src_node, allocator_type *alloc) { absl::container_internal::SanitizerUnpoisonObject(slot(dest_i)); - params_type::transfer(alloc, slot(dest_i), src->slot(src_i)); - absl::container_internal::SanitizerPoisonObject(src->slot(src_i)); + params_type::transfer(alloc, slot(dest_i), src_node->slot(src_i)); + absl::container_internal::SanitizerPoisonObject(src_node->slot(src_i)); } - // Move n values starting at value i in this node into the values starting at - // value j in dest_node. - void uninitialized_move_n(const size_type n, const size_type i, - const size_type j, btree_node *dest_node, - allocator_type *alloc) { + // Transfers `n` values starting at value `src_i` in `src_node` into the + // values starting at value `dest_i` in `this`. + void transfer_n(const size_type n, const size_type dest_i, + const size_type src_i, btree_node *src_node, + allocator_type *alloc) { absl::container_internal::SanitizerUnpoisonMemoryRegion( - dest_node->slot(j), n * sizeof(slot_type)); - for (slot_type *src = slot(i), *end = src + n, *dest = dest_node->slot(j); + slot(dest_i), n * sizeof(slot_type)); + for (slot_type *src = src_node->slot(src_i), *end = src + n, + *dest = slot(dest_i); src != end; ++src, ++dest) { - params_type::construct(alloc, dest, src); + params_type::transfer(alloc, dest, src); } + // We take care to avoid poisoning transferred-to nodes in case of overlap. + const size_type overlap = + this == src_node ? (std::max)(src_i, dest_i + n) - src_i : 0; + assert(n >= overlap); + absl::container_internal::SanitizerPoisonMemoryRegion( + src_node->slot(src_i + overlap), (n - overlap) * sizeof(slot_type)); } - // Destroys a range of n values, starting at index i. - void value_destroy_n(const size_type i, const size_type n, - allocator_type *alloc) { - for (int j = 0; j < n; ++j) { - value_destroy(i + j, alloc); + // Same as above, except that we start at the end and work our way to the + // beginning. + void transfer_n_backward(const size_type n, const size_type dest_i, + const size_type src_i, btree_node *src_node, + allocator_type *alloc) { + absl::container_internal::SanitizerUnpoisonMemoryRegion( + slot(dest_i), n * sizeof(slot_type)); + for (slot_type *src = src_node->slot(src_i + n - 1), *end = src - n, + *dest = slot(dest_i + n - 1); + src != end; --src, --dest) { + params_type::transfer(alloc, dest, src); } + // We take care to avoid poisoning transferred-to nodes in case of overlap. + assert(this != src_node || dest_i >= src_i); + const size_type num_to_poison = + this == src_node ? (std::min)(n, dest_i - src_i) : n; + absl::container_internal::SanitizerPoisonMemoryRegion( + src_node->slot(src_i), num_to_poison * sizeof(slot_type)); } template @@ -1531,10 +1550,8 @@ inline void btree_node

::emplace_value(const size_type i, // Shift old values to create space for new value and then construct it in // place. if (i < finish()) { - value_init(finish(), alloc, slot(finish() - 1)); - for (size_type j = finish() - 1; j > i; --j) - params_type::move(alloc, slot(j - 1), slot(j)); - value_destroy(i, alloc); + transfer_n_backward(finish() - i, /*dest_i=*/i + 1, /*src_i=*/i, this, + alloc); } value_init(i, alloc, std::forward(args)...); set_finish(finish() + 1); @@ -1564,7 +1581,9 @@ template inline void btree_node

::remove_values_ignore_children( const int i, const int to_erase, allocator_type *alloc) { params_type::move(alloc, slot(i + to_erase), finish_slot(), slot(i)); - value_destroy_n(finish() - to_erase, to_erase, alloc); + for (int j = finish() - to_erase; j < finish(); ++j) { + value_destroy(j, alloc); + } set_finish(finish() - to_erase); } @@ -1579,22 +1598,17 @@ void btree_node

::rebalance_right_to_left(const int to_move, assert(to_move <= right->count()); // 1) Move the delimiting value in the parent to the left node. - value_init(finish(), alloc, parent()->slot(position())); + transfer(finish(), position(), parent(), alloc); // 2) Move the (to_move - 1) values from the right node to the left node. - right->uninitialized_move_n(to_move - 1, right->start(), finish() + 1, this, - alloc); + transfer_n(to_move - 1, finish() + 1, right->start(), right, alloc); // 3) Move the new delimiting value to the parent from the right node. - params_type::move(alloc, right->slot(to_move - 1), - parent()->slot(position())); - - // 4) Shift the values in the right node to their correct position. - params_type::move(alloc, right->slot(to_move), right->finish_slot(), - right->start_slot()); + parent()->transfer(position(), right->start() + to_move - 1, right, alloc); - // 5) Destroy the now-empty to_move entries in the right node. - right->value_destroy_n(right->finish() - to_move, to_move, alloc); + // 4) Shift the values in the right node to their correct positions. + right->transfer_n(right->count() - to_move, right->start(), + right->start() + to_move, right, alloc); if (!leaf()) { // Move the child pointers from the right to the left node. @@ -1629,54 +1643,19 @@ void btree_node

::rebalance_left_to_right(const int to_move, // Lastly, a new delimiting value is moved from the left node into the // parent, and the remaining empty left node entries are destroyed. - if (right->count() >= to_move) { - // The original location of the right->count() values are sufficient to hold - // the new to_move entries from the parent and left node. - - // 1) Shift existing values in the right node to their correct positions. - right->uninitialized_move_n(to_move, right->finish() - to_move, - right->finish(), right, alloc); - for (slot_type *src = right->slot(right->finish() - to_move - 1), - *dest = right->slot(right->finish() - 1), - *end = right->start_slot(); - src >= end; --src, --dest) { - params_type::move(alloc, src, dest); - } - - // 2) Move the delimiting value in the parent to the right node. - params_type::move(alloc, parent()->slot(position()), - right->slot(to_move - 1)); + // 1) Shift existing values in the right node to their correct positions. + right->transfer_n_backward(right->count(), right->start() + to_move, + right->start(), right, alloc); - // 3) Move the (to_move - 1) values from the left node to the right node. - params_type::move(alloc, slot(finish() - (to_move - 1)), finish_slot(), - right->start_slot()); - } else { - // The right node does not have enough initialized space to hold the new - // to_move entries, so part of them will move to uninitialized space. - - // 1) Shift existing values in the right node to their correct positions. - right->uninitialized_move_n(right->count(), right->start(), - right->start() + to_move, right, alloc); + // 2) Move the delimiting value in the parent to the right node. + right->transfer(right->start() + to_move - 1, position(), parent(), alloc); - // 2) Move the delimiting value in the parent to the right node. - right->value_init(to_move - 1, alloc, parent()->slot(position())); - - // 3) Move the (to_move - 1) values from the left node to the right node. - const size_type uninitialized_remaining = to_move - right->count() - 1; - uninitialized_move_n(uninitialized_remaining, - finish() - uninitialized_remaining, right->finish(), - right, alloc); - params_type::move(alloc, slot(finish() - (to_move - 1)), - slot(finish() - uninitialized_remaining), - right->start_slot()); - } + // 3) Move the (to_move - 1) values from the left node to the right node. + right->transfer_n(to_move - 1, right->start(), finish() - (to_move - 1), this, + alloc); // 4) Move the new delimiting value to the parent from the left node. - params_type::move(alloc, slot(finish() - to_move), - parent()->slot(position())); - - // 5) Destroy the now-empty to_move entries in the left node. - value_destroy_n(finish() - to_move, to_move, alloc); + parent()->transfer(position(), finish() - to_move, this, alloc); if (!leaf()) { // Move the child pointers from the left to the right node. @@ -1716,10 +1695,7 @@ void btree_node

::split(const int insert_position, btree_node *dest, assert(count() >= 1); // Move values from the left sibling to the right sibling. - uninitialized_move_n(dest->count(), finish(), dest->start(), dest, alloc); - - // Destroy the now-empty entries in the left node. - value_destroy_n(finish(), dest->count(), alloc); + dest->transfer_n(dest->count(), dest->start(), finish(), this, alloc); // The split key is the largest value in the left sibling. --mutable_finish(); @@ -1746,11 +1722,7 @@ void btree_node

::merge(btree_node *src, allocator_type *alloc) { value_init(finish(), alloc, parent()->slot(position())); // Move the values from the right to the left node. - src->uninitialized_move_n(src->count(), src->start(), finish() + 1, this, - alloc); - - // Destroy the now-empty entries in the right node. - src->value_destroy_n(src->start(), src->count(), alloc); + transfer_n(src->count(), finish() + 1, src->start(), src, alloc); if (!leaf()) { // Move the child pointers from the right to the left node. @@ -2474,9 +2446,8 @@ inline auto btree

::internal_emplace(iterator iter, Args &&... args) // Transfer the values from the old root to the new root. node_type *old_root = root(); node_type *new_root = iter.node; - for (int i = old_root->start(), f = old_root->finish(); i < f; ++i) { - new_root->transfer(i, i, old_root, alloc); - } + new_root->transfer_n(old_root->count(), new_root->start(), + old_root->start(), old_root, alloc); new_root->set_finish(old_root->finish()); old_root->set_finish(old_root->start()); delete_leaf_node(old_root); diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel index 8f521bec..ff627924 100644 --- a/absl/debugging/BUILD.bazel +++ b/absl/debugging/BUILD.bazel @@ -55,6 +55,7 @@ cc_library( name = "symbolize", srcs = [ "symbolize.cc", + "symbolize_darwin.inc", "symbolize_elf.inc", "symbolize_unimplemented.inc", "symbolize_win32.inc", @@ -77,6 +78,7 @@ cc_library( "//absl/base:dynamic_annotations", "//absl/base:malloc_internal", "//absl/base:raw_logging_internal", + "//absl/strings", ], ) diff --git a/absl/debugging/CMakeLists.txt b/absl/debugging/CMakeLists.txt index 77336159..995e8887 100644 --- a/absl/debugging/CMakeLists.txt +++ b/absl/debugging/CMakeLists.txt @@ -46,6 +46,7 @@ absl_cc_library( "internal/symbolize.h" SRCS "symbolize.cc" + "symbolize_darwin.inc" "symbolize_elf.inc" "symbolize_unimplemented.inc" "symbolize_win32.inc" @@ -63,6 +64,7 @@ absl_cc_library( absl::dynamic_annotations absl::malloc_internal absl::raw_logging_internal + absl::strings PUBLIC ) diff --git a/absl/debugging/internal/examine_stack.cc b/absl/debugging/internal/examine_stack.cc index a3dd893a..6e5ff1fb 100644 --- a/absl/debugging/internal/examine_stack.cc +++ b/absl/debugging/internal/examine_stack.cc @@ -20,6 +20,10 @@ #include #endif +#ifdef __APPLE__ +#include +#endif + #include #include @@ -64,6 +68,32 @@ void* GetProgramCounter(void* vuc) { return reinterpret_cast(context->uc_mcontext.gregs[16]); #else #error "Undefined Architecture." +#endif + } +#elif defined(__APPLE__) + if (vuc != nullptr) { + ucontext_t* signal_ucontext = reinterpret_cast(vuc); +#if defined(__aarch64__) + return reinterpret_cast( + __darwin_arm_thread_state64_get_pc(signal_ucontext->uc_mcontext->__ss)); +#elif defined(__arm__) +#if __DARWIN_UNIX03 + return reinterpret_cast(signal_ucontext->uc_mcontext->__ss.__pc); +#else + return reinterpret_cast(signal_ucontext->uc_mcontext->ss.pc); +#endif +#elif defined(__i386__) +#if __DARWIN_UNIX03 + return reinterpret_cast(signal_ucontext->uc_mcontext->__ss.__eip); +#else + return reinterpret_cast(signal_ucontext->uc_mcontext->ss.eip); +#endif +#elif defined(__x86_64__) +#if __DARWIN_UNIX03 + return reinterpret_cast(signal_ucontext->uc_mcontext->__ss.__rip); +#else + return reinterpret_cast(signal_ucontext->uc_mcontext->ss.rip); +#endif #endif } #elif defined(__akaros__) diff --git a/absl/debugging/internal/stacktrace_config.h b/absl/debugging/internal/stacktrace_config.h index d4e8480a..8caa97c0 100644 --- a/absl/debugging/internal/stacktrace_config.h +++ b/absl/debugging/internal/stacktrace_config.h @@ -28,6 +28,27 @@ #define ABSL_STACKTRACE_INL_HEADER \ "absl/debugging/internal/stacktrace_win32-inl.inc" +#elif defined(__APPLE__) +// Thread local support required for UnwindImpl. +// Notes: +// * Xcode's clang did not support `thread_local` until version 8, and +// even then not for all iOS < 9.0. +// * Xcode 9.3 started disallowing `thread_local` for 32-bit iOS simulator +// targeting iOS 9.x. +// * Xcode 10 moves the deployment target check for iOS < 9.0 to link time +// making __has_feature unreliable there. +// +// Otherwise, `__has_feature` is only supported by Clang so it has be inside +// `defined(__APPLE__)` check. +#if __has_feature(cxx_thread_local) && \ + !(TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0) +#define ABSL_STACKTRACE_INL_HEADER \ + "absl/debugging/internal/stacktrace_generic-inl.inc" +#else +#define ABSL_STACKTRACE_INL_HEADER \ + "absl/debugging/internal/stacktrace_unimplemented-inl.inc" +#endif + #elif defined(__linux__) && !defined(__ANDROID__) #if !defined(NO_FRAME_POINTER) diff --git a/absl/debugging/internal/symbolize.h b/absl/debugging/internal/symbolize.h index 5d0858b5..8789e69a 100644 --- a/absl/debugging/internal/symbolize.h +++ b/absl/debugging/internal/symbolize.h @@ -59,6 +59,12 @@ ABSL_NAMESPACE_END #endif // ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE +#ifdef ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE +#error ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE cannot be directly set +#elif defined(__APPLE__) +#define ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE 1 +#endif + namespace absl { ABSL_NAMESPACE_BEGIN namespace debugging_internal { diff --git a/absl/debugging/symbolize.cc b/absl/debugging/symbolize.cc index 54ed9700..eec7a6e8 100644 --- a/absl/debugging/symbolize.cc +++ b/absl/debugging/symbolize.cc @@ -20,6 +20,8 @@ // The Windows Symbolizer only works if PDB files containing the debug info // are available to the program at runtime. #include "absl/debugging/symbolize_win32.inc" +#elif defined(__APPLE__) +#include "absl/debugging/symbolize_darwin.inc" #else #include "absl/debugging/symbolize_unimplemented.inc" #endif diff --git a/absl/debugging/symbolize_darwin.inc b/absl/debugging/symbolize_darwin.inc new file mode 100644 index 00000000..cdadd40e --- /dev/null +++ b/absl/debugging/symbolize_darwin.inc @@ -0,0 +1,101 @@ +// 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 +#include + +#include +#include + +#include "absl/base/internal/raw_logging.h" +#include "absl/debugging/internal/demangle.h" +#include "absl/strings/numbers.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +void InitializeSymbolizer(const char*) {} + +namespace debugging_internal { +namespace { + +static std::string GetSymbolString(absl::string_view backtrace_line) { + // Example Backtrace lines: + // 0 libimaging_shared.dylib 0x018c152a + // _ZNSt11_Deque_baseIN3nik7mediadb4PageESaIS2_EE17_M_initialize_mapEm + 3478 + // + // or + // 0 libimaging_shared.dylib 0x0000000001895c39 + // _ZN3nik4util19register_shared_ptrINS_3gpu7TextureEEEvPKvS5_ + 39 + // + // or + // 0 mysterious_app 0x0124000120120009 main + 17 + auto address_pos = backtrace_line.find(" 0x"); + if (address_pos == absl::string_view::npos) return std::string(); + absl::string_view symbol_view = backtrace_line.substr(address_pos + 1); + + auto space_pos = symbol_view.find(" "); + if (space_pos == absl::string_view::npos) return std::string(); + symbol_view = symbol_view.substr(space_pos + 1); // to mangled symbol + + auto plus_pos = symbol_view.find(" + "); + if (plus_pos == absl::string_view::npos) return std::string(); + symbol_view = symbol_view.substr(0, plus_pos); // strip remainng + + return std::string(symbol_view); +} + +} // namespace +} // namespace debugging_internal + +bool Symbolize(const void* pc, char* out, int out_size) { + if (out_size <= 0 || pc == nullptr) { + out = nullptr; + return false; + } + + // This allocates a char* array. + char** frame_strings = backtrace_symbols(const_cast(&pc), 1); + + if (frame_strings == nullptr) return false; + + std::string symbol = debugging_internal::GetSymbolString(frame_strings[0]); + free(frame_strings); + + char tmp_buf[1024]; + if (debugging_internal::Demangle(symbol.c_str(), tmp_buf, sizeof(tmp_buf))) { + int len = strlen(tmp_buf); + if (len + 1 <= out_size) { // +1 for '\0' + assert(len < sizeof(tmp_buf)); + memmove(out, tmp_buf, len + 1); + } + } else { + strncpy(out, symbol.c_str(), out_size); + } + + if (out[out_size - 1] != '\0') { + // strncpy() does not '\0' terminate when it truncates. + static constexpr char kEllipsis[] = "..."; + int ellipsis_size = std::min(sizeof(kEllipsis) - 1, out_size - 1); + memcpy(out + out_size - ellipsis_size - 1, kEllipsis, ellipsis_size); + out[out_size - 1] = '\0'; + } + + return true; +} + +ABSL_NAMESPACE_END +} // namespace absl diff --git a/absl/debugging/symbolize_test.cc b/absl/debugging/symbolize_test.cc index a1d03aab..e476d82a 100644 --- a/absl/debugging/symbolize_test.cc +++ b/absl/debugging/symbolize_test.cc @@ -144,7 +144,8 @@ static const char *TrySymbolize(void *pc) { return TrySymbolizeWithLimit(pc, sizeof(try_symbolize_buffer)); } -#ifdef ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE +#if defined(ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE) || \ + defined(ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE) TEST(Symbolize, Cached) { // Compilers should give us pointers to them. @@ -258,6 +259,7 @@ TEST(Symbolize, SymbolizeWithDemanglingStackConsumption) { #endif // ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION +#ifndef ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE // Use a 64K page size for PPC. const size_t kPageSize = 64 << 10; // We place a read-only symbols into the .text section and verify that we can @@ -413,6 +415,7 @@ TEST(Symbolize, ForEachSection) { close(fd); } +#endif // !ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE // x86 specific tests. Uses some inline assembler. extern "C" { @@ -541,7 +544,8 @@ int main(int argc, char **argv) { absl::InitializeSymbolizer(argv[0]); testing::InitGoogleTest(&argc, argv); -#ifdef ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE +#if defined(ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE) || \ + defined(ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE) TestWithPCInsideInlineFunction(); TestWithPCInsideNonInlineFunction(); TestWithReturnAddress(); diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel index 6ffd07ce..37c9a105 100644 --- a/absl/flags/BUILD.bazel +++ b/absl/flags/BUILD.bazel @@ -159,14 +159,13 @@ cc_library( ) cc_library( - name = "registry", + name = "reflection", srcs = [ - "internal/registry.cc", - "internal/type_erased.cc", + "reflection.cc", ], hdrs = [ "internal/registry.h", - "internal/type_erased.h", + "reflection.h", ], copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, @@ -180,7 +179,6 @@ cc_library( ":private_handle_accessor", "//absl/base:config", "//absl/base:core_headers", - "//absl/base:raw_logging_internal", "//absl/strings", "//absl/synchronization", ], @@ -202,7 +200,7 @@ cc_library( ":commandlineflag_internal", ":config", ":marshalling", - ":registry", + ":reflection", "//absl/base", "//absl/base:config", "//absl/base:core_headers", @@ -228,7 +226,7 @@ cc_library( deps = [ ":config", ":flag_internal", - ":registry", + ":reflection", "//absl/base", "//absl/base:config", "//absl/base:core_headers", @@ -257,7 +255,7 @@ cc_library( ":path_util", ":private_handle_accessor", ":program_name", - ":registry", + ":reflection", "//absl/base:config", "//absl/base:core_headers", "//absl/strings", @@ -300,7 +298,7 @@ cc_library( ":flag_internal", ":private_handle_accessor", ":program_name", - ":registry", + ":reflection", ":usage", ":usage_internal", "//absl/base:config", @@ -327,7 +325,7 @@ cc_test( ":config", ":flag", ":private_handle_accessor", - ":registry", + ":reflection", "//absl/memory", "//absl/strings", "@com_google_googletest//:gtest_main", @@ -362,7 +360,7 @@ cc_test( ":flag", ":flag_internal", ":marshalling", - ":registry", + ":reflection", "//absl/base:core_headers", "//absl/base:malloc_internal", "//absl/strings", @@ -415,7 +413,7 @@ cc_test( deps = [ ":flag", ":parse", - ":registry", + ":reflection", "//absl/base:raw_logging_internal", "//absl/base:scoped_set_env", "//absl/strings", @@ -454,17 +452,18 @@ cc_test( ) cc_test( - name = "type_erased_test", + name = "reflection_test", size = "small", srcs = [ - "internal/type_erased_test.cc", + "reflection_test.cc", ], copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":commandlineflag_internal", ":flag", - ":registry", + ":marshalling", + ":reflection", "//absl/memory", "@com_google_googletest//:gtest_main", ], @@ -501,7 +500,7 @@ cc_test( ":parse", ":path_util", ":program_name", - ":registry", + ":reflection", ":usage", ":usage_internal", "//absl/strings", diff --git a/absl/flags/CMakeLists.txt b/absl/flags/CMakeLists.txt index 2dc7cf45..ef75db8e 100644 --- a/absl/flags/CMakeLists.txt +++ b/absl/flags/CMakeLists.txt @@ -144,16 +144,14 @@ absl_cc_library( absl::strings ) -# Internal-only target, do not depend on directly. absl_cc_library( NAME - flags_registry + flags_reflection SRCS - "internal/registry.cc" - "internal/type_erased.cc" + "reflection.cc" HDRS + "reflection.h" "internal/registry.h" - "internal/type_erased.h" COPTS ${ABSL_DEFAULT_COPTS} LINKOPTS @@ -161,10 +159,8 @@ absl_cc_library( DEPS absl::config absl::flags_commandlineflag - absl::flags_config absl::flags_private_handle_accessor - absl::core_headers - absl::raw_logging_internal + absl::flags_config absl::strings absl::synchronization ) @@ -187,7 +183,6 @@ absl_cc_library( absl::flags_commandlineflag_internal absl::flags_config absl::flags_marshalling - absl::flags_registry absl::synchronization absl::meta absl::utility @@ -211,7 +206,7 @@ absl_cc_library( absl::flags_commandlineflag absl::flags_config absl::flags_internal - absl::flags_registry + absl::flags_reflection absl::base absl::core_headers absl::strings @@ -238,7 +233,7 @@ absl_cc_library( absl::flags_path_util absl::flags_private_handle_accessor absl::flags_program_name - absl::flags_registry + absl::flags_reflection absl::strings absl::synchronization ) @@ -284,7 +279,7 @@ absl_cc_library( absl::flags_internal absl::flags_private_handle_accessor absl::flags_program_name - absl::flags_registry + absl::flags_reflection absl::flags_usage absl::strings absl::synchronization @@ -306,7 +301,7 @@ absl_cc_test( absl::flags_commandlineflag_internal absl::flags_config absl::flags_private_handle_accessor - absl::flags_registry + absl::flags_reflection absl::memory absl::strings gtest_main @@ -338,7 +333,7 @@ absl_cc_test( absl::flags_config absl::flags_internal absl::flags_marshalling - absl::flags_registry + absl::flags_reflection absl::strings absl::time gtest_main @@ -366,7 +361,7 @@ absl_cc_test( DEPS absl::flags absl::flags_parse - absl::flags_registry + absl::flags_reflection absl::raw_logging_internal absl::scoped_set_env absl::span @@ -401,15 +396,15 @@ absl_cc_test( absl_cc_test( NAME - flags_type_erased_test + flags_reflection_test SRCS - "internal/type_erased_test.cc" + "reflection_test.cc" COPTS ${ABSL_TEST_COPTS} DEPS absl::flags_commandlineflag_internal absl::flags - absl::flags_registry + absl::flags_reflection absl::memory absl::strings gtest_main @@ -443,7 +438,7 @@ absl_cc_test( absl::flags_path_util absl::flags_program_name absl::flags_parse - absl::flags_registry + absl::flags_reflection absl::flags_usage absl::strings gtest diff --git a/absl/flags/commandlineflag_test.cc b/absl/flags/commandlineflag_test.cc index 570bbe2f..cc8eae91 100644 --- a/absl/flags/commandlineflag_test.cc +++ b/absl/flags/commandlineflag_test.cc @@ -22,7 +22,7 @@ #include "absl/flags/flag.h" #include "absl/flags/internal/commandlineflag.h" #include "absl/flags/internal/private_handle_accessor.h" -#include "absl/flags/internal/registry.h" +#include "absl/flags/reflection.h" #include "absl/flags/usage_config.h" #include "absl/memory/memory.h" #include "absl/strings/match.h" @@ -64,7 +64,7 @@ class CommandLineFlagTest : public testing::Test { }; TEST_F(CommandLineFlagTest, TestAttributesAccessMethods) { - auto* flag_01 = flags::FindCommandLineFlag("int_flag"); + auto* flag_01 = absl::FindCommandLineFlag("int_flag"); ASSERT_TRUE(flag_01); EXPECT_EQ(flag_01->Name(), "int_flag"); @@ -77,7 +77,7 @@ TEST_F(CommandLineFlagTest, TestAttributesAccessMethods) { "absl/flags/commandlineflag_test.cc")) << flag_01->Filename(); - auto* flag_02 = flags::FindCommandLineFlag("string_flag"); + auto* flag_02 = absl::FindCommandLineFlag("string_flag"); ASSERT_TRUE(flag_02); EXPECT_EQ(flag_02->Name(), "string_flag"); @@ -89,31 +89,20 @@ TEST_F(CommandLineFlagTest, TestAttributesAccessMethods) { EXPECT_TRUE(absl::EndsWith(flag_02->Filename(), "absl/flags/commandlineflag_test.cc")) << flag_02->Filename(); - - auto* flag_03 = flags::FindRetiredFlag("bool_retired_flag"); - - ASSERT_TRUE(flag_03); - EXPECT_EQ(flag_03->Name(), "bool_retired_flag"); - EXPECT_EQ(flag_03->Help(), ""); - EXPECT_TRUE(flag_03->IsRetired()); - EXPECT_TRUE(flag_03->IsOfType()); - EXPECT_TRUE(!flag_03->IsOfType()); - EXPECT_TRUE(!flag_03->IsOfType()); - EXPECT_EQ(flag_03->Filename(), "RETIRED"); } // -------------------------------------------------------------------- TEST_F(CommandLineFlagTest, TestValueAccessMethods) { absl::SetFlag(&FLAGS_int_flag, 301); - auto* flag_01 = flags::FindCommandLineFlag("int_flag"); + auto* flag_01 = absl::FindCommandLineFlag("int_flag"); ASSERT_TRUE(flag_01); EXPECT_EQ(flag_01->CurrentValue(), "301"); EXPECT_EQ(flag_01->DefaultValue(), "201"); absl::SetFlag(&FLAGS_string_flag, "new_str_value"); - auto* flag_02 = flags::FindCommandLineFlag("string_flag"); + auto* flag_02 = absl::FindCommandLineFlag("string_flag"); ASSERT_TRUE(flag_02); EXPECT_EQ(flag_02->CurrentValue(), "new_str_value"); @@ -125,7 +114,7 @@ TEST_F(CommandLineFlagTest, TestValueAccessMethods) { TEST_F(CommandLineFlagTest, TestParseFromCurrentValue) { std::string err; - auto* flag_01 = flags::FindCommandLineFlag("int_flag"); + auto* flag_01 = absl::FindCommandLineFlag("int_flag"); EXPECT_FALSE( flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01)); @@ -173,7 +162,7 @@ TEST_F(CommandLineFlagTest, TestParseFromCurrentValue) { *flag_01, "", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, err)); EXPECT_EQ(err, "Illegal value '' specified for flag 'int_flag'"); - auto* flag_02 = flags::FindCommandLineFlag("string_flag"); + auto* flag_02 = absl::FindCommandLineFlag("string_flag"); EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( *flag_02, "xyz", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, err)); @@ -189,14 +178,14 @@ TEST_F(CommandLineFlagTest, TestParseFromCurrentValue) { TEST_F(CommandLineFlagTest, TestParseFromDefaultValue) { std::string err; - auto* flag_01 = flags::FindCommandLineFlag("int_flag"); + auto* flag_01 = absl::FindCommandLineFlag("int_flag"); EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( *flag_01, "111", flags::SET_FLAGS_DEFAULT, flags::kProgrammaticChange, err)); EXPECT_EQ(flag_01->DefaultValue(), "111"); - auto* flag_02 = flags::FindCommandLineFlag("string_flag"); + auto* flag_02 = absl::FindCommandLineFlag("string_flag"); EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( *flag_02, "abc", flags::SET_FLAGS_DEFAULT, flags::kProgrammaticChange, @@ -209,7 +198,7 @@ TEST_F(CommandLineFlagTest, TestParseFromDefaultValue) { TEST_F(CommandLineFlagTest, TestParseFromIfDefault) { std::string err; - auto* flag_01 = flags::FindCommandLineFlag("int_flag"); + auto* flag_01 = absl::FindCommandLineFlag("int_flag"); EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( *flag_01, "22", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange, diff --git a/absl/flags/flag_test.cc b/absl/flags/flag_test.cc index 71661d39..0c88e24a 100644 --- a/absl/flags/flag_test.cc +++ b/absl/flags/flag_test.cc @@ -29,8 +29,8 @@ #include "absl/flags/config.h" #include "absl/flags/declare.h" #include "absl/flags/internal/flag.h" -#include "absl/flags/internal/registry.h" #include "absl/flags/marshalling.h" +#include "absl/flags/reflection.h" #include "absl/flags/usage_config.h" #include "absl/strings/match.h" #include "absl/strings/numbers.h" @@ -555,29 +555,29 @@ TEST_F(FlagTest, TestGetSet) { // -------------------------------------------------------------------- TEST_F(FlagTest, TestGetViaReflection) { - auto* handle = flags::FindCommandLineFlag("test_flag_01"); + auto* handle = absl::FindCommandLineFlag("test_flag_01"); EXPECT_EQ(*handle->TryGet(), true); - handle = flags::FindCommandLineFlag("test_flag_02"); + handle = absl::FindCommandLineFlag("test_flag_02"); EXPECT_EQ(*handle->TryGet(), 1234); - handle = flags::FindCommandLineFlag("test_flag_03"); + handle = absl::FindCommandLineFlag("test_flag_03"); EXPECT_EQ(*handle->TryGet(), -34); - handle = flags::FindCommandLineFlag("test_flag_04"); + handle = absl::FindCommandLineFlag("test_flag_04"); EXPECT_EQ(*handle->TryGet(), 189); - handle = flags::FindCommandLineFlag("test_flag_05"); + handle = absl::FindCommandLineFlag("test_flag_05"); EXPECT_EQ(*handle->TryGet(), 10765); - handle = flags::FindCommandLineFlag("test_flag_06"); + handle = absl::FindCommandLineFlag("test_flag_06"); EXPECT_EQ(*handle->TryGet(), 40000); - handle = flags::FindCommandLineFlag("test_flag_07"); + handle = absl::FindCommandLineFlag("test_flag_07"); EXPECT_EQ(*handle->TryGet(), -1234567); - handle = flags::FindCommandLineFlag("test_flag_08"); + handle = absl::FindCommandLineFlag("test_flag_08"); EXPECT_EQ(*handle->TryGet(), 9876543); - handle = flags::FindCommandLineFlag("test_flag_09"); + handle = absl::FindCommandLineFlag("test_flag_09"); EXPECT_NEAR(*handle->TryGet(), -9.876e-50, 1e-55); - handle = flags::FindCommandLineFlag("test_flag_10"); + handle = absl::FindCommandLineFlag("test_flag_10"); EXPECT_NEAR(*handle->TryGet(), 1.234e12f, 1e5f); - handle = flags::FindCommandLineFlag("test_flag_11"); + handle = absl::FindCommandLineFlag("test_flag_11"); EXPECT_EQ(*handle->TryGet(), ""); - handle = flags::FindCommandLineFlag("test_flag_12"); + handle = absl::FindCommandLineFlag("test_flag_12"); EXPECT_EQ(*handle->TryGet(), absl::Minutes(10)); } @@ -815,14 +815,15 @@ ABSL_RETIRED_FLAG(std::string, old_str_flag, "", absl::StrCat("old ", "descr")); namespace { TEST_F(FlagTest, TestRetiredFlagRegistration) { - bool is_bool = false; - EXPECT_TRUE(flags::IsRetiredFlag("old_bool_flag", &is_bool)); - EXPECT_TRUE(is_bool); - EXPECT_TRUE(flags::IsRetiredFlag("old_int_flag", &is_bool)); - EXPECT_FALSE(is_bool); - EXPECT_TRUE(flags::IsRetiredFlag("old_str_flag", &is_bool)); - EXPECT_FALSE(is_bool); - EXPECT_FALSE(flags::IsRetiredFlag("some_other_flag", &is_bool)); + auto* handle = absl::FindCommandLineFlag("old_bool_flag"); + EXPECT_TRUE(handle->IsOfType()); + EXPECT_TRUE(handle->IsRetired()); + handle = absl::FindCommandLineFlag("old_int_flag"); + EXPECT_TRUE(handle->IsOfType()); + EXPECT_TRUE(handle->IsRetired()); + handle = absl::FindCommandLineFlag("old_str_flag"); + EXPECT_TRUE(handle->IsOfType()); + EXPECT_TRUE(handle->IsRetired()); } } // namespace diff --git a/absl/flags/internal/registry.cc b/absl/flags/internal/registry.cc deleted file mode 100644 index e582d79d..00000000 --- a/absl/flags/internal/registry.cc +++ /dev/null @@ -1,349 +0,0 @@ -// -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/flags/internal/registry.h" - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "absl/base/config.h" -#include "absl/base/internal/raw_logging.h" -#include "absl/base/thread_annotations.h" -#include "absl/flags/commandlineflag.h" -#include "absl/flags/internal/commandlineflag.h" -#include "absl/flags/internal/private_handle_accessor.h" -#include "absl/flags/usage_config.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" -#include "absl/synchronization/mutex.h" - -// -------------------------------------------------------------------- -// FlagRegistry implementation -// A FlagRegistry holds all flag objects indexed -// by their names so that if you know a flag's name you can access or -// set it. - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace flags_internal { - -// -------------------------------------------------------------------- -// FlagRegistry -// A FlagRegistry singleton object holds all flag objects indexed -// by their names so that if you know a flag's name (as a C -// string), you can access or set it. If the function is named -// FooLocked(), you must own the registry lock before calling -// the function; otherwise, you should *not* hold the lock, and -// the function will acquire it itself if needed. -// -------------------------------------------------------------------- - -class FlagRegistry { - public: - FlagRegistry() = default; - ~FlagRegistry() = default; - - // Store a flag in this registry. Takes ownership of *flag. - void RegisterFlag(CommandLineFlag& flag); - - void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION(lock_) { lock_.Lock(); } - void Unlock() ABSL_UNLOCK_FUNCTION(lock_) { lock_.Unlock(); } - - // Returns the flag object for the specified name, or nullptr if not found. - // Will emit a warning if a 'retired' flag is specified. - CommandLineFlag* FindFlagLocked(absl::string_view name); - - // Returns the retired flag object for the specified name, or nullptr if not - // found or not retired. Does not emit a warning. - CommandLineFlag* FindRetiredFlagLocked(absl::string_view name); - - static FlagRegistry& GlobalRegistry(); // returns a singleton registry - - private: - friend class FlagSaverImpl; // reads all the flags in order to copy them - friend void ForEachFlagUnlocked( - std::function visitor); - - // The map from name to flag, for FindFlagLocked(). - using FlagMap = std::map; - using FlagIterator = FlagMap::iterator; - using FlagConstIterator = FlagMap::const_iterator; - FlagMap flags_; - - absl::Mutex lock_; - - // Disallow - FlagRegistry(const FlagRegistry&); - FlagRegistry& operator=(const FlagRegistry&); -}; - -FlagRegistry& FlagRegistry::GlobalRegistry() { - static FlagRegistry* global_registry = new FlagRegistry; - return *global_registry; -} - -namespace { - -class FlagRegistryLock { - public: - explicit FlagRegistryLock(FlagRegistry& fr) : fr_(fr) { fr_.Lock(); } - ~FlagRegistryLock() { fr_.Unlock(); } - - private: - FlagRegistry& fr_; -}; - -void DestroyRetiredFlag(CommandLineFlag& flag); - -} // namespace - -void FlagRegistry::RegisterFlag(CommandLineFlag& flag) { - FlagRegistryLock registry_lock(*this); - std::pair ins = - flags_.insert(FlagMap::value_type(flag.Name(), &flag)); - if (ins.second == false) { // means the name was already in the map - CommandLineFlag& old_flag = *ins.first->second; - if (flag.IsRetired() != old_flag.IsRetired()) { - // All registrations must agree on the 'retired' flag. - flags_internal::ReportUsageError( - absl::StrCat( - "Retired flag '", flag.Name(), "' was defined normally in file '", - (flag.IsRetired() ? old_flag.Filename() : flag.Filename()), "'."), - true); - } else if (flags_internal::PrivateHandleAccessor::TypeId(flag) != - flags_internal::PrivateHandleAccessor::TypeId(old_flag)) { - flags_internal::ReportUsageError( - absl::StrCat("Flag '", flag.Name(), - "' was defined more than once but with " - "differing types. Defined in files '", - old_flag.Filename(), "' and '", flag.Filename(), "'."), - true); - } else if (old_flag.IsRetired()) { - // Retired flag can just be deleted. - DestroyRetiredFlag(flag); - return; - } else if (old_flag.Filename() != flag.Filename()) { - flags_internal::ReportUsageError( - absl::StrCat("Flag '", flag.Name(), - "' was defined more than once (in files '", - old_flag.Filename(), "' and '", flag.Filename(), "')."), - true); - } else { - flags_internal::ReportUsageError( - absl::StrCat( - "Something wrong with flag '", flag.Name(), "' in file '", - flag.Filename(), "'. One possibility: file '", flag.Filename(), - "' is being linked both statically and dynamically into this " - "executable. e.g. some files listed as srcs to a test and also " - "listed as srcs of some shared lib deps of the same test."), - true); - } - // All cases above are fatal, except for the retired flags. - std::exit(1); - } -} - -CommandLineFlag* FlagRegistry::FindFlagLocked(absl::string_view name) { - FlagConstIterator i = flags_.find(name); - if (i == flags_.end()) { - return nullptr; - } - - if (i->second->IsRetired()) { - flags_internal::ReportUsageError( - absl::StrCat("Accessing retired flag '", name, "'"), false); - } - - return i->second; -} - -CommandLineFlag* FlagRegistry::FindRetiredFlagLocked(absl::string_view name) { - FlagConstIterator i = flags_.find(name); - if (i == flags_.end() || !i->second->IsRetired()) { - return nullptr; - } - - return i->second; -} - -// -------------------------------------------------------------------- -// FlagSaver -// FlagSaverImpl -// This class stores the states of all flags at construct time, -// and restores all flags to that state at destruct time. -// Its major implementation challenge is that it never modifies -// pointers in the 'main' registry, so global FLAG_* vars always -// point to the right place. -// -------------------------------------------------------------------- - -class FlagSaverImpl { - public: - FlagSaverImpl() = default; - FlagSaverImpl(const FlagSaverImpl&) = delete; - void operator=(const FlagSaverImpl&) = delete; - - // Saves the flag states from the flag registry into this object. - // It's an error to call this more than once. - void SaveFromRegistry() { - assert(backup_registry_.empty()); // call only once! - flags_internal::ForEachFlag([&](CommandLineFlag& flag) { - if (auto flag_state = - flags_internal::PrivateHandleAccessor::SaveState(flag)) { - backup_registry_.emplace_back(std::move(flag_state)); - } - }); - } - - // Restores the saved flag states into the flag registry. - void RestoreToRegistry() { - for (const auto& flag_state : backup_registry_) { - flag_state->Restore(); - } - } - - private: - std::vector> - backup_registry_; -}; - -FlagSaver::FlagSaver() : impl_(new FlagSaverImpl) { impl_->SaveFromRegistry(); } - -void FlagSaver::Ignore() { - delete impl_; - impl_ = nullptr; -} - -FlagSaver::~FlagSaver() { - if (!impl_) return; - - impl_->RestoreToRegistry(); - delete impl_; -} - -// -------------------------------------------------------------------- - -CommandLineFlag* FindCommandLineFlag(absl::string_view name) { - if (name.empty()) return nullptr; - FlagRegistry& registry = FlagRegistry::GlobalRegistry(); - FlagRegistryLock frl(registry); - - return registry.FindFlagLocked(name); -} - -CommandLineFlag* FindRetiredFlag(absl::string_view name) { - FlagRegistry& registry = FlagRegistry::GlobalRegistry(); - FlagRegistryLock frl(registry); - - return registry.FindRetiredFlagLocked(name); -} - -// -------------------------------------------------------------------- - -void ForEachFlagUnlocked(std::function visitor) { - FlagRegistry& registry = FlagRegistry::GlobalRegistry(); - for (FlagRegistry::FlagConstIterator i = registry.flags_.begin(); - i != registry.flags_.end(); ++i) { - visitor(*i->second); - } -} - -void ForEachFlag(std::function visitor) { - FlagRegistry& registry = FlagRegistry::GlobalRegistry(); - FlagRegistryLock frl(registry); - ForEachFlagUnlocked(visitor); -} - -// -------------------------------------------------------------------- - -bool RegisterCommandLineFlag(CommandLineFlag& flag) { - FlagRegistry::GlobalRegistry().RegisterFlag(flag); - return true; -} - -// -------------------------------------------------------------------- - -namespace { - -class RetiredFlagObj final : public CommandLineFlag { - public: - constexpr RetiredFlagObj(const char* name, FlagFastTypeId type_id) - : name_(name), type_id_(type_id) {} - - private: - absl::string_view Name() const override { return name_; } - std::string Filename() const override { return "RETIRED"; } - FlagFastTypeId TypeId() const override { return type_id_; } - std::string Help() const override { return ""; } - bool IsRetired() const override { return true; } - bool IsSpecifiedOnCommandLine() const override { return false; } - std::string DefaultValue() const override { return ""; } - std::string CurrentValue() const override { return ""; } - - // Any input is valid - bool ValidateInputValue(absl::string_view) const override { return true; } - - std::unique_ptr SaveState() override { - return nullptr; - } - - bool ParseFrom(absl::string_view, flags_internal::FlagSettingMode, - flags_internal::ValueSource, std::string&) override { - return false; - } - - void CheckDefaultValueParsingRoundtrip() const override {} - - void Read(void*) const override {} - - // Data members - const char* const name_; - const FlagFastTypeId type_id_; -}; - -void DestroyRetiredFlag(CommandLineFlag& flag) { - assert(flag.IsRetired()); - delete static_cast(&flag); -} - -} // namespace - -bool Retire(const char* name, FlagFastTypeId type_id) { - auto* flag = new flags_internal::RetiredFlagObj(name, type_id); - FlagRegistry::GlobalRegistry().RegisterFlag(*flag); - return true; -} - -// -------------------------------------------------------------------- - -bool IsRetiredFlag(absl::string_view name, bool* type_is_bool) { - assert(!name.empty()); - CommandLineFlag* flag = flags_internal::FindRetiredFlag(name); - if (flag == nullptr) { - return false; - } - assert(type_is_bool); - *type_is_bool = flag->IsOfType(); - return true; -} - -} // namespace flags_internal -ABSL_NAMESPACE_END -} // namespace absl diff --git a/absl/flags/internal/registry.h b/absl/flags/internal/registry.h index d207c225..1e655a3e 100644 --- a/absl/flags/internal/registry.h +++ b/absl/flags/internal/registry.h @@ -28,10 +28,14 @@ namespace absl { ABSL_NAMESPACE_BEGIN -namespace flags_internal { +// TODO(rogeeff): remove this declaration CommandLineFlag* FindCommandLineFlag(absl::string_view name); -CommandLineFlag* FindRetiredFlag(absl::string_view name); + +namespace flags_internal { + +// TODO(rogeeff): remove this alias +using absl::FindCommandLineFlag; // Executes specified visitor for each non-retired flag in the registry. // Requires the caller hold the registry lock. @@ -85,11 +89,6 @@ inline bool RetiredFlag(const char* flag_name) { return flags_internal::Retire(flag_name, base_internal::FastTypeId()); } -// If the flag is retired, returns true and indicates in |*type_is_bool| -// whether the type of the retired flag is a bool. -// Only to be called by code that needs to explicitly ignore retired flags. -bool IsRetiredFlag(absl::string_view name, bool* type_is_bool); - //----------------------------------------------------------------------------- // Saves the states (value, default value, whether the user has set // the flag, registered validators, etc) of all flags, and restores diff --git a/absl/flags/internal/type_erased.cc b/absl/flags/internal/type_erased.cc deleted file mode 100644 index b2523b24..00000000 --- a/absl/flags/internal/type_erased.cc +++ /dev/null @@ -1,86 +0,0 @@ -// -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/flags/internal/type_erased.h" - -#include - -#include - -#include "absl/base/config.h" -#include "absl/base/internal/raw_logging.h" -#include "absl/flags/commandlineflag.h" -#include "absl/flags/internal/private_handle_accessor.h" -#include "absl/flags/internal/registry.h" -#include "absl/flags/usage_config.h" -#include "absl/strings/string_view.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace flags_internal { - -bool GetCommandLineOption(absl::string_view name, std::string* value) { - if (name.empty()) return false; - assert(value); - - CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name); - if (flag == nullptr || flag->IsRetired()) { - return false; - } - - *value = flag->CurrentValue(); - return true; -} - -bool SetCommandLineOption(absl::string_view name, absl::string_view value) { - return SetCommandLineOptionWithMode(name, value, - flags_internal::SET_FLAGS_VALUE); -} - -bool SetCommandLineOptionWithMode(absl::string_view name, - absl::string_view value, - FlagSettingMode set_mode) { - CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name); - - if (!flag || flag->IsRetired()) return false; - - std::string error; - if (!flags_internal::PrivateHandleAccessor::ParseFrom( - *flag, value, set_mode, kProgrammaticChange, error)) { - // Errors here are all of the form: the provided name was a recognized - // flag, but the value was invalid (bad type, or validation failed). - flags_internal::ReportUsageError(error, false); - return false; - } - - return true; -} - -// -------------------------------------------------------------------- - -bool IsValidFlagValue(absl::string_view name, absl::string_view value) { - CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name); - - return flag != nullptr && - (flag->IsRetired() || - flags_internal::PrivateHandleAccessor::ValidateInputValue(*flag, - value)); -} - -// -------------------------------------------------------------------- - -} // namespace flags_internal -ABSL_NAMESPACE_END -} // namespace absl diff --git a/absl/flags/internal/type_erased.h b/absl/flags/internal/type_erased.h deleted file mode 100644 index 437a8c28..00000000 --- a/absl/flags/internal/type_erased.h +++ /dev/null @@ -1,80 +0,0 @@ -// -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_FLAGS_INTERNAL_TYPE_ERASED_H_ -#define ABSL_FLAGS_INTERNAL_TYPE_ERASED_H_ - -#include - -#include "absl/base/config.h" -#include "absl/flags/commandlineflag.h" -#include "absl/flags/internal/commandlineflag.h" -#include "absl/flags/internal/registry.h" -#include "absl/strings/string_view.h" - -// -------------------------------------------------------------------- -// Registry interfaces operating on type erased handles. - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace flags_internal { - -// If a flag named "name" exists, store its current value in *OUTPUT -// and return true. Else return false without changing *OUTPUT. -// Thread-safe. -bool GetCommandLineOption(absl::string_view name, std::string* value); - -// Set the value of the flag named "name" to value. If successful, -// returns true. If not successful (e.g., the flag was not found or -// the value is not a valid value), returns false. -// Thread-safe. -bool SetCommandLineOption(absl::string_view name, absl::string_view value); - -bool SetCommandLineOptionWithMode(absl::string_view name, - absl::string_view value, - FlagSettingMode set_mode); - -//----------------------------------------------------------------------------- - -// Returns true iff all of the following conditions are true: -// (a) "name" names a registered flag -// (b) "value" can be parsed succesfully according to the type of the flag -// (c) parsed value passes any validator associated with the flag -bool IsValidFlagValue(absl::string_view name, absl::string_view value); - -//----------------------------------------------------------------------------- - -// If a flag with specified "name" exists and has type T, store -// its current value in *dst and return true. Else return false -// without touching *dst. T must obey all of the requirements for -// types passed to DEFINE_FLAG. -template -inline bool GetByName(absl::string_view name, T* dst) { - CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name); - if (!flag) return false; - - if (auto val = flag->TryGet()) { - *dst = *val; - return true; - } - - return false; -} - -} // namespace flags_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_FLAGS_INTERNAL_TYPE_ERASED_H_ diff --git a/absl/flags/internal/type_erased_test.cc b/absl/flags/internal/type_erased_test.cc deleted file mode 100644 index 42f374dc..00000000 --- a/absl/flags/internal/type_erased_test.cc +++ /dev/null @@ -1,156 +0,0 @@ -// -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/flags/internal/type_erased.h" - -#include -#include - -#include "gtest/gtest.h" -#include "absl/flags/flag.h" -#include "absl/flags/internal/commandlineflag.h" -#include "absl/flags/internal/registry.h" -#include "absl/memory/memory.h" - -ABSL_FLAG(int, int_flag, 1, "int_flag help"); -ABSL_FLAG(std::string, string_flag, "dflt", "string_flag help"); -ABSL_RETIRED_FLAG(bool, bool_retired_flag, false, "bool_retired_flag help"); - -namespace { - -namespace flags = absl::flags_internal; - -class TypeErasedTest : public testing::Test { - protected: - void SetUp() override { flag_saver_ = absl::make_unique(); } - void TearDown() override { flag_saver_.reset(); } - - private: - std::unique_ptr flag_saver_; -}; - -// -------------------------------------------------------------------- - -TEST_F(TypeErasedTest, TestGetCommandLineOption) { - std::string value; - EXPECT_TRUE(flags::GetCommandLineOption("int_flag", &value)); - EXPECT_EQ(value, "1"); - - EXPECT_TRUE(flags::GetCommandLineOption("string_flag", &value)); - EXPECT_EQ(value, "dflt"); - - EXPECT_FALSE(flags::GetCommandLineOption("bool_retired_flag", &value)); - - EXPECT_FALSE(flags::GetCommandLineOption("unknown_flag", &value)); -} - -// -------------------------------------------------------------------- - -TEST_F(TypeErasedTest, TestSetCommandLineOption) { - EXPECT_TRUE(flags::SetCommandLineOption("int_flag", "101")); - EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 101); - - EXPECT_TRUE(flags::SetCommandLineOption("string_flag", "asdfgh")); - EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "asdfgh"); - - EXPECT_FALSE(flags::SetCommandLineOption("bool_retired_flag", "true")); - - EXPECT_FALSE(flags::SetCommandLineOption("unknown_flag", "true")); -} - -// -------------------------------------------------------------------- - -TEST_F(TypeErasedTest, TestSetCommandLineOptionWithMode_SET_FLAGS_VALUE) { - EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "101", - flags::SET_FLAGS_VALUE)); - EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 101); - - EXPECT_TRUE(flags::SetCommandLineOptionWithMode("string_flag", "asdfgh", - flags::SET_FLAGS_VALUE)); - EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "asdfgh"); - - EXPECT_FALSE(flags::SetCommandLineOptionWithMode("bool_retired_flag", "true", - flags::SET_FLAGS_VALUE)); - - EXPECT_FALSE(flags::SetCommandLineOptionWithMode("unknown_flag", "true", - flags::SET_FLAGS_VALUE)); -} - -// -------------------------------------------------------------------- - -TEST_F(TypeErasedTest, TestSetCommandLineOptionWithMode_SET_FLAG_IF_DEFAULT) { - EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "101", - flags::SET_FLAG_IF_DEFAULT)); - EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 101); - - // This semantic is broken. We return true instead of false. Value is not - // updated. - EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "202", - flags::SET_FLAG_IF_DEFAULT)); - EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 101); - - EXPECT_TRUE(flags::SetCommandLineOptionWithMode("string_flag", "asdfgh", - flags::SET_FLAG_IF_DEFAULT)); - EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "asdfgh"); - - EXPECT_FALSE(flags::SetCommandLineOptionWithMode("bool_retired_flag", "true", - flags::SET_FLAG_IF_DEFAULT)); - - EXPECT_FALSE(flags::SetCommandLineOptionWithMode("unknown_flag", "true", - flags::SET_FLAG_IF_DEFAULT)); -} - -// -------------------------------------------------------------------- - -TEST_F(TypeErasedTest, TestSetCommandLineOptionWithMode_SET_FLAGS_DEFAULT) { - EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "101", - flags::SET_FLAGS_DEFAULT)); - - // Set it again to ensure that resetting logic is covered. - EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "102", - flags::SET_FLAGS_DEFAULT)); - - EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "103", - flags::SET_FLAGS_DEFAULT)); - - EXPECT_TRUE(flags::SetCommandLineOptionWithMode("string_flag", "asdfgh", - flags::SET_FLAGS_DEFAULT)); - EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "asdfgh"); - - EXPECT_FALSE(flags::SetCommandLineOptionWithMode("bool_retired_flag", "true", - flags::SET_FLAGS_DEFAULT)); - - EXPECT_FALSE(flags::SetCommandLineOptionWithMode("unknown_flag", "true", - flags::SET_FLAGS_DEFAULT)); - - // This should be successfull, since flag is still is not set - EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "202", - flags::SET_FLAG_IF_DEFAULT)); - EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 202); -} - -// -------------------------------------------------------------------- - -TEST_F(TypeErasedTest, TestIsValidFlagValue) { - EXPECT_TRUE(flags::IsValidFlagValue("int_flag", "57")); - EXPECT_TRUE(flags::IsValidFlagValue("int_flag", "-101")); - EXPECT_FALSE(flags::IsValidFlagValue("int_flag", "1.1")); - - EXPECT_TRUE(flags::IsValidFlagValue("string_flag", "#%^#%^$%DGHDG$W%adsf")); - - EXPECT_TRUE(flags::IsValidFlagValue("bool_retired_flag", "true")); -} - -} // namespace diff --git a/absl/flags/internal/usage_test.cc b/absl/flags/internal/usage_test.cc index 53b4d983..46f85b55 100644 --- a/absl/flags/internal/usage_test.cc +++ b/absl/flags/internal/usage_test.cc @@ -25,7 +25,7 @@ #include "absl/flags/internal/parse.h" #include "absl/flags/internal/path_util.h" #include "absl/flags/internal/program_name.h" -#include "absl/flags/internal/registry.h" +#include "absl/flags/reflection.h" #include "absl/flags/usage.h" #include "absl/flags/usage_config.h" #include "absl/strings/match.h" @@ -110,7 +110,7 @@ TEST_F(UsageReportingDeathTest, TestSetProgramUsageMessage) { // -------------------------------------------------------------------- TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_01) { - const auto* flag = flags::FindCommandLineFlag("usage_reporting_test_flag_01"); + const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_01"); std::stringstream test_buf; flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable); @@ -122,7 +122,7 @@ TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_01) { } TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_02) { - const auto* flag = flags::FindCommandLineFlag("usage_reporting_test_flag_02"); + const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_02"); std::stringstream test_buf; flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable); @@ -134,7 +134,7 @@ TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_02) { } TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_03) { - const auto* flag = flags::FindCommandLineFlag("usage_reporting_test_flag_03"); + const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_03"); std::stringstream test_buf; flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable); @@ -146,7 +146,7 @@ TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_03) { } TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_04) { - const auto* flag = flags::FindCommandLineFlag("usage_reporting_test_flag_04"); + const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_04"); std::stringstream test_buf; flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable); @@ -158,7 +158,7 @@ TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_04) { } TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_05) { - const auto* flag = flags::FindCommandLineFlag("usage_reporting_test_flag_05"); + const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_05"); std::stringstream test_buf; flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable); diff --git a/absl/flags/parse.cc b/absl/flags/parse.cc index f0a131f2..e2c88ff8 100644 --- a/absl/flags/parse.cc +++ b/absl/flags/parse.cc @@ -42,8 +42,8 @@ #include "absl/flags/internal/parse.h" #include "absl/flags/internal/private_handle_accessor.h" #include "absl/flags/internal/program_name.h" -#include "absl/flags/internal/registry.h" #include "absl/flags/internal/usage.h" +#include "absl/flags/reflection.h" #include "absl/flags/usage.h" #include "absl/flags/usage_config.h" #include "absl/strings/ascii.h" @@ -290,11 +290,11 @@ std::tuple SplitNameAndValue( // found flag or nullptr // is negative in case of --nofoo std::tuple LocateFlag(absl::string_view flag_name) { - CommandLineFlag* flag = flags_internal::FindCommandLineFlag(flag_name); + CommandLineFlag* flag = absl::FindCommandLineFlag(flag_name); bool is_negative = false; if (!flag && absl::ConsumePrefix(&flag_name, "no")) { - flag = flags_internal::FindCommandLineFlag(flag_name); + flag = absl::FindCommandLineFlag(flag_name); is_negative = true; } diff --git a/absl/flags/parse_test.cc b/absl/flags/parse_test.cc index aea068ee..1ab87690 100644 --- a/absl/flags/parse_test.cc +++ b/absl/flags/parse_test.cc @@ -28,7 +28,7 @@ #include "absl/flags/declare.h" #include "absl/flags/flag.h" #include "absl/flags/internal/parse.h" -#include "absl/flags/internal/registry.h" +#include "absl/flags/reflection.h" #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" #include "absl/strings/substitute.h" diff --git a/absl/flags/reflection.cc b/absl/flags/reflection.cc new file mode 100644 index 00000000..02bb6c2e --- /dev/null +++ b/absl/flags/reflection.cc @@ -0,0 +1,319 @@ +// +// 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/reflection.h" + +#include + +#include +#include + +#include "absl/base/config.h" +#include "absl/base/thread_annotations.h" +#include "absl/flags/commandlineflag.h" +#include "absl/flags/internal/private_handle_accessor.h" +#include "absl/flags/internal/registry.h" +#include "absl/flags/usage_config.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" +#include "absl/synchronization/mutex.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace flags_internal { + +// -------------------------------------------------------------------- +// FlagRegistry +// A FlagRegistry singleton object holds all flag objects indexed by their +// names so that if you know a flag's name, you can access or set it. If the +// function is named FooLocked(), you must own the registry lock before +// calling the function; otherwise, you should *not* hold the lock, and the +// function will acquire it itself if needed. +// -------------------------------------------------------------------- + +class FlagRegistry { + public: + FlagRegistry() = default; + ~FlagRegistry() = default; + + // Store a flag in this registry. Takes ownership of *flag. + void RegisterFlag(CommandLineFlag& flag); + + void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION(lock_) { lock_.Lock(); } + void Unlock() ABSL_UNLOCK_FUNCTION(lock_) { lock_.Unlock(); } + + // Returns the flag object for the specified name, or nullptr if not found. + // Will emit a warning if a 'retired' flag is specified. + CommandLineFlag* FindFlagLocked(absl::string_view name); + + // Returns the retired flag object for the specified name, or nullptr if not + // found or not retired. Does not emit a warning. + CommandLineFlag* FindRetiredFlagLocked(absl::string_view name); + + static FlagRegistry& GlobalRegistry(); // returns a singleton registry + + private: + friend class FlagSaverImpl; // reads all the flags in order to copy them + friend void ForEachFlagUnlocked( + std::function visitor); + + // The map from name to flag, for FindFlagLocked(). + using FlagMap = std::map; + using FlagIterator = FlagMap::iterator; + using FlagConstIterator = FlagMap::const_iterator; + FlagMap flags_; + + absl::Mutex lock_; + + // Disallow + FlagRegistry(const FlagRegistry&); + FlagRegistry& operator=(const FlagRegistry&); +}; + +CommandLineFlag* FlagRegistry::FindFlagLocked(absl::string_view name) { + FlagConstIterator i = flags_.find(name); + if (i == flags_.end()) { + return nullptr; + } + + if (i->second->IsRetired()) { + flags_internal::ReportUsageError( + absl::StrCat("Accessing retired flag '", name, "'"), false); + } + + return i->second; +} + +CommandLineFlag* FlagRegistry::FindRetiredFlagLocked(absl::string_view name) { + FlagConstIterator i = flags_.find(name); + if (i == flags_.end() || !i->second->IsRetired()) { + return nullptr; + } + + return i->second; +} + +namespace { + +class FlagRegistryLock { + public: + explicit FlagRegistryLock(FlagRegistry& fr) : fr_(fr) { fr_.Lock(); } + ~FlagRegistryLock() { fr_.Unlock(); } + + private: + FlagRegistry& fr_; +}; + +void DestroyRetiredFlag(CommandLineFlag& flag); + +} // namespace + +void FlagRegistry::RegisterFlag(CommandLineFlag& flag) { + FlagRegistryLock registry_lock(*this); + std::pair ins = + flags_.insert(FlagMap::value_type(flag.Name(), &flag)); + if (ins.second == false) { // means the name was already in the map + CommandLineFlag& old_flag = *ins.first->second; + if (flag.IsRetired() != old_flag.IsRetired()) { + // All registrations must agree on the 'retired' flag. + flags_internal::ReportUsageError( + absl::StrCat( + "Retired flag '", flag.Name(), "' was defined normally in file '", + (flag.IsRetired() ? old_flag.Filename() : flag.Filename()), "'."), + true); + } else if (flags_internal::PrivateHandleAccessor::TypeId(flag) != + flags_internal::PrivateHandleAccessor::TypeId(old_flag)) { + flags_internal::ReportUsageError( + absl::StrCat("Flag '", flag.Name(), + "' was defined more than once but with " + "differing types. Defined in files '", + old_flag.Filename(), "' and '", flag.Filename(), "'."), + true); + } else if (old_flag.IsRetired()) { + // Retired flag can just be deleted. + DestroyRetiredFlag(flag); + return; + } else if (old_flag.Filename() != flag.Filename()) { + flags_internal::ReportUsageError( + absl::StrCat("Flag '", flag.Name(), + "' was defined more than once (in files '", + old_flag.Filename(), "' and '", flag.Filename(), "')."), + true); + } else { + flags_internal::ReportUsageError( + absl::StrCat( + "Something wrong with flag '", flag.Name(), "' in file '", + flag.Filename(), "'. One possibility: file '", flag.Filename(), + "' is being linked both statically and dynamically into this " + "executable. e.g. some files listed as srcs to a test and also " + "listed as srcs of some shared lib deps of the same test."), + true); + } + // All cases above are fatal, except for the retired flags. + std::exit(1); + } +} + +FlagRegistry& FlagRegistry::GlobalRegistry() { + static FlagRegistry* global_registry = new FlagRegistry; + return *global_registry; +} + +// -------------------------------------------------------------------- + +void ForEachFlagUnlocked(std::function visitor) { + FlagRegistry& registry = FlagRegistry::GlobalRegistry(); + for (FlagRegistry::FlagConstIterator i = registry.flags_.begin(); + i != registry.flags_.end(); ++i) { + visitor(*i->second); + } +} + +void ForEachFlag(std::function visitor) { + FlagRegistry& registry = FlagRegistry::GlobalRegistry(); + FlagRegistryLock frl(registry); + ForEachFlagUnlocked(visitor); +} + +// -------------------------------------------------------------------- + +bool RegisterCommandLineFlag(CommandLineFlag& flag) { + FlagRegistry::GlobalRegistry().RegisterFlag(flag); + return true; +} + +// -------------------------------------------------------------------- + +namespace { + +class RetiredFlagObj final : public CommandLineFlag { + public: + constexpr RetiredFlagObj(const char* name, FlagFastTypeId type_id) + : name_(name), type_id_(type_id) {} + + private: + absl::string_view Name() const override { return name_; } + std::string Filename() const override { return "RETIRED"; } + FlagFastTypeId TypeId() const override { return type_id_; } + std::string Help() const override { return ""; } + bool IsRetired() const override { return true; } + bool IsSpecifiedOnCommandLine() const override { return false; } + std::string DefaultValue() const override { return ""; } + std::string CurrentValue() const override { return ""; } + + // Any input is valid + bool ValidateInputValue(absl::string_view) const override { return true; } + + std::unique_ptr SaveState() override { + return nullptr; + } + + bool ParseFrom(absl::string_view, flags_internal::FlagSettingMode, + flags_internal::ValueSource, std::string&) override { + return false; + } + + void CheckDefaultValueParsingRoundtrip() const override {} + + void Read(void*) const override {} + + // Data members + const char* const name_; + const FlagFastTypeId type_id_; +}; + +void DestroyRetiredFlag(CommandLineFlag& flag) { + assert(flag.IsRetired()); + delete static_cast(&flag); +} + +} // namespace + +bool Retire(const char* name, FlagFastTypeId type_id) { + auto* flag = new flags_internal::RetiredFlagObj(name, type_id); + FlagRegistry::GlobalRegistry().RegisterFlag(*flag); + return true; +} + +// -------------------------------------------------------------------- + +// FlagSaver +// FlagSaverImpl +// This class stores the states of all flags at construct time, +// and restores all flags to that state at destruct time. +// Its major implementation challenge is that it never modifies +// pointers in the 'main' registry, so global FLAG_* vars always +// point to the right place. +// -------------------------------------------------------------------- + +class FlagSaverImpl { + public: + FlagSaverImpl() = default; + FlagSaverImpl(const FlagSaverImpl&) = delete; + void operator=(const FlagSaverImpl&) = delete; + + // Saves the flag states from the flag registry into this object. + // It's an error to call this more than once. + void SaveFromRegistry() { + assert(backup_registry_.empty()); // call only once! + flags_internal::ForEachFlag([&](CommandLineFlag& flag) { + if (auto flag_state = + flags_internal::PrivateHandleAccessor::SaveState(flag)) { + backup_registry_.emplace_back(std::move(flag_state)); + } + }); + } + + // Restores the saved flag states into the flag registry. + void RestoreToRegistry() { + for (const auto& flag_state : backup_registry_) { + flag_state->Restore(); + } + } + + private: + std::vector> + backup_registry_; +}; + +FlagSaver::FlagSaver() : impl_(new FlagSaverImpl) { impl_->SaveFromRegistry(); } + +void FlagSaver::Ignore() { + delete impl_; + impl_ = nullptr; +} + +FlagSaver::~FlagSaver() { + if (!impl_) return; + + impl_->RestoreToRegistry(); + delete impl_; +} + +// -------------------------------------------------------------------- + +} // namespace flags_internal + +CommandLineFlag* FindCommandLineFlag(absl::string_view name) { + if (name.empty()) return nullptr; + flags_internal::FlagRegistry& registry = + flags_internal::FlagRegistry::GlobalRegistry(); + flags_internal::FlagRegistryLock frl(registry); + + return registry.FindFlagLocked(name); +} + +ABSL_NAMESPACE_END +} // namespace absl diff --git a/absl/flags/reflection.h b/absl/flags/reflection.h new file mode 100644 index 00000000..e8e24f68 --- /dev/null +++ b/absl/flags/reflection.h @@ -0,0 +1,47 @@ +// +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ----------------------------------------------------------------------------- +// File: reflection.h +// ----------------------------------------------------------------------------- +// +// This file defines the routines to access and operate on an Abseil Flag's +// reflection handle. + +#ifndef ABSL_FLAGS_REFLECTION_H_ +#define ABSL_FLAGS_REFLECTION_H_ + +#include + +#include "absl/base/config.h" +#include "absl/flags/commandlineflag.h" +#include "absl/flags/internal/commandlineflag.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +// FindCommandLineFlag() +// +// Returns the reflection handle of an Abseil flag of the specified name, or +// `nullptr` if not found. This function will emit a warning if the name of a +// 'retired' flag is specified. +CommandLineFlag* FindCommandLineFlag(absl::string_view name); + +//----------------------------------------------------------------------------- + +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_FLAGS_REFLECTION_H_ diff --git a/absl/flags/reflection_test.cc b/absl/flags/reflection_test.cc new file mode 100644 index 00000000..2a137bf7 --- /dev/null +++ b/absl/flags/reflection_test.cc @@ -0,0 +1,60 @@ +// +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/flags/reflection.h" + +#include +#include + +#include "gtest/gtest.h" +#include "absl/flags/flag.h" +#include "absl/flags/internal/commandlineflag.h" +#include "absl/flags/marshalling.h" +#include "absl/memory/memory.h" + +ABSL_FLAG(int, int_flag, 1, "int_flag help"); +ABSL_FLAG(std::string, string_flag, "dflt", "string_flag help"); +ABSL_RETIRED_FLAG(bool, bool_retired_flag, false, "bool_retired_flag help"); + +namespace { + +namespace flags = absl::flags_internal; + +class ReflectionTest : public testing::Test { + protected: + void SetUp() override { flag_saver_ = absl::make_unique(); } + void TearDown() override { flag_saver_.reset(); } + + private: + std::unique_ptr flag_saver_; +}; + +// -------------------------------------------------------------------- + +TEST_F(ReflectionTest, TestFindCommandLineFlag) { + auto* handle = absl::FindCommandLineFlag("some_flag"); + EXPECT_EQ(handle, nullptr); + + handle = absl::FindCommandLineFlag("int_flag"); + EXPECT_NE(handle, nullptr); + + handle = absl::FindCommandLineFlag("string_flag"); + EXPECT_NE(handle, nullptr); + + handle = absl::FindCommandLineFlag("bool_retired_flag"); + EXPECT_NE(handle, nullptr); +} + +} // namespace diff --git a/absl/random/BUILD.bazel b/absl/random/BUILD.bazel index 4b804c86..694331c2 100644 --- a/absl/random/BUILD.bazel +++ b/absl/random/BUILD.bazel @@ -115,11 +115,12 @@ cc_library( copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ + ":random", "//absl/base:core_headers", + "//absl/base:fast_type_id", "//absl/meta:type_traits", "//absl/random/internal:distribution_caller", "//absl/random/internal:fast_uniform_bits", - "//absl/random/internal:mocking_bit_gen_base", ], ) @@ -145,10 +146,11 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":distributions", + ":random", + "//absl/base:fast_type_id", "//absl/container:flat_hash_map", "//absl/meta:type_traits", "//absl/random/internal:distribution_caller", - "//absl/random/internal:mocking_bit_gen_base", "//absl/strings", "//absl/types:span", "//absl/types:variant", @@ -410,6 +412,7 @@ cc_test( deps = [ ":bit_gen_ref", ":random", + "//absl/base:fast_type_id", "//absl/random/internal:sequence_urbg", "@com_google_googletest//:gtest_main", ], diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt index 85a2ea37..8875b309 100644 --- a/absl/random/CMakeLists.txt +++ b/absl/random/CMakeLists.txt @@ -45,7 +45,6 @@ absl_cc_library( absl::core_headers absl::random_internal_distribution_caller absl::random_internal_fast_uniform_bits - absl::random_internal_mocking_bit_gen_base absl::type_traits ) @@ -62,25 +61,11 @@ absl_cc_test( absl::random_bit_gen_ref absl::random_random absl::random_internal_sequence_urbg + absl::fast_type_id gmock gtest_main ) -# Internal-only target, do not depend on directly. -absl_cc_library( - NAME - random_internal_mocking_bit_gen_base - HDRS - "internal/mocking_bit_gen_base.h" - COPTS - ${ABSL_DEFAULT_COPTS} - LINKOPTS - ${ABSL_DEFAULT_LINKOPTS} - DEPS - absl::random_random - absl::strings -) - # Internal-only target, do not depend on directly. absl_cc_library( NAME @@ -93,6 +78,7 @@ absl_cc_library( ${ABSL_DEFAULT_LINKOPTS} DEPS absl::random_mocking_bit_gen + absl::fast_type_id TESTONLY ) @@ -111,8 +97,8 @@ absl_cc_library( absl::raw_logging_internal absl::random_distributions absl::random_internal_distribution_caller - absl::random_internal_mocking_bit_gen_base absl::random_internal_mock_overload_set + absl::random_random absl::strings absl::span absl::type_traits @@ -533,6 +519,8 @@ absl_cc_library( ${ABSL_DEFAULT_LINKOPTS} DEPS absl::config + absl::utility + absl::fast_type_id ) # Internal-only target, do not depend on directly. diff --git a/absl/random/bit_gen_ref.h b/absl/random/bit_gen_ref.h index 59591a47..00e36248 100644 --- a/absl/random/bit_gen_ref.h +++ b/absl/random/bit_gen_ref.h @@ -24,11 +24,11 @@ #ifndef ABSL_RANDOM_BIT_GEN_REF_H_ #define ABSL_RANDOM_BIT_GEN_REF_H_ +#include "absl/base/internal/fast_type_id.h" #include "absl/base/macros.h" #include "absl/meta/type_traits.h" #include "absl/random/internal/distribution_caller.h" #include "absl/random/internal/fast_uniform_bits.h" -#include "absl/random/internal/mocking_bit_gen_base.h" namespace absl { ABSL_NAMESPACE_BEGIN @@ -51,6 +51,9 @@ struct is_urbg< typename std::decay()())>::type>::value>> : std::true_type {}; +template +struct DistributionCaller; + } // namespace random_internal // ----------------------------------------------------------------------------- @@ -77,23 +80,50 @@ struct is_urbg< // } // class BitGenRef { - public: - using result_type = uint64_t; + // SFINAE to detect whether the URBG type includes a member matching + // bool InvokeMock(base_internal::FastTypeIdType, void*, void*). + // + // These live inside BitGenRef so that they have friend access + // to MockingBitGen. (see similar methods in DistributionCaller). + template